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