aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7115.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-09-30 23:45:41 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-30 23:45:41 -0400
commit1c7da74c4aab595a994beb5fe728ebf0d0b41f59 (patch)
tree64128abdf9550ebb51d8f3ee6732d7350b9c62f2 /drivers/media/video/saa7115.c
parentaebb1153ac54ddbbd3d3f0481a193f4bf0ead53b (diff)
parent1bdfd554be94def718323659173517c5d4a69d25 (diff)
Merge branch 'master' into upstream
Diffstat (limited to 'drivers/media/video/saa7115.c')
-rw-r--r--drivers/media/video/saa7115.c1250
1 files changed, 702 insertions, 548 deletions
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index b59c11717273..974179d4d389 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1,4 +1,6 @@
1/* saa7115 - Philips SAA7113/SAA7114/SAA7115 video decoder driver 1/* saa711x - Philips SAA711x video decoder driver
2 * This driver can work with saa7111, saa7111a, saa7113, saa7114,
3 * saa7115 and saa7118.
2 * 4 *
3 * Based on saa7114 driver by Maxim Yevtyushkin, which is based on 5 * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
4 * the saa7111 driver by Dave Perks. 6 * the saa7111 driver by Dave Perks.
@@ -16,7 +18,9 @@
16 * (2/17/2003) 18 * (2/17/2003)
17 * 19 *
18 * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl> 20 * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
19 * SAA7113 support by Mauro Carvalho Chehab <mchehab@infradead.org> 21 *
22 * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
23 * SAA7111, SAA7113 and SAA7118 support
20 * 24 *
21 * This program is free software; you can redistribute it and/or 25 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License 26 * modify it under the terms of the GNU General Public License
@@ -33,6 +37,7 @@
33 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 37 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
34 */ 38 */
35 39
40#include "saa711x_regs.h"
36 41
37#include <linux/kernel.h> 42#include <linux/kernel.h>
38#include <linux/module.h> 43#include <linux/module.h>
@@ -43,7 +48,9 @@
43#include <media/saa7115.h> 48#include <media/saa7115.h>
44#include <asm/div64.h> 49#include <asm/div64.h>
45 50
46MODULE_DESCRIPTION("Philips SAA7113/SAA7114/SAA7115 video decoder driver"); 51#define VRES_60HZ (480+16)
52
53MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
47MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, " 54MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
48 "Hans Verkuil, Mauro Carvalho Chehab"); 55 "Hans Verkuil, Mauro Carvalho Chehab");
49MODULE_LICENSE("GPL"); 56MODULE_LICENSE("GPL");
@@ -54,14 +61,14 @@ module_param(debug, bool, 0644);
54MODULE_PARM_DESC(debug, "Debug level (0-1)"); 61MODULE_PARM_DESC(debug, "Debug level (0-1)");
55 62
56static unsigned short normal_i2c[] = { 63static unsigned short normal_i2c[] = {
57 0x4a >> 1, 0x48 >> 1, /* SAA7113 */ 64 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
58 0x42 >> 1, 0x40 >> 1, /* SAA7114 and SAA7115 */ 65 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
59 I2C_CLIENT_END }; 66 I2C_CLIENT_END };
60 67
61 68
62I2C_CLIENT_INSMOD; 69I2C_CLIENT_INSMOD;
63 70
64struct saa7115_state { 71struct saa711x_state {
65 v4l2_std_id std; 72 v4l2_std_id std;
66 int input; 73 int input;
67 int enable; 74 int enable;
@@ -70,6 +77,8 @@ struct saa7115_state {
70 int contrast; 77 int contrast;
71 int hue; 78 int hue;
72 int sat; 79 int sat;
80 int width;
81 int height;
73 enum v4l2_chip_ident ident; 82 enum v4l2_chip_ident ident;
74 u32 audclk_freq; 83 u32 audclk_freq;
75 u32 crystal_freq; 84 u32 crystal_freq;
@@ -80,420 +89,508 @@ struct saa7115_state {
80 89
81/* ----------------------------------------------------------------------- */ 90/* ----------------------------------------------------------------------- */
82 91
83static inline int saa7115_write(struct i2c_client *client, u8 reg, u8 value) 92static inline int saa711x_write(struct i2c_client *client, u8 reg, u8 value)
84{ 93{
85 return i2c_smbus_write_byte_data(client, reg, value); 94 return i2c_smbus_write_byte_data(client, reg, value);
86} 95}
87 96
88static int saa7115_writeregs(struct i2c_client *client, const unsigned char *regs) 97/* Sanity routine to check if a register is present */
98static int saa711x_has_reg(const int id, const u8 reg)
89{ 99{
100 if (id == V4L2_IDENT_SAA7111)
101 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
102 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
103
104 /* common for saa7113/4/5/8 */
105 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
106 reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
107 reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
108 reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
109 return 0;
110
111 switch (id) {
112 case V4L2_IDENT_SAA7113:
113 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
114 reg != 0x5d && reg < 0x63;
115 case V4L2_IDENT_SAA7114:
116 return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
117 (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
118 reg != 0x81 && reg < 0xf0;
119 case V4L2_IDENT_SAA7115:
120 return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
121 case V4L2_IDENT_SAA7118:
122 return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
123 (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
124 (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
125 }
126 return 1;
127}
128
129static int saa711x_writeregs(struct i2c_client *client, const unsigned char *regs)
130{
131 struct saa711x_state *state = i2c_get_clientdata(client);
90 unsigned char reg, data; 132 unsigned char reg, data;
91 133
92 while (*regs != 0x00) { 134 while (*regs != 0x00) {
93 reg = *(regs++); 135 reg = *(regs++);
94 data = *(regs++); 136 data = *(regs++);
95 if (saa7115_write(client, reg, data) < 0) 137
96 return -1; 138 /* According with datasheets, reserved regs should be
139 filled with 0 - seems better not to touch on they */
140 if (saa711x_has_reg(state->ident,reg)) {
141 if (saa711x_write(client, reg, data) < 0)
142 return -1;
143 } else {
144 v4l_dbg(1, debug, client, "tried to access reserved reg 0x%02x\n", reg);
145 }
97 } 146 }
98 return 0; 147 return 0;
99} 148}
100 149
101static inline int saa7115_read(struct i2c_client *client, u8 reg) 150static inline int saa711x_read(struct i2c_client *client, u8 reg)
102{ 151{
103 return i2c_smbus_read_byte_data(client, reg); 152 return i2c_smbus_read_byte_data(client, reg);
104} 153}
105 154
106/* ----------------------------------------------------------------------- */ 155/* ----------------------------------------------------------------------- */
107 156
157/* SAA7111 initialization table */
158static const unsigned char saa7111_init[] = {
159 R_01_INC_DELAY, 0x00, /* reserved */
160
161 /*front end */
162 R_02_INPUT_CNTL_1, 0xd0, /* FUSE=3, GUDL=2, MODE=0 */
163 R_03_INPUT_CNTL_2, 0x23, /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,
164 * GAFIX=0, GAI1=256, GAI2=256 */
165 R_04_INPUT_CNTL_3, 0x00, /* GAI1=256 */
166 R_05_INPUT_CNTL_4, 0x00, /* GAI2=256 */
167
168 /* decoder */
169 R_06_H_SYNC_START, 0xf3, /* HSB at 13(50Hz) / 17(60Hz)
170 * pixels after end of last line */
171 R_07_H_SYNC_STOP, 0xe8, /* HSS seems to be needed to
172 * work with NTSC, too */
173 R_08_SYNC_CNTL, 0xc8, /* AUFD=1, FSEL=1, EXFIL=0,
174 * VTRC=1, HPLL=0, VNOI=0 */
175 R_09_LUMA_CNTL, 0x01, /* BYPS=0, PREF=0, BPSS=0,
176 * VBLB=0, UPTCV=0, APER=1 */
177 R_0A_LUMA_BRIGHT_CNTL, 0x80,
178 R_0B_LUMA_CONTRAST_CNTL, 0x47, /* 0b - CONT=1.109 */
179 R_0C_CHROMA_SAT_CNTL, 0x40,
180 R_0D_CHROMA_HUE_CNTL, 0x00,
181 R_0E_CHROMA_CNTL_1, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
182 * FCTC=0, CHBW=1 */
183 R_0F_CHROMA_GAIN_CNTL, 0x00, /* reserved */
184 R_10_CHROMA_CNTL_2, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
185 R_11_MODE_DELAY_CNTL, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
186 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
187 R_12_RT_SIGNAL_CNTL, 0x00, /* 12 - output control 2 */
188 R_13_RT_X_PORT_OUT_CNTL, 0x00, /* 13 - output control 3 */
189 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
190 R_15_VGATE_START_FID_CHG, 0x00,
191 R_16_VGATE_STOP, 0x00,
192 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
193
194 0x00, 0x00
195};
196
197/* SAA7113 init codes */
198static const unsigned char saa7113_init[] = {
199 R_01_INC_DELAY, 0x08,
200 R_02_INPUT_CNTL_1, 0xc2,
201 R_03_INPUT_CNTL_2, 0x30,
202 R_04_INPUT_CNTL_3, 0x00,
203 R_05_INPUT_CNTL_4, 0x00,
204 R_06_H_SYNC_START, 0x89,
205 R_07_H_SYNC_STOP, 0x0d,
206 R_08_SYNC_CNTL, 0x88,
207 R_09_LUMA_CNTL, 0x01,
208 R_0A_LUMA_BRIGHT_CNTL, 0x80,
209 R_0B_LUMA_CONTRAST_CNTL, 0x47,
210 R_0C_CHROMA_SAT_CNTL, 0x40,
211 R_0D_CHROMA_HUE_CNTL, 0x00,
212 R_0E_CHROMA_CNTL_1, 0x01,
213 R_0F_CHROMA_GAIN_CNTL, 0x2a,
214 R_10_CHROMA_CNTL_2, 0x08,
215 R_11_MODE_DELAY_CNTL, 0x0c,
216 R_12_RT_SIGNAL_CNTL, 0x07,
217 R_13_RT_X_PORT_OUT_CNTL, 0x00,
218 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
219 R_15_VGATE_START_FID_CHG, 0x00,
220 R_16_VGATE_STOP, 0x00,
221 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
222
223 0x00, 0x00
224};
225
108/* If a value differs from the Hauppauge driver values, then the comment starts with 226/* If a value differs from the Hauppauge driver values, then the comment starts with
109 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the 227 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
110 Hauppauge driver sets. */ 228 Hauppauge driver sets. */
111 229
230/* SAA7114 and SAA7115 initialization table */
112static const unsigned char saa7115_init_auto_input[] = { 231static const unsigned char saa7115_init_auto_input[] = {
113 /* Front-End Part */ 232 /* Front-End Part */
114 0x01, 0x48, /* white peak control disabled */ 233 R_01_INC_DELAY, 0x48, /* white peak control disabled */
115 0x03, 0x20, /* was 0x30. 0x20: long vertical blanking */ 234 R_03_INPUT_CNTL_2, 0x20, /* was 0x30. 0x20: long vertical blanking */
116 0x04, 0x90, /* analog gain set to 0 */ 235 R_04_INPUT_CNTL_3, 0x90, /* analog gain set to 0 */
117 0x05, 0x90, /* analog gain set to 0 */ 236 R_05_INPUT_CNTL_4, 0x90, /* analog gain set to 0 */
118 /* Decoder Part */ 237 /* Decoder Part */
119 0x06, 0xeb, /* horiz sync begin = -21 */ 238 R_06_H_SYNC_START, 0xeb, /* horiz sync begin = -21 */
120 0x07, 0xe0, /* horiz sync stop = -17 */ 239 R_07_H_SYNC_STOP, 0xe0, /* horiz sync stop = -17 */
121 0x0a, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */ 240 R_09_LUMA_CNTL, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
122 0x0b, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */ 241 R_0A_LUMA_BRIGHT_CNTL, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
123 0x0c, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */ 242 R_0B_LUMA_CONTRAST_CNTL, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
124 0x0d, 0x00, /* chrominance hue control */ 243 R_0C_CHROMA_SAT_CNTL, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
125 0x0f, 0x00, /* chrominance gain control: use automicatic mode */ 244 R_0D_CHROMA_HUE_CNTL, 0x00,
126 0x10, 0x06, /* chrominance/luminance control: active adaptive combfilter */ 245 R_0F_CHROMA_GAIN_CNTL, 0x00, /* use automatic gain */
127 0x11, 0x00, /* delay control */ 246 R_10_CHROMA_CNTL_2, 0x06, /* chroma: active adaptive combfilter */
128 0x12, 0x9d, /* RTS0 output control: VGATE */ 247 R_11_MODE_DELAY_CNTL, 0x00,
129 0x13, 0x80, /* X-port output control: ITU656 standard mode, RTCO output enable RTCE */ 248 R_12_RT_SIGNAL_CNTL, 0x9d, /* RTS0 output control: VGATE */
130 0x14, 0x00, /* analog/ADC/auto compatibility control */ 249 R_13_RT_X_PORT_OUT_CNTL, 0x80, /* ITU656 standard mode, RTCO output enable RTCE */
131 0x18, 0x40, /* raw data gain 0x00 = nominal */ 250 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
132 0x19, 0x80, /* raw data offset 0x80 = 0 LSB */ 251 R_18_RAW_DATA_GAIN_CNTL, 0x40, /* gain 0x00 = nominal */
133 0x1a, 0x77, /* color killer level control 0x77 = recommended */ 252 R_19_RAW_DATA_OFF_CNTL, 0x80,
134 0x1b, 0x42, /* misc chroma control 0x42 = recommended */ 253 R_1A_COLOR_KILL_LVL_CNTL, 0x77, /* recommended value */
135 0x1c, 0xa9, /* combfilter control 0xA9 = recommended */ 254 R_1B_MISC_TVVCRDET, 0x42, /* recommended value */
136 0x1d, 0x01, /* combfilter control 0x01 = recommended */ 255 R_1C_ENHAN_COMB_CTRL1, 0xa9, /* recommended value */
256 R_1D_ENHAN_COMB_CTRL2, 0x01, /* recommended value */
257
258
259 R_80_GLOBAL_CNTL_1, 0x0, /* No tasks enabled at init */
137 260
138 /* Power Device Control */ 261 /* Power Device Control */
139 0x88, 0xd0, /* reset device */ 262 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset device */
140 0x88, 0xf0, /* set device programmed, all in operational mode */ 263 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* set device programmed, all in operational mode */
141 0x00, 0x00 264 0x00, 0x00
142}; 265};
143 266
267/* Used to reset saa7113, saa7114 and saa7115 */
144static const unsigned char saa7115_cfg_reset_scaler[] = { 268static const unsigned char saa7115_cfg_reset_scaler[] = {
145 0x87, 0x00, /* disable I-port output */ 269 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00, /* disable I-port output */
146 0x88, 0xd0, /* reset scaler */ 270 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
147 0x88, 0xf0, /* activate scaler */ 271 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
148 0x87, 0x01, /* enable I-port output */ 272 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* enable I-port output */
149 0x00, 0x00 273 0x00, 0x00
150}; 274};
151 275
152/* ============== SAA7715 VIDEO templates ============= */ 276/* ============== SAA7715 VIDEO templates ============= */
153 277
154static const unsigned char saa7115_cfg_60hz_fullres_x[] = { 278static const unsigned char saa7115_cfg_60hz_video[] = {
155 0xcc, 0xd0, /* hsize low (output), hor. output window size = 0x2d0 = 720 */ 279 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
156 0xcd, 0x02, /* hsize hi (output) */ 280 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
157 281
158 /* Why not in 60hz-Land, too? */ 282 R_15_VGATE_START_FID_CHG, 0x03,
159 0xd0, 0x01, /* downscale = 1 */ 283 R_16_VGATE_STOP, 0x11,
160 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */ 284 R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
161 0xd9, 0x04,
162 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
163 0xdd, 0x02, /* H-scaling incr chroma */
164 285
165 0x00, 0x00 286 R_08_SYNC_CNTL, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
166}; 287 R_0E_CHROMA_CNTL_1, 0x07, /* video autodetection is on */
167static const unsigned char saa7115_cfg_60hz_fullres_y[] = {
168 0xce, 0xf8, /* vsize low (output), ver. output window size = 248 (but 60hz is 240?) */
169 0xcf, 0x00, /* vsize hi (output) */
170 288
171 /* Why not in 60hz-Land, too? */ 289 R_5A_V_OFF_FOR_SLICER, 0x06, /* standard 60hz value for ITU656 line counting */
172 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */
173 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */
174 290
175 0xe0, 0x00, /* V-scaling incr luma low */ 291 /* Task A */
176 0xe1, 0x04, /* " hi */ 292 R_90_A_TASK_HANDLING_CNTL, 0x80,
177 0xe2, 0x00, /* V-scaling incr chroma low */ 293 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
178 0xe3, 0x04, /* " hi */ 294 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
295 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
179 296
180 0x00, 0x00 297 /* hoffset low (input), 0x0002 is minimum */
181}; 298 R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,
299 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
182 300
183static const unsigned char saa7115_cfg_60hz_video[] = { 301 /* hsize low (input), 0x02d0 = 720 */
184 0x80, 0x00, /* reset tasks */ 302 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
185 0x88, 0xd0, /* reset scaler */ 303 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
186 304
187 0x15, 0x03, /* VGATE pulse start */ 305 R_98_A_VERT_INPUT_WINDOW_START, 0x05,
188 0x16, 0x11, /* VGATE pulse stop */ 306 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
189 0x17, 0x9c, /* VGATE MSB and other values */
190 307
191 0x08, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */ 308 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,
192 0x0e, 0x07, /* lots of different stuff... video autodetection is on */ 309 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
193 310
194 0x5a, 0x06, /* Vertical offset, standard 60hz value for ITU656 line counting */ 311 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
312 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
195 313
196 /* Task A */ 314 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,
197 0x90, 0x80, /* Task Handling Control */ 315 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
198 0x91, 0x48, /* X-port formats/config */
199 0x92, 0x40, /* Input Ref. signal Def. */
200 0x93, 0x84, /* I-port config */
201 0x94, 0x01, /* hoffset low (input), 0x0002 is minimum */
202 0x95, 0x00, /* hoffset hi (input) */
203 0x96, 0xd0, /* hsize low (input), 0x02d0 = 720 */
204 0x97, 0x02, /* hsize hi (input) */
205 0x98, 0x05, /* voffset low (input) */
206 0x99, 0x00, /* voffset hi (input) */
207 0x9a, 0x0c, /* vsize low (input), 0x0c = 12 */
208 0x9b, 0x00, /* vsize hi (input) */
209 0x9c, 0xa0, /* hsize low (output), 0x05a0 = 1440 */
210 0x9d, 0x05, /* hsize hi (output) */
211 0x9e, 0x0c, /* vsize low (output), 0x0c = 12 */
212 0x9f, 0x00, /* vsize hi (output) */
213 316
214 /* Task B */ 317 /* Task B */
215 0xc0, 0x00, /* Task Handling Control */ 318 R_C0_B_TASK_HANDLING_CNTL, 0x00,
216 0xc1, 0x08, /* X-port formats/config */ 319 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
217 0xc2, 0x00, /* Input Ref. signal Def. */ 320 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
218 0xc3, 0x80, /* I-port config */ 321 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
219 0xc4, 0x02, /* hoffset low (input), 0x0002 is minimum */
220 0xc5, 0x00, /* hoffset hi (input) */
221 0xc6, 0xd0, /* hsize low (input), 0x02d0 = 720 */
222 0xc7, 0x02, /* hsize hi (input) */
223 0xc8, 0x12, /* voffset low (input), 0x12 = 18 */
224 0xc9, 0x00, /* voffset hi (input) */
225 0xca, 0xf8, /* vsize low (input), 0xf8 = 248 */
226 0xcb, 0x00, /* vsize hi (input) */
227 0xcc, 0xd0, /* hsize low (output), 0x02d0 = 720 */
228 0xcd, 0x02, /* hsize hi (output) */
229
230 0xf0, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
231 0xf1, 0x05, /* low bit with 0xF0 */
232 0xf5, 0xad, /* Set pulse generator register */
233 0xf6, 0x01,
234
235 0x87, 0x00, /* Disable I-port output */
236 0x88, 0xd0, /* reset scaler */
237 0x80, 0x20, /* Activate only task "B", continuous mode (was 0xA0) */
238 0x88, 0xf0, /* activate scaler */
239 0x87, 0x01, /* Enable I-port output */
240 0x00, 0x00
241};
242 322
243static const unsigned char saa7115_cfg_50hz_fullres_x[] = { 323 /* 0x0002 is minimum */
244 0xcc, 0xd0, /* hsize low (output), 720 same as 60hz */ 324 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
245 0xcd, 0x02, /* hsize hi (output) */ 325 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
246 326
247 0xd0, 0x01, /* down scale = 1 */ 327 /* 0x02d0 = 720 */
248 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */ 328 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
249 0xd9, 0x04, 329 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
250 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
251 0xdd, 0x02, /* H-scaling incr chroma */
252 330
253 0x00, 0x00 331 /* vwindow start 0x12 = 18 */
254}; 332 R_C8_B_VERT_INPUT_WINDOW_START, 0x12,
255static const unsigned char saa7115_cfg_50hz_fullres_y[] = { 333 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
256 0xce, 0x20, /* vsize low (output), 0x0120 = 288 */ 334
257 0xcf, 0x01, /* vsize hi (output) */ 335 /* vwindow length 0xf8 = 248 */
336 R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
337 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
258 338
259 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */ 339 /* hwindow 0x02d0 = 720 */
260 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */ 340 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
341 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
261 342
262 0xe0, 0x00, /* V-scaling incr luma low */ 343 R_F0_LFCO_PER_LINE, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
263 0xe1, 0x04, /* " hi */ 344 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0 */
264 0xe2, 0x00, /* V-scaling incr chroma low */ 345 R_F5_PULSGEN_LINE_LENGTH, 0xad,
265 0xe3, 0x04, /* " hi */ 346 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
266 347
267 0x00, 0x00 348 0x00, 0x00
268}; 349};
269 350
270static const unsigned char saa7115_cfg_50hz_video[] = { 351static const unsigned char saa7115_cfg_50hz_video[] = {
271 0x80, 0x00, /* reset tasks */ 352 R_80_GLOBAL_CNTL_1, 0x00,
272 0x88, 0xd0, /* reset scaler */ 353 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
273 354
274 0x15, 0x37, /* VGATE start */ 355 R_15_VGATE_START_FID_CHG, 0x37, /* VGATE start */
275 0x16, 0x16, /* VGATE stop */ 356 R_16_VGATE_STOP, 0x16,
276 0x17, 0x99, /* VGATE MSB and other values */ 357 R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
277 358
278 0x08, 0x28, /* 0x28 = PAL */ 359 R_08_SYNC_CNTL, 0x28, /* 0x28 = PAL */
279 0x0e, 0x07, /* chrominance control 1 */ 360 R_0E_CHROMA_CNTL_1, 0x07,
280 361
281 0x5a, 0x03, /* Vertical offset, standard 50hz value */ 362 R_5A_V_OFF_FOR_SLICER, 0x03, /* standard 50hz value */
282 363
283 /* Task A */ 364 /* Task A */
284 0x90, 0x81, /* Task Handling Control */ 365 R_90_A_TASK_HANDLING_CNTL, 0x81,
285 0x91, 0x48, /* X-port formats/config */ 366 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
286 0x92, 0x40, /* Input Ref. signal Def. */ 367 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
287 0x93, 0x84, /* I-port config */ 368 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
369
288 /* This is weird: the datasheet says that you should use 2 as the minimum value, */ 370 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
289 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */ 371 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
290 0x94, 0x00, /* hoffset low (input), 0x0002 is minimum */ 372 /* hoffset low (input), 0x0002 is minimum */
291 0x95, 0x00, /* hoffset hi (input) */ 373 R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,
292 0x96, 0xd0, /* hsize low (input), 0x02d0 = 720 */ 374 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
293 0x97, 0x02, /* hsize hi (input) */ 375
294 0x98, 0x03, /* voffset low (input) */ 376 /* hsize low (input), 0x02d0 = 720 */
295 0x99, 0x00, /* voffset hi (input) */ 377 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
296 0x9a, 0x12, /* vsize low (input), 0x12 = 18 */ 378 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
297 0x9b, 0x00, /* vsize hi (input) */ 379
298 0x9c, 0xa0, /* hsize low (output), 0x05a0 = 1440 */ 380 R_98_A_VERT_INPUT_WINDOW_START, 0x03,
299 0x9d, 0x05, /* hsize hi (output) */ 381 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
300 0x9e, 0x12, /* vsize low (output), 0x12 = 18 */ 382
301 0x9f, 0x00, /* vsize hi (output) */ 383 /* vsize 0x12 = 18 */
384 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,
385 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
386
387 /* hsize 0x05a0 = 1440 */
388 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
389 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05, /* hsize hi (output) */
390 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12, /* vsize low (output), 0x12 = 18 */
391 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00, /* vsize hi (output) */
302 392
303 /* Task B */ 393 /* Task B */
304 0xc0, 0x00, /* Task Handling Control */ 394 R_C0_B_TASK_HANDLING_CNTL, 0x00,
305 0xc1, 0x08, /* X-port formats/config */ 395 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
306 0xc2, 0x00, /* Input Ref. signal Def. */ 396 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
307 0xc3, 0x80, /* I-port config */ 397 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
308 0xc4, 0x00, /* hoffset low (input), 0x0002 is minimum. See comment at 0x94 above. */ 398
309 0xc5, 0x00, /* hoffset hi (input) */ 399 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
310 0xc6, 0xd0, /* hsize low (input), 0x02d0 = 720 */ 400 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
311 0xc7, 0x02, /* hsize hi (input) */ 401 /* hoffset low (input), 0x0002 is minimum. See comment above. */
312 0xc8, 0x16, /* voffset low (input), 0x16 = 22 */ 402 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,
313 0xc9, 0x00, /* voffset hi (input) */ 403 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
314 0xca, 0x20, /* vsize low (input), 0x0120 = 288 */ 404
315 0xcb, 0x01, /* vsize hi (input) */ 405 /* hsize 0x02d0 = 720 */
316 0xcc, 0xd0, /* hsize low (output), 0x02d0 = 720 */ 406 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
317 0xcd, 0x02, /* hsize hi (output) */ 407 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
318 0xce, 0x20, /* vsize low (output), 0x0120 = 288 */ 408
319 0xcf, 0x01, /* vsize hi (output) */ 409 /* voffset 0x16 = 22 */
320 410 R_C8_B_VERT_INPUT_WINDOW_START, 0x16,
321 0xf0, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */ 411 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
322 0xf1, 0x05, /* low bit with 0xF0, (was 0x05) */ 412
323 0xf5, 0xb0, /* Set pulse generator register */ 413 /* vsize 0x0120 = 288 */
324 0xf6, 0x01, 414 R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20,
325 415 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01,
326 0x87, 0x00, /* Disable I-port output */ 416
327 0x88, 0xd0, /* reset scaler (was 0xD0) */ 417 /* hsize 0x02d0 = 720 */
328 0x80, 0x20, /* Activate only task "B" */ 418 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
329 0x88, 0xf0, /* activate scaler */ 419 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
330 0x87, 0x01, /* Enable I-port output */ 420
421 R_F0_LFCO_PER_LINE, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
422 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0, (was 0x05) */
423 R_F5_PULSGEN_LINE_LENGTH, 0xb0,
424 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
425
331 0x00, 0x00 426 0x00, 0x00
332}; 427};
333 428
334/* ============== SAA7715 VIDEO templates (end) ======= */ 429/* ============== SAA7715 VIDEO templates (end) ======= */
335 430
336static const unsigned char saa7115_cfg_vbi_on[] = { 431static const unsigned char saa7115_cfg_vbi_on[] = {
337 0x80, 0x00, /* reset tasks */ 432 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
338 0x88, 0xd0, /* reset scaler */ 433 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
339 0x80, 0x30, /* Activate both tasks */ 434 R_80_GLOBAL_CNTL_1, 0x30, /* Activate both tasks */
340 0x88, 0xf0, /* activate scaler */ 435 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
341 0x87, 0x01, /* Enable I-port output */ 436 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
437
342 0x00, 0x00 438 0x00, 0x00
343}; 439};
344 440
345static const unsigned char saa7115_cfg_vbi_off[] = { 441static const unsigned char saa7115_cfg_vbi_off[] = {
346 0x80, 0x00, /* reset tasks */ 442 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
347 0x88, 0xd0, /* reset scaler */ 443 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
348 0x80, 0x20, /* Activate only task "B" */ 444 R_80_GLOBAL_CNTL_1, 0x20, /* Activate only task "B" */
349 0x88, 0xf0, /* activate scaler */ 445 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
350 0x87, 0x01, /* Enable I-port output */ 446 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
351 0x00, 0x00
352};
353 447
354static const unsigned char saa7113_init_auto_input[] = {
355 0x01, 0x08, /* PH7113_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */
356 0x02, 0xc2, /* PH7113_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */
357 0x03, 0x30, /* PH7113_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */
358 0x04, 0x00, /* PH7113_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */
359 0x05, 0x00, /* PH7113_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */
360 0x06, 0x89, /* PH7113_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */
361 0x07, 0x0d, /* PH7113_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */
362 0x08, 0x88, /* PH7113_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */
363 0x09, 0x01, /* PH7113_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */
364 0x0a, 0x80, /* PH7113_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */
365 0x0b, 0x47, /* PH7113_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */
366 0x0c, 0x40, /* PH7113_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */
367 0x0d, 0x00, /* PH7113_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */
368 0x0e, 0x01, /* PH7113_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */
369 0x0f, 0x2a, /* PH7113_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */
370 0x10, 0x08, /* PH7113_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */
371 0x11, 0x0c, /* PH7113_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */
372 0x12, 0x07, /* PH7113_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */
373 0x13, 0x00, /* PH7113_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */
374 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */
375 0x15, 0x00, /* PH7113_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */
376 0x16, 0x00, /* PH7113_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */
377 0x17, 0x00, /* PH7113_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */
378 0x00, 0x00 448 0x00, 0x00
379}; 449};
380 450
451
381static const unsigned char saa7115_init_misc[] = { 452static const unsigned char saa7115_init_misc[] = {
382 0x81, 0x01, /* reg 0x15,0x16 define blanking window */ 453 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
383 0x82, 0x00, 454 R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
384 0x83, 0x01, /* I port settings */ 455 R_84_I_PORT_SIGNAL_DEF, 0x20,
385 0x84, 0x20, 456 R_85_I_PORT_SIGNAL_POLAR, 0x21,
386 0x85, 0x21, 457 R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5,
387 0x86, 0xc5, 458 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
388 0x87, 0x01,
389 459
390 /* Task A */ 460 /* Task A */
391 0xa0, 0x01, /* down scale = 1 */ 461 R_A0_A_HORIZ_PRESCALING, 0x01,
392 0xa1, 0x00, /* prescale accumulation length = 1 */ 462 R_A1_A_ACCUMULATION_LENGTH, 0x00,
393 0xa2, 0x00, /* dc gain and fir prefilter control */ 463 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
394 0xa4, 0x80, /* Lum Brightness, nominal value = 0x80 */ 464
395 0xa5, 0x40, /* Lum contrast, nominal value = 0x40 */ 465 /* Configure controls at nominal value*/
396 0xa6, 0x40, /* Chroma satur. nominal value = 0x80 */ 466 R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80,
397 0xa8, 0x00, /* hor lum scaling 0x0200 = 2 zoom */ 467 R_A5_A_LUMA_CONTRAST_CNTL, 0x40,
398 0xa9, 0x02, /* note: 2 x zoom ensures that VBI lines have same length as video lines. */ 468 R_A6_A_CHROMA_SATURATION_CNTL, 0x40,
399 0xaa, 0x00, /* H-phase offset Luma = 0 */ 469
400 0xac, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */ 470 /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
401 0xad, 0x01, /* H-scaling incr chroma */ 471 R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00,
402 0xae, 0x00, /* H-phase offset chroma. must be offset luma / 2 */ 472 R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02,
403 473
404 0xb0, 0x00, /* V-scaling incr luma low */ 474 R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00,
405 0xb1, 0x04, /* " hi */ 475
406 0xb2, 0x00, /* V-scaling incr chroma low */ 476 /* must be horiz lum scaling / 2 */
407 0xb3, 0x04, /* " hi */ 477 R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00,
408 0xb4, 0x01, /* V-scaling mode control */ 478 R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01,
409 0xb8, 0x00, /* V-phase offset chroma 00 */ 479
410 0xb9, 0x00, /* V-phase offset chroma 01 */ 480 /* must be offset luma / 2 */
411 0xba, 0x00, /* V-phase offset chroma 10 */ 481 R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00,
412 0xbb, 0x00, /* V-phase offset chroma 11 */ 482
413 0xbc, 0x00, /* V-phase offset luma 00 */ 483 R_B0_A_VERT_LUMA_SCALING_INC, 0x00,
414 0xbd, 0x00, /* V-phase offset luma 01 */ 484 R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04,
415 0xbe, 0x00, /* V-phase offset luma 10 */ 485
416 0xbf, 0x00, /* V-phase offset luma 11 */ 486 R_B2_A_VERT_CHROMA_SCALING_INC, 0x00,
487 R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04,
488
489 R_B4_A_VERT_SCALING_MODE_CNTL, 0x01,
490
491 R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00,
492 R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00,
493 R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00,
494 R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00,
495
496 R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00,
497 R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00,
498 R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00,
499 R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00,
417 500
418 /* Task B */ 501 /* Task B */
419 0xd0, 0x01, /* down scale = 1 */ 502 R_D0_B_HORIZ_PRESCALING, 0x01,
420 0xd1, 0x00, /* prescale accumulation length = 1 */ 503 R_D1_B_ACCUMULATION_LENGTH, 0x00,
421 0xd2, 0x00, /* dc gain and fir prefilter control */ 504 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
422 0xd4, 0x80, /* Lum Brightness, nominal value = 0x80 */ 505
423 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */ 506 /* Configure controls at nominal value*/
424 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */ 507 R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80,
425 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */ 508 R_D5_B_LUMA_CONTRAST_CNTL, 0x40,
426 0xd9, 0x04, 509 R_D6_B_CHROMA_SATURATION_CNTL, 0x40,
427 0xda, 0x00, /* H-phase offset Luma = 0 */ 510
428 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */ 511 /* hor lum scaling 0x0400 = 1 */
429 0xdd, 0x02, /* H-scaling incr chroma */ 512 R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
430 0xde, 0x00, /* H-phase offset chroma. must be offset luma / 2 */ 513 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
431 514
432 0xe0, 0x00, /* V-scaling incr luma low */ 515 R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00,
433 0xe1, 0x04, /* " hi */ 516
434 0xe2, 0x00, /* V-scaling incr chroma low */ 517 /* must be hor lum scaling / 2 */
435 0xe3, 0x04, /* " hi */ 518 R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
436 0xe4, 0x01, /* V-scaling mode control */ 519 R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
437 0xe8, 0x00, /* V-phase offset chroma 00 */ 520
438 0xe9, 0x00, /* V-phase offset chroma 01 */ 521 /* must be offset luma / 2 */
439 0xea, 0x00, /* V-phase offset chroma 10 */ 522 R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00,
440 0xeb, 0x00, /* V-phase offset chroma 11 */ 523
441 0xec, 0x00, /* V-phase offset luma 00 */ 524 R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
442 0xed, 0x00, /* V-phase offset luma 01 */ 525 R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
443 0xee, 0x00, /* V-phase offset luma 10 */ 526
444 0xef, 0x00, /* V-phase offset luma 11 */ 527 R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
445 528 R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
446 0xf2, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */ 529
447 0xf3, 0x46, 530 R_E4_B_VERT_SCALING_MODE_CNTL, 0x01,
448 0xf4, 0x00, 531
449 0xf7, 0x4b, /* not the recommended settings! */ 532 R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00,
450 0xf8, 0x00, 533 R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00,
451 0xf9, 0x4b, 534 R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00,
452 0xfa, 0x00, 535 R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00,
453 0xfb, 0x4b, 536
454 0xff, 0x88, /* PLL2 lock detection settings: 71 lines 50% phase error */ 537 R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00,
538 R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00,
539 R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00,
540 R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00,
541
542 R_F2_NOMINAL_PLL2_DTO, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
543 R_F3_PLL_INCREMENT, 0x46,
544 R_F4_PLL2_STATUS, 0x00,
545 R_F7_PULSE_A_POS_MSB, 0x4b, /* not the recommended settings! */
546 R_F8_PULSE_B_POS, 0x00,
547 R_F9_PULSE_B_POS_MSB, 0x4b,
548 R_FA_PULSE_C_POS, 0x00,
549 R_FB_PULSE_C_POS_MSB, 0x4b,
550
551 /* PLL2 lock detection settings: 71 lines 50% phase error */
552 R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88,
455 553
456 /* Turn off VBI */ 554 /* Turn off VBI */
457 0x40, 0x20, /* No framing code errors allowed. */ 555 R_40_SLICER_CNTL_1, 0x20, /* No framing code errors allowed. */
458 0x41, 0xff, 556 R_41_LCR_BASE, 0xff,
459 0x42, 0xff, 557 R_41_LCR_BASE+1, 0xff,
460 0x43, 0xff, 558 R_41_LCR_BASE+2, 0xff,
461 0x44, 0xff, 559 R_41_LCR_BASE+3, 0xff,
462 0x45, 0xff, 560 R_41_LCR_BASE+4, 0xff,
463 0x46, 0xff, 561 R_41_LCR_BASE+5, 0xff,
464 0x47, 0xff, 562 R_41_LCR_BASE+6, 0xff,
465 0x48, 0xff, 563 R_41_LCR_BASE+7, 0xff,
466 0x49, 0xff, 564 R_41_LCR_BASE+8, 0xff,
467 0x4a, 0xff, 565 R_41_LCR_BASE+9, 0xff,
468 0x4b, 0xff, 566 R_41_LCR_BASE+10, 0xff,
469 0x4c, 0xff, 567 R_41_LCR_BASE+11, 0xff,
470 0x4d, 0xff, 568 R_41_LCR_BASE+12, 0xff,
471 0x4e, 0xff, 569 R_41_LCR_BASE+13, 0xff,
472 0x4f, 0xff, 570 R_41_LCR_BASE+14, 0xff,
473 0x50, 0xff, 571 R_41_LCR_BASE+15, 0xff,
474 0x51, 0xff, 572 R_41_LCR_BASE+16, 0xff,
475 0x52, 0xff, 573 R_41_LCR_BASE+17, 0xff,
476 0x53, 0xff, 574 R_41_LCR_BASE+18, 0xff,
477 0x54, 0xff, 575 R_41_LCR_BASE+19, 0xff,
478 0x55, 0xff, 576 R_41_LCR_BASE+20, 0xff,
479 0x56, 0xff, 577 R_41_LCR_BASE+21, 0xff,
480 0x57, 0xff, 578 R_41_LCR_BASE+22, 0xff,
481 0x58, 0x40, 579 R_58_PROGRAM_FRAMING_CODE, 0x40,
482 0x59, 0x47, 580 R_59_H_OFF_FOR_SLICER, 0x47,
483 0x5b, 0x83, 581 R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83,
484 0x5d, 0xbd, 582 R_5D_DID, 0xbd,
485 0x5e, 0x35, 583 R_5E_SDID, 0x35,
486 584
487 0x02, 0x84, /* input tuner -> input 4, amplifier active */ 585 R_02_INPUT_CNTL_1, 0x84, /* input tuner -> input 4, amplifier active */
488 0x09, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */ 586
489 587 R_80_GLOBAL_CNTL_1, 0x20, /* enable task B */
490 0x80, 0x20, /* enable task B */ 588 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
491 0x88, 0xd0, 589 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
492 0x88, 0xf0,
493 0x00, 0x00 590 0x00, 0x00
494}; 591};
495 592
496static int saa7115_odd_parity(u8 c) 593static int saa711x_odd_parity(u8 c)
497{ 594{
498 c ^= (c >> 4); 595 c ^= (c >> 4);
499 c ^= (c >> 2); 596 c ^= (c >> 2);
@@ -502,7 +599,7 @@ static int saa7115_odd_parity(u8 c)
502 return c & 1; 599 return c & 1;
503} 600}
504 601
505static int saa7115_decode_vps(u8 * dst, u8 * p) 602static int saa711x_decode_vps(u8 * dst, u8 * p)
506{ 603{
507 static const u8 biphase_tbl[] = { 604 static const u8 biphase_tbl[] = {
508 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, 605 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
@@ -549,7 +646,7 @@ static int saa7115_decode_vps(u8 * dst, u8 * p)
549 return err & 0xf0; 646 return err & 0xf0;
550} 647}
551 648
552static int saa7115_decode_wss(u8 * p) 649static int saa711x_decode_wss(u8 * p)
553{ 650{
554 static const int wss_bits[8] = { 651 static const int wss_bits[8] = {
555 0, 0, 0, 1, 0, 1, 1, 1 652 0, 0, 0, 1, 0, 1, 1, 1
@@ -576,26 +673,25 @@ static int saa7115_decode_wss(u8 * p)
576 return wss; 673 return wss;
577} 674}
578 675
579 676static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq)
580static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
581{ 677{
582 struct saa7115_state *state = i2c_get_clientdata(client); 678 struct saa711x_state *state = i2c_get_clientdata(client);
583 u32 acpf; 679 u32 acpf;
584 u32 acni; 680 u32 acni;
585 u32 hz; 681 u32 hz;
586 u64 f; 682 u64 f;
587 u8 acc = 0; /* reg 0x3a, audio clock control */ 683 u8 acc = 0; /* reg 0x3a, audio clock control */
588 684
685 /* Checks for chips that don't have audio clock (saa7111, saa7113) */
686 if (!saa711x_has_reg(state->ident,R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
687 return 0;
688
589 v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq); 689 v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq);
590 690
591 /* sanity check */ 691 /* sanity check */
592 if (freq < 32000 || freq > 48000) 692 if (freq < 32000 || freq > 48000)
593 return -EINVAL; 693 return -EINVAL;
594 694
595 /* The saa7113 has no audio clock */
596 if (state->ident == V4L2_IDENT_SAA7113)
597 return 0;
598
599 /* hz is the refresh rate times 100 */ 695 /* hz is the refresh rate times 100 */
600 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000; 696 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
601 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */ 697 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
@@ -617,22 +713,26 @@ static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
617 if (state->apll) 713 if (state->apll)
618 acc |= 0x08; 714 acc |= 0x08;
619 715
620 saa7115_write(client, 0x38, 0x03); 716 saa711x_write(client, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
621 saa7115_write(client, 0x39, 0x10); 717 saa711x_write(client, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
622 saa7115_write(client, 0x3a, acc); 718 saa711x_write(client, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
623 saa7115_write(client, 0x30, acpf & 0xff); 719
624 saa7115_write(client, 0x31, (acpf >> 8) & 0xff); 720 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
625 saa7115_write(client, 0x32, (acpf >> 16) & 0x03); 721 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
626 saa7115_write(client, 0x34, acni & 0xff); 722 (acpf >> 8) & 0xff);
627 saa7115_write(client, 0x35, (acni >> 8) & 0xff); 723 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
628 saa7115_write(client, 0x36, (acni >> 16) & 0x3f); 724 (acpf >> 16) & 0x03);
725
726 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
727 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
728 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
629 state->audclk_freq = freq; 729 state->audclk_freq = freq;
630 return 0; 730 return 0;
631} 731}
632 732
633static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 733static int saa711x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
634{ 734{
635 struct saa7115_state *state = i2c_get_clientdata(client); 735 struct saa711x_state *state = i2c_get_clientdata(client);
636 736
637 switch (ctrl->id) { 737 switch (ctrl->id) {
638 case V4L2_CID_BRIGHTNESS: 738 case V4L2_CID_BRIGHTNESS:
@@ -642,7 +742,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
642 } 742 }
643 743
644 state->bright = ctrl->value; 744 state->bright = ctrl->value;
645 saa7115_write(client, 0x0a, state->bright); 745 saa711x_write(client, R_0A_LUMA_BRIGHT_CNTL, state->bright);
646 break; 746 break;
647 747
648 case V4L2_CID_CONTRAST: 748 case V4L2_CID_CONTRAST:
@@ -652,7 +752,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
652 } 752 }
653 753
654 state->contrast = ctrl->value; 754 state->contrast = ctrl->value;
655 saa7115_write(client, 0x0b, state->contrast); 755 saa711x_write(client, R_0B_LUMA_CONTRAST_CNTL, state->contrast);
656 break; 756 break;
657 757
658 case V4L2_CID_SATURATION: 758 case V4L2_CID_SATURATION:
@@ -662,7 +762,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
662 } 762 }
663 763
664 state->sat = ctrl->value; 764 state->sat = ctrl->value;
665 saa7115_write(client, 0x0c, state->sat); 765 saa711x_write(client, R_0C_CHROMA_SAT_CNTL, state->sat);
666 break; 766 break;
667 767
668 case V4L2_CID_HUE: 768 case V4L2_CID_HUE:
@@ -672,7 +772,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
672 } 772 }
673 773
674 state->hue = ctrl->value; 774 state->hue = ctrl->value;
675 saa7115_write(client, 0x0d, state->hue); 775 saa711x_write(client, R_0D_CHROMA_HUE_CNTL, state->hue);
676 break; 776 break;
677 777
678 default: 778 default:
@@ -682,9 +782,9 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
682 return 0; 782 return 0;
683} 783}
684 784
685static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 785static int saa711x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
686{ 786{
687 struct saa7115_state *state = i2c_get_clientdata(client); 787 struct saa711x_state *state = i2c_get_clientdata(client);
688 788
689 switch (ctrl->id) { 789 switch (ctrl->id) {
690 case V4L2_CID_BRIGHTNESS: 790 case V4L2_CID_BRIGHTNESS:
@@ -706,10 +806,115 @@ static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *c
706 return 0; 806 return 0;
707} 807}
708 808
709static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std) 809static int saa711x_set_size(struct i2c_client *client, int width, int height)
810{
811 struct saa711x_state *state = i2c_get_clientdata(client);
812 int HPSC, HFSC;
813 int VSCY;
814 int res;
815 int is_50hz = state->std & V4L2_STD_625_50;
816 int Vsrc = is_50hz ? 576 : 480;
817
818 v4l_dbg(1, debug, client, "decoder set size to %ix%i\n",width,height);
819
820 /* FIXME need better bounds checking here */
821 if ((width < 1) || (width > 1440))
822 return -EINVAL;
823 if ((height < 1) || (height > Vsrc))
824 return -EINVAL;
825
826 if (!saa711x_has_reg(state->ident,R_D0_B_HORIZ_PRESCALING)) {
827 /* Decoder only supports 720 columns and 480 or 576 lines */
828 if (width != 720)
829 return -EINVAL;
830 if (height != Vsrc)
831 return -EINVAL;
832 }
833
834 state->width = width;
835 state->height = height;
836
837 if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
838 return 0;
839
840 /* probably have a valid size, let's set it */
841 /* Set output width/height */
842 /* width */
843
844 saa711x_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
845 (u8) (width & 0xff));
846 saa711x_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
847 (u8) ((width >> 8) & 0xff));
848
849 /* Vertical Scaling uses height/2 */
850 res=height/2;
851
852 /* On 60Hz, it is using a higher Vertical Output Size */
853 if (!is_50hz)
854 res+=(VRES_60HZ-480)>>1;
855
856 /* height */
857 saa711x_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
858 (u8) (res & 0xff));
859 saa711x_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
860 (u8) ((res >> 8) & 0xff));
861
862 /* Scaling settings */
863 /* Hprescaler is floor(inres/outres) */
864 HPSC = (int)(720 / width);
865 /* 0 is not allowed (div. by zero) */
866 HPSC = HPSC ? HPSC : 1;
867 HFSC = (int)((1024 * 720) / (HPSC * width));
868 /* FIXME hardcodes to "Task B"
869 * write H prescaler integer */
870 saa711x_write(client, R_D0_B_HORIZ_PRESCALING,
871 (u8) (HPSC & 0x3f));
872
873 v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
874 /* write H fine-scaling (luminance) */
875 saa711x_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC,
876 (u8) (HFSC & 0xff));
877 saa711x_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
878 (u8) ((HFSC >> 8) & 0xff));
879 /* write H fine-scaling (chrominance)
880 * must be lum/2, so i'll just bitshift :) */
881 saa711x_write(client, R_DC_B_HORIZ_CHROMA_SCALING,
882 (u8) ((HFSC >> 1) & 0xff));
883 saa711x_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
884 (u8) ((HFSC >> 9) & 0xff));
885
886 VSCY = (int)((1024 * Vsrc) / height);
887 v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
888
889 /* Correct Contrast and Luminance */
890 saa711x_write(client, R_D5_B_LUMA_CONTRAST_CNTL,
891 (u8) (64 * 1024 / VSCY));
892 saa711x_write(client, R_D6_B_CHROMA_SATURATION_CNTL,
893 (u8) (64 * 1024 / VSCY));
894
895 /* write V fine-scaling (luminance) */
896 saa711x_write(client, R_E0_B_VERT_LUMA_SCALING_INC,
897 (u8) (VSCY & 0xff));
898 saa711x_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
899 (u8) ((VSCY >> 8) & 0xff));
900 /* write V fine-scaling (chrominance) */
901 saa711x_write(client, R_E2_B_VERT_CHROMA_SCALING_INC,
902 (u8) (VSCY & 0xff));
903 saa711x_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
904 (u8) ((VSCY >> 8) & 0xff));
905
906 saa711x_writeregs(client, saa7115_cfg_reset_scaler);
907
908 /* Activates task "B" */
909 saa711x_write(client, R_80_GLOBAL_CNTL_1,
910 saa711x_read(client,R_80_GLOBAL_CNTL_1)|0x20);
911
912 return 0;
913}
914
915static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
710{ 916{
711 struct saa7115_state *state = i2c_get_clientdata(client); 917 struct saa711x_state *state = i2c_get_clientdata(client);
712 int taskb = saa7115_read(client, 0x80) & 0x10;
713 918
714 /* Prevent unnecessary standard changes. During a standard 919 /* Prevent unnecessary standard changes. During a standard
715 change the I-Port is temporarily disabled. Any devices 920 change the I-Port is temporarily disabled. Any devices
@@ -721,17 +926,21 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
721 if (std == state->std) 926 if (std == state->std)
722 return; 927 return;
723 928
929 state->std = std;
930
724 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants. 931 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
725 if (std & V4L2_STD_525_60) { 932 if (std & V4L2_STD_525_60) {
726 v4l_dbg(1, debug, client, "decoder set standard 60 Hz\n"); 933 v4l_dbg(1, debug, client, "decoder set standard 60 Hz\n");
727 saa7115_writeregs(client, saa7115_cfg_60hz_video); 934 saa711x_writeregs(client, saa7115_cfg_60hz_video);
935 saa711x_set_size(client,720,480);
728 } else { 936 } else {
729 v4l_dbg(1, debug, client, "decoder set standard 50 Hz\n"); 937 v4l_dbg(1, debug, client, "decoder set standard 50 Hz\n");
730 saa7115_writeregs(client, saa7115_cfg_50hz_video); 938 saa711x_writeregs(client, saa7115_cfg_50hz_video);
939 saa711x_set_size(client,720,576);
731 } 940 }
732 941
733 /* Register 0E - Bits D6-D4 on NO-AUTO mode 942 /* Register 0E - Bits D6-D4 on NO-AUTO mode
734 (SAA7113 doesn't have auto mode) 943 (SAA7111 and SAA7113 doesn't have auto mode)
735 50 Hz / 625 lines 60 Hz / 525 lines 944 50 Hz / 625 lines 60 Hz / 525 lines
736 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz) 945 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz)
737 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz) 946 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz)
@@ -739,8 +948,9 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
739 011 NTSC N (3.58MHz) PAL M (3.58MHz) 948 011 NTSC N (3.58MHz) PAL M (3.58MHz)
740 100 reserved NTSC-Japan (3.58MHz) 949 100 reserved NTSC-Japan (3.58MHz)
741 */ 950 */
742 if (state->ident == V4L2_IDENT_SAA7113) { 951 if (state->ident == V4L2_IDENT_SAA7111 ||
743 u8 reg = saa7115_read(client, 0x0e) & 0x8f; 952 state->ident == V4L2_IDENT_SAA7113) {
953 u8 reg = saa711x_read(client, R_0E_CHROMA_CNTL_1) & 0x8f;
744 954
745 if (std == V4L2_STD_PAL_M) { 955 if (std == V4L2_STD_PAL_M) {
746 reg |= 0x30; 956 reg |= 0x30;
@@ -751,31 +961,30 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
751 } else if (std == V4L2_STD_NTSC_M_JP) { 961 } else if (std == V4L2_STD_NTSC_M_JP) {
752 reg |= 0x40; 962 reg |= 0x40;
753 } 963 }
754 saa7115_write(client, 0x0e, reg); 964 saa711x_write(client, R_0E_CHROMA_CNTL_1, reg);
755 } 965 } else {
756 966 /* restart task B if needed */
967 int taskb = saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10;
757 968
758 state->std = std; 969 if (taskb && state->ident == V4L2_IDENT_SAA7114) {
970 saa711x_writeregs(client, saa7115_cfg_vbi_on);
971 }
759 972
760 /* restart task B if needed */ 973 /* switch audio mode too! */
761 if (taskb && state->ident != V4L2_IDENT_SAA7115) { 974 saa711x_set_audio_clock_freq(client, state->audclk_freq);
762 saa7115_writeregs(client, saa7115_cfg_vbi_on);
763 } 975 }
764
765 /* switch audio mode too! */
766 saa7115_set_audio_clock_freq(client, state->audclk_freq);
767} 976}
768 977
769static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client) 978static v4l2_std_id saa711x_get_v4lstd(struct i2c_client *client)
770{ 979{
771 struct saa7115_state *state = i2c_get_clientdata(client); 980 struct saa711x_state *state = i2c_get_clientdata(client);
772 981
773 return state->std; 982 return state->std;
774} 983}
775 984
776static void saa7115_log_status(struct i2c_client *client) 985static void saa711x_log_status(struct i2c_client *client)
777{ 986{
778 struct saa7115_state *state = i2c_get_clientdata(client); 987 struct saa711x_state *state = i2c_get_clientdata(client);
779 int reg1e, reg1f; 988 int reg1e, reg1f;
780 int signalOk; 989 int signalOk;
781 int vcr; 990 int vcr;
@@ -783,7 +992,7 @@ static void saa7115_log_status(struct i2c_client *client)
783 v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq); 992 v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
784 if (state->ident != V4L2_IDENT_SAA7115) { 993 if (state->ident != V4L2_IDENT_SAA7115) {
785 /* status for the saa7114 */ 994 /* status for the saa7114 */
786 reg1f = saa7115_read(client, 0x1f); 995 reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
787 signalOk = (reg1f & 0xc1) == 0x81; 996 signalOk = (reg1f & 0xc1) == 0x81;
788 v4l_info(client, "Video signal: %s\n", signalOk ? "ok" : "bad"); 997 v4l_info(client, "Video signal: %s\n", signalOk ? "ok" : "bad");
789 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz"); 998 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
@@ -791,8 +1000,8 @@ static void saa7115_log_status(struct i2c_client *client)
791 } 1000 }
792 1001
793 /* status for the saa7115 */ 1002 /* status for the saa7115 */
794 reg1e = saa7115_read(client, 0x1e); 1003 reg1e = saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC);
795 reg1f = saa7115_read(client, 0x1f); 1004 reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
796 1005
797 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80; 1006 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
798 vcr = !(reg1f & 0x10); 1007 vcr = !(reg1f & 0x10);
@@ -819,19 +1028,27 @@ static void saa7115_log_status(struct i2c_client *client)
819 v4l_info(client, "Detected format: BW/No color\n"); 1028 v4l_info(client, "Detected format: BW/No color\n");
820 break; 1029 break;
821 } 1030 }
1031 v4l_info(client, "Width, Height: %d, %d\n", state->width, state->height);
822} 1032}
823 1033
824/* setup the sliced VBI lcr registers according to the sliced VBI format */ 1034/* setup the sliced VBI lcr registers according to the sliced VBI format */
825static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt) 1035static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
826{ 1036{
827 struct saa7115_state *state = i2c_get_clientdata(client); 1037 struct saa711x_state *state = i2c_get_clientdata(client);
828 int is_50hz = (state->std & V4L2_STD_625_50); 1038 int is_50hz = (state->std & V4L2_STD_625_50);
829 u8 lcr[24]; 1039 u8 lcr[24];
830 int i, x; 1040 int i, x;
831 1041
832 /* saa7113/7114 doesn't yet support VBI */ 1042#if 1
1043 /* saa7113/7114/7118 VBI support are experimental */
1044 if (!saa711x_has_reg(state->ident,R_41_LCR_BASE))
1045 return;
1046
1047#else
1048 /* SAA7113 and SAA7118 also should support VBI - Need testing */
833 if (state->ident != V4L2_IDENT_SAA7115) 1049 if (state->ident != V4L2_IDENT_SAA7115)
834 return; 1050 return;
1051#endif
835 1052
836 for (i = 0; i <= 23; i++) 1053 for (i = 0; i <= 23; i++)
837 lcr[i] = 0xff; 1054 lcr[i] = 0xff;
@@ -888,14 +1105,16 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
888 1105
889 /* write the lcr registers */ 1106 /* write the lcr registers */
890 for (i = 2; i <= 23; i++) { 1107 for (i = 2; i <= 23; i++) {
891 saa7115_write(client, i - 2 + 0x41, lcr[i]); 1108 saa711x_write(client, i - 2 + R_41_LCR_BASE, lcr[i]);
892 } 1109 }
893 1110
894 /* enable/disable raw VBI capturing */ 1111 /* enable/disable raw VBI capturing */
895 saa7115_writeregs(client, fmt->service_set == 0 ? saa7115_cfg_vbi_on : saa7115_cfg_vbi_off); 1112 saa711x_writeregs(client, fmt->service_set == 0 ?
1113 saa7115_cfg_vbi_on :
1114 saa7115_cfg_vbi_off);
896} 1115}
897 1116
898static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 1117static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
899{ 1118{
900 static u16 lcr2vbi[] = { 1119 static u16 lcr2vbi[] = {
901 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 1120 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
@@ -911,10 +1130,10 @@ static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
911 return -EINVAL; 1130 return -EINVAL;
912 memset(sliced, 0, sizeof(*sliced)); 1131 memset(sliced, 0, sizeof(*sliced));
913 /* done if using raw VBI */ 1132 /* done if using raw VBI */
914 if (saa7115_read(client, 0x80) & 0x10) 1133 if (saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10)
915 return 0; 1134 return 0;
916 for (i = 2; i <= 23; i++) { 1135 for (i = 2; i <= 23; i++) {
917 u8 v = saa7115_read(client, i - 2 + 0x41); 1136 u8 v = saa711x_read(client, i - 2 + R_41_LCR_BASE);
918 1137
919 sliced->service_lines[0][i] = lcr2vbi[v >> 4]; 1138 sliced->service_lines[0][i] = lcr2vbi[v >> 4];
920 sliced->service_lines[1][i] = lcr2vbi[v & 0xf]; 1139 sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
@@ -924,114 +1143,31 @@ static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
924 return 0; 1143 return 0;
925} 1144}
926 1145
927static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 1146static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
928{ 1147{
929 struct saa7115_state *state = i2c_get_clientdata(client);
930 struct v4l2_pix_format *pix;
931 int HPSC, HFSC;
932 int VSCY, Vsrc;
933 int is_50hz = state->std & V4L2_STD_625_50;
934
935 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { 1148 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
936 saa7115_set_lcr(client, &fmt->fmt.sliced); 1149 saa711x_set_lcr(client, &fmt->fmt.sliced);
937 return 0; 1150 return 0;
938 } 1151 }
939 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1152 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
940 return -EINVAL; 1153 return -EINVAL;
941 1154
942 pix = &(fmt->fmt.pix); 1155 return saa711x_set_size(client,fmt->fmt.pix.width,fmt->fmt.pix.height);
943
944 v4l_dbg(1, debug, client, "decoder set size\n");
945
946 /* FIXME need better bounds checking here */
947 if ((pix->width < 1) || (pix->width > 1440))
948 return -EINVAL;
949 if ((pix->height < 1) || (pix->height > 960))
950 return -EINVAL;
951
952 /* probably have a valid size, let's set it */
953 /* Set output width/height */
954 /* width */
955 saa7115_write(client, 0xcc, (u8) (pix->width & 0xff));
956 saa7115_write(client, 0xcd, (u8) ((pix->width >> 8) & 0xff));
957 /* height */
958 saa7115_write(client, 0xce, (u8) (pix->height & 0xff));
959 saa7115_write(client, 0xcf, (u8) ((pix->height >> 8) & 0xff));
960
961 /* Scaling settings */
962 /* Hprescaler is floor(inres/outres) */
963 /* FIXME hardcoding input res */
964 if (pix->width != 720) {
965 HPSC = (int)(720 / pix->width);
966 /* 0 is not allowed (div. by zero) */
967 HPSC = HPSC ? HPSC : 1;
968 HFSC = (int)((1024 * 720) / (HPSC * pix->width));
969
970 v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
971 /* FIXME hardcodes to "Task B"
972 * write H prescaler integer */
973 saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f));
974
975 /* write H fine-scaling (luminance) */
976 saa7115_write(client, 0xd8, (u8) (HFSC & 0xff));
977 saa7115_write(client, 0xd9, (u8) ((HFSC >> 8) & 0xff));
978 /* write H fine-scaling (chrominance)
979 * must be lum/2, so i'll just bitshift :) */
980 saa7115_write(client, 0xDC, (u8) ((HFSC >> 1) & 0xff));
981 saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff));
982 } else {
983 if (is_50hz) {
984 v4l_dbg(1, debug, client, "Setting full 50hz width\n");
985 saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x);
986 } else {
987 v4l_dbg(1, debug, client, "Setting full 60hz width\n");
988 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
989 }
990 }
991
992 Vsrc = is_50hz ? 576 : 480;
993
994 if (pix->height != Vsrc) {
995 VSCY = (int)((1024 * Vsrc) / pix->height);
996 v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
997
998 /* Correct Contrast and Luminance */
999 saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY));
1000 saa7115_write(client, 0xd6, (u8) (64 * 1024 / VSCY));
1001
1002 /* write V fine-scaling (luminance) */
1003 saa7115_write(client, 0xe0, (u8) (VSCY & 0xff));
1004 saa7115_write(client, 0xe1, (u8) ((VSCY >> 8) & 0xff));
1005 /* write V fine-scaling (chrominance) */
1006 saa7115_write(client, 0xe2, (u8) (VSCY & 0xff));
1007 saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff));
1008 } else {
1009 if (is_50hz) {
1010 v4l_dbg(1, debug, client, "Setting full 50Hz height\n");
1011 saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y);
1012 } else {
1013 v4l_dbg(1, debug, client, "Setting full 60hz height\n");
1014 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
1015 }
1016 }
1017
1018 saa7115_writeregs(client, saa7115_cfg_reset_scaler);
1019 return 0;
1020} 1156}
1021 1157
1022/* Decode the sliced VBI data stream as created by the saa7115. 1158/* Decode the sliced VBI data stream as created by the saa7115.
1023 The format is described in the saa7115 datasheet in Tables 25 and 26 1159 The format is described in the saa7115 datasheet in Tables 25 and 26
1024 and in Figure 33. 1160 and in Figure 33.
1025 The current implementation uses SAV/EAV codes and not the ancillary data 1161 The current implementation uses SAV/EAV codes and not the ancillary data
1026 headers. The vbi->p pointer points to the SDID byte right after the SAV 1162 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
1027 code. */ 1163 code. */
1028static void saa7115_decode_vbi_line(struct i2c_client *client, 1164static void saa711x_decode_vbi_line(struct i2c_client *client,
1029 struct v4l2_decode_vbi_line *vbi) 1165 struct v4l2_decode_vbi_line *vbi)
1030{ 1166{
1031 static const char vbi_no_data_pattern[] = { 1167 static const char vbi_no_data_pattern[] = {
1032 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0 1168 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1033 }; 1169 };
1034 struct saa7115_state *state = i2c_get_clientdata(client); 1170 struct saa711x_state *state = i2c_get_clientdata(client);
1035 u8 *p = vbi->p; 1171 u8 *p = vbi->p;
1036 u32 wss; 1172 u32 wss;
1037 int id1, id2; /* the ID1 and ID2 bytes from the internal header */ 1173 int id1, id2; /* the ID1 and ID2 bytes from the internal header */
@@ -1066,12 +1202,12 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
1066 vbi->type = V4L2_SLICED_TELETEXT_B; 1202 vbi->type = V4L2_SLICED_TELETEXT_B;
1067 break; 1203 break;
1068 case 4: 1204 case 4:
1069 if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1])) 1205 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
1070 return; 1206 return;
1071 vbi->type = V4L2_SLICED_CAPTION_525; 1207 vbi->type = V4L2_SLICED_CAPTION_525;
1072 break; 1208 break;
1073 case 5: 1209 case 5:
1074 wss = saa7115_decode_wss(p); 1210 wss = saa711x_decode_wss(p);
1075 if (wss == -1) 1211 if (wss == -1)
1076 return; 1212 return;
1077 p[0] = wss & 0xff; 1213 p[0] = wss & 0xff;
@@ -1079,7 +1215,7 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
1079 vbi->type = V4L2_SLICED_WSS_625; 1215 vbi->type = V4L2_SLICED_WSS_625;
1080 break; 1216 break;
1081 case 7: 1217 case 7:
1082 if (saa7115_decode_vps(p, p) != 0) 1218 if (saa711x_decode_vps(p, p) != 0)
1083 return; 1219 return;
1084 vbi->type = V4L2_SLICED_VPS; 1220 vbi->type = V4L2_SLICED_VPS;
1085 break; 1221 break;
@@ -1090,21 +1226,21 @@ static void saa7115_decode_vbi_line(struct i2c_client *client,
1090 1226
1091/* ============ SAA7115 AUDIO settings (end) ============= */ 1227/* ============ SAA7115 AUDIO settings (end) ============= */
1092 1228
1093static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) 1229static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *arg)
1094{ 1230{
1095 struct saa7115_state *state = i2c_get_clientdata(client); 1231 struct saa711x_state *state = i2c_get_clientdata(client);
1096 int *iarg = arg; 1232 int *iarg = arg;
1097 1233
1098 /* ioctls to allow direct access to the saa7115 registers for testing */ 1234 /* ioctls to allow direct access to the saa7115 registers for testing */
1099 switch (cmd) { 1235 switch (cmd) {
1100 case VIDIOC_S_FMT: 1236 case VIDIOC_S_FMT:
1101 return saa7115_set_v4lfmt(client, (struct v4l2_format *)arg); 1237 return saa711x_set_v4lfmt(client, (struct v4l2_format *)arg);
1102 1238
1103 case VIDIOC_G_FMT: 1239 case VIDIOC_G_FMT:
1104 return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg); 1240 return saa711x_get_v4lfmt(client, (struct v4l2_format *)arg);
1105 1241
1106 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 1242 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
1107 return saa7115_set_audio_clock_freq(client, *(u32 *)arg); 1243 return saa711x_set_audio_clock_freq(client, *(u32 *)arg);
1108 1244
1109 case VIDIOC_G_TUNER: 1245 case VIDIOC_G_TUNER:
1110 { 1246 {
@@ -1113,7 +1249,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1113 1249
1114 if (state->radio) 1250 if (state->radio)
1115 break; 1251 break;
1116 status = saa7115_read(client, 0x1f); 1252 status = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
1117 1253
1118 v4l_dbg(1, debug, client, "status: 0x%02x\n", status); 1254 v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
1119 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0; 1255 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
@@ -1121,14 +1257,14 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1121 } 1257 }
1122 1258
1123 case VIDIOC_LOG_STATUS: 1259 case VIDIOC_LOG_STATUS:
1124 saa7115_log_status(client); 1260 saa711x_log_status(client);
1125 break; 1261 break;
1126 1262
1127 case VIDIOC_G_CTRL: 1263 case VIDIOC_G_CTRL:
1128 return saa7115_get_v4lctrl(client, (struct v4l2_control *)arg); 1264 return saa711x_get_v4lctrl(client, (struct v4l2_control *)arg);
1129 1265
1130 case VIDIOC_S_CTRL: 1266 case VIDIOC_S_CTRL:
1131 return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg); 1267 return saa711x_set_v4lctrl(client, (struct v4l2_control *)arg);
1132 1268
1133 case VIDIOC_QUERYCTRL: 1269 case VIDIOC_QUERYCTRL:
1134 { 1270 {
@@ -1146,12 +1282,12 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1146 } 1282 }
1147 1283
1148 case VIDIOC_G_STD: 1284 case VIDIOC_G_STD:
1149 *(v4l2_std_id *)arg = saa7115_get_v4lstd(client); 1285 *(v4l2_std_id *)arg = saa711x_get_v4lstd(client);
1150 break; 1286 break;
1151 1287
1152 case VIDIOC_S_STD: 1288 case VIDIOC_S_STD:
1153 state->radio = 0; 1289 state->radio = 0;
1154 saa7115_set_v4lstd(client, *(v4l2_std_id *)arg); 1290 saa711x_set_v4lstd(client, *(v4l2_std_id *)arg);
1155 break; 1291 break;
1156 1292
1157 case AUDC_SET_RADIO: 1293 case AUDC_SET_RADIO:
@@ -1187,13 +1323,13 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1187 state->input = route->input; 1323 state->input = route->input;
1188 1324
1189 /* select mode */ 1325 /* select mode */
1190 saa7115_write(client, 0x02, 1326 saa711x_write(client, R_02_INPUT_CNTL_1,
1191 (saa7115_read(client, 0x02) & 0xf0) | 1327 (saa711x_read(client, R_02_INPUT_CNTL_1) & 0xf0) |
1192 state->input); 1328 state->input);
1193 1329
1194 /* bypass chrominance trap for S-Video modes */ 1330 /* bypass chrominance trap for S-Video modes */
1195 saa7115_write(client, 0x09, 1331 saa711x_write(client, R_09_LUMA_CNTL,
1196 (saa7115_read(client, 0x09) & 0x7f) | 1332 (saa711x_read(client, R_09_LUMA_CNTL) & 0x7f) |
1197 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0)); 1333 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
1198 break; 1334 break;
1199 } 1335 }
@@ -1205,7 +1341,9 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1205 1341
1206 if (state->enable != (cmd == VIDIOC_STREAMON)) { 1342 if (state->enable != (cmd == VIDIOC_STREAMON)) {
1207 state->enable = (cmd == VIDIOC_STREAMON); 1343 state->enable = (cmd == VIDIOC_STREAMON);
1208 saa7115_write(client, 0x87, state->enable); 1344 saa711x_write(client,
1345 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
1346 state->enable);
1209 } 1347 }
1210 break; 1348 break;
1211 1349
@@ -1220,17 +1358,17 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1220 state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4; 1358 state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1221 state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0; 1359 state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
1222 state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0; 1360 state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
1223 saa7115_set_audio_clock_freq(client, state->audclk_freq); 1361 saa711x_set_audio_clock_freq(client, state->audclk_freq);
1224 break; 1362 break;
1225 } 1363 }
1226 1364
1227 case VIDIOC_INT_DECODE_VBI_LINE: 1365 case VIDIOC_INT_DECODE_VBI_LINE:
1228 saa7115_decode_vbi_line(client, arg); 1366 saa711x_decode_vbi_line(client, arg);
1229 break; 1367 break;
1230 1368
1231 case VIDIOC_INT_RESET: 1369 case VIDIOC_INT_RESET:
1232 v4l_dbg(1, debug, client, "decoder RESET\n"); 1370 v4l_dbg(1, debug, client, "decoder RESET\n");
1233 saa7115_writeregs(client, saa7115_cfg_reset_scaler); 1371 saa711x_writeregs(client, saa7115_cfg_reset_scaler);
1234 break; 1372 break;
1235 1373
1236 case VIDIOC_INT_G_VBI_DATA: 1374 case VIDIOC_INT_G_VBI_DATA:
@@ -1239,25 +1377,25 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1239 1377
1240 switch (data->id) { 1378 switch (data->id) {
1241 case V4L2_SLICED_WSS_625: 1379 case V4L2_SLICED_WSS_625:
1242 if (saa7115_read(client, 0x6b) & 0xc0) 1380 if (saa711x_read(client, 0x6b) & 0xc0)
1243 return -EIO; 1381 return -EIO;
1244 data->data[0] = saa7115_read(client, 0x6c); 1382 data->data[0] = saa711x_read(client, 0x6c);
1245 data->data[1] = saa7115_read(client, 0x6d); 1383 data->data[1] = saa711x_read(client, 0x6d);
1246 return 0; 1384 return 0;
1247 case V4L2_SLICED_CAPTION_525: 1385 case V4L2_SLICED_CAPTION_525:
1248 if (data->field == 0) { 1386 if (data->field == 0) {
1249 /* CC */ 1387 /* CC */
1250 if (saa7115_read(client, 0x66) & 0xc0) 1388 if (saa711x_read(client, 0x66) & 0xc0)
1251 return -EIO; 1389 return -EIO;
1252 data->data[0] = saa7115_read(client, 0x67); 1390 data->data[0] = saa711x_read(client, 0x67);
1253 data->data[1] = saa7115_read(client, 0x68); 1391 data->data[1] = saa711x_read(client, 0x68);
1254 return 0; 1392 return 0;
1255 } 1393 }
1256 /* XDS */ 1394 /* XDS */
1257 if (saa7115_read(client, 0x66) & 0x30) 1395 if (saa711x_read(client, 0x66) & 0x30)
1258 return -EIO; 1396 return -EIO;
1259 data->data[0] = saa7115_read(client, 0x69); 1397 data->data[0] = saa711x_read(client, 0x69);
1260 data->data[1] = saa7115_read(client, 0x6a); 1398 data->data[1] = saa711x_read(client, 0x6a);
1261 return 0; 1399 return 0;
1262 default: 1400 default:
1263 return -EINVAL; 1401 return -EINVAL;
@@ -1272,7 +1410,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1272 1410
1273 if (reg->i2c_id != I2C_DRIVERID_SAA711X) 1411 if (reg->i2c_id != I2C_DRIVERID_SAA711X)
1274 return -EINVAL; 1412 return -EINVAL;
1275 reg->val = saa7115_read(client, reg->reg & 0xff); 1413 reg->val = saa711x_read(client, reg->reg & 0xff);
1276 break; 1414 break;
1277 } 1415 }
1278 1416
@@ -1284,7 +1422,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1284 return -EINVAL; 1422 return -EINVAL;
1285 if (!capable(CAP_SYS_ADMIN)) 1423 if (!capable(CAP_SYS_ADMIN))
1286 return -EPERM; 1424 return -EPERM;
1287 saa7115_write(client, reg->reg & 0xff, reg->val & 0xff); 1425 saa711x_write(client, reg->reg & 0xff, reg->val & 0xff);
1288 break; 1426 break;
1289 } 1427 }
1290#endif 1428#endif
@@ -1302,12 +1440,14 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar
1302 1440
1303/* ----------------------------------------------------------------------- */ 1441/* ----------------------------------------------------------------------- */
1304 1442
1305static struct i2c_driver i2c_driver_saa7115; 1443static struct i2c_driver i2c_driver_saa711x;
1306 1444
1307static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) 1445static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind)
1308{ 1446{
1309 struct i2c_client *client; 1447 struct i2c_client *client;
1310 struct saa7115_state *state; 1448 struct saa711x_state *state;
1449 int i;
1450 char name[17];
1311 u8 chip_id; 1451 u8 chip_id;
1312 1452
1313 /* Check if the adapter supports the needed features */ 1453 /* Check if the adapter supports the needed features */
@@ -1319,28 +1459,31 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1319 return -ENOMEM; 1459 return -ENOMEM;
1320 client->addr = address; 1460 client->addr = address;
1321 client->adapter = adapter; 1461 client->adapter = adapter;
1322 client->driver = &i2c_driver_saa7115; 1462 client->driver = &i2c_driver_saa711x;
1323 snprintf(client->name, sizeof(client->name) - 1, "saa7115"); 1463 snprintf(client->name, sizeof(client->name) - 1, "saa7115");
1324 1464
1325 v4l_dbg(1, debug, client, "detecting saa7115 client on address 0x%x\n", address << 1); 1465 v4l_dbg(1, debug, client, "detecting saa7115 client on address 0x%x\n", address << 1);
1326 1466
1327 saa7115_write(client, 0, 5); 1467 for (i=0;i<0x0f;i++) {
1328 chip_id = saa7115_read(client, 0) & 0x0f; 1468 saa711x_write(client, 0, i);
1329 if (chip_id < 3 && chip_id > 5) { 1469 name[i] = (saa711x_read(client, 0) &0x0f) +'0';
1330 v4l_dbg(1, debug, client, "saa7115 not found\n"); 1470 if (name[i]>'9')
1331 kfree(client); 1471 name[i]+='a'-'9'-1;
1332 return 0;
1333 } 1472 }
1473 name[i]='\0';
1474
1475 saa711x_write(client, 0, 5);
1476 chip_id = saa711x_read(client, 0) & 0x0f;
1477
1334 snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id); 1478 snprintf(client->name, sizeof(client->name) - 1, "saa711%d",chip_id);
1335 v4l_info(client, "saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name); 1479 v4l_info(client, "saa711%d found (%s) @ 0x%x (%s)\n", chip_id, name, address << 1, adapter->name);
1336 1480
1337 state = kzalloc(sizeof(struct saa7115_state), GFP_KERNEL); 1481 state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
1338 i2c_set_clientdata(client, state); 1482 i2c_set_clientdata(client, state);
1339 if (state == NULL) { 1483 if (state == NULL) {
1340 kfree(client); 1484 kfree(client);
1341 return -ENOMEM; 1485 return -ENOMEM;
1342 } 1486 }
1343 state->std = V4L2_STD_NTSC;
1344 state->input = -1; 1487 state->input = -1;
1345 state->enable = 1; 1488 state->enable = 1;
1346 state->radio = 0; 1489 state->radio = 0;
@@ -1349,15 +1492,25 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1349 state->hue = 0; 1492 state->hue = 0;
1350 state->sat = 64; 1493 state->sat = 64;
1351 switch (chip_id) { 1494 switch (chip_id) {
1495 case 1:
1496 state->ident = V4L2_IDENT_SAA7111;
1497 break;
1352 case 3: 1498 case 3:
1353 state->ident = V4L2_IDENT_SAA7113; 1499 state->ident = V4L2_IDENT_SAA7113;
1354 break; 1500 break;
1355 case 4: 1501 case 4:
1356 state->ident = V4L2_IDENT_SAA7114; 1502 state->ident = V4L2_IDENT_SAA7114;
1357 break; 1503 break;
1358 default: 1504 case 5:
1359 state->ident = V4L2_IDENT_SAA7115; 1505 state->ident = V4L2_IDENT_SAA7115;
1360 break; 1506 break;
1507 case 8:
1508 state->ident = V4L2_IDENT_SAA7118;
1509 break;
1510 default:
1511 state->ident = V4L2_IDENT_SAA7111;
1512 v4l_info(client, "WARNING: Chip is not known - Falling back to saa7111\n");
1513
1361 } 1514 }
1362 1515
1363 state->audclk_freq = 48000; 1516 state->audclk_freq = 48000;
@@ -1365,38 +1518,39 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
1365 v4l_dbg(1, debug, client, "writing init values\n"); 1518 v4l_dbg(1, debug, client, "writing init values\n");
1366 1519
1367 /* init to 60hz/48khz */ 1520 /* init to 60hz/48khz */
1368 if (state->ident == V4L2_IDENT_SAA7113) { 1521 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1369 state->crystal_freq = SAA7115_FREQ_24_576_MHZ; 1522 switch (state->ident) {
1370 saa7115_writeregs(client, saa7113_init_auto_input); 1523 case V4L2_IDENT_SAA7111:
1371 } else { 1524 saa711x_writeregs(client, saa7111_init);
1525 break;
1526 case V4L2_IDENT_SAA7113:
1527 saa711x_writeregs(client, saa7113_init);
1528 break;
1529 default:
1372 state->crystal_freq = SAA7115_FREQ_32_11_MHZ; 1530 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1373 saa7115_writeregs(client, saa7115_init_auto_input); 1531 saa711x_writeregs(client, saa7115_init_auto_input);
1374 } 1532 }
1375 saa7115_writeregs(client, saa7115_init_misc); 1533 saa711x_writeregs(client, saa7115_init_misc);
1376 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); 1534 saa711x_set_v4lstd(client, V4L2_STD_NTSC);
1377 saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
1378 saa7115_writeregs(client, saa7115_cfg_60hz_video);
1379 saa7115_set_audio_clock_freq(client, state->audclk_freq);
1380 saa7115_writeregs(client, saa7115_cfg_reset_scaler);
1381 1535
1382 i2c_attach_client(client); 1536 i2c_attach_client(client);
1383 1537
1384 v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n", 1538 v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1385 saa7115_read(client, 0x1e), saa7115_read(client, 0x1f)); 1539 saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC));
1386 1540
1387 return 0; 1541 return 0;
1388} 1542}
1389 1543
1390static int saa7115_probe(struct i2c_adapter *adapter) 1544static int saa711x_probe(struct i2c_adapter *adapter)
1391{ 1545{
1392 if (adapter->class & I2C_CLASS_TV_ANALOG) 1546 if (adapter->class & I2C_CLASS_TV_ANALOG)
1393 return i2c_probe(adapter, &addr_data, &saa7115_attach); 1547 return i2c_probe(adapter, &addr_data, &saa711x_attach);
1394 return 0; 1548 return 0;
1395} 1549}
1396 1550
1397static int saa7115_detach(struct i2c_client *client) 1551static int saa711x_detach(struct i2c_client *client)
1398{ 1552{
1399 struct saa7115_state *state = i2c_get_clientdata(client); 1553 struct saa711x_state *state = i2c_get_clientdata(client);
1400 int err; 1554 int err;
1401 1555
1402 err = i2c_detach_client(client); 1556 err = i2c_detach_client(client);
@@ -1412,26 +1566,26 @@ static int saa7115_detach(struct i2c_client *client)
1412/* ----------------------------------------------------------------------- */ 1566/* ----------------------------------------------------------------------- */
1413 1567
1414/* i2c implementation */ 1568/* i2c implementation */
1415static struct i2c_driver i2c_driver_saa7115 = { 1569static struct i2c_driver i2c_driver_saa711x = {
1416 .driver = { 1570 .driver = {
1417 .name = "saa7115", 1571 .name = "saa7115",
1418 }, 1572 },
1419 .id = I2C_DRIVERID_SAA711X, 1573 .id = I2C_DRIVERID_SAA711X,
1420 .attach_adapter = saa7115_probe, 1574 .attach_adapter = saa711x_probe,
1421 .detach_client = saa7115_detach, 1575 .detach_client = saa711x_detach,
1422 .command = saa7115_command, 1576 .command = saa711x_command,
1423}; 1577};
1424 1578
1425 1579
1426static int __init saa7115_init_module(void) 1580static int __init saa711x_init_module(void)
1427{ 1581{
1428 return i2c_add_driver(&i2c_driver_saa7115); 1582 return i2c_add_driver(&i2c_driver_saa711x);
1429} 1583}
1430 1584
1431static void __exit saa7115_cleanup_module(void) 1585static void __exit saa711x_cleanup_module(void)
1432{ 1586{
1433 i2c_del_driver(&i2c_driver_saa7115); 1587 i2c_del_driver(&i2c_driver_saa711x);
1434} 1588}
1435 1589
1436module_init(saa7115_init_module); 1590module_init(saa711x_init_module);
1437module_exit(saa7115_cleanup_module); 1591module_exit(saa711x_cleanup_module);