]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/i2c/saa7115.c
[media] saa7115: Do not load saa7115_init_misc for gm7113c
[mirror_ubuntu-artful-kernel.git] / drivers / media / i2c / saa7115.c
CommitLineData
89f75ffc
MCC
1/* saa711x - Philips SAA711x video decoder driver
2 * This driver can work with saa7111, saa7111a, saa7113, saa7114,
3 * saa7115 and saa7118.
e19b2fcc
HV
4 *
5 * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
6 * the saa7111 driver by Dave Perks.
7 *
8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
10 *
11 * Slight changes for video timing and attachment output by
12 * Wolfgang Scherr <scherr@net4you.net>
13 *
14 * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
15 * by Ronald Bultje <rbultje@ronald.bitfreak.net>
16 *
17 * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
18 * (2/17/2003)
19 *
20 * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
89f75ffc
MCC
21 *
22 * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
23 * SAA7111, SAA7113 and SAA7118 support
e19b2fcc
HV
24 *
25 * This program is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * as published by the Free Software Foundation; either version 2
28 * of the License, or (at your option) any later version.
29 *
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
34 *
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
38 */
39
96ecfc4e 40#include "saa711x_regs.h"
e19b2fcc
HV
41
42#include <linux/kernel.h>
43#include <linux/module.h>
44#include <linux/slab.h>
45#include <linux/i2c.h>
46#include <linux/videodev2.h>
9415f4b2 47#include <media/v4l2-device.h>
e3560543 48#include <media/v4l2-ctrls.h>
1f8f5fa9 49#include <media/saa7115.h>
3578d3dd 50#include <asm/div64.h>
e19b2fcc 51
97d9e80e 52#define VRES_60HZ (480+16)
d9dce96f 53
89f75ffc 54MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
f5762e44
MCC
55MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
56 "Hans Verkuil, Mauro Carvalho Chehab");
e19b2fcc
HV
57MODULE_LICENSE("GPL");
58
90ab5ee9 59static bool debug;
fac9e899 60module_param(debug, bool, 0644);
e19b2fcc
HV
61
62MODULE_PARM_DESC(debug, "Debug level (0-1)");
63
e19b2fcc 64
e1277110
HV
65enum saa711x_model {
66 SAA7111A,
67 SAA7111,
68 SAA7113,
69 GM7113C,
70 SAA7114,
71 SAA7115,
72 SAA7118,
73};
74
66ec1193 75struct saa711x_state {
9415f4b2 76 struct v4l2_subdev sd;
e3560543
HV
77 struct v4l2_ctrl_handler hdl;
78
79 struct {
80 /* chroma gain control cluster */
81 struct v4l2_ctrl *agc;
82 struct v4l2_ctrl *gain;
83 };
84
e19b2fcc
HV
85 v4l2_std_id std;
86 int input;
4cbca185 87 int output;
e19b2fcc 88 int enable;
3faeeae4 89 int radio;
d9dce96f
MCC
90 int width;
91 int height;
e1277110 92 enum saa711x_model ident;
3578d3dd 93 u32 audclk_freq;
b7f8292c 94 u32 crystal_freq;
1589037f 95 bool ucgc;
b7f8292c 96 u8 cgcdiv;
1589037f
HV
97 bool apll;
98 bool double_asclk;
e19b2fcc
HV
99};
100
9415f4b2
HV
101static inline struct saa711x_state *to_state(struct v4l2_subdev *sd)
102{
103 return container_of(sd, struct saa711x_state, sd);
104}
105
e3560543
HV
106static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
107{
108 return &container_of(ctrl->handler, struct saa711x_state, hdl)->sd;
109}
110
e19b2fcc
HV
111/* ----------------------------------------------------------------------- */
112
9415f4b2 113static inline int saa711x_write(struct v4l2_subdev *sd, u8 reg, u8 value)
e19b2fcc 114{
9415f4b2
HV
115 struct i2c_client *client = v4l2_get_subdevdata(sd);
116
e19b2fcc
HV
117 return i2c_smbus_write_byte_data(client, reg, value);
118}
119
89f75ffc
MCC
120/* Sanity routine to check if a register is present */
121static int saa711x_has_reg(const int id, const u8 reg)
122{
e1277110 123 if (id == SAA7111)
d9dce96f
MCC
124 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
125 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
e1277110 126 if (id == SAA7111A)
340dde81
HV
127 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
128 reg != 0x14 && reg != 0x18 && reg != 0x19 &&
129 reg != 0x1d && reg != 0x1e;
d9dce96f
MCC
130
131 /* common for saa7113/4/5/8 */
132 if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
133 reg == 0xa3 || reg == 0xa7 || reg == 0xab || reg == 0xaf || (reg >= 0xb5 && reg <= 0xb7) ||
134 reg == 0xd3 || reg == 0xd7 || reg == 0xdb || reg == 0xdf || (reg >= 0xe5 && reg <= 0xe7) ||
135 reg == 0x82 || (reg >= 0x89 && reg <= 0x8e)))
136 return 0;
137
89f75ffc 138 switch (id) {
e1277110 139 case GM7113C:
241d89fc 140 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && reg < 0x20;
e1277110 141 case SAA7113:
d9dce96f
MCC
142 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
143 reg != 0x5d && reg < 0x63;
e1277110 144 case SAA7114:
d9dce96f
MCC
145 return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
146 (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
147 reg != 0x81 && reg < 0xf0;
e1277110 148 case SAA7115:
d9dce96f 149 return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
e1277110 150 case SAA7118:
d9dce96f
MCC
151 return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
152 (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
153 (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
89f75ffc 154 }
89f75ffc
MCC
155 return 1;
156}
157
9415f4b2 158static int saa711x_writeregs(struct v4l2_subdev *sd, const unsigned char *regs)
e19b2fcc 159{
9415f4b2 160 struct saa711x_state *state = to_state(sd);
e19b2fcc
HV
161 unsigned char reg, data;
162
163 while (*regs != 0x00) {
164 reg = *(regs++);
165 data = *(regs++);
89f75ffc
MCC
166
167 /* According with datasheets, reserved regs should be
168 filled with 0 - seems better not to touch on they */
9415f4b2
HV
169 if (saa711x_has_reg(state->ident, reg)) {
170 if (saa711x_write(sd, reg, data) < 0)
89f75ffc 171 return -1;
d87edf26 172 } else {
9415f4b2 173 v4l2_dbg(1, debug, sd, "tried to access reserved reg 0x%02x\n", reg);
89f75ffc 174 }
e19b2fcc
HV
175 }
176 return 0;
177}
178
9415f4b2 179static inline int saa711x_read(struct v4l2_subdev *sd, u8 reg)
e19b2fcc 180{
9415f4b2
HV
181 struct i2c_client *client = v4l2_get_subdevdata(sd);
182
e19b2fcc
HV
183 return i2c_smbus_read_byte_data(client, reg);
184}
185
186/* ----------------------------------------------------------------------- */
187
89f75ffc 188/* SAA7111 initialization table */
183d896a 189static const unsigned char saa7111_init[] = {
89f75ffc
MCC
190 R_01_INC_DELAY, 0x00, /* reserved */
191
192 /*front end */
193 R_02_INPUT_CNTL_1, 0xd0, /* FUSE=3, GUDL=2, MODE=0 */
194 R_03_INPUT_CNTL_2, 0x23, /* HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0,
195 * GAFIX=0, GAI1=256, GAI2=256 */
196 R_04_INPUT_CNTL_3, 0x00, /* GAI1=256 */
197 R_05_INPUT_CNTL_4, 0x00, /* GAI2=256 */
198
199 /* decoder */
200 R_06_H_SYNC_START, 0xf3, /* HSB at 13(50Hz) / 17(60Hz)
201 * pixels after end of last line */
202 R_07_H_SYNC_STOP, 0xe8, /* HSS seems to be needed to
203 * work with NTSC, too */
204 R_08_SYNC_CNTL, 0xc8, /* AUFD=1, FSEL=1, EXFIL=0,
205 * VTRC=1, HPLL=0, VNOI=0 */
206 R_09_LUMA_CNTL, 0x01, /* BYPS=0, PREF=0, BPSS=0,
207 * VBLB=0, UPTCV=0, APER=1 */
208 R_0A_LUMA_BRIGHT_CNTL, 0x80,
209 R_0B_LUMA_CONTRAST_CNTL, 0x47, /* 0b - CONT=1.109 */
210 R_0C_CHROMA_SAT_CNTL, 0x40,
211 R_0D_CHROMA_HUE_CNTL, 0x00,
212 R_0E_CHROMA_CNTL_1, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
213 * FCTC=0, CHBW=1 */
214 R_0F_CHROMA_GAIN_CNTL, 0x00, /* reserved */
215 R_10_CHROMA_CNTL_2, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
216 R_11_MODE_DELAY_CNTL, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
217 * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
218 R_12_RT_SIGNAL_CNTL, 0x00, /* 12 - output control 2 */
219 R_13_RT_X_PORT_OUT_CNTL, 0x00, /* 13 - output control 3 */
220 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
221 R_15_VGATE_START_FID_CHG, 0x00,
222 R_16_VGATE_STOP, 0x00,
223 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
224
225 0x00, 0x00
226};
227
241d89fc
JAJ
228/* SAA7113/GM7113C init codes
229 * It's important that R_14... R_17 == 0x00
230 * for the gm7113c chip to deliver stable video
231 */
183d896a 232static const unsigned char saa7113_init[] = {
89f75ffc
MCC
233 R_01_INC_DELAY, 0x08,
234 R_02_INPUT_CNTL_1, 0xc2,
235 R_03_INPUT_CNTL_2, 0x30,
236 R_04_INPUT_CNTL_3, 0x00,
237 R_05_INPUT_CNTL_4, 0x00,
238 R_06_H_SYNC_START, 0x89,
239 R_07_H_SYNC_STOP, 0x0d,
240 R_08_SYNC_CNTL, 0x88,
241 R_09_LUMA_CNTL, 0x01,
242 R_0A_LUMA_BRIGHT_CNTL, 0x80,
243 R_0B_LUMA_CONTRAST_CNTL, 0x47,
244 R_0C_CHROMA_SAT_CNTL, 0x40,
245 R_0D_CHROMA_HUE_CNTL, 0x00,
246 R_0E_CHROMA_CNTL_1, 0x01,
247 R_0F_CHROMA_GAIN_CNTL, 0x2a,
248 R_10_CHROMA_CNTL_2, 0x08,
249 R_11_MODE_DELAY_CNTL, 0x0c,
250 R_12_RT_SIGNAL_CNTL, 0x07,
251 R_13_RT_X_PORT_OUT_CNTL, 0x00,
252 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
253 R_15_VGATE_START_FID_CHG, 0x00,
254 R_16_VGATE_STOP, 0x00,
255 R_17_MISC_VGATE_CONF_AND_MSB, 0x00,
256
257 0x00, 0x00
258};
259
e19b2fcc
HV
260/* If a value differs from the Hauppauge driver values, then the comment starts with
261 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
262 Hauppauge driver sets. */
263
89f75ffc 264/* SAA7114 and SAA7115 initialization table */
e19b2fcc 265static const unsigned char saa7115_init_auto_input[] = {
f5762e44 266 /* Front-End Part */
96ecfc4e
MCC
267 R_01_INC_DELAY, 0x48, /* white peak control disabled */
268 R_03_INPUT_CNTL_2, 0x20, /* was 0x30. 0x20: long vertical blanking */
269 R_04_INPUT_CNTL_3, 0x90, /* analog gain set to 0 */
270 R_05_INPUT_CNTL_4, 0x90, /* analog gain set to 0 */
f5762e44 271 /* Decoder Part */
96ecfc4e
MCC
272 R_06_H_SYNC_START, 0xeb, /* horiz sync begin = -21 */
273 R_07_H_SYNC_STOP, 0xe0, /* horiz sync stop = -17 */
183d896a 274 R_09_LUMA_CNTL, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
96ecfc4e
MCC
275 R_0A_LUMA_BRIGHT_CNTL, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
276 R_0B_LUMA_CONTRAST_CNTL, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
277 R_0C_CHROMA_SAT_CNTL, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
278 R_0D_CHROMA_HUE_CNTL, 0x00,
279 R_0F_CHROMA_GAIN_CNTL, 0x00, /* use automatic gain */
280 R_10_CHROMA_CNTL_2, 0x06, /* chroma: active adaptive combfilter */
281 R_11_MODE_DELAY_CNTL, 0x00,
282 R_12_RT_SIGNAL_CNTL, 0x9d, /* RTS0 output control: VGATE */
283 R_13_RT_X_PORT_OUT_CNTL, 0x80, /* ITU656 standard mode, RTCO output enable RTCE */
284 R_14_ANAL_ADC_COMPAT_CNTL, 0x00,
285 R_18_RAW_DATA_GAIN_CNTL, 0x40, /* gain 0x00 = nominal */
286 R_19_RAW_DATA_OFF_CNTL, 0x80,
287 R_1A_COLOR_KILL_LVL_CNTL, 0x77, /* recommended value */
288 R_1B_MISC_TVVCRDET, 0x42, /* recommended value */
289 R_1C_ENHAN_COMB_CTRL1, 0xa9, /* recommended value */
290 R_1D_ENHAN_COMB_CTRL2, 0x01, /* recommended value */
f5762e44 291
d9dce96f
MCC
292
293 R_80_GLOBAL_CNTL_1, 0x0, /* No tasks enabled at init */
294
f5762e44 295 /* Power Device Control */
96ecfc4e
MCC
296 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset device */
297 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* set device programmed, all in operational mode */
e19b2fcc
HV
298 0x00, 0x00
299};
300
89f75ffc 301/* Used to reset saa7113, saa7114 and saa7115 */
e19b2fcc 302static const unsigned char saa7115_cfg_reset_scaler[] = {
96ecfc4e
MCC
303 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x00, /* disable I-port output */
304 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
305 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
306 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* enable I-port output */
e19b2fcc
HV
307 0x00, 0x00
308};
309
310/* ============== SAA7715 VIDEO templates ============= */
311
e19b2fcc 312static const unsigned char saa7115_cfg_60hz_video[] = {
96ecfc4e
MCC
313 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
314 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
e19b2fcc 315
96ecfc4e
MCC
316 R_15_VGATE_START_FID_CHG, 0x03,
317 R_16_VGATE_STOP, 0x11,
318 R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
e19b2fcc 319
96ecfc4e
MCC
320 R_08_SYNC_CNTL, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
321 R_0E_CHROMA_CNTL_1, 0x07, /* video autodetection is on */
e19b2fcc 322
96ecfc4e 323 R_5A_V_OFF_FOR_SLICER, 0x06, /* standard 60hz value for ITU656 line counting */
e19b2fcc
HV
324
325 /* Task A */
96ecfc4e
MCC
326 R_90_A_TASK_HANDLING_CNTL, 0x80,
327 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
328 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
329 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
330
331 /* hoffset low (input), 0x0002 is minimum */
332 R_94_A_HORIZ_INPUT_WINDOW_START, 0x01,
333 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
334
335 /* hsize low (input), 0x02d0 = 720 */
336 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
337 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
338
339 R_98_A_VERT_INPUT_WINDOW_START, 0x05,
340 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
341
342 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x0c,
343 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
344
345 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
346 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05,
347
348 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x0c,
349 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
e19b2fcc
HV
350
351 /* Task B */
96ecfc4e
MCC
352 R_C0_B_TASK_HANDLING_CNTL, 0x00,
353 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
354 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
355 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
356
357 /* 0x0002 is minimum */
358 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
359 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
360
361 /* 0x02d0 = 720 */
362 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
363 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
364
365 /* vwindow start 0x12 = 18 */
366 R_C8_B_VERT_INPUT_WINDOW_START, 0x12,
367 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
368
369 /* vwindow length 0xf8 = 248 */
97d9e80e
MCC
370 R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
371 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
96ecfc4e
MCC
372
373 /* hwindow 0x02d0 = 720 */
374 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
375 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
376
377 R_F0_LFCO_PER_LINE, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
378 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0 */
379 R_F5_PULSGEN_LINE_LENGTH, 0xad,
380 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
381
e19b2fcc
HV
382 0x00, 0x00
383};
384
e19b2fcc 385static const unsigned char saa7115_cfg_50hz_video[] = {
96ecfc4e
MCC
386 R_80_GLOBAL_CNTL_1, 0x00,
387 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
e19b2fcc 388
96ecfc4e
MCC
389 R_15_VGATE_START_FID_CHG, 0x37, /* VGATE start */
390 R_16_VGATE_STOP, 0x16,
391 R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
e19b2fcc 392
96ecfc4e
MCC
393 R_08_SYNC_CNTL, 0x28, /* 0x28 = PAL */
394 R_0E_CHROMA_CNTL_1, 0x07,
e19b2fcc 395
96ecfc4e 396 R_5A_V_OFF_FOR_SLICER, 0x03, /* standard 50hz value */
e19b2fcc
HV
397
398 /* Task A */
96ecfc4e
MCC
399 R_90_A_TASK_HANDLING_CNTL, 0x81,
400 R_91_A_X_PORT_FORMATS_AND_CONF, 0x48,
401 R_92_A_X_PORT_INPUT_REFERENCE_SIGNAL, 0x40,
402 R_93_A_I_PORT_OUTPUT_FORMATS_AND_CONF, 0x84,
403
e19b2fcc
HV
404 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
405 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
96ecfc4e
MCC
406 /* hoffset low (input), 0x0002 is minimum */
407 R_94_A_HORIZ_INPUT_WINDOW_START, 0x00,
408 R_95_A_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
409
410 /* hsize low (input), 0x02d0 = 720 */
411 R_96_A_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
412 R_97_A_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
413
414 R_98_A_VERT_INPUT_WINDOW_START, 0x03,
415 R_99_A_VERT_INPUT_WINDOW_START_MSB, 0x00,
416
417 /* vsize 0x12 = 18 */
418 R_9A_A_VERT_INPUT_WINDOW_LENGTH, 0x12,
419 R_9B_A_VERT_INPUT_WINDOW_LENGTH_MSB, 0x00,
420
421 /* hsize 0x05a0 = 1440 */
422 R_9C_A_HORIZ_OUTPUT_WINDOW_LENGTH, 0xa0,
423 R_9D_A_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x05, /* hsize hi (output) */
424 R_9E_A_VERT_OUTPUT_WINDOW_LENGTH, 0x12, /* vsize low (output), 0x12 = 18 */
425 R_9F_A_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00, /* vsize hi (output) */
e19b2fcc
HV
426
427 /* Task B */
96ecfc4e
MCC
428 R_C0_B_TASK_HANDLING_CNTL, 0x00,
429 R_C1_B_X_PORT_FORMATS_AND_CONF, 0x08,
430 R_C2_B_INPUT_REFERENCE_SIGNAL_DEFINITION, 0x00,
431 R_C3_B_I_PORT_FORMATS_AND_CONF, 0x80,
432
433 /* This is weird: the datasheet says that you should use 2 as the minimum value, */
434 /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
435 /* hoffset low (input), 0x0002 is minimum. See comment above. */
436 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x00,
437 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
438
439 /* hsize 0x02d0 = 720 */
440 R_C6_B_HORIZ_INPUT_WINDOW_LENGTH, 0xd0,
441 R_C7_B_HORIZ_INPUT_WINDOW_LENGTH_MSB, 0x02,
442
443 /* voffset 0x16 = 22 */
444 R_C8_B_VERT_INPUT_WINDOW_START, 0x16,
445 R_C9_B_VERT_INPUT_WINDOW_START_MSB, 0x00,
446
447 /* vsize 0x0120 = 288 */
448 R_CA_B_VERT_INPUT_WINDOW_LENGTH, 0x20,
449 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, 0x01,
450
451 /* hsize 0x02d0 = 720 */
452 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
453 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
454
96ecfc4e
MCC
455 R_F0_LFCO_PER_LINE, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
456 R_F1_P_I_PARAM_SELECT, 0x05, /* low bit with 0xF0, (was 0x05) */
457 R_F5_PULSGEN_LINE_LENGTH, 0xb0,
458 R_F6_PULSE_A_POS_LSB_AND_PULSEGEN_CONFIG, 0x01,
459
e19b2fcc
HV
460 0x00, 0x00
461};
462
463/* ============== SAA7715 VIDEO templates (end) ======= */
464
465static const unsigned char saa7115_cfg_vbi_on[] = {
96ecfc4e
MCC
466 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
467 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
468 R_80_GLOBAL_CNTL_1, 0x30, /* Activate both tasks */
469 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
470 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
471
e19b2fcc
HV
472 0x00, 0x00
473};
474
475static const unsigned char saa7115_cfg_vbi_off[] = {
96ecfc4e
MCC
476 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
477 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
478 R_80_GLOBAL_CNTL_1, 0x20, /* Activate only task "B" */
479 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0, /* activate scaler */
480 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01, /* Enable I-port output */
481
e19b2fcc
HV
482 0x00, 0x00
483};
484
f5762e44 485
e19b2fcc 486static const unsigned char saa7115_init_misc[] = {
96ecfc4e 487 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
96ecfc4e
MCC
488 R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 0x01,
489 R_84_I_PORT_SIGNAL_DEF, 0x20,
490 R_85_I_PORT_SIGNAL_POLAR, 0x21,
491 R_86_I_PORT_FIFO_FLAG_CNTL_AND_ARBIT, 0xc5,
492 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, 0x01,
e19b2fcc
HV
493
494 /* Task A */
96ecfc4e
MCC
495 R_A0_A_HORIZ_PRESCALING, 0x01,
496 R_A1_A_ACCUMULATION_LENGTH, 0x00,
497 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
498
499 /* Configure controls at nominal value*/
500 R_A4_A_LUMA_BRIGHTNESS_CNTL, 0x80,
501 R_A5_A_LUMA_CONTRAST_CNTL, 0x40,
502 R_A6_A_CHROMA_SATURATION_CNTL, 0x40,
503
504 /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
505 R_A8_A_HORIZ_LUMA_SCALING_INC, 0x00,
506 R_A9_A_HORIZ_LUMA_SCALING_INC_MSB, 0x02,
507
508 R_AA_A_HORIZ_LUMA_PHASE_OFF, 0x00,
509
510 /* must be horiz lum scaling / 2 */
511 R_AC_A_HORIZ_CHROMA_SCALING_INC, 0x00,
512 R_AD_A_HORIZ_CHROMA_SCALING_INC_MSB, 0x01,
513
514 /* must be offset luma / 2 */
515 R_AE_A_HORIZ_CHROMA_PHASE_OFF, 0x00,
516
517 R_B0_A_VERT_LUMA_SCALING_INC, 0x00,
518 R_B1_A_VERT_LUMA_SCALING_INC_MSB, 0x04,
519
520 R_B2_A_VERT_CHROMA_SCALING_INC, 0x00,
521 R_B3_A_VERT_CHROMA_SCALING_INC_MSB, 0x04,
522
523 R_B4_A_VERT_SCALING_MODE_CNTL, 0x01,
524
525 R_B8_A_VERT_CHROMA_PHASE_OFF_00, 0x00,
526 R_B9_A_VERT_CHROMA_PHASE_OFF_01, 0x00,
527 R_BA_A_VERT_CHROMA_PHASE_OFF_10, 0x00,
528 R_BB_A_VERT_CHROMA_PHASE_OFF_11, 0x00,
529
530 R_BC_A_VERT_LUMA_PHASE_OFF_00, 0x00,
531 R_BD_A_VERT_LUMA_PHASE_OFF_01, 0x00,
532 R_BE_A_VERT_LUMA_PHASE_OFF_10, 0x00,
533 R_BF_A_VERT_LUMA_PHASE_OFF_11, 0x00,
e19b2fcc
HV
534
535 /* Task B */
96ecfc4e
MCC
536 R_D0_B_HORIZ_PRESCALING, 0x01,
537 R_D1_B_ACCUMULATION_LENGTH, 0x00,
538 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
539
540 /* Configure controls at nominal value*/
541 R_D4_B_LUMA_BRIGHTNESS_CNTL, 0x80,
542 R_D5_B_LUMA_CONTRAST_CNTL, 0x40,
543 R_D6_B_CHROMA_SATURATION_CNTL, 0x40,
544
545 /* hor lum scaling 0x0400 = 1 */
546 R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
547 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
548
549 R_DA_B_HORIZ_LUMA_PHASE_OFF, 0x00,
550
551 /* must be hor lum scaling / 2 */
552 R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
553 R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
554
555 /* must be offset luma / 2 */
556 R_DE_B_HORIZ_PHASE_OFFSET_CRHOMA, 0x00,
557
558 R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
559 R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
560
561 R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
562 R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
563
564 R_E4_B_VERT_SCALING_MODE_CNTL, 0x01,
565
566 R_E8_B_VERT_CHROMA_PHASE_OFF_00, 0x00,
567 R_E9_B_VERT_CHROMA_PHASE_OFF_01, 0x00,
568 R_EA_B_VERT_CHROMA_PHASE_OFF_10, 0x00,
569 R_EB_B_VERT_CHROMA_PHASE_OFF_11, 0x00,
570
571 R_EC_B_VERT_LUMA_PHASE_OFF_00, 0x00,
572 R_ED_B_VERT_LUMA_PHASE_OFF_01, 0x00,
573 R_EE_B_VERT_LUMA_PHASE_OFF_10, 0x00,
574 R_EF_B_VERT_LUMA_PHASE_OFF_11, 0x00,
575
576 R_F2_NOMINAL_PLL2_DTO, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
577 R_F3_PLL_INCREMENT, 0x46,
578 R_F4_PLL2_STATUS, 0x00,
579 R_F7_PULSE_A_POS_MSB, 0x4b, /* not the recommended settings! */
580 R_F8_PULSE_B_POS, 0x00,
581 R_F9_PULSE_B_POS_MSB, 0x4b,
582 R_FA_PULSE_C_POS, 0x00,
583 R_FB_PULSE_C_POS_MSB, 0x4b,
584
585 /* PLL2 lock detection settings: 71 lines 50% phase error */
586 R_FF_S_PLL_MAX_PHASE_ERR_THRESH_NUM_LINES, 0x88,
e19b2fcc
HV
587
588 /* Turn off VBI */
96ecfc4e
MCC
589 R_40_SLICER_CNTL_1, 0x20, /* No framing code errors allowed. */
590 R_41_LCR_BASE, 0xff,
591 R_41_LCR_BASE+1, 0xff,
592 R_41_LCR_BASE+2, 0xff,
593 R_41_LCR_BASE+3, 0xff,
594 R_41_LCR_BASE+4, 0xff,
595 R_41_LCR_BASE+5, 0xff,
596 R_41_LCR_BASE+6, 0xff,
597 R_41_LCR_BASE+7, 0xff,
598 R_41_LCR_BASE+8, 0xff,
599 R_41_LCR_BASE+9, 0xff,
600 R_41_LCR_BASE+10, 0xff,
601 R_41_LCR_BASE+11, 0xff,
602 R_41_LCR_BASE+12, 0xff,
603 R_41_LCR_BASE+13, 0xff,
604 R_41_LCR_BASE+14, 0xff,
605 R_41_LCR_BASE+15, 0xff,
606 R_41_LCR_BASE+16, 0xff,
607 R_41_LCR_BASE+17, 0xff,
608 R_41_LCR_BASE+18, 0xff,
609 R_41_LCR_BASE+19, 0xff,
610 R_41_LCR_BASE+20, 0xff,
611 R_41_LCR_BASE+21, 0xff,
612 R_41_LCR_BASE+22, 0xff,
613 R_58_PROGRAM_FRAMING_CODE, 0x40,
614 R_59_H_OFF_FOR_SLICER, 0x47,
615 R_5B_FLD_OFF_AND_MSB_FOR_H_AND_V_OFF, 0x83,
616 R_5D_DID, 0xbd,
617 R_5E_SDID, 0x35,
618
fea551fa 619 R_02_INPUT_CNTL_1, 0xc4, /* input tuner -> input 4, amplifier active */
96ecfc4e
MCC
620
621 R_80_GLOBAL_CNTL_1, 0x20, /* enable task B */
622 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,
623 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xf0,
e19b2fcc
HV
624 0x00, 0x00
625};
626
66ec1193 627static int saa711x_odd_parity(u8 c)
e19b2fcc
HV
628{
629 c ^= (c >> 4);
630 c ^= (c >> 2);
631 c ^= (c >> 1);
632
633 return c & 1;
634}
635
9415f4b2 636static int saa711x_decode_vps(u8 *dst, u8 *p)
e19b2fcc
HV
637{
638 static const u8 biphase_tbl[] = {
639 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
640 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
641 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
642 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
643 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
644 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
645 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
646 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
647 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
648 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
649 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
650 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
651 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
652 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
653 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
654 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
655 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
656 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
657 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
658 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
659 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
660 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
661 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
662 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
663 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
664 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
665 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
666 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
667 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
668 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
669 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
670 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
671 };
672 int i;
673 u8 c, err = 0;
674
675 for (i = 0; i < 2 * 13; i += 2) {
676 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
677 c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
678 dst[i / 2] = c;
679 }
680 return err & 0xf0;
681}
682
9415f4b2 683static int saa711x_decode_wss(u8 *p)
e19b2fcc
HV
684{
685 static const int wss_bits[8] = {
686 0, 0, 0, 1, 0, 1, 1, 1
687 };
688 unsigned char parity;
689 int wss = 0;
690 int i;
691
692 for (i = 0; i < 16; i++) {
693 int b1 = wss_bits[p[i] & 7];
694 int b2 = wss_bits[(p[i] >> 3) & 7];
695
696 if (b1 == b2)
697 return -1;
698 wss |= b2 << i;
699 }
700 parity = wss & 15;
701 parity ^= parity >> 2;
702 parity ^= parity >> 1;
703
704 if (!(parity & 1))
705 return -1;
706
707 return wss;
708}
709
9415f4b2 710static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
e19b2fcc 711{
9415f4b2 712 struct saa711x_state *state = to_state(sd);
3578d3dd
HV
713 u32 acpf;
714 u32 acni;
715 u32 hz;
716 u64 f;
b7f8292c 717 u8 acc = 0; /* reg 0x3a, audio clock control */
e19b2fcc 718
89f75ffc 719 /* Checks for chips that don't have audio clock (saa7111, saa7113) */
9415f4b2 720 if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
89f75ffc
MCC
721 return 0;
722
9415f4b2 723 v4l2_dbg(1, debug, sd, "set audio clock freq: %d\n", freq);
3578d3dd
HV
724
725 /* sanity check */
726 if (freq < 32000 || freq > 48000)
727 return -EINVAL;
728
729 /* hz is the refresh rate times 100 */
730 hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
731 /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
732 acpf = (25600 * freq) / hz;
733 /* acni = (256 * freq * 2^23) / crystal_frequency =
734 (freq * 2^(8+23)) / crystal_frequency =
b7f8292c 735 (freq << 31) / crystal_frequency */
3578d3dd
HV
736 f = freq;
737 f = f << 31;
b7f8292c 738 do_div(f, state->crystal_freq);
3578d3dd 739 acni = f;
b7f8292c
HV
740 if (state->ucgc) {
741 acpf = acpf * state->cgcdiv / 16;
742 acni = acni * state->cgcdiv / 16;
743 acc = 0x80;
744 if (state->cgcdiv == 3)
745 acc |= 0x40;
746 }
747 if (state->apll)
748 acc |= 0x08;
3578d3dd 749
1589037f
HV
750 if (state->double_asclk) {
751 acpf <<= 1;
752 acni <<= 1;
753 }
9415f4b2 754 saa711x_write(sd, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
1589037f 755 saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10 << state->double_asclk);
9415f4b2 756 saa711x_write(sd, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
96ecfc4e 757
9415f4b2
HV
758 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
759 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
96ecfc4e 760 (acpf >> 8) & 0xff);
9415f4b2 761 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
96ecfc4e
MCC
762 (acpf >> 16) & 0x03);
763
9415f4b2
HV
764 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
765 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
766 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
e19b2fcc
HV
767 state->audclk_freq = freq;
768 return 0;
769}
770
e3560543 771static int saa711x_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
e19b2fcc 772{
e3560543 773 struct v4l2_subdev *sd = to_sd(ctrl);
9415f4b2 774 struct saa711x_state *state = to_state(sd);
e19b2fcc
HV
775
776 switch (ctrl->id) {
87a6fe4a 777 case V4L2_CID_CHROMA_AGC:
e3560543 778 /* chroma gain cluster */
ddac5c10
HV
779 if (state->agc->val)
780 state->gain->val =
e3560543 781 saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL) & 0x7f;
87a6fe4a 782 break;
e19b2fcc 783 }
e19b2fcc
HV
784 return 0;
785}
786
e3560543 787static int saa711x_s_ctrl(struct v4l2_ctrl *ctrl)
e19b2fcc 788{
e3560543 789 struct v4l2_subdev *sd = to_sd(ctrl);
9415f4b2 790 struct saa711x_state *state = to_state(sd);
e19b2fcc
HV
791
792 switch (ctrl->id) {
793 case V4L2_CID_BRIGHTNESS:
e3560543 794 saa711x_write(sd, R_0A_LUMA_BRIGHT_CNTL, ctrl->val);
e19b2fcc 795 break;
e3560543 796
e19b2fcc 797 case V4L2_CID_CONTRAST:
e3560543 798 saa711x_write(sd, R_0B_LUMA_CONTRAST_CNTL, ctrl->val);
e19b2fcc 799 break;
e3560543 800
e19b2fcc 801 case V4L2_CID_SATURATION:
e3560543 802 saa711x_write(sd, R_0C_CHROMA_SAT_CNTL, ctrl->val);
e19b2fcc 803 break;
e3560543 804
e19b2fcc 805 case V4L2_CID_HUE:
e3560543 806 saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, ctrl->val);
e19b2fcc 807 break;
e3560543 808
87a6fe4a 809 case V4L2_CID_CHROMA_AGC:
e3560543
HV
810 /* chroma gain cluster */
811 if (state->agc->val)
812 saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val);
813 else
814 saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val | 0x80);
87a6fe4a 815 break;
e3560543 816
e19b2fcc
HV
817 default:
818 return -EINVAL;
819 }
820
821 return 0;
822}
823
9415f4b2 824static int saa711x_set_size(struct v4l2_subdev *sd, int width, int height)
d9dce96f 825{
9415f4b2 826 struct saa711x_state *state = to_state(sd);
d9dce96f
MCC
827 int HPSC, HFSC;
828 int VSCY;
829 int res;
830 int is_50hz = state->std & V4L2_STD_625_50;
831 int Vsrc = is_50hz ? 576 : 480;
832
9415f4b2 833 v4l2_dbg(1, debug, sd, "decoder set size to %ix%i\n", width, height);
d9dce96f
MCC
834
835 /* FIXME need better bounds checking here */
836 if ((width < 1) || (width > 1440))
837 return -EINVAL;
838 if ((height < 1) || (height > Vsrc))
839 return -EINVAL;
840
9415f4b2 841 if (!saa711x_has_reg(state->ident, R_D0_B_HORIZ_PRESCALING)) {
d9dce96f
MCC
842 /* Decoder only supports 720 columns and 480 or 576 lines */
843 if (width != 720)
844 return -EINVAL;
845 if (height != Vsrc)
846 return -EINVAL;
847 }
848
849 state->width = width;
850 state->height = height;
851
852 if (!saa711x_has_reg(state->ident, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
853 return 0;
854
855 /* probably have a valid size, let's set it */
856 /* Set output width/height */
857 /* width */
858
9415f4b2 859 saa711x_write(sd, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
d9dce96f 860 (u8) (width & 0xff));
9415f4b2 861 saa711x_write(sd, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
d9dce96f
MCC
862 (u8) ((width >> 8) & 0xff));
863
864 /* Vertical Scaling uses height/2 */
9415f4b2 865 res = height / 2;
d9dce96f
MCC
866
867 /* On 60Hz, it is using a higher Vertical Output Size */
868 if (!is_50hz)
d0d30c03 869 res += (VRES_60HZ - 480) >> 1;
d9dce96f
MCC
870
871 /* height */
9415f4b2 872 saa711x_write(sd, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
d9dce96f 873 (u8) (res & 0xff));
9415f4b2 874 saa711x_write(sd, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
d9dce96f
MCC
875 (u8) ((res >> 8) & 0xff));
876
877 /* Scaling settings */
878 /* Hprescaler is floor(inres/outres) */
879 HPSC = (int)(720 / width);
880 /* 0 is not allowed (div. by zero) */
881 HPSC = HPSC ? HPSC : 1;
882 HFSC = (int)((1024 * 720) / (HPSC * width));
883 /* FIXME hardcodes to "Task B"
884 * write H prescaler integer */
9415f4b2 885 saa711x_write(sd, R_D0_B_HORIZ_PRESCALING,
d9dce96f
MCC
886 (u8) (HPSC & 0x3f));
887
9415f4b2 888 v4l2_dbg(1, debug, sd, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
d9dce96f 889 /* write H fine-scaling (luminance) */
9415f4b2 890 saa711x_write(sd, R_D8_B_HORIZ_LUMA_SCALING_INC,
d9dce96f 891 (u8) (HFSC & 0xff));
9415f4b2 892 saa711x_write(sd, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
d9dce96f
MCC
893 (u8) ((HFSC >> 8) & 0xff));
894 /* write H fine-scaling (chrominance)
895 * must be lum/2, so i'll just bitshift :) */
9415f4b2 896 saa711x_write(sd, R_DC_B_HORIZ_CHROMA_SCALING,
d9dce96f 897 (u8) ((HFSC >> 1) & 0xff));
9415f4b2 898 saa711x_write(sd, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
d9dce96f
MCC
899 (u8) ((HFSC >> 9) & 0xff));
900
901 VSCY = (int)((1024 * Vsrc) / height);
9415f4b2 902 v4l2_dbg(1, debug, sd, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
d9dce96f
MCC
903
904 /* Correct Contrast and Luminance */
9415f4b2 905 saa711x_write(sd, R_D5_B_LUMA_CONTRAST_CNTL,
d9dce96f 906 (u8) (64 * 1024 / VSCY));
9415f4b2 907 saa711x_write(sd, R_D6_B_CHROMA_SATURATION_CNTL,
d9dce96f
MCC
908 (u8) (64 * 1024 / VSCY));
909
910 /* write V fine-scaling (luminance) */
9415f4b2 911 saa711x_write(sd, R_E0_B_VERT_LUMA_SCALING_INC,
d9dce96f 912 (u8) (VSCY & 0xff));
9415f4b2 913 saa711x_write(sd, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
d9dce96f
MCC
914 (u8) ((VSCY >> 8) & 0xff));
915 /* write V fine-scaling (chrominance) */
9415f4b2 916 saa711x_write(sd, R_E2_B_VERT_CHROMA_SCALING_INC,
d9dce96f 917 (u8) (VSCY & 0xff));
9415f4b2 918 saa711x_write(sd, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
d9dce96f
MCC
919 (u8) ((VSCY >> 8) & 0xff));
920
9415f4b2 921 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
d9dce96f
MCC
922
923 /* Activates task "B" */
9415f4b2
HV
924 saa711x_write(sd, R_80_GLOBAL_CNTL_1,
925 saa711x_read(sd, R_80_GLOBAL_CNTL_1) | 0x20);
d9dce96f
MCC
926
927 return 0;
928}
929
9415f4b2 930static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
e19b2fcc 931{
9415f4b2 932 struct saa711x_state *state = to_state(sd);
e19b2fcc 933
30b54d50
HV
934 /* Prevent unnecessary standard changes. During a standard
935 change the I-Port is temporarily disabled. Any devices
936 reading from that port can get confused.
bccfa449
HV
937 Note that s_std is also used to switch from
938 radio to TV mode, so if a s_std is broadcast to
30b54d50
HV
939 all I2C devices then you do not want to have an unwanted
940 side-effect here. */
941 if (std == state->std)
942 return;
943
d9dce96f
MCC
944 state->std = std;
945
e19b2fcc
HV
946 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
947 if (std & V4L2_STD_525_60) {
9415f4b2 948 v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
8b77dfdd
JAJ
949 if (state->ident == GM7113C) {
950 u8 reg = saa711x_read(sd, R_08_SYNC_CNTL);
951 reg &= ~(SAA7113_R_08_FSEL | SAA7113_R_08_AUFD);
952 reg |= SAA7113_R_08_FSEL;
953 saa711x_write(sd, R_08_SYNC_CNTL, reg);
954 } else {
241d89fc 955 saa711x_writeregs(sd, saa7115_cfg_60hz_video);
8b77dfdd 956 }
9415f4b2 957 saa711x_set_size(sd, 720, 480);
e19b2fcc 958 } else {
9415f4b2 959 v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
8b77dfdd
JAJ
960 if (state->ident == GM7113C) {
961 u8 reg = saa711x_read(sd, R_08_SYNC_CNTL);
962 reg &= ~(SAA7113_R_08_FSEL | SAA7113_R_08_AUFD);
963 saa711x_write(sd, R_08_SYNC_CNTL, reg);
964 } else {
241d89fc 965 saa711x_writeregs(sd, saa7115_cfg_50hz_video);
8b77dfdd 966 }
9415f4b2 967 saa711x_set_size(sd, 720, 576);
e19b2fcc
HV
968 }
969
f89982a9 970 /* Register 0E - Bits D6-D4 on NO-AUTO mode
89f75ffc 971 (SAA7111 and SAA7113 doesn't have auto mode)
f89982a9
MCC
972 50 Hz / 625 lines 60 Hz / 525 lines
973 000 PAL BGDHI (4.43Mhz) NTSC M (3.58MHz)
974 001 NTSC 4.43 (50 Hz) PAL 4.43 (60 Hz)
975 010 Combination-PAL N (3.58MHz) NTSC 4.43 (60 Hz)
976 011 NTSC N (3.58MHz) PAL M (3.58MHz)
977 100 reserved NTSC-Japan (3.58MHz)
978 */
e1277110
HV
979 if (state->ident <= SAA7113 ||
980 state->ident == GM7113C) {
9415f4b2 981 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
f89982a9 982
02c17224 983 if (std == V4L2_STD_PAL_M) {
01342358 984 reg |= 0x30;
e0028027 985 } else if (std == V4L2_STD_PAL_Nc) {
01342358 986 reg |= 0x20;
02c17224 987 } else if (std == V4L2_STD_PAL_60) {
01342358 988 reg |= 0x10;
02c17224 989 } else if (std == V4L2_STD_NTSC_M_JP) {
01342358 990 reg |= 0x40;
a9aaec4e 991 } else if (std & V4L2_STD_SECAM) {