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