blob: 58062b41c923e48e1c87fdc421cf195b9bdb3e07 [file] [log] [blame]
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -03001/* saa711x - Philips SAA711x video decoder driver
2 * This driver can work with saa7111, saa7111a, saa7113, saa7114,
3 * saa7115 and saa7118.
Hans Verkuile19b2fc2005-11-13 16:08:04 -08004 *
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>
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -030021 *
22 * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
23 * SAA7111, SAA7113 and SAA7118 support
Hans Verkuile19b2fc2005-11-13 16:08:04 -080024 *
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
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -030040#include "saa711x_regs.h"
Hans Verkuile19b2fc2005-11-13 16:08:04 -080041
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>
Hans Verkuil9415f4b2008-11-29 12:55:19 -030047#include <media/v4l2-device.h>
Hans Verkuile3560542010-05-24 10:00:52 -030048#include <media/v4l2-ctrls.h>
Mauro Carvalho Chehabaf7d3742016-01-29 08:44:28 -020049#include <media/v4l2-mc.h>
Mauro Carvalho Chehabb5dcee22015-11-10 12:01:44 -020050#include <media/i2c/saa7115.h>
Hans Verkuil3578d3d2006-01-09 15:25:41 -020051#include <asm/div64.h>
Hans Verkuile19b2fc2005-11-13 16:08:04 -080052
Mauro Carvalho Chehab97d9e802006-09-03 09:38:11 -030053#define VRES_60HZ (480+16)
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -030054
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -030055MODULE_DESCRIPTION("Philips SAA7111/SAA7113/SAA7114/SAA7115/SAA7118 video decoder driver");
Mauro Carvalho Chehabf5762e42006-03-13 13:31:31 -030056MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
57 "Hans Verkuil, Mauro Carvalho Chehab");
Hans Verkuile19b2fc2005-11-13 16:08:04 -080058MODULE_LICENSE("GPL");
59
Rusty Russell90ab5ee2012-01-13 09:32:20 +103060static bool debug;
Hans Verkuilfac9e892006-01-09 15:32:40 -020061module_param(debug, bool, 0644);
Hans Verkuile19b2fc2005-11-13 16:08:04 -080062
63MODULE_PARM_DESC(debug, "Debug level (0-1)");
64
Hans Verkuile19b2fc2005-11-13 16:08:04 -080065
Hans Verkuile1277112013-05-29 06:59:51 -030066enum saa711x_model {
67 SAA7111A,
68 SAA7111,
69 SAA7113,
70 GM7113C,
71 SAA7114,
72 SAA7115,
73 SAA7118,
74};
75
Mauro Carvalho Chehab66ec11932006-08-29 22:52:32 -030076struct saa711x_state {
Hans Verkuil9415f4b2008-11-29 12:55:19 -030077 struct v4l2_subdev sd;
Mauro Carvalho Chehabaf7d3742016-01-29 08:44:28 -020078#ifdef CONFIG_MEDIA_CONTROLLER
79 struct media_pad pads[DEMOD_NUM_PADS];
80#endif
Hans Verkuile3560542010-05-24 10:00:52 -030081 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
Hans Verkuile19b2fc2005-11-13 16:08:04 -080089 v4l2_std_id std;
90 int input;
Marco Schluessler4cbca182007-01-21 19:43:38 -030091 int output;
Hans Verkuile19b2fc2005-11-13 16:08:04 -080092 int enable;
Hans Verkuil3faeeae2006-01-09 15:25:44 -020093 int radio;
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -030094 int width;
95 int height;
Hans Verkuile1277112013-05-29 06:59:51 -030096 enum saa711x_model ident;
Hans Verkuil3578d3d2006-01-09 15:25:41 -020097 u32 audclk_freq;
Hans Verkuilb7f82922006-04-02 12:50:42 -030098 u32 crystal_freq;
Hans Verkuil15890372013-03-11 03:47:25 -030099 bool ucgc;
Hans Verkuilb7f82922006-04-02 12:50:42 -0300100 u8 cgcdiv;
Hans Verkuil15890372013-03-11 03:47:25 -0300101 bool apll;
102 bool double_asclk;
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800103};
104
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300105static inline struct saa711x_state *to_state(struct v4l2_subdev *sd)
106{
107 return container_of(sd, struct saa711x_state, sd);
108}
109
Hans Verkuile3560542010-05-24 10:00:52 -0300110static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
111{
112 return &container_of(ctrl->handler, struct saa711x_state, hdl)->sd;
113}
114
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800115/* ----------------------------------------------------------------------- */
116
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300117static inline int saa711x_write(struct v4l2_subdev *sd, u8 reg, u8 value)
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800118{
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300119 struct i2c_client *client = v4l2_get_subdevdata(sd);
120
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800121 return i2c_smbus_write_byte_data(client, reg, value);
122}
123
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300124/* Sanity routine to check if a register is present */
125static int saa711x_has_reg(const int id, const u8 reg)
126{
Hans Verkuile1277112013-05-29 06:59:51 -0300127 if (id == SAA7111)
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300128 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
129 (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
Hans Verkuile1277112013-05-29 06:59:51 -0300130 if (id == SAA7111A)
Hans Verkuil340dde82010-02-20 08:07:51 -0300131 return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
132 reg != 0x14 && reg != 0x18 && reg != 0x19 &&
133 reg != 0x1d && reg != 0x1e;
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300134
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300135 /* 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)))
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300140 return 0;
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300141
142 switch (id) {
Hans Verkuile1277112013-05-29 06:59:51 -0300143 case GM7113C:
Jon Arne Jørgensen241d89f2013-05-10 03:52:28 -0300144 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && reg < 0x20;
Hans Verkuile1277112013-05-29 06:59:51 -0300145 case SAA7113:
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300146 return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
147 reg != 0x5d && reg < 0x63;
Hans Verkuile1277112013-05-29 06:59:51 -0300148 case SAA7114:
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300149 return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
150 (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
151 reg != 0x81 && reg < 0xf0;
Hans Verkuile1277112013-05-29 06:59:51 -0300152 case SAA7115:
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300153 return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
Hans Verkuile1277112013-05-29 06:59:51 -0300154 case SAA7118:
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300155 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;
158 }
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300159 return 1;
160}
161
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300162static int saa711x_writeregs(struct v4l2_subdev *sd, const unsigned char *regs)
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800163{
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300164 struct saa711x_state *state = to_state(sd);
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800165 unsigned char reg, data;
166
167 while (*regs != 0x00) {
168 reg = *(regs++);
169 data = *(regs++);
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300170
171 /* According with datasheets, reserved regs should be
172 filled with 0 - seems better not to touch on they */
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300173 if (saa711x_has_reg(state->ident, reg)) {
174 if (saa711x_write(sd, reg, data) < 0)
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300175 return -1;
Mauro Carvalho Chehabd87edf22006-09-01 09:37:11 -0300176 } else {
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300177 v4l2_dbg(1, debug, sd, "tried to access reserved reg 0x%02x\n", reg);
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300178 }
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800179 }
180 return 0;
181}
182
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300183static inline int saa711x_read(struct v4l2_subdev *sd, u8 reg)
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800184{
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300185 struct i2c_client *client = v4l2_get_subdevdata(sd);
186
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800187 return i2c_smbus_read_byte_data(client, reg);
188}
189
190/* ----------------------------------------------------------------------- */
191
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300192/* SAA7111 initialization table */
Mauro Carvalho Chehab183d8962006-09-12 20:02:09 -0300193static const unsigned char saa7111_init[] = {
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300194 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
Mauro Carvalho Chehab04074f12013-08-18 08:35:36 -0300232/*
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 */
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -0300240
241/* SAA7113 Init codes */
Mauro Carvalho Chehab183d8962006-09-12 20:02:09 -0300242static const unsigned char saa7113_init[] = {
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300243 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,
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -0300248 R_06_H_SYNC_START, 0x89, /* Illegal value -119,
249 * min. value = -108 (0x94) */
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300250 R_07_H_SYNC_STOP, 0x0d,
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -0300251 R_08_SYNC_CNTL, 0x88, /* Not datasheet default.
252 * HTC = VTR mode, should be 0x98 */
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300253 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,
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -0300260 R_10_CHROMA_CNTL_2, 0x08, /* Not datsheet default.
261 * VRLN enabled, should be 0x00 */
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300262 R_11_MODE_DELAY_CNTL, 0x0c,
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -0300263 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
Mauro Carvalho Chehab04074f12013-08-18 08:35:36 -0300274/*
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 */
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -0300280static 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,
287 R_07_H_SYNC_STOP, 0x0d,
288 R_08_SYNC_CNTL, 0x98,
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,
296 R_10_CHROMA_CNTL_2, 0x00,
297 R_11_MODE_DELAY_CNTL, 0x0c,
298 R_12_RT_SIGNAL_CNTL, 0x01,
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300299 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
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800308/* 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
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300312/* SAA7114 and SAA7115 initialization table */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800313static const unsigned char saa7115_init_auto_input[] = {
Mauro Carvalho Chehabf5762e42006-03-13 13:31:31 -0300314 /* Front-End Part */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300315 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 */
Mauro Carvalho Chehabf5762e42006-03-13 13:31:31 -0300319 /* Decoder Part */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300320 R_06_H_SYNC_START, 0xeb, /* horiz sync begin = -21 */
321 R_07_H_SYNC_STOP, 0xe0, /* horiz sync stop = -17 */
Mauro Carvalho Chehab183d8962006-09-12 20:02:09 -0300322 R_09_LUMA_CNTL, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300323 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 */
Mauro Carvalho Chehabf5762e42006-03-13 13:31:31 -0300339
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300340
341 R_80_GLOBAL_CNTL_1, 0x0, /* No tasks enabled at init */
342
Mauro Carvalho Chehabf5762e42006-03-13 13:31:31 -0300343 /* Power Device Control */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300344 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 */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800346 0x00, 0x00
347};
348
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300349/* Used to reset saa7113, saa7114 and saa7115 */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800350static const unsigned char saa7115_cfg_reset_scaler[] = {
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300351 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 */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800355 0x00, 0x00
356};
357
358/* ============== SAA7715 VIDEO templates ============= */
359
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800360static const unsigned char saa7115_cfg_60hz_video[] = {
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300361 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
362 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800363
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300364 R_15_VGATE_START_FID_CHG, 0x03,
365 R_16_VGATE_STOP, 0x11,
366 R_17_MISC_VGATE_CONF_AND_MSB, 0x9c,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800367
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300368 R_08_SYNC_CNTL, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
369 R_0E_CHROMA_CNTL_1, 0x07, /* video autodetection is on */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800370
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300371 R_5A_V_OFF_FOR_SLICER, 0x06, /* standard 60hz value for ITU656 line counting */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800372
373 /* Task A */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300374 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,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800398
399 /* Task B */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300400 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,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800404
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300405 /* 0x0002 is minimum */
406 R_C4_B_HORIZ_INPUT_WINDOW_START, 0x02,
407 R_C5_B_HORIZ_INPUT_WINDOW_START_MSB, 0x00,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800408
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300409 /* 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 */
Mauro Carvalho Chehab97d9e802006-09-03 09:38:11 -0300418 R_CA_B_VERT_INPUT_WINDOW_LENGTH, VRES_60HZ>>1,
419 R_CB_B_VERT_INPUT_WINDOW_LENGTH_MSB, VRES_60HZ>>9,
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300420
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
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800430 0x00, 0x00
431};
432
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800433static const unsigned char saa7115_cfg_50hz_video[] = {
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300434 R_80_GLOBAL_CNTL_1, 0x00,
435 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800436
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300437 R_15_VGATE_START_FID_CHG, 0x37, /* VGATE start */
438 R_16_VGATE_STOP, 0x16,
439 R_17_MISC_VGATE_CONF_AND_MSB, 0x99,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800440
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300441 R_08_SYNC_CNTL, 0x28, /* 0x28 = PAL */
442 R_0E_CHROMA_CNTL_1, 0x07,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800443
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300444 R_5A_V_OFF_FOR_SLICER, 0x03, /* standard 50hz value */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800445
446 /* Task A */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300447 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
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800452 /* 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) */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300454 /* 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) */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800474
475 /* Task B */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300476 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,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800480
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300481 /* 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,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800486
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300487 /* 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
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300503 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
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800508 0x00, 0x00
509};
510
511/* ============== SAA7715 VIDEO templates (end) ======= */
512
513static const unsigned char saa7115_cfg_vbi_on[] = {
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300514 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
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800520 0x00, 0x00
521};
522
523static const unsigned char saa7115_cfg_vbi_off[] = {
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300524 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
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800530 0x00, 0x00
531};
532
Mauro Carvalho Chehabf5762e42006-03-13 13:31:31 -0300533
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800534static const unsigned char saa7115_init_misc[] = {
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300535 R_81_V_SYNC_FLD_ID_SRC_SEL_AND_RETIMED_V_F, 0x01,
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300536 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,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800541
542 /* Task A */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300543 R_A0_A_HORIZ_PRESCALING, 0x01,
544 R_A1_A_ACCUMULATION_LENGTH, 0x00,
545 R_A2_A_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800546
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300547 /* 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,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800582
583 /* Task B */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300584 R_D0_B_HORIZ_PRESCALING, 0x01,
585 R_D1_B_ACCUMULATION_LENGTH, 0x00,
586 R_D2_B_PRESCALER_DC_GAIN_AND_FIR_PREFILTER, 0x00,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800587
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300588 /* 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,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800592
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300593 /* 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,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800635
636 /* Turn off VBI */
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300637 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,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800666
Devin Heitmuellerfea551f2010-02-03 00:33:48 -0300667 R_02_INPUT_CNTL_1, 0xc4, /* input tuner -> input 4, amplifier active */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800668
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300669 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,
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800672 0x00, 0x00
673};
674
Mauro Carvalho Chehab66ec11932006-08-29 22:52:32 -0300675static int saa711x_odd_parity(u8 c)
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800676{
677 c ^= (c >> 4);
678 c ^= (c >> 2);
679 c ^= (c >> 1);
680
681 return c & 1;
682}
683
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300684static int saa711x_decode_vps(u8 *dst, u8 *p)
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800685{
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
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300731static int saa711x_decode_wss(u8 *p)
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800732{
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
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300758static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800759{
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300760 struct saa711x_state *state = to_state(sd);
Hans Verkuil3578d3d2006-01-09 15:25:41 -0200761 u32 acpf;
762 u32 acni;
763 u32 hz;
764 u64 f;
Hans Verkuilb7f82922006-04-02 12:50:42 -0300765 u8 acc = 0; /* reg 0x3a, audio clock control */
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800766
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300767 /* Checks for chips that don't have audio clock (saa7111, saa7113) */
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300768 if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -0300769 return 0;
770
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300771 v4l2_dbg(1, debug, sd, "set audio clock freq: %d\n", freq);
Hans Verkuil3578d3d2006-01-09 15:25:41 -0200772
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 =
Hans Verkuilb7f82922006-04-02 12:50:42 -0300783 (freq << 31) / crystal_frequency */
Hans Verkuil3578d3d2006-01-09 15:25:41 -0200784 f = freq;
785 f = f << 31;
Hans Verkuilb7f82922006-04-02 12:50:42 -0300786 do_div(f, state->crystal_freq);
Hans Verkuil3578d3d2006-01-09 15:25:41 -0200787 acni = f;
Hans Verkuilb7f82922006-04-02 12:50:42 -0300788 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;
Hans Verkuil3578d3d2006-01-09 15:25:41 -0200797
Hans Verkuil15890372013-03-11 03:47:25 -0300798 if (state->double_asclk) {
799 acpf <<= 1;
800 acni <<= 1;
801 }
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300802 saa711x_write(sd, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
Hans Verkuil15890372013-03-11 03:47:25 -0300803 saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10 << state->double_asclk);
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300804 saa711x_write(sd, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300805
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300806 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,
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300808 (acpf >> 8) & 0xff);
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300809 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -0300810 (acpf >> 16) & 0x03);
811
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300812 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);
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800815 state->audclk_freq = freq;
816 return 0;
817}
818
Hans Verkuile3560542010-05-24 10:00:52 -0300819static int saa711x_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800820{
Hans Verkuile3560542010-05-24 10:00:52 -0300821 struct v4l2_subdev *sd = to_sd(ctrl);
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300822 struct saa711x_state *state = to_state(sd);
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800823
824 switch (ctrl->id) {
Devin Heitmueller87a6fe42010-03-11 21:49:24 -0300825 case V4L2_CID_CHROMA_AGC:
Hans Verkuile3560542010-05-24 10:00:52 -0300826 /* chroma gain cluster */
Hans Verkuilddac5c12011-06-10 05:43:34 -0300827 if (state->agc->val)
828 state->gain->val =
Hans Verkuile3560542010-05-24 10:00:52 -0300829 saa711x_read(sd, R_0F_CHROMA_GAIN_CNTL) & 0x7f;
Devin Heitmueller87a6fe42010-03-11 21:49:24 -0300830 break;
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800831 }
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800832 return 0;
833}
834
Hans Verkuile3560542010-05-24 10:00:52 -0300835static int saa711x_s_ctrl(struct v4l2_ctrl *ctrl)
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800836{
Hans Verkuile3560542010-05-24 10:00:52 -0300837 struct v4l2_subdev *sd = to_sd(ctrl);
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300838 struct saa711x_state *state = to_state(sd);
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800839
840 switch (ctrl->id) {
841 case V4L2_CID_BRIGHTNESS:
Hans Verkuile3560542010-05-24 10:00:52 -0300842 saa711x_write(sd, R_0A_LUMA_BRIGHT_CNTL, ctrl->val);
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800843 break;
Hans Verkuile3560542010-05-24 10:00:52 -0300844
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800845 case V4L2_CID_CONTRAST:
Hans Verkuile3560542010-05-24 10:00:52 -0300846 saa711x_write(sd, R_0B_LUMA_CONTRAST_CNTL, ctrl->val);
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800847 break;
Hans Verkuile3560542010-05-24 10:00:52 -0300848
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800849 case V4L2_CID_SATURATION:
Hans Verkuile3560542010-05-24 10:00:52 -0300850 saa711x_write(sd, R_0C_CHROMA_SAT_CNTL, ctrl->val);
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800851 break;
Hans Verkuile3560542010-05-24 10:00:52 -0300852
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800853 case V4L2_CID_HUE:
Hans Verkuile3560542010-05-24 10:00:52 -0300854 saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, ctrl->val);
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800855 break;
Hans Verkuile3560542010-05-24 10:00:52 -0300856
Devin Heitmueller87a6fe42010-03-11 21:49:24 -0300857 case V4L2_CID_CHROMA_AGC:
Hans Verkuile3560542010-05-24 10:00:52 -0300858 /* 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);
Devin Heitmueller87a6fe42010-03-11 21:49:24 -0300863 break;
Hans Verkuile3560542010-05-24 10:00:52 -0300864
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800865 default:
866 return -EINVAL;
867 }
868
869 return 0;
870}
871
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300872static int saa711x_set_size(struct v4l2_subdev *sd, int width, int height)
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300873{
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300874 struct saa711x_state *state = to_state(sd);
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300875 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
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300881 v4l2_dbg(1, debug, sd, "decoder set size to %ix%i\n", width, height);
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300882
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
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300889 if (!saa711x_has_reg(state->ident, R_D0_B_HORIZ_PRESCALING)) {
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300890 /* 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
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300907 saa711x_write(sd, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300908 (u8) (width & 0xff));
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300909 saa711x_write(sd, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300910 (u8) ((width >> 8) & 0xff));
911
912 /* Vertical Scaling uses height/2 */
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300913 res = height / 2;
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300914
915 /* On 60Hz, it is using a higher Vertical Output Size */
916 if (!is_50hz)
Hans Verkuild0d30c02006-11-25 09:45:50 -0300917 res += (VRES_60HZ - 480) >> 1;
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300918
919 /* height */
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300920 saa711x_write(sd, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300921 (u8) (res & 0xff));
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300922 saa711x_write(sd, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300923 (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 */
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300933 saa711x_write(sd, R_D0_B_HORIZ_PRESCALING,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300934 (u8) (HPSC & 0x3f));
935
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300936 v4l2_dbg(1, debug, sd, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300937 /* write H fine-scaling (luminance) */
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300938 saa711x_write(sd, R_D8_B_HORIZ_LUMA_SCALING_INC,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300939 (u8) (HFSC & 0xff));
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300940 saa711x_write(sd, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300941 (u8) ((HFSC >> 8) & 0xff));
942 /* write H fine-scaling (chrominance)
943 * must be lum/2, so i'll just bitshift :) */
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300944 saa711x_write(sd, R_DC_B_HORIZ_CHROMA_SCALING,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300945 (u8) ((HFSC >> 1) & 0xff));
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300946 saa711x_write(sd, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300947 (u8) ((HFSC >> 9) & 0xff));
948
949 VSCY = (int)((1024 * Vsrc) / height);
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300950 v4l2_dbg(1, debug, sd, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300951
952 /* Correct Contrast and Luminance */
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300953 saa711x_write(sd, R_D5_B_LUMA_CONTRAST_CNTL,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300954 (u8) (64 * 1024 / VSCY));
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300955 saa711x_write(sd, R_D6_B_CHROMA_SATURATION_CNTL,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300956 (u8) (64 * 1024 / VSCY));
957
958 /* write V fine-scaling (luminance) */
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300959 saa711x_write(sd, R_E0_B_VERT_LUMA_SCALING_INC,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300960 (u8) (VSCY & 0xff));
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300961 saa711x_write(sd, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300962 (u8) ((VSCY >> 8) & 0xff));
963 /* write V fine-scaling (chrominance) */
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300964 saa711x_write(sd, R_E2_B_VERT_CHROMA_SCALING_INC,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300965 (u8) (VSCY & 0xff));
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300966 saa711x_write(sd, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300967 (u8) ((VSCY >> 8) & 0xff));
968
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300969 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300970
971 /* Activates task "B" */
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300972 saa711x_write(sd, R_80_GLOBAL_CNTL_1,
973 saa711x_read(sd, R_80_GLOBAL_CNTL_1) | 0x20);
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300974
975 return 0;
976}
977
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300978static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800979{
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300980 struct saa711x_state *state = to_state(sd);
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800981
Hans Verkuil30b54d52006-01-09 15:25:43 -0200982 /* 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.
Hans Verkuilbccfa442009-03-30 06:55:27 -0300985 Note that s_std is also used to switch from
986 radio to TV mode, so if a s_std is broadcast to
Hans Verkuil30b54d52006-01-09 15:25:43 -0200987 all I2C devices then you do not want to have an unwanted
988 side-effect here. */
989 if (std == state->std)
990 return;
991
Mauro Carvalho Chehabd9dce962006-09-02 12:59:38 -0300992 state->std = std;
993
Hans Verkuile19b2fc2005-11-13 16:08:04 -0800994 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
995 if (std & V4L2_STD_525_60) {
Hans Verkuil9415f4b2008-11-29 12:55:19 -0300996 v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
Jon Arne Jørgensen8b77dfd2013-08-03 09:19:35 -0300997 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 {
Jon Arne Jørgensen241d89f2013-05-10 03:52:28 -03001003 saa711x_writeregs(sd, saa7115_cfg_60hz_video);
Jon Arne Jørgensen8b77dfd2013-08-03 09:19:35 -03001004 }
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001005 saa711x_set_size(sd, 720, 480);
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001006 } else {
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001007 v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
Jon Arne Jørgensen8b77dfd2013-08-03 09:19:35 -03001008 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 {
Jon Arne Jørgensen241d89f2013-05-10 03:52:28 -03001013 saa711x_writeregs(sd, saa7115_cfg_50hz_video);
Jon Arne Jørgensen8b77dfd2013-08-03 09:19:35 -03001014 }
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001015 saa711x_set_size(sd, 720, 576);
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001016 }
1017
Mauro Carvalho Chehabf89982a2006-03-14 16:33:33 -03001018 /* Register 0E - Bits D6-D4 on NO-AUTO mode
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -03001019 (SAA7111 and SAA7113 doesn't have auto mode)
Mauro Carvalho Chehabf89982a2006-03-14 16:33:33 -03001020 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 */
Hans Verkuile1277112013-05-29 06:59:51 -03001027 if (state->ident <= SAA7113 ||
1028 state->ident == GM7113C) {
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001029 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
Mauro Carvalho Chehabf89982a2006-03-14 16:33:33 -03001030
Mauro Carvalho Chehab02c17222006-03-16 18:44:07 -03001031 if (std == V4L2_STD_PAL_M) {
Hans Verkuil01342352006-03-25 08:19:47 -03001032 reg |= 0x30;
Hans Verkuile0028022008-04-22 14:45:51 -03001033 } else if (std == V4L2_STD_PAL_Nc) {
Hans Verkuil01342352006-03-25 08:19:47 -03001034 reg |= 0x20;
Mauro Carvalho Chehab02c17222006-03-16 18:44:07 -03001035 } else if (std == V4L2_STD_PAL_60) {
Hans Verkuil01342352006-03-25 08:19:47 -03001036 reg |= 0x10;
Mauro Carvalho Chehab02c17222006-03-16 18:44:07 -03001037 } else if (std == V4L2_STD_NTSC_M_JP) {
Hans Verkuil01342352006-03-25 08:19:47 -03001038 reg |= 0x40;
Mauro Carvalho Chehaba9aaec42007-03-13 13:41:49 -03001039 } else if (std & V4L2_STD_SECAM) {
Pádraig Bradyfc2fa312006-10-09 08:02:17 -03001040 reg |= 0x50;
Mauro Carvalho Chehabf89982a2006-03-14 16:33:33 -03001041 }
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001042 saa711x_write(sd, R_0E_CHROMA_CNTL_1, reg);
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -03001043 } else {
1044 /* restart task B if needed */
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001045 int taskb = saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10;
Mauro Carvalho Chehabf89982a2006-03-14 16:33:33 -03001046
Hans Verkuile1277112013-05-29 06:59:51 -03001047 if (taskb && state->ident == SAA7114)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001048 saa711x_writeregs(sd, saa7115_cfg_vbi_on);
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -03001049
1050 /* switch audio mode too! */
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001051 saa711x_s_clock_freq(sd, state->audclk_freq);
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -03001052 }
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001053}
1054
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001055/* setup the sliced VBI lcr registers according to the sliced VBI format */
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001056static void saa711x_set_lcr(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001057{
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001058 struct saa711x_state *state = to_state(sd);
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001059 int is_50hz = (state->std & V4L2_STD_625_50);
1060 u8 lcr[24];
1061 int i, x;
1062
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -03001063#if 1
1064 /* saa7113/7114/7118 VBI support are experimental */
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001065 if (!saa711x_has_reg(state->ident, R_41_LCR_BASE))
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -03001066 return;
1067
1068#else
1069 /* SAA7113 and SAA7118 also should support VBI - Need testing */
Hans Verkuile1277112013-05-29 06:59:51 -03001070 if (state->ident != SAA7115)
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001071 return;
Mauro Carvalho Chehab89f75ff2006-08-29 22:07:03 -03001072#endif
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001073
1074 for (i = 0; i <= 23; i++)
1075 lcr[i] = 0xff;
1076
Hans Verkuila8b86432008-10-04 08:05:30 -03001077 if (fmt == NULL) {
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001078 /* raw VBI */
1079 if (is_50hz)
1080 for (i = 6; i <= 23; i++)
1081 lcr[i] = 0xdd;
1082 else
1083 for (i = 10; i <= 21; i++)
1084 lcr[i] = 0xdd;
1085 } else {
1086 /* sliced VBI */
1087 /* first clear lines that cannot be captured */
1088 if (is_50hz) {
1089 for (i = 0; i <= 5; i++)
1090 fmt->service_lines[0][i] =
1091 fmt->service_lines[1][i] = 0;
1092 }
1093 else {
1094 for (i = 0; i <= 9; i++)
1095 fmt->service_lines[0][i] =
1096 fmt->service_lines[1][i] = 0;
1097 for (i = 22; i <= 23; i++)
1098 fmt->service_lines[0][i] =
1099 fmt->service_lines[1][i] = 0;
1100 }
1101
1102 /* Now set the lcr values according to the specified service */
1103 for (i = 6; i <= 23; i++) {
1104 lcr[i] = 0;
1105 for (x = 0; x <= 1; x++) {
1106 switch (fmt->service_lines[1-x][i]) {
1107 case 0:
1108 lcr[i] |= 0xf << (4 * x);
1109 break;
Hans Verkuil9bc74002006-03-29 18:02:51 -03001110 case V4L2_SLICED_TELETEXT_B:
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001111 lcr[i] |= 1 << (4 * x);
1112 break;
1113 case V4L2_SLICED_CAPTION_525:
1114 lcr[i] |= 4 << (4 * x);
1115 break;
1116 case V4L2_SLICED_WSS_625:
1117 lcr[i] |= 5 << (4 * x);
1118 break;
1119 case V4L2_SLICED_VPS:
1120 lcr[i] |= 7 << (4 * x);
1121 break;
1122 }
1123 }
1124 }
1125 }
1126
1127 /* write the lcr registers */
1128 for (i = 2; i <= 23; i++) {
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001129 saa711x_write(sd, i - 2 + R_41_LCR_BASE, lcr[i]);
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001130 }
1131
1132 /* enable/disable raw VBI capturing */
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001133 saa711x_writeregs(sd, fmt == NULL ?
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -03001134 saa7115_cfg_vbi_on :
1135 saa7115_cfg_vbi_off);
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001136}
1137
Hans Verkuil63d8adc2010-03-14 10:10:14 -03001138static int saa711x_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *sliced)
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001139{
1140 static u16 lcr2vbi[] = {
Hans Verkuil9bc74002006-03-29 18:02:51 -03001141 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001142 0, V4L2_SLICED_CAPTION_525, /* 4 */
1143 V4L2_SLICED_WSS_625, 0, /* 5 */
1144 V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */
1145 0, 0, 0, 0
1146 };
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001147 int i;
1148
Hans Verkuil30634e82012-09-05 10:38:10 -03001149 memset(sliced->service_lines, 0, sizeof(sliced->service_lines));
1150 sliced->service_set = 0;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001151 /* done if using raw VBI */
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001152 if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10)
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001153 return 0;
1154 for (i = 2; i <= 23; i++) {
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001155 u8 v = saa711x_read(sd, i - 2 + R_41_LCR_BASE);
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001156
1157 sliced->service_lines[0][i] = lcr2vbi[v >> 4];
1158 sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
1159 sliced->service_set |=
1160 sliced->service_lines[0][i] | sliced->service_lines[1][i];
1161 }
1162 return 0;
1163}
1164
Hans Verkuil63d8adc2010-03-14 10:10:14 -03001165static int saa711x_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
1166{
1167 saa711x_set_lcr(sd, NULL);
1168 return 0;
1169}
1170
1171static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
1172{
1173 saa711x_set_lcr(sd, fmt);
1174 return 0;
1175}
1176
Hans Verkuil6e80c472015-03-21 09:39:09 -03001177static int saa711x_set_fmt(struct v4l2_subdev *sd,
1178 struct v4l2_subdev_pad_config *cfg,
1179 struct v4l2_subdev_format *format)
Hans Verkuilc463d932010-05-09 09:47:23 -03001180{
Hans Verkuil6e80c472015-03-21 09:39:09 -03001181 struct v4l2_mbus_framefmt *fmt = &format->format;
1182
1183 if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED)
Hans Verkuilc463d932010-05-09 09:47:23 -03001184 return -EINVAL;
1185 fmt->field = V4L2_FIELD_INTERLACED;
1186 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
Hans Verkuil6e80c472015-03-21 09:39:09 -03001187 if (format->which == V4L2_SUBDEV_FORMAT_TRY)
1188 return 0;
Hans Verkuilc463d932010-05-09 09:47:23 -03001189 return saa711x_set_size(sd, fmt->width, fmt->height);
1190}
1191
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001192/* Decode the sliced VBI data stream as created by the saa7115.
1193 The format is described in the saa7115 datasheet in Tables 25 and 26
1194 and in Figure 33.
1195 The current implementation uses SAV/EAV codes and not the ancillary data
Mauro Carvalho Chehab96ecfc42006-08-28 19:18:49 -03001196 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001197 code. */
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001198static int saa711x_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001199{
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001200 struct saa711x_state *state = to_state(sd);
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001201 static const char vbi_no_data_pattern[] = {
1202 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1203 };
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001204 u8 *p = vbi->p;
1205 u32 wss;
1206 int id1, id2; /* the ID1 and ID2 bytes from the internal header */
1207
1208 vbi->type = 0; /* mark result as a failure */
1209 id1 = p[2];
1210 id2 = p[3];
1211 /* Note: the field bit is inverted for 60 Hz video */
1212 if (state->std & V4L2_STD_525_60)
1213 id1 ^= 0x40;
1214
1215 /* Skip internal header, p now points to the start of the payload */
1216 p += 4;
1217 vbi->p = p;
1218
1219 /* calculate field and line number of the VBI packet (1-23) */
1220 vbi->is_second_field = ((id1 & 0x40) != 0);
1221 vbi->line = (id1 & 0x3f) << 3;
1222 vbi->line |= (id2 & 0x70) >> 4;
1223
1224 /* Obtain data type */
1225 id2 &= 0xf;
1226
1227 /* If the VBI slicer does not detect any signal it will fill up
1228 the payload buffer with 0xa0 bytes. */
1229 if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001230 return 0;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001231
1232 /* decode payloads */
1233 switch (id2) {
1234 case 1:
Hans Verkuil9bc74002006-03-29 18:02:51 -03001235 vbi->type = V4L2_SLICED_TELETEXT_B;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001236 break;
1237 case 4:
Mauro Carvalho Chehab59ba9152006-08-30 05:34:36 -03001238 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001239 return 0;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001240 vbi->type = V4L2_SLICED_CAPTION_525;
1241 break;
1242 case 5:
Mauro Carvalho Chehab66ec11932006-08-29 22:52:32 -03001243 wss = saa711x_decode_wss(p);
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001244 if (wss == -1)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001245 return 0;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001246 p[0] = wss & 0xff;
1247 p[1] = wss >> 8;
1248 vbi->type = V4L2_SLICED_WSS_625;
1249 break;
1250 case 7:
Mauro Carvalho Chehab66ec11932006-08-29 22:52:32 -03001251 if (saa711x_decode_vps(p, p) != 0)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001252 return 0;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001253 vbi->type = V4L2_SLICED_VPS;
1254 break;
1255 default:
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001256 break;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001257 }
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001258 return 0;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001259}
1260
1261/* ============ SAA7115 AUDIO settings (end) ============= */
1262
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001263static int saa711x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001264{
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001265 struct saa711x_state *state = to_state(sd);
1266 int status;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001267
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001268 if (state->radio)
1269 return 0;
1270 status = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001271
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001272 v4l2_dbg(1, debug, sd, "status: 0x%02x\n", status);
1273 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1274 return 0;
1275}
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001276
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001277static int saa711x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1278{
1279 struct saa711x_state *state = to_state(sd);
1280
1281 state->radio = 0;
1282 saa711x_set_v4lstd(sd, std);
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001283 return 0;
1284}
1285
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001286static int saa711x_s_radio(struct v4l2_subdev *sd)
1287{
1288 struct saa711x_state *state = to_state(sd);
1289
1290 state->radio = 1;
1291 return 0;
1292}
1293
Hans Verkuil5325b422009-04-02 11:26:22 -03001294static int saa711x_s_routing(struct v4l2_subdev *sd,
1295 u32 input, u32 output, u32 config)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001296{
1297 struct saa711x_state *state = to_state(sd);
Hans Verkuile1277112013-05-29 06:59:51 -03001298 u8 mask = (state->ident <= SAA7111A) ? 0xf8 : 0xf0;
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001299
Hans Verkuil5325b422009-04-02 11:26:22 -03001300 v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
1301 input, output);
1302
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001303 /* saa7111/3 does not have these inputs */
Hans Verkuile1277112013-05-29 06:59:51 -03001304 if ((state->ident <= SAA7113 ||
1305 state->ident == GM7113C) &&
Hans Verkuil5325b422009-04-02 11:26:22 -03001306 (input == SAA7115_COMPOSITE4 ||
1307 input == SAA7115_COMPOSITE5)) {
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001308 return -EINVAL;
1309 }
Hans Verkuil5325b422009-04-02 11:26:22 -03001310 if (input > SAA7115_SVIDEO3)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001311 return -EINVAL;
Hans Verkuil5325b422009-04-02 11:26:22 -03001312 if (state->input == input && state->output == output)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001313 return 0;
1314 v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
Hans Verkuil5325b422009-04-02 11:26:22 -03001315 (input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
1316 (output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
1317 state->input = input;
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001318
1319 /* saa7111 has slightly different input numbering */
Hans Verkuile1277112013-05-29 06:59:51 -03001320 if (state->ident <= SAA7111A) {
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001321 if (input >= SAA7115_COMPOSITE4)
1322 input -= 2;
1323 /* saa7111 specific */
1324 saa711x_write(sd, R_10_CHROMA_CNTL_2,
1325 (saa711x_read(sd, R_10_CHROMA_CNTL_2) & 0x3f) |
Hans Verkuil5325b422009-04-02 11:26:22 -03001326 ((output & 0xc0) ^ 0x40));
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001327 saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL,
1328 (saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
Hans Verkuil5325b422009-04-02 11:26:22 -03001329 ((output & 2) ? 0x0a : 0));
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001330 }
1331
1332 /* select mode */
1333 saa711x_write(sd, R_02_INPUT_CNTL_1,
1334 (saa711x_read(sd, R_02_INPUT_CNTL_1) & mask) |
1335 input);
1336
1337 /* bypass chrominance trap for S-Video modes */
1338 saa711x_write(sd, R_09_LUMA_CNTL,
1339 (saa711x_read(sd, R_09_LUMA_CNTL) & 0x7f) |
1340 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
1341
Hans Verkuil5325b422009-04-02 11:26:22 -03001342 state->output = output;
Hans Verkuile1277112013-05-29 06:59:51 -03001343 if (state->ident == SAA7114 ||
1344 state->ident == SAA7115) {
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001345 saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
1346 (saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
1347 (state->output & 0x01));
1348 }
Hans Verkuile1277112013-05-29 06:59:51 -03001349 if (state->ident > SAA7111A) {
Hans Verkuila0fc5882013-03-08 11:22:03 -03001350 if (config & SAA7115_IDQ_IS_DEFAULT)
1351 saa711x_write(sd, R_85_I_PORT_SIGNAL_POLAR, 0x20);
1352 else
1353 saa711x_write(sd, R_85_I_PORT_SIGNAL_POLAR, 0x21);
1354 }
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001355 return 0;
1356}
1357
1358static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val)
1359{
1360 struct saa711x_state *state = to_state(sd);
1361
Hans Verkuile1277112013-05-29 06:59:51 -03001362 if (state->ident > SAA7111A)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001363 return -EINVAL;
1364 saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
1365 (val ? 0x80 : 0));
1366 return 0;
1367}
1368
1369static int saa711x_s_stream(struct v4l2_subdev *sd, int enable)
1370{
1371 struct saa711x_state *state = to_state(sd);
1372
1373 v4l2_dbg(1, debug, sd, "%s output\n",
1374 enable ? "enable" : "disable");
1375
Hans Verkuil674a3232009-02-18 12:22:16 -03001376 if (state->enable == enable)
1377 return 0;
1378 state->enable = enable;
1379 if (!saa711x_has_reg(state->ident, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED))
1380 return 0;
1381 saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, state->enable);
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001382 return 0;
1383}
1384
Hans Verkuil3ff4ad82009-04-01 03:15:52 -03001385static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, u32 freq, u32 flags)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001386{
1387 struct saa711x_state *state = to_state(sd);
1388
Hans Verkuil3ff4ad82009-04-01 03:15:52 -03001389 if (freq != SAA7115_FREQ_32_11_MHZ && freq != SAA7115_FREQ_24_576_MHZ)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001390 return -EINVAL;
Hans Verkuil3ff4ad82009-04-01 03:15:52 -03001391 state->crystal_freq = freq;
Hans Verkuil15890372013-03-11 03:47:25 -03001392 state->double_asclk = flags & SAA7115_FREQ_FL_DOUBLE_ASCLK;
Hans Verkuil3ff4ad82009-04-01 03:15:52 -03001393 state->cgcdiv = (flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
Hans Verkuil15890372013-03-11 03:47:25 -03001394 state->ucgc = flags & SAA7115_FREQ_FL_UCGC;
1395 state->apll = flags & SAA7115_FREQ_FL_APLL;
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001396 saa711x_s_clock_freq(sd, state->audclk_freq);
1397 return 0;
1398}
1399
1400static int saa711x_reset(struct v4l2_subdev *sd, u32 val)
1401{
1402 v4l2_dbg(1, debug, sd, "decoder RESET\n");
1403 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
1404 return 0;
1405}
1406
1407static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *data)
1408{
1409 /* Note: the internal field ID is inverted for NTSC,
1410 so data->field 0 maps to the saa7115 even field,
1411 whereas for PAL it maps to the saa7115 odd field. */
1412 switch (data->id) {
1413 case V4L2_SLICED_WSS_625:
1414 if (saa711x_read(sd, 0x6b) & 0xc0)
1415 return -EIO;
1416 data->data[0] = saa711x_read(sd, 0x6c);
1417 data->data[1] = saa711x_read(sd, 0x6d);
1418 return 0;
1419 case V4L2_SLICED_CAPTION_525:
1420 if (data->field == 0) {
1421 /* CC */
1422 if (saa711x_read(sd, 0x66) & 0x30)
1423 return -EIO;
1424 data->data[0] = saa711x_read(sd, 0x69);
1425 data->data[1] = saa711x_read(sd, 0x6a);
1426 return 0;
1427 }
1428 /* XDS */
1429 if (saa711x_read(sd, 0x66) & 0xc0)
1430 return -EIO;
1431 data->data[0] = saa711x_read(sd, 0x67);
1432 data->data[1] = saa711x_read(sd, 0x68);
1433 return 0;
1434 default:
1435 return -EINVAL;
1436 }
1437}
1438
Hans Verkuil17bdd9d2009-02-18 12:35:33 -03001439static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
1440{
1441 struct saa711x_state *state = to_state(sd);
Mauro Carvalho Chehabb7286662011-10-03 12:01:22 -03001442 int reg1f, reg1e;
Hans Verkuil17bdd9d2009-02-18 12:35:33 -03001443
Mauro Carvalho Chehabe41567a2011-10-04 09:40:18 -03001444 /*
1445 * The V4L2 core already initializes std with all supported
1446 * Standards. All driver needs to do is to mask it, to remove
1447 * standards that don't apply from the mask
1448 */
1449
Mauro Carvalho Chehabb7286662011-10-03 12:01:22 -03001450 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
Hans Verkuilc875dee2013-03-10 09:59:37 -03001451
Hans Verkuile1277112013-05-29 06:59:51 -03001452 if (state->ident == SAA7115) {
Hans Verkuilc875dee2013-03-10 09:59:37 -03001453 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1454
1455 v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e);
1456
1457 switch (reg1e & 0x03) {
1458 case 1:
1459 *std &= V4L2_STD_NTSC;
1460 break;
1461 case 2:
1462 /*
1463 * V4L2_STD_PAL just cover the european PAL standards.
1464 * This is wrong, as the device could also be using an
1465 * other PAL standard.
1466 */
1467 *std &= V4L2_STD_PAL | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc |
1468 V4L2_STD_PAL_M | V4L2_STD_PAL_60;
1469 break;
1470 case 3:
1471 *std &= V4L2_STD_SECAM;
1472 break;
1473 default:
Hans Verkuilaf1f7282013-05-29 10:18:58 -03001474 *std = V4L2_STD_UNKNOWN;
Hans Verkuilc875dee2013-03-10 09:59:37 -03001475 /* Can't detect anything */
1476 break;
1477 }
1478 }
1479
Mauro Carvalho Chehabb7286662011-10-03 12:01:22 -03001480 v4l2_dbg(1, debug, sd, "Status byte 2 (0x1f)=0x%02x\n", reg1f);
Mauro Carvalho Chehabe41567a2011-10-04 09:40:18 -03001481
1482 /* horizontal/vertical not locked */
Hans Verkuilaf1f7282013-05-29 10:18:58 -03001483 if (reg1f & 0x40) {
1484 *std = V4L2_STD_UNKNOWN;
Mauro Carvalho Chehabb7286662011-10-03 12:01:22 -03001485 goto ret;
Hans Verkuilaf1f7282013-05-29 10:18:58 -03001486 }
Mauro Carvalho Chehabe41567a2011-10-04 09:40:18 -03001487
Mauro Carvalho Chehabb7286662011-10-03 12:01:22 -03001488 if (reg1f & 0x20)
Mauro Carvalho Chehabe41567a2011-10-04 09:40:18 -03001489 *std &= V4L2_STD_525_60;
Mauro Carvalho Chehabb7286662011-10-03 12:01:22 -03001490 else
Mauro Carvalho Chehabe41567a2011-10-04 09:40:18 -03001491 *std &= V4L2_STD_625_50;
Mauro Carvalho Chehabb7286662011-10-03 12:01:22 -03001492
Mauro Carvalho Chehabb7286662011-10-03 12:01:22 -03001493ret:
1494 v4l2_dbg(1, debug, sd, "detected std mask = %08Lx\n", *std);
1495
Hans Verkuil17bdd9d2009-02-18 12:35:33 -03001496 return 0;
1497}
1498
1499static int saa711x_g_input_status(struct v4l2_subdev *sd, u32 *status)
1500{
1501 struct saa711x_state *state = to_state(sd);
1502 int reg1e = 0x80;
1503 int reg1f;
1504
1505 *status = V4L2_IN_ST_NO_SIGNAL;
Hans Verkuile1277112013-05-29 06:59:51 -03001506 if (state->ident == SAA7115)
Hans Verkuil17bdd9d2009-02-18 12:35:33 -03001507 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1508 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1509 if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80)
1510 *status = 0;
1511 return 0;
1512}
1513
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001514#ifdef CONFIG_VIDEO_ADV_DEBUG
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001515static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001516{
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001517 reg->val = saa711x_read(sd, reg->reg & 0xff);
Hans Verkuilaecde8b52008-12-30 07:14:19 -03001518 reg->size = 1;
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001519 return 0;
1520}
1521
Hans Verkuil977ba3b2013-03-24 08:28:46 -03001522static int saa711x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001523{
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001524 saa711x_write(sd, reg->reg & 0xff, reg->val & 0xff);
1525 return 0;
1526}
1527#endif
1528
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001529static int saa711x_log_status(struct v4l2_subdev *sd)
1530{
1531 struct saa711x_state *state = to_state(sd);
1532 int reg1e, reg1f;
1533 int signalOk;
1534 int vcr;
1535
1536 v4l2_info(sd, "Audio frequency: %d Hz\n", state->audclk_freq);
Hans Verkuile1277112013-05-29 06:59:51 -03001537 if (state->ident != SAA7115) {
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001538 /* status for the saa7114 */
1539 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1540 signalOk = (reg1f & 0xc1) == 0x81;
1541 v4l2_info(sd, "Video signal: %s\n", signalOk ? "ok" : "bad");
1542 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1543 return 0;
1544 }
1545
1546 /* status for the saa7115 */
1547 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1548 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1549
1550 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
1551 vcr = !(reg1f & 0x10);
1552
1553 if (state->input >= 6)
1554 v4l2_info(sd, "Input: S-Video %d\n", state->input - 6);
1555 else
1556 v4l2_info(sd, "Input: Composite %d\n", state->input);
1557 v4l2_info(sd, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
1558 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1559
1560 switch (reg1e & 0x03) {
1561 case 1:
1562 v4l2_info(sd, "Detected format: NTSC\n");
1563 break;
1564 case 2:
1565 v4l2_info(sd, "Detected format: PAL\n");
1566 break;
1567 case 3:
1568 v4l2_info(sd, "Detected format: SECAM\n");
1569 break;
1570 default:
1571 v4l2_info(sd, "Detected format: BW/No color\n");
1572 break;
1573 }
1574 v4l2_info(sd, "Width, Height: %d, %d\n", state->width, state->height);
Hans Verkuile3560542010-05-24 10:00:52 -03001575 v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001576 return 0;
1577}
1578
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001579/* ----------------------------------------------------------------------- */
1580
Hans Verkuile3560542010-05-24 10:00:52 -03001581static const struct v4l2_ctrl_ops saa711x_ctrl_ops = {
1582 .s_ctrl = saa711x_s_ctrl,
1583 .g_volatile_ctrl = saa711x_g_volatile_ctrl,
1584};
1585
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001586static const struct v4l2_subdev_core_ops saa711x_core_ops = {
1587 .log_status = saa711x_log_status,
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001588 .reset = saa711x_reset,
1589 .s_gpio = saa711x_s_gpio,
1590#ifdef CONFIG_VIDEO_ADV_DEBUG
1591 .g_register = saa711x_g_register,
1592 .s_register = saa711x_s_register,
1593#endif
1594};
1595
1596static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops = {
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001597 .s_radio = saa711x_s_radio,
1598 .g_tuner = saa711x_g_tuner,
1599};
1600
1601static const struct v4l2_subdev_audio_ops saa711x_audio_ops = {
1602 .s_clock_freq = saa711x_s_clock_freq,
1603};
1604
1605static const struct v4l2_subdev_video_ops saa711x_video_ops = {
Laurent Pinchart8774bed2014-04-28 16:53:01 -03001606 .s_std = saa711x_s_std,
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001607 .s_routing = saa711x_s_routing,
1608 .s_crystal_freq = saa711x_s_crystal_freq,
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001609 .s_stream = saa711x_s_stream,
Hans Verkuil17bdd9d2009-02-18 12:35:33 -03001610 .querystd = saa711x_querystd,
1611 .g_input_status = saa711x_g_input_status,
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001612};
1613
Hans Verkuil32cd5272010-03-14 09:57:30 -03001614static const struct v4l2_subdev_vbi_ops saa711x_vbi_ops = {
1615 .g_vbi_data = saa711x_g_vbi_data,
1616 .decode_vbi_line = saa711x_decode_vbi_line,
Hans Verkuil63d8adc2010-03-14 10:10:14 -03001617 .g_sliced_fmt = saa711x_g_sliced_fmt,
1618 .s_sliced_fmt = saa711x_s_sliced_fmt,
1619 .s_raw_fmt = saa711x_s_raw_fmt,
Hans Verkuil32cd5272010-03-14 09:57:30 -03001620};
1621
Hans Verkuil6e80c472015-03-21 09:39:09 -03001622static const struct v4l2_subdev_pad_ops saa711x_pad_ops = {
1623 .set_fmt = saa711x_set_fmt,
1624};
1625
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001626static const struct v4l2_subdev_ops saa711x_ops = {
1627 .core = &saa711x_core_ops,
1628 .tuner = &saa711x_tuner_ops,
1629 .audio = &saa711x_audio_ops,
1630 .video = &saa711x_video_ops,
Hans Verkuil32cd5272010-03-14 09:57:30 -03001631 .vbi = &saa711x_vbi_ops,
Hans Verkuil6e80c472015-03-21 09:39:09 -03001632 .pad = &saa711x_pad_ops,
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001633};
1634
Mauro Carvalho Chehab6a084d62013-05-21 11:36:30 -03001635#define CHIP_VER_SIZE 16
1636
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001637/* ----------------------------------------------------------------------- */
1638
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -03001639static void saa711x_write_platform_data(struct saa711x_state *state,
1640 struct saa7115_platform_data *data)
1641{
1642 struct v4l2_subdev *sd = &state->sd;
1643 u8 work;
1644
1645 if (state->ident != GM7113C &&
1646 state->ident != SAA7113)
1647 return;
1648
1649 if (data->saa7113_r08_htc) {
1650 work = saa711x_read(sd, R_08_SYNC_CNTL);
1651 work &= ~SAA7113_R_08_HTC_MASK;
1652 work |= ((*data->saa7113_r08_htc) << SAA7113_R_08_HTC_OFFSET);
1653 saa711x_write(sd, R_08_SYNC_CNTL, work);
1654 }
1655
1656 if (data->saa7113_r10_vrln) {
1657 work = saa711x_read(sd, R_10_CHROMA_CNTL_2);
1658 work &= ~SAA7113_R_10_VRLN_MASK;
1659 if (*data->saa7113_r10_vrln)
1660 work |= (1 << SAA7113_R_10_VRLN_OFFSET);
1661 saa711x_write(sd, R_10_CHROMA_CNTL_2, work);
1662 }
1663
1664 if (data->saa7113_r10_ofts) {
1665 work = saa711x_read(sd, R_10_CHROMA_CNTL_2);
1666 work &= ~SAA7113_R_10_OFTS_MASK;
1667 work |= (*data->saa7113_r10_ofts << SAA7113_R_10_OFTS_OFFSET);
1668 saa711x_write(sd, R_10_CHROMA_CNTL_2, work);
1669 }
1670
1671 if (data->saa7113_r12_rts0) {
1672 work = saa711x_read(sd, R_12_RT_SIGNAL_CNTL);
1673 work &= ~SAA7113_R_12_RTS0_MASK;
1674 work |= (*data->saa7113_r12_rts0 << SAA7113_R_12_RTS0_OFFSET);
1675
1676 /* According to the datasheet,
1677 * SAA7113_RTS_DOT_IN should only be used on RTS1 */
1678 WARN_ON(*data->saa7113_r12_rts0 == SAA7113_RTS_DOT_IN);
1679 saa711x_write(sd, R_12_RT_SIGNAL_CNTL, work);
1680 }
1681
1682 if (data->saa7113_r12_rts1) {
1683 work = saa711x_read(sd, R_12_RT_SIGNAL_CNTL);
1684 work &= ~SAA7113_R_12_RTS1_MASK;
1685 work |= (*data->saa7113_r12_rts1 << SAA7113_R_12_RTS1_OFFSET);
1686 saa711x_write(sd, R_12_RT_SIGNAL_CNTL, work);
1687 }
1688
1689 if (data->saa7113_r13_adlsb) {
1690 work = saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL);
1691 work &= ~SAA7113_R_13_ADLSB_MASK;
1692 if (*data->saa7113_r13_adlsb)
1693 work |= (1 << SAA7113_R_13_ADLSB_OFFSET);
1694 saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL, work);
1695 }
1696}
1697
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001698/**
1699 * saa711x_detect_chip - Detects the saa711x (or clone) variant
1700 * @client: I2C client structure.
1701 * @id: I2C device ID structure.
1702 * @name: Name of the device to be filled.
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001703 *
1704 * Detects the Philips/NXP saa711x chip, or some clone of it.
1705 * if 'id' is NULL or id->driver_data is equal to 1, it auto-probes
1706 * the analog demod.
1707 * If the tuner is not found, it returns -ENODEV.
1708 * If auto-detection is disabled and the tuner doesn't match what it was
Jonathan McCrohan39c1cb22013-10-20 21:34:01 -03001709 * required, it returns -EINVAL and fills 'name'.
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001710 * If the chip is found, it returns the chip ID and fills 'name'.
1711 */
1712static int saa711x_detect_chip(struct i2c_client *client,
1713 const struct i2c_device_id *id,
Mauro Carvalho Chehab6a084d62013-05-21 11:36:30 -03001714 char *name)
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001715{
Mauro Carvalho Chehab6a084d62013-05-21 11:36:30 -03001716 char chip_ver[CHIP_VER_SIZE];
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001717 char chip_id;
1718 int i;
1719 int autodetect;
1720
1721 autodetect = !id || id->driver_data == 1;
1722
1723 /* Read the chip version register */
Mauro Carvalho Chehab6a084d62013-05-21 11:36:30 -03001724 for (i = 0; i < CHIP_VER_SIZE; i++) {
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001725 i2c_smbus_write_byte_data(client, 0, i);
1726 chip_ver[i] = i2c_smbus_read_byte_data(client, 0);
1727 name[i] = (chip_ver[i] & 0x0f) + '0';
1728 if (name[i] > '9')
1729 name[i] += 'a' - '9' - 1;
1730 }
1731 name[i] = '\0';
1732
1733 /* Check if it is a Philips/NXP chip */
1734 if (!memcmp(name + 1, "f711", 4)) {
1735 chip_id = name[5];
Mauro Carvalho Chehab6a084d62013-05-21 11:36:30 -03001736 snprintf(name, CHIP_VER_SIZE, "saa711%c", chip_id);
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001737
1738 if (!autodetect && strcmp(name, id->name))
1739 return -EINVAL;
1740
1741 switch (chip_id) {
1742 case '1':
1743 if (chip_ver[0] & 0xf0) {
Mauro Carvalho Chehab6a084d62013-05-21 11:36:30 -03001744 snprintf(name, CHIP_VER_SIZE, "saa711%ca", chip_id);
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001745 v4l_info(client, "saa7111a variant found\n");
Hans Verkuile1277112013-05-29 06:59:51 -03001746 return SAA7111A;
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001747 }
Hans Verkuile1277112013-05-29 06:59:51 -03001748 return SAA7111;
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001749 case '3':
Hans Verkuile1277112013-05-29 06:59:51 -03001750 return SAA7113;
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001751 case '4':
Hans Verkuile1277112013-05-29 06:59:51 -03001752 return SAA7114;
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001753 case '5':
Hans Verkuile1277112013-05-29 06:59:51 -03001754 return SAA7115;
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001755 case '8':
Hans Verkuile1277112013-05-29 06:59:51 -03001756 return SAA7118;
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001757 default:
1758 v4l2_info(client,
1759 "WARNING: Philips/NXP chip unknown - Falling back to saa7111\n");
Hans Verkuile1277112013-05-29 06:59:51 -03001760 return SAA7111;
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001761 }
1762 }
1763
Mauro Carvalho Chehabb11460b2013-04-26 10:22:48 -03001764 /* Check if it is a gm7113c */
1765 if (!memcmp(name, "0000", 4)) {
1766 chip_id = 0;
1767 for (i = 0; i < 4; i++) {
1768 chip_id = chip_id << 1;
1769 chip_id |= (chip_ver[i] & 0x80) ? 1 : 0;
1770 }
1771
1772 /*
1773 * Note: From the datasheet, only versions 1 and 2
1774 * exists. However, tests on a device labeled as:
1775 * "GM7113C 1145" returned "10" on all 16 chip
1776 * version (reg 0x00) reads. So, we need to also
1777 * accept at least verion 0. For now, let's just
1778 * assume that a device that returns "0000" for
1779 * the lower nibble is a gm7113c.
1780 */
1781
Mauro Carvalho Chehab6a084d62013-05-21 11:36:30 -03001782 strlcpy(name, "gm7113c", CHIP_VER_SIZE);
Mauro Carvalho Chehabb11460b2013-04-26 10:22:48 -03001783
1784 if (!autodetect && strcmp(name, id->name))
1785 return -EINVAL;
1786
1787 v4l_dbg(1, debug, client,
1788 "It seems to be a %s chip (%*ph) @ 0x%x.\n",
1789 name, 16, chip_ver, client->addr << 1);
1790
Hans Verkuile1277112013-05-29 06:59:51 -03001791 return GM7113C;
Mauro Carvalho Chehabb11460b2013-04-26 10:22:48 -03001792 }
1793
Kevin Fitch7e312232016-03-23 01:23:32 -03001794 /* Check if it is a CJC7113 */
1795 if (!memcmp(name, "1111111111111111", CHIP_VER_SIZE)) {
1796 strlcpy(name, "cjc7113", CHIP_VER_SIZE);
1797
1798 if (!autodetect && strcmp(name, id->name))
1799 return -EINVAL;
1800
1801 v4l_dbg(1, debug, client,
1802 "It seems to be a %s chip (%*ph) @ 0x%x.\n",
1803 name, 16, chip_ver, client->addr << 1);
1804
1805 /* CJC7113 seems to be SAA7113-compatible */
1806 return SAA7113;
1807 }
1808
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001809 /* Chip was not discovered. Return its ID and don't bind */
1810 v4l_dbg(1, debug, client, "chip %*ph @ 0x%x is unknown.\n",
1811 16, chip_ver, client->addr << 1);
1812 return -ENODEV;
1813}
1814
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001815static int saa711x_probe(struct i2c_client *client,
Jean Delvared2653e92008-04-29 23:11:39 +02001816 const struct i2c_device_id *id)
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001817{
Mauro Carvalho Chehab66ec11932006-08-29 22:52:32 -03001818 struct saa711x_state *state;
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001819 struct v4l2_subdev *sd;
Hans Verkuile3560542010-05-24 10:00:52 -03001820 struct v4l2_ctrl_handler *hdl;
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -03001821 struct saa7115_platform_data *pdata;
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001822 int ident;
Mauro Carvalho Chehab6a084d62013-05-21 11:36:30 -03001823 char name[CHIP_VER_SIZE + 1];
Mauro Carvalho Chehabaf7d3742016-01-29 08:44:28 -02001824#if defined(CONFIG_MEDIA_CONTROLLER)
1825 int ret;
1826#endif
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001827
1828 /* Check if the adapter supports the needed features */
Hans Verkuilfbaa3d0d2007-09-13 11:19:39 -03001829 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
Hans Verkuil188f3452007-09-16 10:47:15 -03001830 return -EIO;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001831
Mauro Carvalho Chehab6a084d62013-05-21 11:36:30 -03001832 ident = saa711x_detect_chip(client, id, name);
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001833 if (ident == -EINVAL) {
1834 /* Chip exists, but doesn't match */
1835 v4l_warn(client, "found %s while %s was expected\n",
1836 name, id->name);
Hans Verkuil188f3452007-09-16 10:47:15 -03001837 return -ENODEV;
Hans Verkuilf7668162006-11-25 09:40:28 -03001838 }
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001839 if (ident < 0)
1840 return ident;
Hans Verkuilf7668162006-11-25 09:40:28 -03001841
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001842 strlcpy(client->name, name, sizeof(client->name));
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001843
Laurent Pinchartc02b2112013-05-02 08:29:43 -03001844 state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
Hans Verkuilc5bf2042008-09-03 17:12:09 -03001845 if (state == NULL)
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001846 return -ENOMEM;
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001847 sd = &state->sd;
1848 v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
Hans Verkuile3560542010-05-24 10:00:52 -03001849
Mauro Carvalho Chehabaf7d3742016-01-29 08:44:28 -02001850#if defined(CONFIG_MEDIA_CONTROLLER)
1851 state->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
1852 state->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
1853 state->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
1854
1855 sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
1856
1857 ret = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, state->pads);
1858 if (ret < 0)
1859 return ret;
1860#endif
1861
Hans Verkuile84e91e2013-05-29 06:59:37 -03001862 v4l_info(client, "%s found @ 0x%x (%s)\n", name,
1863 client->addr << 1, client->adapter->name);
Hans Verkuile3560542010-05-24 10:00:52 -03001864 hdl = &state->hdl;
1865 v4l2_ctrl_handler_init(hdl, 6);
1866 /* add in ascending ID order */
1867 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1868 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1869 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1870 V4L2_CID_CONTRAST, 0, 127, 1, 64);
1871 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1872 V4L2_CID_SATURATION, 0, 127, 1, 64);
1873 v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1874 V4L2_CID_HUE, -128, 127, 1, 0);
1875 state->agc = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1876 V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
1877 state->gain = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
1878 V4L2_CID_CHROMA_GAIN, 0, 127, 1, 40);
Hans Verkuile3560542010-05-24 10:00:52 -03001879 sd->ctrl_handler = hdl;
1880 if (hdl->error) {
1881 int err = hdl->error;
1882
1883 v4l2_ctrl_handler_free(hdl);
Hans Verkuile3560542010-05-24 10:00:52 -03001884 return err;
1885 }
Hans Verkuil6f43dbf2011-08-26 08:46:29 -03001886 v4l2_ctrl_auto_cluster(2, &state->agc, 0, true);
Hans Verkuile3560542010-05-24 10:00:52 -03001887
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001888 state->input = -1;
Marco Schluessler4cbca182007-01-21 19:43:38 -03001889 state->output = SAA7115_IPORT_ON;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001890 state->enable = 1;
Hans Verkuil3faeeae2006-01-09 15:25:44 -02001891 state->radio = 0;
Mauro Carvalho Chehabe0909012013-04-26 10:22:47 -03001892 state->ident = ident;
Mauro Carvalho Chehabf5762e42006-03-13 13:31:31 -03001893
Hans Verkuil3578d3d2006-01-09 15:25:41 -02001894 state->audclk_freq = 48000;
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001895
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001896 v4l2_dbg(1, debug, sd, "writing init values\n");
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001897
1898 /* init to 60hz/48khz */
Mauro Carvalho Chehab183d8962006-09-12 20:02:09 -03001899 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -03001900 pdata = client->dev.platform_data;
Mauro Carvalho Chehab183d8962006-09-12 20:02:09 -03001901 switch (state->ident) {
Hans Verkuile1277112013-05-29 06:59:51 -03001902 case SAA7111:
1903 case SAA7111A:
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001904 saa711x_writeregs(sd, saa7111_init);
Mauro Carvalho Chehab183d8962006-09-12 20:02:09 -03001905 break;
Hans Verkuile1277112013-05-29 06:59:51 -03001906 case GM7113C:
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -03001907 saa711x_writeregs(sd, gm7113c_init);
1908 break;
Hans Verkuile1277112013-05-29 06:59:51 -03001909 case SAA7113:
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -03001910 if (pdata && pdata->saa7113_force_gm7113c_init)
1911 saa711x_writeregs(sd, gm7113c_init);
1912 else
1913 saa711x_writeregs(sd, saa7113_init);
Mauro Carvalho Chehab183d8962006-09-12 20:02:09 -03001914 break;
1915 default:
Hans Verkuilb7f82922006-04-02 12:50:42 -03001916 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001917 saa711x_writeregs(sd, saa7115_init_auto_input);
Hans Verkuilb7f82922006-04-02 12:50:42 -03001918 }
Jon Arne Jørgensenb9798bc2013-08-03 09:19:36 -03001919 if (state->ident > SAA7111A && state->ident != GM7113C)
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001920 saa711x_writeregs(sd, saa7115_init_misc);
Jon Arne Jørgensen2ccf12a2013-08-03 09:19:37 -03001921
1922 if (pdata)
1923 saa711x_write_platform_data(state, pdata);
1924
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001925 saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
Hans Verkuile3560542010-05-24 10:00:52 -03001926 v4l2_ctrl_handler_setup(hdl);
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001927
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001928 v4l2_dbg(1, debug, sd, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1929 saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC),
1930 saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC));
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001931 return 0;
1932}
1933
1934/* ----------------------------------------------------------------------- */
1935
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001936static int saa711x_remove(struct i2c_client *client)
Hans Verkuilfbaa3d0d2007-09-13 11:19:39 -03001937{
Hans Verkuil9415f4b2008-11-29 12:55:19 -03001938 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1939
1940 v4l2_device_unregister_subdev(sd);
Hans Verkuile3560542010-05-24 10:00:52 -03001941 v4l2_ctrl_handler_free(sd->ctrl_handler);
Hans Verkuilfbaa3d0d2007-09-13 11:19:39 -03001942 return 0;
1943}
1944
Hans Verkuilaac23532010-09-15 15:04:55 -03001945static const struct i2c_device_id saa711x_id[] = {
Hans Verkuil9edd350f2008-07-17 13:22:51 -03001946 { "saa7115_auto", 1 }, /* autodetect */
Jean Delvareaf294862008-05-18 20:49:40 +02001947 { "saa7111", 0 },
1948 { "saa7113", 0 },
1949 { "saa7114", 0 },
1950 { "saa7115", 0 },
1951 { "saa7118", 0 },
Mauro Carvalho Chehabb11460b2013-04-26 10:22:48 -03001952 { "gm7113c", 0 },
Jean Delvareaf294862008-05-18 20:49:40 +02001953 { }
1954};
Hans Verkuilaac23532010-09-15 15:04:55 -03001955MODULE_DEVICE_TABLE(i2c, saa711x_id);
Jean Delvareaf294862008-05-18 20:49:40 +02001956
Hans Verkuilaac23532010-09-15 15:04:55 -03001957static struct i2c_driver saa711x_driver = {
1958 .driver = {
Hans Verkuilaac23532010-09-15 15:04:55 -03001959 .name = "saa7115",
1960 },
1961 .probe = saa711x_probe,
1962 .remove = saa711x_remove,
1963 .id_table = saa711x_id,
Hans Verkuile19b2fc2005-11-13 16:08:04 -08001964};
Hans Verkuilaac23532010-09-15 15:04:55 -03001965
Axel Linc6e8d862012-02-12 06:56:32 -03001966module_i2c_driver(saa711x_driver);