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