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