xref: /openbmc/linux/drivers/media/i2c/saa717x.c (revision 6e80c473)
1cb7a01acSMauro Carvalho Chehab /*
2cb7a01acSMauro Carvalho Chehab  * saa717x - Philips SAA717xHL video decoder driver
3cb7a01acSMauro Carvalho Chehab  *
4cb7a01acSMauro Carvalho Chehab  * Based on the saa7115 driver
5cb7a01acSMauro Carvalho Chehab  *
6cb7a01acSMauro Carvalho Chehab  * Changes by Ohta Kyuma <alpha292@bremen.or.jp>
7cb7a01acSMauro Carvalho Chehab  *    - Apply to SAA717x,NEC uPD64031,uPD64083. (1/31/2004)
8cb7a01acSMauro Carvalho Chehab  *
9cb7a01acSMauro Carvalho Chehab  * Changes by T.Adachi (tadachi@tadachi-net.com)
10cb7a01acSMauro Carvalho Chehab  *    - support audio, video scaler etc, and checked the initialize sequence.
11cb7a01acSMauro Carvalho Chehab  *
12cb7a01acSMauro Carvalho Chehab  * Cleaned up by Hans Verkuil <hverkuil@xs4all.nl>
13cb7a01acSMauro Carvalho Chehab  *
14cb7a01acSMauro Carvalho Chehab  * Note: this is a reversed engineered driver based on captures from
15cb7a01acSMauro Carvalho Chehab  * the I2C bus under Windows. This chip is very similar to the saa7134,
16cb7a01acSMauro Carvalho Chehab  * though. Unfortunately, this driver is currently only working for NTSC.
17cb7a01acSMauro Carvalho Chehab  *
18cb7a01acSMauro Carvalho Chehab  * This program is free software; you can redistribute it and/or modify
19cb7a01acSMauro Carvalho Chehab  * it under the terms of the GNU General Public License as published by
20cb7a01acSMauro Carvalho Chehab  * the Free Software Foundation; either version 2 of the License, or
21cb7a01acSMauro Carvalho Chehab  * (at your option) any later version.
22cb7a01acSMauro Carvalho Chehab  *
23cb7a01acSMauro Carvalho Chehab  * This program is distributed in the hope that it will be useful,
24cb7a01acSMauro Carvalho Chehab  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25cb7a01acSMauro Carvalho Chehab  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26cb7a01acSMauro Carvalho Chehab  * GNU General Public License for more details.
27cb7a01acSMauro Carvalho Chehab  *
28cb7a01acSMauro Carvalho Chehab  * You should have received a copy of the GNU General Public License
29cb7a01acSMauro Carvalho Chehab  * along with this program; if not, write to the Free Software
30cb7a01acSMauro Carvalho Chehab  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31cb7a01acSMauro Carvalho Chehab  */
32cb7a01acSMauro Carvalho Chehab 
33cb7a01acSMauro Carvalho Chehab #include <linux/module.h>
34cb7a01acSMauro Carvalho Chehab #include <linux/kernel.h>
35cb7a01acSMauro Carvalho Chehab #include <linux/slab.h>
36cb7a01acSMauro Carvalho Chehab #include <linux/sched.h>
37cb7a01acSMauro Carvalho Chehab 
38cb7a01acSMauro Carvalho Chehab #include <linux/videodev2.h>
39cb7a01acSMauro Carvalho Chehab #include <linux/i2c.h>
40cb7a01acSMauro Carvalho Chehab #include <media/v4l2-device.h>
41cb7a01acSMauro Carvalho Chehab #include <media/v4l2-ctrls.h>
42cb7a01acSMauro Carvalho Chehab 
43cb7a01acSMauro Carvalho Chehab MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver");
44cb7a01acSMauro Carvalho Chehab MODULE_AUTHOR("K. Ohta, T. Adachi, Hans Verkuil");
45cb7a01acSMauro Carvalho Chehab MODULE_LICENSE("GPL");
46cb7a01acSMauro Carvalho Chehab 
47cb7a01acSMauro Carvalho Chehab static int debug;
48cb7a01acSMauro Carvalho Chehab module_param(debug, int, 0644);
49cb7a01acSMauro Carvalho Chehab MODULE_PARM_DESC(debug, "Debug level (0-1)");
50cb7a01acSMauro Carvalho Chehab 
51cb7a01acSMauro Carvalho Chehab /*
52cb7a01acSMauro Carvalho Chehab  * Generic i2c probe
53cb7a01acSMauro Carvalho Chehab  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
54cb7a01acSMauro Carvalho Chehab  */
55cb7a01acSMauro Carvalho Chehab 
56cb7a01acSMauro Carvalho Chehab struct saa717x_state {
57cb7a01acSMauro Carvalho Chehab 	struct v4l2_subdev sd;
58cb7a01acSMauro Carvalho Chehab 	struct v4l2_ctrl_handler hdl;
59cb7a01acSMauro Carvalho Chehab 	v4l2_std_id std;
60cb7a01acSMauro Carvalho Chehab 	int input;
61cb7a01acSMauro Carvalho Chehab 	int enable;
62cb7a01acSMauro Carvalho Chehab 	int radio;
63cb7a01acSMauro Carvalho Chehab 	int playback;
64cb7a01acSMauro Carvalho Chehab 	int audio;
65cb7a01acSMauro Carvalho Chehab 	int tuner_audio_mode;
66cb7a01acSMauro Carvalho Chehab 	int audio_main_mute;
67cb7a01acSMauro Carvalho Chehab 	int audio_main_vol_r;
68cb7a01acSMauro Carvalho Chehab 	int audio_main_vol_l;
69cb7a01acSMauro Carvalho Chehab 	u16 audio_main_bass;
70cb7a01acSMauro Carvalho Chehab 	u16 audio_main_treble;
71cb7a01acSMauro Carvalho Chehab 	u16 audio_main_volume;
72cb7a01acSMauro Carvalho Chehab 	u16 audio_main_balance;
73cb7a01acSMauro Carvalho Chehab 	int audio_input;
74cb7a01acSMauro Carvalho Chehab };
75cb7a01acSMauro Carvalho Chehab 
76cb7a01acSMauro Carvalho Chehab static inline struct saa717x_state *to_state(struct v4l2_subdev *sd)
77cb7a01acSMauro Carvalho Chehab {
78cb7a01acSMauro Carvalho Chehab 	return container_of(sd, struct saa717x_state, sd);
79cb7a01acSMauro Carvalho Chehab }
80cb7a01acSMauro Carvalho Chehab 
81cb7a01acSMauro Carvalho Chehab static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
82cb7a01acSMauro Carvalho Chehab {
83cb7a01acSMauro Carvalho Chehab 	return &container_of(ctrl->handler, struct saa717x_state, hdl)->sd;
84cb7a01acSMauro Carvalho Chehab }
85cb7a01acSMauro Carvalho Chehab 
86cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */
87cb7a01acSMauro Carvalho Chehab 
88cb7a01acSMauro Carvalho Chehab /* for audio mode */
89cb7a01acSMauro Carvalho Chehab #define TUNER_AUDIO_MONO   	0  /* LL */
90cb7a01acSMauro Carvalho Chehab #define TUNER_AUDIO_STEREO 	1  /* LR */
91cb7a01acSMauro Carvalho Chehab #define TUNER_AUDIO_LANG1  	2  /* LL */
92cb7a01acSMauro Carvalho Chehab #define TUNER_AUDIO_LANG2  	3  /* RR */
93cb7a01acSMauro Carvalho Chehab 
94cb7a01acSMauro Carvalho Chehab #define SAA717X_NTSC_WIDTH   	(704)
95cb7a01acSMauro Carvalho Chehab #define SAA717X_NTSC_HEIGHT  	(480)
96cb7a01acSMauro Carvalho Chehab 
97cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */
98cb7a01acSMauro Carvalho Chehab 
99cb7a01acSMauro Carvalho Chehab static int saa717x_write(struct v4l2_subdev *sd, u32 reg, u32 value)
100cb7a01acSMauro Carvalho Chehab {
101cb7a01acSMauro Carvalho Chehab 	struct i2c_client *client = v4l2_get_subdevdata(sd);
102cb7a01acSMauro Carvalho Chehab 	struct i2c_adapter *adap = client->adapter;
103cb7a01acSMauro Carvalho Chehab 	int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488;
104cb7a01acSMauro Carvalho Chehab 	unsigned char mm1[6];
105cb7a01acSMauro Carvalho Chehab 	struct i2c_msg msg;
106cb7a01acSMauro Carvalho Chehab 
107cb7a01acSMauro Carvalho Chehab 	msg.flags = 0;
108cb7a01acSMauro Carvalho Chehab 	msg.addr = client->addr;
109cb7a01acSMauro Carvalho Chehab 	mm1[0] = (reg >> 8) & 0xff;
110cb7a01acSMauro Carvalho Chehab 	mm1[1] = reg & 0xff;
111cb7a01acSMauro Carvalho Chehab 
112cb7a01acSMauro Carvalho Chehab 	if (fw_addr) {
113cb7a01acSMauro Carvalho Chehab 		mm1[4] = (value >> 16) & 0xff;
114cb7a01acSMauro Carvalho Chehab 		mm1[3] = (value >> 8) & 0xff;
115cb7a01acSMauro Carvalho Chehab 		mm1[2] = value & 0xff;
116cb7a01acSMauro Carvalho Chehab 	} else {
117cb7a01acSMauro Carvalho Chehab 		mm1[2] = value & 0xff;
118cb7a01acSMauro Carvalho Chehab 	}
119cb7a01acSMauro Carvalho Chehab 	msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */
120cb7a01acSMauro Carvalho Chehab 	msg.buf = mm1;
121cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(2, debug, sd, "wrote:  reg 0x%03x=%08x\n", reg, value);
122cb7a01acSMauro Carvalho Chehab 	return i2c_transfer(adap, &msg, 1) == 1;
123cb7a01acSMauro Carvalho Chehab }
124cb7a01acSMauro Carvalho Chehab 
125cb7a01acSMauro Carvalho Chehab static void saa717x_write_regs(struct v4l2_subdev *sd, u32 *data)
126cb7a01acSMauro Carvalho Chehab {
127cb7a01acSMauro Carvalho Chehab 	while (data[0] || data[1]) {
128cb7a01acSMauro Carvalho Chehab 		saa717x_write(sd, data[0], data[1]);
129cb7a01acSMauro Carvalho Chehab 		data += 2;
130cb7a01acSMauro Carvalho Chehab 	}
131cb7a01acSMauro Carvalho Chehab }
132cb7a01acSMauro Carvalho Chehab 
133cb7a01acSMauro Carvalho Chehab static u32 saa717x_read(struct v4l2_subdev *sd, u32 reg)
134cb7a01acSMauro Carvalho Chehab {
135cb7a01acSMauro Carvalho Chehab 	struct i2c_client *client = v4l2_get_subdevdata(sd);
136cb7a01acSMauro Carvalho Chehab 	struct i2c_adapter *adap = client->adapter;
137cb7a01acSMauro Carvalho Chehab 	int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528;
138cb7a01acSMauro Carvalho Chehab 	unsigned char mm1[2];
139cb7a01acSMauro Carvalho Chehab 	unsigned char mm2[4] = { 0, 0, 0, 0 };
140cb7a01acSMauro Carvalho Chehab 	struct i2c_msg msgs[2];
141cb7a01acSMauro Carvalho Chehab 	u32 value;
142cb7a01acSMauro Carvalho Chehab 
143cb7a01acSMauro Carvalho Chehab 	msgs[0].flags = 0;
144cb7a01acSMauro Carvalho Chehab 	msgs[1].flags = I2C_M_RD;
145cb7a01acSMauro Carvalho Chehab 	msgs[0].addr = msgs[1].addr = client->addr;
146cb7a01acSMauro Carvalho Chehab 	mm1[0] = (reg >> 8) & 0xff;
147cb7a01acSMauro Carvalho Chehab 	mm1[1] = reg & 0xff;
148cb7a01acSMauro Carvalho Chehab 	msgs[0].len = 2;
149cb7a01acSMauro Carvalho Chehab 	msgs[0].buf = mm1;
150cb7a01acSMauro Carvalho Chehab 	msgs[1].len = fw_addr ? 3 : 1; /* Multibyte Registers contains *only* 3 bytes */
151cb7a01acSMauro Carvalho Chehab 	msgs[1].buf = mm2;
152cb7a01acSMauro Carvalho Chehab 	i2c_transfer(adap, msgs, 2);
153cb7a01acSMauro Carvalho Chehab 
154cb7a01acSMauro Carvalho Chehab 	if (fw_addr)
1554c7ba408SMauro Carvalho Chehab 		value = (mm2[2] << 16)  | (mm2[1] << 8) | mm2[0];
156cb7a01acSMauro Carvalho Chehab 	else
1574c7ba408SMauro Carvalho Chehab 		value = mm2[0];
158cb7a01acSMauro Carvalho Chehab 
159cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(2, debug, sd, "read:  reg 0x%03x=0x%08x\n", reg, value);
160cb7a01acSMauro Carvalho Chehab 	return value;
161cb7a01acSMauro Carvalho Chehab }
162cb7a01acSMauro Carvalho Chehab 
163cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */
164cb7a01acSMauro Carvalho Chehab 
165cb7a01acSMauro Carvalho Chehab static u32 reg_init_initialize[] =
166cb7a01acSMauro Carvalho Chehab {
167cb7a01acSMauro Carvalho Chehab 	/* from linux driver */
168cb7a01acSMauro Carvalho Chehab 	0x101, 0x008, /* Increment delay */
169cb7a01acSMauro Carvalho Chehab 
170cb7a01acSMauro Carvalho Chehab 	0x103, 0x000, /* Analog input control 2 */
171cb7a01acSMauro Carvalho Chehab 	0x104, 0x090, /* Analog input control 3 */
172cb7a01acSMauro Carvalho Chehab 	0x105, 0x090, /* Analog input control 4 */
173cb7a01acSMauro Carvalho Chehab 	0x106, 0x0eb, /* Horizontal sync start */
174cb7a01acSMauro Carvalho Chehab 	0x107, 0x0e0, /* Horizontal sync stop */
175cb7a01acSMauro Carvalho Chehab 	0x109, 0x055, /* Luminance control */
176cb7a01acSMauro Carvalho Chehab 
177cb7a01acSMauro Carvalho Chehab 	0x10f, 0x02a, /* Chroma gain control */
178cb7a01acSMauro Carvalho Chehab 	0x110, 0x000, /* Chroma control 2 */
179cb7a01acSMauro Carvalho Chehab 
180cb7a01acSMauro Carvalho Chehab 	0x114, 0x045, /* analog/ADC */
181cb7a01acSMauro Carvalho Chehab 
182cb7a01acSMauro Carvalho Chehab 	0x118, 0x040, /* RAW data gain */
183cb7a01acSMauro Carvalho Chehab 	0x119, 0x080, /* RAW data offset */
184cb7a01acSMauro Carvalho Chehab 
185cb7a01acSMauro Carvalho Chehab 	0x044, 0x000, /* VBI horizontal input window start (L) TASK A */
186cb7a01acSMauro Carvalho Chehab 	0x045, 0x000, /* VBI horizontal input window start (H) TASK A */
187cb7a01acSMauro Carvalho Chehab 	0x046, 0x0cf, /* VBI horizontal input window stop (L) TASK A */
188cb7a01acSMauro Carvalho Chehab 	0x047, 0x002, /* VBI horizontal input window stop (H) TASK A */
189cb7a01acSMauro Carvalho Chehab 
190cb7a01acSMauro Carvalho Chehab 	0x049, 0x000, /* VBI vertical input window start (H) TASK A */
191cb7a01acSMauro Carvalho Chehab 
192cb7a01acSMauro Carvalho Chehab 	0x04c, 0x0d0, /* VBI horizontal output length (L) TASK A */
193cb7a01acSMauro Carvalho Chehab 	0x04d, 0x002, /* VBI horizontal output length (H) TASK A */
194cb7a01acSMauro Carvalho Chehab 
195cb7a01acSMauro Carvalho Chehab 	0x064, 0x080, /* Lumina brightness TASK A */
196cb7a01acSMauro Carvalho Chehab 	0x065, 0x040, /* Luminance contrast TASK A */
197cb7a01acSMauro Carvalho Chehab 	0x066, 0x040, /* Chroma saturation TASK A */
198cb7a01acSMauro Carvalho Chehab 	/* 067H: Reserved */
199cb7a01acSMauro Carvalho Chehab 	0x068, 0x000, /* VBI horizontal scaling increment (L) TASK A */
200cb7a01acSMauro Carvalho Chehab 	0x069, 0x004, /* VBI horizontal scaling increment (H) TASK A */
201cb7a01acSMauro Carvalho Chehab 	0x06a, 0x000, /* VBI phase offset TASK A */
202cb7a01acSMauro Carvalho Chehab 
203cb7a01acSMauro Carvalho Chehab 	0x06e, 0x000, /* Horizontal phase offset Luma TASK A */
204cb7a01acSMauro Carvalho Chehab 	0x06f, 0x000, /* Horizontal phase offset Chroma TASK A */
205cb7a01acSMauro Carvalho Chehab 
206cb7a01acSMauro Carvalho Chehab 	0x072, 0x000, /* Vertical filter mode TASK A */
207cb7a01acSMauro Carvalho Chehab 
208cb7a01acSMauro Carvalho Chehab 	0x084, 0x000, /* VBI horizontal input window start (L) TAKS B */
209cb7a01acSMauro Carvalho Chehab 	0x085, 0x000, /* VBI horizontal input window start (H) TAKS B */
210cb7a01acSMauro Carvalho Chehab 	0x086, 0x0cf, /* VBI horizontal input window stop (L) TAKS B */
211cb7a01acSMauro Carvalho Chehab 	0x087, 0x002, /* VBI horizontal input window stop (H) TAKS B */
212cb7a01acSMauro Carvalho Chehab 
213cb7a01acSMauro Carvalho Chehab 	0x089, 0x000, /* VBI vertical input window start (H) TAKS B */
214cb7a01acSMauro Carvalho Chehab 
215cb7a01acSMauro Carvalho Chehab 	0x08c, 0x0d0, /* VBI horizontal output length (L) TASK B */
216cb7a01acSMauro Carvalho Chehab 	0x08d, 0x002, /* VBI horizontal output length (H) TASK B */
217cb7a01acSMauro Carvalho Chehab 
218cb7a01acSMauro Carvalho Chehab 	0x0a4, 0x080, /* Lumina brightness TASK B */
219cb7a01acSMauro Carvalho Chehab 	0x0a5, 0x040, /* Luminance contrast TASK B */
220cb7a01acSMauro Carvalho Chehab 	0x0a6, 0x040, /* Chroma saturation TASK B */
221cb7a01acSMauro Carvalho Chehab 	/* 0A7H reserved */
222cb7a01acSMauro Carvalho Chehab 	0x0a8, 0x000, /* VBI horizontal scaling increment (L) TASK B */
223cb7a01acSMauro Carvalho Chehab 	0x0a9, 0x004, /* VBI horizontal scaling increment (H) TASK B */
224cb7a01acSMauro Carvalho Chehab 	0x0aa, 0x000, /* VBI phase offset TASK B */
225cb7a01acSMauro Carvalho Chehab 
226cb7a01acSMauro Carvalho Chehab 	0x0ae, 0x000, /* Horizontal phase offset Luma TASK B */
227cb7a01acSMauro Carvalho Chehab 	0x0af, 0x000, /*Horizontal phase offset Chroma TASK B */
228cb7a01acSMauro Carvalho Chehab 
229cb7a01acSMauro Carvalho Chehab 	0x0b2, 0x000, /* Vertical filter mode TASK B */
230cb7a01acSMauro Carvalho Chehab 
231cb7a01acSMauro Carvalho Chehab 	0x00c, 0x000, /* Start point GREEN path */
232cb7a01acSMauro Carvalho Chehab 	0x00d, 0x000, /* Start point BLUE path */
233cb7a01acSMauro Carvalho Chehab 	0x00e, 0x000, /* Start point RED path */
234cb7a01acSMauro Carvalho Chehab 
235cb7a01acSMauro Carvalho Chehab 	0x010, 0x010, /* GREEN path gamma curve --- */
236cb7a01acSMauro Carvalho Chehab 	0x011, 0x020,
237cb7a01acSMauro Carvalho Chehab 	0x012, 0x030,
238cb7a01acSMauro Carvalho Chehab 	0x013, 0x040,
239cb7a01acSMauro Carvalho Chehab 	0x014, 0x050,
240cb7a01acSMauro Carvalho Chehab 	0x015, 0x060,
241cb7a01acSMauro Carvalho Chehab 	0x016, 0x070,
242cb7a01acSMauro Carvalho Chehab 	0x017, 0x080,
243cb7a01acSMauro Carvalho Chehab 	0x018, 0x090,
244cb7a01acSMauro Carvalho Chehab 	0x019, 0x0a0,
245cb7a01acSMauro Carvalho Chehab 	0x01a, 0x0b0,
246cb7a01acSMauro Carvalho Chehab 	0x01b, 0x0c0,
247cb7a01acSMauro Carvalho Chehab 	0x01c, 0x0d0,
248cb7a01acSMauro Carvalho Chehab 	0x01d, 0x0e0,
249cb7a01acSMauro Carvalho Chehab 	0x01e, 0x0f0,
250cb7a01acSMauro Carvalho Chehab 	0x01f, 0x0ff, /* --- GREEN path gamma curve */
251cb7a01acSMauro Carvalho Chehab 
252cb7a01acSMauro Carvalho Chehab 	0x020, 0x010, /* BLUE path gamma curve --- */
253cb7a01acSMauro Carvalho Chehab 	0x021, 0x020,
254cb7a01acSMauro Carvalho Chehab 	0x022, 0x030,
255cb7a01acSMauro Carvalho Chehab 	0x023, 0x040,
256cb7a01acSMauro Carvalho Chehab 	0x024, 0x050,
257cb7a01acSMauro Carvalho Chehab 	0x025, 0x060,
258cb7a01acSMauro Carvalho Chehab 	0x026, 0x070,
259cb7a01acSMauro Carvalho Chehab 	0x027, 0x080,
260cb7a01acSMauro Carvalho Chehab 	0x028, 0x090,
261cb7a01acSMauro Carvalho Chehab 	0x029, 0x0a0,
262cb7a01acSMauro Carvalho Chehab 	0x02a, 0x0b0,
263cb7a01acSMauro Carvalho Chehab 	0x02b, 0x0c0,
264cb7a01acSMauro Carvalho Chehab 	0x02c, 0x0d0,
265cb7a01acSMauro Carvalho Chehab 	0x02d, 0x0e0,
266cb7a01acSMauro Carvalho Chehab 	0x02e, 0x0f0,
267cb7a01acSMauro Carvalho Chehab 	0x02f, 0x0ff, /* --- BLUE path gamma curve */
268cb7a01acSMauro Carvalho Chehab 
269cb7a01acSMauro Carvalho Chehab 	0x030, 0x010, /* RED path gamma curve --- */
270cb7a01acSMauro Carvalho Chehab 	0x031, 0x020,
271cb7a01acSMauro Carvalho Chehab 	0x032, 0x030,
272cb7a01acSMauro Carvalho Chehab 	0x033, 0x040,
273cb7a01acSMauro Carvalho Chehab 	0x034, 0x050,
274cb7a01acSMauro Carvalho Chehab 	0x035, 0x060,
275cb7a01acSMauro Carvalho Chehab 	0x036, 0x070,
276cb7a01acSMauro Carvalho Chehab 	0x037, 0x080,
277cb7a01acSMauro Carvalho Chehab 	0x038, 0x090,
278cb7a01acSMauro Carvalho Chehab 	0x039, 0x0a0,
279cb7a01acSMauro Carvalho Chehab 	0x03a, 0x0b0,
280cb7a01acSMauro Carvalho Chehab 	0x03b, 0x0c0,
281cb7a01acSMauro Carvalho Chehab 	0x03c, 0x0d0,
282cb7a01acSMauro Carvalho Chehab 	0x03d, 0x0e0,
283cb7a01acSMauro Carvalho Chehab 	0x03e, 0x0f0,
284cb7a01acSMauro Carvalho Chehab 	0x03f, 0x0ff, /* --- RED path gamma curve */
285cb7a01acSMauro Carvalho Chehab 
286cb7a01acSMauro Carvalho Chehab 	0x109, 0x085, /* Luminance control  */
287cb7a01acSMauro Carvalho Chehab 
288cb7a01acSMauro Carvalho Chehab 	/**** from app start ****/
289cb7a01acSMauro Carvalho Chehab 	0x584, 0x000, /* AGC gain control */
290cb7a01acSMauro Carvalho Chehab 	0x585, 0x000, /* Program count */
291cb7a01acSMauro Carvalho Chehab 	0x586, 0x003, /* Status reset */
292cb7a01acSMauro Carvalho Chehab 	0x588, 0x0ff, /* Number of audio samples (L) */
293cb7a01acSMauro Carvalho Chehab 	0x589, 0x00f, /* Number of audio samples (M) */
294cb7a01acSMauro Carvalho Chehab 	0x58a, 0x000, /* Number of audio samples (H) */
295cb7a01acSMauro Carvalho Chehab 	0x58b, 0x000, /* Audio select */
296cb7a01acSMauro Carvalho Chehab 	0x58c, 0x010, /* Audio channel assign1 */
297cb7a01acSMauro Carvalho Chehab 	0x58d, 0x032, /* Audio channel assign2 */
298cb7a01acSMauro Carvalho Chehab 	0x58e, 0x054, /* Audio channel assign3 */
299cb7a01acSMauro Carvalho Chehab 	0x58f, 0x023, /* Audio format */
300cb7a01acSMauro Carvalho Chehab 	0x590, 0x000, /* SIF control */
301cb7a01acSMauro Carvalho Chehab 
302cb7a01acSMauro Carvalho Chehab 	0x595, 0x000, /* ?? */
303cb7a01acSMauro Carvalho Chehab 	0x596, 0x000, /* ?? */
304cb7a01acSMauro Carvalho Chehab 	0x597, 0x000, /* ?? */
305cb7a01acSMauro Carvalho Chehab 
306cb7a01acSMauro Carvalho Chehab 	0x464, 0x00, /* Digital input crossbar1 */
307cb7a01acSMauro Carvalho Chehab 
308cb7a01acSMauro Carvalho Chehab 	0x46c, 0xbbbb10, /* Digital output selection1-3 */
309cb7a01acSMauro Carvalho Chehab 	0x470, 0x101010, /* Digital output selection4-6 */
310cb7a01acSMauro Carvalho Chehab 
311cb7a01acSMauro Carvalho Chehab 	0x478, 0x00, /* Sound feature control */
312cb7a01acSMauro Carvalho Chehab 
313cb7a01acSMauro Carvalho Chehab 	0x474, 0x18, /* Softmute control */
314cb7a01acSMauro Carvalho Chehab 
315cb7a01acSMauro Carvalho Chehab 	0x454, 0x0425b9, /* Sound Easy programming(reset) */
316cb7a01acSMauro Carvalho Chehab 	0x454, 0x042539, /* Sound Easy programming(reset) */
317cb7a01acSMauro Carvalho Chehab 
318cb7a01acSMauro Carvalho Chehab 
319cb7a01acSMauro Carvalho Chehab 	/**** common setting( of DVD play, including scaler commands) ****/
320cb7a01acSMauro Carvalho Chehab 	0x042, 0x003, /* Data path configuration for VBI (TASK A) */
321cb7a01acSMauro Carvalho Chehab 
322cb7a01acSMauro Carvalho Chehab 	0x082, 0x003, /* Data path configuration for VBI (TASK B) */
323cb7a01acSMauro Carvalho Chehab 
324cb7a01acSMauro Carvalho Chehab 	0x108, 0x0f8, /* Sync control */
325cb7a01acSMauro Carvalho Chehab 	0x2a9, 0x0fd, /* ??? */
326cb7a01acSMauro Carvalho Chehab 	0x102, 0x089, /* select video input "mode 9" */
327cb7a01acSMauro Carvalho Chehab 	0x111, 0x000, /* Mode/delay control */
328cb7a01acSMauro Carvalho Chehab 
329cb7a01acSMauro Carvalho Chehab 	0x10e, 0x00a, /* Chroma control 1 */
330cb7a01acSMauro Carvalho Chehab 
331cb7a01acSMauro Carvalho Chehab 	0x594, 0x002, /* SIF, analog I/O select */
332cb7a01acSMauro Carvalho Chehab 
333cb7a01acSMauro Carvalho Chehab 	0x454, 0x0425b9, /* Sound  */
334cb7a01acSMauro Carvalho Chehab 	0x454, 0x042539,
335cb7a01acSMauro Carvalho Chehab 
336cb7a01acSMauro Carvalho Chehab 	0x111, 0x000,
337cb7a01acSMauro Carvalho Chehab 	0x10e, 0x00a,
338cb7a01acSMauro Carvalho Chehab 	0x464, 0x000,
339cb7a01acSMauro Carvalho Chehab 	0x300, 0x000,
340cb7a01acSMauro Carvalho Chehab 	0x301, 0x006,
341cb7a01acSMauro Carvalho Chehab 	0x302, 0x000,
342cb7a01acSMauro Carvalho Chehab 	0x303, 0x006,
343cb7a01acSMauro Carvalho Chehab 	0x308, 0x040,
344cb7a01acSMauro Carvalho Chehab 	0x309, 0x000,
345cb7a01acSMauro Carvalho Chehab 	0x30a, 0x000,
346cb7a01acSMauro Carvalho Chehab 	0x30b, 0x000,
347cb7a01acSMauro Carvalho Chehab 	0x000, 0x002,
348cb7a01acSMauro Carvalho Chehab 	0x001, 0x000,
349cb7a01acSMauro Carvalho Chehab 	0x002, 0x000,
350cb7a01acSMauro Carvalho Chehab 	0x003, 0x000,
351cb7a01acSMauro Carvalho Chehab 	0x004, 0x033,
352cb7a01acSMauro Carvalho Chehab 	0x040, 0x01d,
353cb7a01acSMauro Carvalho Chehab 	0x041, 0x001,
354cb7a01acSMauro Carvalho Chehab 	0x042, 0x004,
355cb7a01acSMauro Carvalho Chehab 	0x043, 0x000,
356cb7a01acSMauro Carvalho Chehab 	0x080, 0x01e,
357cb7a01acSMauro Carvalho Chehab 	0x081, 0x001,
358cb7a01acSMauro Carvalho Chehab 	0x082, 0x004,
359cb7a01acSMauro Carvalho Chehab 	0x083, 0x000,
360cb7a01acSMauro Carvalho Chehab 	0x190, 0x018,
361cb7a01acSMauro Carvalho Chehab 	0x115, 0x000,
362cb7a01acSMauro Carvalho Chehab 	0x116, 0x012,
363cb7a01acSMauro Carvalho Chehab 	0x117, 0x018,
364cb7a01acSMauro Carvalho Chehab 	0x04a, 0x011,
365cb7a01acSMauro Carvalho Chehab 	0x08a, 0x011,
366cb7a01acSMauro Carvalho Chehab 	0x04b, 0x000,
367cb7a01acSMauro Carvalho Chehab 	0x08b, 0x000,
368cb7a01acSMauro Carvalho Chehab 	0x048, 0x000,
369cb7a01acSMauro Carvalho Chehab 	0x088, 0x000,
370cb7a01acSMauro Carvalho Chehab 	0x04e, 0x012,
371cb7a01acSMauro Carvalho Chehab 	0x08e, 0x012,
372cb7a01acSMauro Carvalho Chehab 	0x058, 0x012,
373cb7a01acSMauro Carvalho Chehab 	0x098, 0x012,
374cb7a01acSMauro Carvalho Chehab 	0x059, 0x000,
375cb7a01acSMauro Carvalho Chehab 	0x099, 0x000,
376cb7a01acSMauro Carvalho Chehab 	0x05a, 0x003,
377cb7a01acSMauro Carvalho Chehab 	0x09a, 0x003,
378cb7a01acSMauro Carvalho Chehab 	0x05b, 0x001,
379cb7a01acSMauro Carvalho Chehab 	0x09b, 0x001,
380cb7a01acSMauro Carvalho Chehab 	0x054, 0x008,
381cb7a01acSMauro Carvalho Chehab 	0x094, 0x008,
382cb7a01acSMauro Carvalho Chehab 	0x055, 0x000,
383cb7a01acSMauro Carvalho Chehab 	0x095, 0x000,
384cb7a01acSMauro Carvalho Chehab 	0x056, 0x0c7,
385cb7a01acSMauro Carvalho Chehab 	0x096, 0x0c7,
386cb7a01acSMauro Carvalho Chehab 	0x057, 0x002,
387cb7a01acSMauro Carvalho Chehab 	0x097, 0x002,
388cb7a01acSMauro Carvalho Chehab 	0x0ff, 0x0ff,
389cb7a01acSMauro Carvalho Chehab 	0x060, 0x001,
390cb7a01acSMauro Carvalho Chehab 	0x0a0, 0x001,
391cb7a01acSMauro Carvalho Chehab 	0x061, 0x000,
392cb7a01acSMauro Carvalho Chehab 	0x0a1, 0x000,
393cb7a01acSMauro Carvalho Chehab 	0x062, 0x000,
394cb7a01acSMauro Carvalho Chehab 	0x0a2, 0x000,
395cb7a01acSMauro Carvalho Chehab 	0x063, 0x000,
396cb7a01acSMauro Carvalho Chehab 	0x0a3, 0x000,
397cb7a01acSMauro Carvalho Chehab 	0x070, 0x000,
398cb7a01acSMauro Carvalho Chehab 	0x0b0, 0x000,
399cb7a01acSMauro Carvalho Chehab 	0x071, 0x004,
400cb7a01acSMauro Carvalho Chehab 	0x0b1, 0x004,
401cb7a01acSMauro Carvalho Chehab 	0x06c, 0x0e9,
402cb7a01acSMauro Carvalho Chehab 	0x0ac, 0x0e9,
403cb7a01acSMauro Carvalho Chehab 	0x06d, 0x003,
404cb7a01acSMauro Carvalho Chehab 	0x0ad, 0x003,
405cb7a01acSMauro Carvalho Chehab 	0x05c, 0x0d0,
406cb7a01acSMauro Carvalho Chehab 	0x09c, 0x0d0,
407cb7a01acSMauro Carvalho Chehab 	0x05d, 0x002,
408cb7a01acSMauro Carvalho Chehab 	0x09d, 0x002,
409cb7a01acSMauro Carvalho Chehab 	0x05e, 0x0f2,
410cb7a01acSMauro Carvalho Chehab 	0x09e, 0x0f2,
411cb7a01acSMauro Carvalho Chehab 	0x05f, 0x000,
412cb7a01acSMauro Carvalho Chehab 	0x09f, 0x000,
413cb7a01acSMauro Carvalho Chehab 	0x074, 0x000,
414cb7a01acSMauro Carvalho Chehab 	0x0b4, 0x000,
415cb7a01acSMauro Carvalho Chehab 	0x075, 0x000,
416cb7a01acSMauro Carvalho Chehab 	0x0b5, 0x000,
417cb7a01acSMauro Carvalho Chehab 	0x076, 0x000,
418cb7a01acSMauro Carvalho Chehab 	0x0b6, 0x000,
419cb7a01acSMauro Carvalho Chehab 	0x077, 0x000,
420cb7a01acSMauro Carvalho Chehab 	0x0b7, 0x000,
421cb7a01acSMauro Carvalho Chehab 	0x195, 0x008,
422cb7a01acSMauro Carvalho Chehab 	0x0ff, 0x0ff,
423cb7a01acSMauro Carvalho Chehab 	0x108, 0x0f8,
424cb7a01acSMauro Carvalho Chehab 	0x111, 0x000,
425cb7a01acSMauro Carvalho Chehab 	0x10e, 0x00a,
426cb7a01acSMauro Carvalho Chehab 	0x2a9, 0x0fd,
427cb7a01acSMauro Carvalho Chehab 	0x464, 0x001,
428cb7a01acSMauro Carvalho Chehab 	0x454, 0x042135,
429cb7a01acSMauro Carvalho Chehab 	0x598, 0x0e7,
430cb7a01acSMauro Carvalho Chehab 	0x599, 0x07d,
431cb7a01acSMauro Carvalho Chehab 	0x59a, 0x018,
432cb7a01acSMauro Carvalho Chehab 	0x59c, 0x066,
433cb7a01acSMauro Carvalho Chehab 	0x59d, 0x090,
434cb7a01acSMauro Carvalho Chehab 	0x59e, 0x001,
435cb7a01acSMauro Carvalho Chehab 	0x584, 0x000,
436cb7a01acSMauro Carvalho Chehab 	0x585, 0x000,
437cb7a01acSMauro Carvalho Chehab 	0x586, 0x003,
438cb7a01acSMauro Carvalho Chehab 	0x588, 0x0ff,
439cb7a01acSMauro Carvalho Chehab 	0x589, 0x00f,
440cb7a01acSMauro Carvalho Chehab 	0x58a, 0x000,
441cb7a01acSMauro Carvalho Chehab 	0x58b, 0x000,
442cb7a01acSMauro Carvalho Chehab 	0x58c, 0x010,
443cb7a01acSMauro Carvalho Chehab 	0x58d, 0x032,
444cb7a01acSMauro Carvalho Chehab 	0x58e, 0x054,
445cb7a01acSMauro Carvalho Chehab 	0x58f, 0x023,
446cb7a01acSMauro Carvalho Chehab 	0x590, 0x000,
447cb7a01acSMauro Carvalho Chehab 	0x595, 0x000,
448cb7a01acSMauro Carvalho Chehab 	0x596, 0x000,
449cb7a01acSMauro Carvalho Chehab 	0x597, 0x000,
450cb7a01acSMauro Carvalho Chehab 	0x464, 0x000,
451cb7a01acSMauro Carvalho Chehab 	0x46c, 0xbbbb10,
452cb7a01acSMauro Carvalho Chehab 	0x470, 0x101010,
453cb7a01acSMauro Carvalho Chehab 
454cb7a01acSMauro Carvalho Chehab 
455cb7a01acSMauro Carvalho Chehab 	0x478, 0x000,
456cb7a01acSMauro Carvalho Chehab 	0x474, 0x018,
457cb7a01acSMauro Carvalho Chehab 	0x454, 0x042135,
458cb7a01acSMauro Carvalho Chehab 	0x598, 0x0e7,
459cb7a01acSMauro Carvalho Chehab 	0x599, 0x07d,
460cb7a01acSMauro Carvalho Chehab 	0x59a, 0x018,
461cb7a01acSMauro Carvalho Chehab 	0x59c, 0x066,
462cb7a01acSMauro Carvalho Chehab 	0x59d, 0x090,
463cb7a01acSMauro Carvalho Chehab 	0x59e, 0x001,
464cb7a01acSMauro Carvalho Chehab 	0x584, 0x000,
465cb7a01acSMauro Carvalho Chehab 	0x585, 0x000,
466cb7a01acSMauro Carvalho Chehab 	0x586, 0x003,
467cb7a01acSMauro Carvalho Chehab 	0x588, 0x0ff,
468cb7a01acSMauro Carvalho Chehab 	0x589, 0x00f,
469cb7a01acSMauro Carvalho Chehab 	0x58a, 0x000,
470cb7a01acSMauro Carvalho Chehab 	0x58b, 0x000,
471cb7a01acSMauro Carvalho Chehab 	0x58c, 0x010,
472cb7a01acSMauro Carvalho Chehab 	0x58d, 0x032,
473cb7a01acSMauro Carvalho Chehab 	0x58e, 0x054,
474cb7a01acSMauro Carvalho Chehab 	0x58f, 0x023,
475cb7a01acSMauro Carvalho Chehab 	0x590, 0x000,
476cb7a01acSMauro Carvalho Chehab 	0x595, 0x000,
477cb7a01acSMauro Carvalho Chehab 	0x596, 0x000,
478cb7a01acSMauro Carvalho Chehab 	0x597, 0x000,
479cb7a01acSMauro Carvalho Chehab 	0x464, 0x000,
480cb7a01acSMauro Carvalho Chehab 	0x46c, 0xbbbb10,
481cb7a01acSMauro Carvalho Chehab 	0x470, 0x101010,
482cb7a01acSMauro Carvalho Chehab 
483cb7a01acSMauro Carvalho Chehab 	0x478, 0x000,
484cb7a01acSMauro Carvalho Chehab 	0x474, 0x018,
485cb7a01acSMauro Carvalho Chehab 	0x454, 0x042135,
486cb7a01acSMauro Carvalho Chehab 	0x598, 0x0e7,
487cb7a01acSMauro Carvalho Chehab 	0x599, 0x07d,
488cb7a01acSMauro Carvalho Chehab 	0x59a, 0x018,
489cb7a01acSMauro Carvalho Chehab 	0x59c, 0x066,
490cb7a01acSMauro Carvalho Chehab 	0x59d, 0x090,
491cb7a01acSMauro Carvalho Chehab 	0x59e, 0x001,
492cb7a01acSMauro Carvalho Chehab 	0x584, 0x000,
493cb7a01acSMauro Carvalho Chehab 	0x585, 0x000,
494cb7a01acSMauro Carvalho Chehab 	0x586, 0x003,
495cb7a01acSMauro Carvalho Chehab 	0x588, 0x0ff,
496cb7a01acSMauro Carvalho Chehab 	0x589, 0x00f,
497cb7a01acSMauro Carvalho Chehab 	0x58a, 0x000,
498cb7a01acSMauro Carvalho Chehab 	0x58b, 0x000,
499cb7a01acSMauro Carvalho Chehab 	0x58c, 0x010,
500cb7a01acSMauro Carvalho Chehab 	0x58d, 0x032,
501cb7a01acSMauro Carvalho Chehab 	0x58e, 0x054,
502cb7a01acSMauro Carvalho Chehab 	0x58f, 0x023,
503cb7a01acSMauro Carvalho Chehab 	0x590, 0x000,
504cb7a01acSMauro Carvalho Chehab 	0x595, 0x000,
505cb7a01acSMauro Carvalho Chehab 	0x596, 0x000,
506cb7a01acSMauro Carvalho Chehab 	0x597, 0x000,
507cb7a01acSMauro Carvalho Chehab 	0x464, 0x000,
508cb7a01acSMauro Carvalho Chehab 	0x46c, 0xbbbb10,
509cb7a01acSMauro Carvalho Chehab 	0x470, 0x101010,
510cb7a01acSMauro Carvalho Chehab 	0x478, 0x000,
511cb7a01acSMauro Carvalho Chehab 	0x474, 0x018,
512cb7a01acSMauro Carvalho Chehab 	0x454, 0x042135,
513cb7a01acSMauro Carvalho Chehab 	0x193, 0x000,
514cb7a01acSMauro Carvalho Chehab 	0x300, 0x000,
515cb7a01acSMauro Carvalho Chehab 	0x301, 0x006,
516cb7a01acSMauro Carvalho Chehab 	0x302, 0x000,
517cb7a01acSMauro Carvalho Chehab 	0x303, 0x006,
518cb7a01acSMauro Carvalho Chehab 	0x308, 0x040,
519cb7a01acSMauro Carvalho Chehab 	0x309, 0x000,
520cb7a01acSMauro Carvalho Chehab 	0x30a, 0x000,
521cb7a01acSMauro Carvalho Chehab 	0x30b, 0x000,
522cb7a01acSMauro Carvalho Chehab 	0x000, 0x002,
523cb7a01acSMauro Carvalho Chehab 	0x001, 0x000,
524cb7a01acSMauro Carvalho Chehab 	0x002, 0x000,
525cb7a01acSMauro Carvalho Chehab 	0x003, 0x000,
526cb7a01acSMauro Carvalho Chehab 	0x004, 0x033,
527cb7a01acSMauro Carvalho Chehab 	0x040, 0x01d,
528cb7a01acSMauro Carvalho Chehab 	0x041, 0x001,
529cb7a01acSMauro Carvalho Chehab 	0x042, 0x004,
530cb7a01acSMauro Carvalho Chehab 	0x043, 0x000,
531cb7a01acSMauro Carvalho Chehab 	0x080, 0x01e,
532cb7a01acSMauro Carvalho Chehab 	0x081, 0x001,
533cb7a01acSMauro Carvalho Chehab 	0x082, 0x004,
534cb7a01acSMauro Carvalho Chehab 	0x083, 0x000,
535cb7a01acSMauro Carvalho Chehab 	0x190, 0x018,
536cb7a01acSMauro Carvalho Chehab 	0x115, 0x000,
537cb7a01acSMauro Carvalho Chehab 	0x116, 0x012,
538cb7a01acSMauro Carvalho Chehab 	0x117, 0x018,
539cb7a01acSMauro Carvalho Chehab 	0x04a, 0x011,
540cb7a01acSMauro Carvalho Chehab 	0x08a, 0x011,
541cb7a01acSMauro Carvalho Chehab 	0x04b, 0x000,
542cb7a01acSMauro Carvalho Chehab 	0x08b, 0x000,
543cb7a01acSMauro Carvalho Chehab 	0x048, 0x000,
544cb7a01acSMauro Carvalho Chehab 	0x088, 0x000,
545cb7a01acSMauro Carvalho Chehab 	0x04e, 0x012,
546cb7a01acSMauro Carvalho Chehab 	0x08e, 0x012,
547cb7a01acSMauro Carvalho Chehab 	0x058, 0x012,
548cb7a01acSMauro Carvalho Chehab 	0x098, 0x012,
549cb7a01acSMauro Carvalho Chehab 	0x059, 0x000,
550cb7a01acSMauro Carvalho Chehab 	0x099, 0x000,
551cb7a01acSMauro Carvalho Chehab 	0x05a, 0x003,
552cb7a01acSMauro Carvalho Chehab 	0x09a, 0x003,
553cb7a01acSMauro Carvalho Chehab 	0x05b, 0x001,
554cb7a01acSMauro Carvalho Chehab 	0x09b, 0x001,
555cb7a01acSMauro Carvalho Chehab 	0x054, 0x008,
556cb7a01acSMauro Carvalho Chehab 	0x094, 0x008,
557cb7a01acSMauro Carvalho Chehab 	0x055, 0x000,
558cb7a01acSMauro Carvalho Chehab 	0x095, 0x000,
559cb7a01acSMauro Carvalho Chehab 	0x056, 0x0c7,
560cb7a01acSMauro Carvalho Chehab 	0x096, 0x0c7,
561cb7a01acSMauro Carvalho Chehab 	0x057, 0x002,
562cb7a01acSMauro Carvalho Chehab 	0x097, 0x002,
563cb7a01acSMauro Carvalho Chehab 	0x060, 0x001,
564cb7a01acSMauro Carvalho Chehab 	0x0a0, 0x001,
565cb7a01acSMauro Carvalho Chehab 	0x061, 0x000,
566cb7a01acSMauro Carvalho Chehab 	0x0a1, 0x000,
567cb7a01acSMauro Carvalho Chehab 	0x062, 0x000,
568cb7a01acSMauro Carvalho Chehab 	0x0a2, 0x000,
569cb7a01acSMauro Carvalho Chehab 	0x063, 0x000,
570cb7a01acSMauro Carvalho Chehab 	0x0a3, 0x000,
571cb7a01acSMauro Carvalho Chehab 	0x070, 0x000,
572cb7a01acSMauro Carvalho Chehab 	0x0b0, 0x000,
573cb7a01acSMauro Carvalho Chehab 	0x071, 0x004,
574cb7a01acSMauro Carvalho Chehab 	0x0b1, 0x004,
575cb7a01acSMauro Carvalho Chehab 	0x06c, 0x0e9,
576cb7a01acSMauro Carvalho Chehab 	0x0ac, 0x0e9,
577cb7a01acSMauro Carvalho Chehab 	0x06d, 0x003,
578cb7a01acSMauro Carvalho Chehab 	0x0ad, 0x003,
579cb7a01acSMauro Carvalho Chehab 	0x05c, 0x0d0,
580cb7a01acSMauro Carvalho Chehab 	0x09c, 0x0d0,
581cb7a01acSMauro Carvalho Chehab 	0x05d, 0x002,
582cb7a01acSMauro Carvalho Chehab 	0x09d, 0x002,
583cb7a01acSMauro Carvalho Chehab 	0x05e, 0x0f2,
584cb7a01acSMauro Carvalho Chehab 	0x09e, 0x0f2,
585cb7a01acSMauro Carvalho Chehab 	0x05f, 0x000,
586cb7a01acSMauro Carvalho Chehab 	0x09f, 0x000,
587cb7a01acSMauro Carvalho Chehab 	0x074, 0x000,
588cb7a01acSMauro Carvalho Chehab 	0x0b4, 0x000,
589cb7a01acSMauro Carvalho Chehab 	0x075, 0x000,
590cb7a01acSMauro Carvalho Chehab 	0x0b5, 0x000,
591cb7a01acSMauro Carvalho Chehab 	0x076, 0x000,
592cb7a01acSMauro Carvalho Chehab 	0x0b6, 0x000,
593cb7a01acSMauro Carvalho Chehab 	0x077, 0x000,
594cb7a01acSMauro Carvalho Chehab 	0x0b7, 0x000,
595cb7a01acSMauro Carvalho Chehab 	0x195, 0x008,
596cb7a01acSMauro Carvalho Chehab 	0x598, 0x0e7,
597cb7a01acSMauro Carvalho Chehab 	0x599, 0x07d,
598cb7a01acSMauro Carvalho Chehab 	0x59a, 0x018,
599cb7a01acSMauro Carvalho Chehab 	0x59c, 0x066,
600cb7a01acSMauro Carvalho Chehab 	0x59d, 0x090,
601cb7a01acSMauro Carvalho Chehab 	0x59e, 0x001,
602cb7a01acSMauro Carvalho Chehab 	0x584, 0x000,
603cb7a01acSMauro Carvalho Chehab 	0x585, 0x000,
604cb7a01acSMauro Carvalho Chehab 	0x586, 0x003,
605cb7a01acSMauro Carvalho Chehab 	0x588, 0x0ff,
606cb7a01acSMauro Carvalho Chehab 	0x589, 0x00f,
607cb7a01acSMauro Carvalho Chehab 	0x58a, 0x000,
608cb7a01acSMauro Carvalho Chehab 	0x58b, 0x000,
609cb7a01acSMauro Carvalho Chehab 	0x58c, 0x010,
610cb7a01acSMauro Carvalho Chehab 	0x58d, 0x032,
611cb7a01acSMauro Carvalho Chehab 	0x58e, 0x054,
612cb7a01acSMauro Carvalho Chehab 	0x58f, 0x023,
613cb7a01acSMauro Carvalho Chehab 	0x590, 0x000,
614cb7a01acSMauro Carvalho Chehab 	0x595, 0x000,
615cb7a01acSMauro Carvalho Chehab 	0x596, 0x000,
616cb7a01acSMauro Carvalho Chehab 	0x597, 0x000,
617cb7a01acSMauro Carvalho Chehab 	0x464, 0x000,
618cb7a01acSMauro Carvalho Chehab 	0x46c, 0xbbbb10,
619cb7a01acSMauro Carvalho Chehab 	0x470, 0x101010,
620cb7a01acSMauro Carvalho Chehab 	0x478, 0x000,
621cb7a01acSMauro Carvalho Chehab 	0x474, 0x018,
622cb7a01acSMauro Carvalho Chehab 	0x454, 0x042135,
623cb7a01acSMauro Carvalho Chehab 	0x193, 0x0a6,
624cb7a01acSMauro Carvalho Chehab 	0x108, 0x0f8,
625cb7a01acSMauro Carvalho Chehab 	0x042, 0x003,
626cb7a01acSMauro Carvalho Chehab 	0x082, 0x003,
627cb7a01acSMauro Carvalho Chehab 	0x454, 0x0425b9,
628cb7a01acSMauro Carvalho Chehab 	0x454, 0x042539,
629cb7a01acSMauro Carvalho Chehab 	0x193, 0x000,
630cb7a01acSMauro Carvalho Chehab 	0x193, 0x0a6,
631cb7a01acSMauro Carvalho Chehab 	0x464, 0x000,
632cb7a01acSMauro Carvalho Chehab 
633cb7a01acSMauro Carvalho Chehab 	0, 0
634cb7a01acSMauro Carvalho Chehab };
635cb7a01acSMauro Carvalho Chehab 
636cb7a01acSMauro Carvalho Chehab /* Tuner */
637cb7a01acSMauro Carvalho Chehab static u32 reg_init_tuner_input[] = {
638cb7a01acSMauro Carvalho Chehab 	0x108, 0x0f8, /* Sync control */
639cb7a01acSMauro Carvalho Chehab 	0x111, 0x000, /* Mode/delay control */
640cb7a01acSMauro Carvalho Chehab 	0x10e, 0x00a, /* Chroma control 1 */
641cb7a01acSMauro Carvalho Chehab 	0, 0
642cb7a01acSMauro Carvalho Chehab };
643cb7a01acSMauro Carvalho Chehab 
644cb7a01acSMauro Carvalho Chehab /* Composite */
645cb7a01acSMauro Carvalho Chehab static u32 reg_init_composite_input[] = {
646cb7a01acSMauro Carvalho Chehab 	0x108, 0x0e8, /* Sync control */
647cb7a01acSMauro Carvalho Chehab 	0x111, 0x000, /* Mode/delay control */
648cb7a01acSMauro Carvalho Chehab 	0x10e, 0x04a, /* Chroma control 1 */
649cb7a01acSMauro Carvalho Chehab 	0, 0
650cb7a01acSMauro Carvalho Chehab };
651cb7a01acSMauro Carvalho Chehab 
652cb7a01acSMauro Carvalho Chehab /* S-Video */
653cb7a01acSMauro Carvalho Chehab static u32 reg_init_svideo_input[] = {
654cb7a01acSMauro Carvalho Chehab 	0x108, 0x0e8, /* Sync control */
655cb7a01acSMauro Carvalho Chehab 	0x111, 0x000, /* Mode/delay control */
656cb7a01acSMauro Carvalho Chehab 	0x10e, 0x04a, /* Chroma control 1 */
657cb7a01acSMauro Carvalho Chehab 	0, 0
658cb7a01acSMauro Carvalho Chehab };
659cb7a01acSMauro Carvalho Chehab 
660cb7a01acSMauro Carvalho Chehab static u32 reg_set_audio_template[4][2] =
661cb7a01acSMauro Carvalho Chehab {
662cb7a01acSMauro Carvalho Chehab 	{ /* for MONO
663cb7a01acSMauro Carvalho Chehab 		tadachi 6/29 DMA audio output select?
664cb7a01acSMauro Carvalho Chehab 		Register 0x46c
665cb7a01acSMauro Carvalho Chehab 		7-4: DMA2, 3-0: DMA1 ch. DMA4, DMA3 DMA2, DMA1
666cb7a01acSMauro Carvalho Chehab 		0: MAIN left,  1: MAIN right
667cb7a01acSMauro Carvalho Chehab 		2: AUX1 left,  3: AUX1 right
668cb7a01acSMauro Carvalho Chehab 		4: AUX2 left,  5: AUX2 right
669cb7a01acSMauro Carvalho Chehab 		6: DPL left,   7: DPL  right
670cb7a01acSMauro Carvalho Chehab 		8: DPL center, 9: DPL surround
671cb7a01acSMauro Carvalho Chehab 		A: monitor output, B: digital sense */
672cb7a01acSMauro Carvalho Chehab 		0xbbbb00,
673cb7a01acSMauro Carvalho Chehab 
674cb7a01acSMauro Carvalho Chehab 		/* tadachi 6/29 DAC and I2S output select?
675cb7a01acSMauro Carvalho Chehab 		   Register 0x470
676cb7a01acSMauro Carvalho Chehab 		   7-4:DAC right ch. 3-0:DAC left ch.
677cb7a01acSMauro Carvalho Chehab 		   I2S1 right,left  I2S2 right,left */
678cb7a01acSMauro Carvalho Chehab 		0x00,
679cb7a01acSMauro Carvalho Chehab 	},
680cb7a01acSMauro Carvalho Chehab 	{ /* for STEREO */
681cb7a01acSMauro Carvalho Chehab 		0xbbbb10, 0x101010,
682cb7a01acSMauro Carvalho Chehab 	},
683cb7a01acSMauro Carvalho Chehab 	{ /* for LANG1 */
684cb7a01acSMauro Carvalho Chehab 		0xbbbb00, 0x00,
685cb7a01acSMauro Carvalho Chehab 	},
686cb7a01acSMauro Carvalho Chehab 	{ /* for LANG2/SAP */
687cb7a01acSMauro Carvalho Chehab 		0xbbbb11, 0x111111,
688cb7a01acSMauro Carvalho Chehab 	}
689cb7a01acSMauro Carvalho Chehab };
690cb7a01acSMauro Carvalho Chehab 
691cb7a01acSMauro Carvalho Chehab 
692cb7a01acSMauro Carvalho Chehab /* Get detected audio flags (from saa7134 driver) */
693cb7a01acSMauro Carvalho Chehab static void get_inf_dev_status(struct v4l2_subdev *sd,
694cb7a01acSMauro Carvalho Chehab 		int *dual_flag, int *stereo_flag)
695cb7a01acSMauro Carvalho Chehab {
696cb7a01acSMauro Carvalho Chehab 	u32 reg_data3;
697cb7a01acSMauro Carvalho Chehab 
698cb7a01acSMauro Carvalho Chehab 	static char *stdres[0x20] = {
699cb7a01acSMauro Carvalho Chehab 		[0x00] = "no standard detected",
700cb7a01acSMauro Carvalho Chehab 		[0x01] = "B/G (in progress)",
701cb7a01acSMauro Carvalho Chehab 		[0x02] = "D/K (in progress)",
702cb7a01acSMauro Carvalho Chehab 		[0x03] = "M (in progress)",
703cb7a01acSMauro Carvalho Chehab 
704cb7a01acSMauro Carvalho Chehab 		[0x04] = "B/G A2",
705cb7a01acSMauro Carvalho Chehab 		[0x05] = "B/G NICAM",
706cb7a01acSMauro Carvalho Chehab 		[0x06] = "D/K A2 (1)",
707cb7a01acSMauro Carvalho Chehab 		[0x07] = "D/K A2 (2)",
708cb7a01acSMauro Carvalho Chehab 		[0x08] = "D/K A2 (3)",
709cb7a01acSMauro Carvalho Chehab 		[0x09] = "D/K NICAM",
710cb7a01acSMauro Carvalho Chehab 		[0x0a] = "L NICAM",
711cb7a01acSMauro Carvalho Chehab 		[0x0b] = "I NICAM",
712cb7a01acSMauro Carvalho Chehab 
713cb7a01acSMauro Carvalho Chehab 		[0x0c] = "M Korea",
714cb7a01acSMauro Carvalho Chehab 		[0x0d] = "M BTSC ",
715cb7a01acSMauro Carvalho Chehab 		[0x0e] = "M EIAJ",
716cb7a01acSMauro Carvalho Chehab 
717cb7a01acSMauro Carvalho Chehab 		[0x0f] = "FM radio / IF 10.7 / 50 deemp",
718cb7a01acSMauro Carvalho Chehab 		[0x10] = "FM radio / IF 10.7 / 75 deemp",
719cb7a01acSMauro Carvalho Chehab 		[0x11] = "FM radio / IF sel / 50 deemp",
720cb7a01acSMauro Carvalho Chehab 		[0x12] = "FM radio / IF sel / 75 deemp",
721cb7a01acSMauro Carvalho Chehab 
722cb7a01acSMauro Carvalho Chehab 		[0x13 ... 0x1e] = "unknown",
723cb7a01acSMauro Carvalho Chehab 		[0x1f] = "??? [in progress]",
724cb7a01acSMauro Carvalho Chehab 	};
725cb7a01acSMauro Carvalho Chehab 
726cb7a01acSMauro Carvalho Chehab 
727cb7a01acSMauro Carvalho Chehab 	*dual_flag = *stereo_flag = 0;
728cb7a01acSMauro Carvalho Chehab 
729cb7a01acSMauro Carvalho Chehab 	/* (demdec status: 0x528) */
730cb7a01acSMauro Carvalho Chehab 
731cb7a01acSMauro Carvalho Chehab 	/* read current status */
732cb7a01acSMauro Carvalho Chehab 	reg_data3 = saa717x_read(sd, 0x0528);
733cb7a01acSMauro Carvalho Chehab 
734cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "tvaudio thread status: 0x%x [%s%s%s]\n",
735cb7a01acSMauro Carvalho Chehab 		reg_data3, stdres[reg_data3 & 0x1f],
736cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x000020) ? ",stereo" : "",
737cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x000040) ? ",dual"   : "");
738cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "detailed status: "
739cb7a01acSMauro Carvalho Chehab 		"%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n",
740cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x000080) ? " A2/EIAJ pilot tone "     : "",
741cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x000100) ? " A2/EIAJ dual "           : "",
742cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x000200) ? " A2/EIAJ stereo "         : "",
743cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x000400) ? " A2/EIAJ noise mute "     : "",
744cb7a01acSMauro Carvalho Chehab 
745cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x000800) ? " BTSC/FM radio pilot "    : "",
746cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x001000) ? " SAP carrier "            : "",
747cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x002000) ? " BTSC stereo noise mute " : "",
748cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x004000) ? " SAP noise mute "         : "",
749cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x008000) ? " VDSP "                   : "",
750cb7a01acSMauro Carvalho Chehab 
751cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x010000) ? " NICST "                  : "",
752cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x020000) ? " NICDU "                  : "",
753cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x040000) ? " NICAM muted "            : "",
754cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x080000) ? " NICAM reserve sound "    : "",
755cb7a01acSMauro Carvalho Chehab 
756cb7a01acSMauro Carvalho Chehab 		(reg_data3 & 0x100000) ? " init done "              : "");
757cb7a01acSMauro Carvalho Chehab 
758cb7a01acSMauro Carvalho Chehab 	if (reg_data3 & 0x000220) {
759cb7a01acSMauro Carvalho Chehab 		v4l2_dbg(1, debug, sd, "ST!!!\n");
760cb7a01acSMauro Carvalho Chehab 		*stereo_flag = 1;
761cb7a01acSMauro Carvalho Chehab 	}
762cb7a01acSMauro Carvalho Chehab 
763cb7a01acSMauro Carvalho Chehab 	if (reg_data3 & 0x000140) {
764cb7a01acSMauro Carvalho Chehab 		v4l2_dbg(1, debug, sd, "DUAL!!!\n");
765cb7a01acSMauro Carvalho Chehab 		*dual_flag = 1;
766cb7a01acSMauro Carvalho Chehab 	}
767cb7a01acSMauro Carvalho Chehab }
768cb7a01acSMauro Carvalho Chehab 
769cb7a01acSMauro Carvalho Chehab /* regs write to set audio mode */
770cb7a01acSMauro Carvalho Chehab static void set_audio_mode(struct v4l2_subdev *sd, int audio_mode)
771cb7a01acSMauro Carvalho Chehab {
772cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "writing registers to set audio mode by set %d\n",
773cb7a01acSMauro Carvalho Chehab 			audio_mode);
774cb7a01acSMauro Carvalho Chehab 
775cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x46c, reg_set_audio_template[audio_mode][0]);
776cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x470, reg_set_audio_template[audio_mode][1]);
777cb7a01acSMauro Carvalho Chehab }
778cb7a01acSMauro Carvalho Chehab 
779cb7a01acSMauro Carvalho Chehab /* write regs to set audio volume, bass and treble */
780cb7a01acSMauro Carvalho Chehab static int set_audio_regs(struct v4l2_subdev *sd,
781cb7a01acSMauro Carvalho Chehab 		struct saa717x_state *decoder)
782cb7a01acSMauro Carvalho Chehab {
783cb7a01acSMauro Carvalho Chehab 	u8 mute = 0xac; /* -84 dB */
784cb7a01acSMauro Carvalho Chehab 	u32 val;
785cb7a01acSMauro Carvalho Chehab 	unsigned int work_l, work_r;
786cb7a01acSMauro Carvalho Chehab 
787cb7a01acSMauro Carvalho Chehab 	/* set SIF analog I/O select */
788cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x0594, decoder->audio_input);
789cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "set audio input %d\n",
790cb7a01acSMauro Carvalho Chehab 			decoder->audio_input);
791cb7a01acSMauro Carvalho Chehab 
792cb7a01acSMauro Carvalho Chehab 	/* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */
793cb7a01acSMauro Carvalho Chehab 	work_l = (min(65536 - decoder->audio_main_balance, 32768) * decoder->audio_main_volume) / 32768;
794cb7a01acSMauro Carvalho Chehab 	work_r = (min(decoder->audio_main_balance, (u16)32768) * decoder->audio_main_volume) / 32768;
795cb7a01acSMauro Carvalho Chehab 	decoder->audio_main_vol_l = (long)work_l * (24 - (-40)) / 65535 - 40;
796cb7a01acSMauro Carvalho Chehab 	decoder->audio_main_vol_r = (long)work_r * (24 - (-40)) / 65535 - 40;
797cb7a01acSMauro Carvalho Chehab 
798cb7a01acSMauro Carvalho Chehab 	/* set main volume */
799cb7a01acSMauro Carvalho Chehab 	/* main volume L[7-0],R[7-0],0x00  24=24dB,-83dB, -84(mute) */
800cb7a01acSMauro Carvalho Chehab 	/*    def:0dB->6dB(MPG600GR) */
801cb7a01acSMauro Carvalho Chehab 	/* if mute is on, set mute */
802cb7a01acSMauro Carvalho Chehab 	if (decoder->audio_main_mute) {
803cb7a01acSMauro Carvalho Chehab 		val = mute | (mute << 8);
804cb7a01acSMauro Carvalho Chehab 	} else {
805cb7a01acSMauro Carvalho Chehab 		val = (u8)decoder->audio_main_vol_l |
806cb7a01acSMauro Carvalho Chehab 			((u8)decoder->audio_main_vol_r << 8);
807cb7a01acSMauro Carvalho Chehab 	}
808cb7a01acSMauro Carvalho Chehab 
809cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x480, val);
810cb7a01acSMauro Carvalho Chehab 
811cb7a01acSMauro Carvalho Chehab 	/* set bass and treble */
812cb7a01acSMauro Carvalho Chehab 	val = decoder->audio_main_bass & 0x1f;
813cb7a01acSMauro Carvalho Chehab 	val |= (decoder->audio_main_treble & 0x1f) << 5;
814cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x488, val);
815cb7a01acSMauro Carvalho Chehab 	return 0;
816cb7a01acSMauro Carvalho Chehab }
817cb7a01acSMauro Carvalho Chehab 
818cb7a01acSMauro Carvalho Chehab /********** scaling staff ***********/
819cb7a01acSMauro Carvalho Chehab static void set_h_prescale(struct v4l2_subdev *sd,
820cb7a01acSMauro Carvalho Chehab 		int task, int prescale)
821cb7a01acSMauro Carvalho Chehab {
822cb7a01acSMauro Carvalho Chehab 	static const struct {
823cb7a01acSMauro Carvalho Chehab 		int xpsc;
824cb7a01acSMauro Carvalho Chehab 		int xacl;
825cb7a01acSMauro Carvalho Chehab 		int xc2_1;
826cb7a01acSMauro Carvalho Chehab 		int xdcg;
827cb7a01acSMauro Carvalho Chehab 		int vpfy;
828cb7a01acSMauro Carvalho Chehab 	} vals[] = {
829cb7a01acSMauro Carvalho Chehab 		/* XPSC XACL XC2_1 XDCG VPFY */
830cb7a01acSMauro Carvalho Chehab 		{    1,   0,    0,    0,   0 },
831cb7a01acSMauro Carvalho Chehab 		{    2,   2,    1,    2,   2 },
832cb7a01acSMauro Carvalho Chehab 		{    3,   4,    1,    3,   2 },
833cb7a01acSMauro Carvalho Chehab 		{    4,   8,    1,    4,   2 },
834cb7a01acSMauro Carvalho Chehab 		{    5,   8,    1,    4,   2 },
835cb7a01acSMauro Carvalho Chehab 		{    6,   8,    1,    4,   3 },
836cb7a01acSMauro Carvalho Chehab 		{    7,   8,    1,    4,   3 },
837cb7a01acSMauro Carvalho Chehab 		{    8,  15,    0,    4,   3 },
838cb7a01acSMauro Carvalho Chehab 		{    9,  15,    0,    4,   3 },
839cb7a01acSMauro Carvalho Chehab 		{   10,  16,    1,    5,   3 },
840cb7a01acSMauro Carvalho Chehab 	};
841cb7a01acSMauro Carvalho Chehab 	static const int count = ARRAY_SIZE(vals);
842cb7a01acSMauro Carvalho Chehab 	int i, task_shift;
843cb7a01acSMauro Carvalho Chehab 
844cb7a01acSMauro Carvalho Chehab 	task_shift = task * 0x40;
845cb7a01acSMauro Carvalho Chehab 	for (i = 0; i < count; i++)
846cb7a01acSMauro Carvalho Chehab 		if (vals[i].xpsc == prescale)
847cb7a01acSMauro Carvalho Chehab 			break;
848cb7a01acSMauro Carvalho Chehab 	if (i == count)
849cb7a01acSMauro Carvalho Chehab 		return;
850cb7a01acSMauro Carvalho Chehab 
851cb7a01acSMauro Carvalho Chehab 	/* horizonal prescaling */
852cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x60 + task_shift, vals[i].xpsc);
853cb7a01acSMauro Carvalho Chehab 	/* accumulation length */
854cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x61 + task_shift, vals[i].xacl);
855cb7a01acSMauro Carvalho Chehab 	/* level control */
856cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x62 + task_shift,
857cb7a01acSMauro Carvalho Chehab 			(vals[i].xc2_1 << 3) | vals[i].xdcg);
858cb7a01acSMauro Carvalho Chehab 	/*FIR prefilter control */
859cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x63 + task_shift,
860cb7a01acSMauro Carvalho Chehab 			(vals[i].vpfy << 2) | vals[i].vpfy);
861cb7a01acSMauro Carvalho Chehab }
862cb7a01acSMauro Carvalho Chehab 
863cb7a01acSMauro Carvalho Chehab /********** scaling staff ***********/
864cb7a01acSMauro Carvalho Chehab static void set_v_scale(struct v4l2_subdev *sd, int task, int yscale)
865cb7a01acSMauro Carvalho Chehab {
866cb7a01acSMauro Carvalho Chehab 	int task_shift;
867cb7a01acSMauro Carvalho Chehab 
868cb7a01acSMauro Carvalho Chehab 	task_shift = task * 0x40;
869cb7a01acSMauro Carvalho Chehab 	/* Vertical scaling ratio (LOW) */
870cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x70 + task_shift, yscale & 0xff);
871cb7a01acSMauro Carvalho Chehab 	/* Vertical scaling ratio (HI) */
872cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x71 + task_shift, yscale >> 8);
873cb7a01acSMauro Carvalho Chehab }
874cb7a01acSMauro Carvalho Chehab 
875cb7a01acSMauro Carvalho Chehab static int saa717x_s_ctrl(struct v4l2_ctrl *ctrl)
876cb7a01acSMauro Carvalho Chehab {
877cb7a01acSMauro Carvalho Chehab 	struct v4l2_subdev *sd = to_sd(ctrl);
878cb7a01acSMauro Carvalho Chehab 	struct saa717x_state *state = to_state(sd);
879cb7a01acSMauro Carvalho Chehab 
880cb7a01acSMauro Carvalho Chehab 	switch (ctrl->id) {
881cb7a01acSMauro Carvalho Chehab 	case V4L2_CID_BRIGHTNESS:
882cb7a01acSMauro Carvalho Chehab 		saa717x_write(sd, 0x10a, ctrl->val);
883cb7a01acSMauro Carvalho Chehab 		return 0;
884cb7a01acSMauro Carvalho Chehab 
885cb7a01acSMauro Carvalho Chehab 	case V4L2_CID_CONTRAST:
886cb7a01acSMauro Carvalho Chehab 		saa717x_write(sd, 0x10b, ctrl->val);
887cb7a01acSMauro Carvalho Chehab 		return 0;
888cb7a01acSMauro Carvalho Chehab 
889cb7a01acSMauro Carvalho Chehab 	case V4L2_CID_SATURATION:
890cb7a01acSMauro Carvalho Chehab 		saa717x_write(sd, 0x10c, ctrl->val);
891cb7a01acSMauro Carvalho Chehab 		return 0;
892cb7a01acSMauro Carvalho Chehab 
893cb7a01acSMauro Carvalho Chehab 	case V4L2_CID_HUE:
894cb7a01acSMauro Carvalho Chehab 		saa717x_write(sd, 0x10d, ctrl->val);
895cb7a01acSMauro Carvalho Chehab 		return 0;
896cb7a01acSMauro Carvalho Chehab 
897cb7a01acSMauro Carvalho Chehab 	case V4L2_CID_AUDIO_MUTE:
898cb7a01acSMauro Carvalho Chehab 		state->audio_main_mute = ctrl->val;
899cb7a01acSMauro Carvalho Chehab 		break;
900cb7a01acSMauro Carvalho Chehab 
901cb7a01acSMauro Carvalho Chehab 	case V4L2_CID_AUDIO_VOLUME:
902cb7a01acSMauro Carvalho Chehab 		state->audio_main_volume = ctrl->val;
903cb7a01acSMauro Carvalho Chehab 		break;
904cb7a01acSMauro Carvalho Chehab 
905cb7a01acSMauro Carvalho Chehab 	case V4L2_CID_AUDIO_BALANCE:
906cb7a01acSMauro Carvalho Chehab 		state->audio_main_balance = ctrl->val;
907cb7a01acSMauro Carvalho Chehab 		break;
908cb7a01acSMauro Carvalho Chehab 
909cb7a01acSMauro Carvalho Chehab 	case V4L2_CID_AUDIO_TREBLE:
910cb7a01acSMauro Carvalho Chehab 		state->audio_main_treble = ctrl->val;
911cb7a01acSMauro Carvalho Chehab 		break;
912cb7a01acSMauro Carvalho Chehab 
913cb7a01acSMauro Carvalho Chehab 	case V4L2_CID_AUDIO_BASS:
914cb7a01acSMauro Carvalho Chehab 		state->audio_main_bass = ctrl->val;
915cb7a01acSMauro Carvalho Chehab 		break;
916cb7a01acSMauro Carvalho Chehab 
917cb7a01acSMauro Carvalho Chehab 	default:
918cb7a01acSMauro Carvalho Chehab 		return 0;
919cb7a01acSMauro Carvalho Chehab 	}
920cb7a01acSMauro Carvalho Chehab 	set_audio_regs(sd, state);
921cb7a01acSMauro Carvalho Chehab 	return 0;
922cb7a01acSMauro Carvalho Chehab }
923cb7a01acSMauro Carvalho Chehab 
924cb7a01acSMauro Carvalho Chehab static int saa717x_s_video_routing(struct v4l2_subdev *sd,
925cb7a01acSMauro Carvalho Chehab 				   u32 input, u32 output, u32 config)
926cb7a01acSMauro Carvalho Chehab {
927cb7a01acSMauro Carvalho Chehab 	struct saa717x_state *decoder = to_state(sd);
928cb7a01acSMauro Carvalho Chehab 	int is_tuner = input & 0x80;  /* tuner input flag */
929cb7a01acSMauro Carvalho Chehab 
930cb7a01acSMauro Carvalho Chehab 	input &= 0x7f;
931cb7a01acSMauro Carvalho Chehab 
932cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input);
933cb7a01acSMauro Carvalho Chehab 	/* inputs from 0-9 are available*/
934cb7a01acSMauro Carvalho Chehab 	/* saa717x have mode0-mode9 but mode5 is reserved. */
935cb7a01acSMauro Carvalho Chehab 	if (input > 9 || input == 5)
936cb7a01acSMauro Carvalho Chehab 		return -EINVAL;
937cb7a01acSMauro Carvalho Chehab 
938cb7a01acSMauro Carvalho Chehab 	if (decoder->input != input) {
939cb7a01acSMauro Carvalho Chehab 		int input_line = input;
940cb7a01acSMauro Carvalho Chehab 
941cb7a01acSMauro Carvalho Chehab 		decoder->input = input_line;
942cb7a01acSMauro Carvalho Chehab 		v4l2_dbg(1, debug, sd,  "now setting %s input %d\n",
943cb7a01acSMauro Carvalho Chehab 				input_line >= 6 ? "S-Video" : "Composite",
944cb7a01acSMauro Carvalho Chehab 				input_line);
945cb7a01acSMauro Carvalho Chehab 
946cb7a01acSMauro Carvalho Chehab 		/* select mode */
947cb7a01acSMauro Carvalho Chehab 		saa717x_write(sd, 0x102,
948cb7a01acSMauro Carvalho Chehab 				(saa717x_read(sd, 0x102) & 0xf0) |
949cb7a01acSMauro Carvalho Chehab 				input_line);
950cb7a01acSMauro Carvalho Chehab 
951cb7a01acSMauro Carvalho Chehab 		/* bypass chrominance trap for modes 6..9 */
952cb7a01acSMauro Carvalho Chehab 		saa717x_write(sd, 0x109,
953cb7a01acSMauro Carvalho Chehab 				(saa717x_read(sd, 0x109) & 0x7f) |
954cb7a01acSMauro Carvalho Chehab 				(input_line < 6 ? 0x0 : 0x80));
955cb7a01acSMauro Carvalho Chehab 
956cb7a01acSMauro Carvalho Chehab 		/* change audio_mode */
957cb7a01acSMauro Carvalho Chehab 		if (is_tuner) {
958cb7a01acSMauro Carvalho Chehab 			/* tuner */
959cb7a01acSMauro Carvalho Chehab 			set_audio_mode(sd, decoder->tuner_audio_mode);
960cb7a01acSMauro Carvalho Chehab 		} else {
961cb7a01acSMauro Carvalho Chehab 			/* Force to STEREO mode if Composite or
962cb7a01acSMauro Carvalho Chehab 			 * S-Video were chosen */
963cb7a01acSMauro Carvalho Chehab 			set_audio_mode(sd, TUNER_AUDIO_STEREO);
964cb7a01acSMauro Carvalho Chehab 		}
965cb7a01acSMauro Carvalho Chehab 		/* change initialize procedure (Composite/S-Video) */
966cb7a01acSMauro Carvalho Chehab 		if (is_tuner)
967cb7a01acSMauro Carvalho Chehab 			saa717x_write_regs(sd, reg_init_tuner_input);
968cb7a01acSMauro Carvalho Chehab 		else if (input_line >= 6)
969cb7a01acSMauro Carvalho Chehab 			saa717x_write_regs(sd, reg_init_svideo_input);
970cb7a01acSMauro Carvalho Chehab 		else
971cb7a01acSMauro Carvalho Chehab 			saa717x_write_regs(sd, reg_init_composite_input);
972cb7a01acSMauro Carvalho Chehab 	}
973cb7a01acSMauro Carvalho Chehab 
974cb7a01acSMauro Carvalho Chehab 	return 0;
975cb7a01acSMauro Carvalho Chehab }
976cb7a01acSMauro Carvalho Chehab 
977cb7a01acSMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
978cb7a01acSMauro Carvalho Chehab static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
979cb7a01acSMauro Carvalho Chehab {
980cb7a01acSMauro Carvalho Chehab 	reg->val = saa717x_read(sd, reg->reg);
981cb7a01acSMauro Carvalho Chehab 	reg->size = 1;
982cb7a01acSMauro Carvalho Chehab 	return 0;
983cb7a01acSMauro Carvalho Chehab }
984cb7a01acSMauro Carvalho Chehab 
985977ba3b1SHans Verkuil static int saa717x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
986cb7a01acSMauro Carvalho Chehab {
987cb7a01acSMauro Carvalho Chehab 	u16 addr = reg->reg & 0xffff;
988cb7a01acSMauro Carvalho Chehab 	u8 val = reg->val & 0xff;
989cb7a01acSMauro Carvalho Chehab 
990cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, addr, val);
991cb7a01acSMauro Carvalho Chehab 	return 0;
992cb7a01acSMauro Carvalho Chehab }
993cb7a01acSMauro Carvalho Chehab #endif
994cb7a01acSMauro Carvalho Chehab 
9956e80c473SHans Verkuil static int saa717x_set_fmt(struct v4l2_subdev *sd,
9966e80c473SHans Verkuil 		struct v4l2_subdev_pad_config *cfg,
9976e80c473SHans Verkuil 		struct v4l2_subdev_format *format)
998cb7a01acSMauro Carvalho Chehab {
9996e80c473SHans Verkuil 	struct v4l2_mbus_framefmt *fmt = &format->format;
1000cb7a01acSMauro Carvalho Chehab 	int prescale, h_scale, v_scale;
1001cb7a01acSMauro Carvalho Chehab 
1002cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "decoder set size\n");
1003cb7a01acSMauro Carvalho Chehab 
10046e80c473SHans Verkuil 	if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED)
1005cb7a01acSMauro Carvalho Chehab 		return -EINVAL;
1006cb7a01acSMauro Carvalho Chehab 
1007cb7a01acSMauro Carvalho Chehab 	/* FIXME need better bounds checking here */
1008cb7a01acSMauro Carvalho Chehab 	if (fmt->width < 1 || fmt->width > 1440)
1009cb7a01acSMauro Carvalho Chehab 		return -EINVAL;
1010cb7a01acSMauro Carvalho Chehab 	if (fmt->height < 1 || fmt->height > 960)
1011cb7a01acSMauro Carvalho Chehab 		return -EINVAL;
1012cb7a01acSMauro Carvalho Chehab 
1013cb7a01acSMauro Carvalho Chehab 	fmt->field = V4L2_FIELD_INTERLACED;
1014cb7a01acSMauro Carvalho Chehab 	fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
1015cb7a01acSMauro Carvalho Chehab 
10166e80c473SHans Verkuil 	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
10176e80c473SHans Verkuil 		return 0;
10186e80c473SHans Verkuil 
1019cb7a01acSMauro Carvalho Chehab 	/* scaling setting */
1020cb7a01acSMauro Carvalho Chehab 	/* NTSC and interlace only */
1021cb7a01acSMauro Carvalho Chehab 	prescale = SAA717X_NTSC_WIDTH / fmt->width;
1022cb7a01acSMauro Carvalho Chehab 	if (prescale == 0)
1023cb7a01acSMauro Carvalho Chehab 		prescale = 1;
1024cb7a01acSMauro Carvalho Chehab 	h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / fmt->width;
1025cb7a01acSMauro Carvalho Chehab 	/* interlace */
1026cb7a01acSMauro Carvalho Chehab 	v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / fmt->height;
1027cb7a01acSMauro Carvalho Chehab 
1028cb7a01acSMauro Carvalho Chehab 	/* Horizontal prescaling etc */
1029cb7a01acSMauro Carvalho Chehab 	set_h_prescale(sd, 0, prescale);
1030cb7a01acSMauro Carvalho Chehab 	set_h_prescale(sd, 1, prescale);
1031cb7a01acSMauro Carvalho Chehab 
1032cb7a01acSMauro Carvalho Chehab 	/* Horizontal scaling increment */
1033cb7a01acSMauro Carvalho Chehab 	/* TASK A */
1034cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x6C, (u8)(h_scale & 0xFF));
1035cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x6D, (u8)((h_scale >> 8) & 0xFF));
1036cb7a01acSMauro Carvalho Chehab 	/* TASK B */
1037cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0xAC, (u8)(h_scale & 0xFF));
1038cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0xAD, (u8)((h_scale >> 8) & 0xFF));
1039cb7a01acSMauro Carvalho Chehab 
1040cb7a01acSMauro Carvalho Chehab 	/* Vertical prescaling etc */
1041cb7a01acSMauro Carvalho Chehab 	set_v_scale(sd, 0, v_scale);
1042cb7a01acSMauro Carvalho Chehab 	set_v_scale(sd, 1, v_scale);
1043cb7a01acSMauro Carvalho Chehab 
1044cb7a01acSMauro Carvalho Chehab 	/* set video output size */
1045cb7a01acSMauro Carvalho Chehab 	/* video number of pixels at output */
1046cb7a01acSMauro Carvalho Chehab 	/* TASK A */
1047cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x5C, (u8)(fmt->width & 0xFF));
1048cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x5D, (u8)((fmt->width >> 8) & 0xFF));
1049cb7a01acSMauro Carvalho Chehab 	/* TASK B */
1050cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x9C, (u8)(fmt->width & 0xFF));
1051cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x9D, (u8)((fmt->width >> 8) & 0xFF));
1052cb7a01acSMauro Carvalho Chehab 
1053cb7a01acSMauro Carvalho Chehab 	/* video number of lines at output */
1054cb7a01acSMauro Carvalho Chehab 	/* TASK A */
1055cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x5E, (u8)(fmt->height & 0xFF));
1056cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x5F, (u8)((fmt->height >> 8) & 0xFF));
1057cb7a01acSMauro Carvalho Chehab 	/* TASK B */
1058cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x9E, (u8)(fmt->height & 0xFF));
1059cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x9F, (u8)((fmt->height >> 8) & 0xFF));
1060cb7a01acSMauro Carvalho Chehab 	return 0;
1061cb7a01acSMauro Carvalho Chehab }
1062cb7a01acSMauro Carvalho Chehab 
1063cb7a01acSMauro Carvalho Chehab static int saa717x_s_radio(struct v4l2_subdev *sd)
1064cb7a01acSMauro Carvalho Chehab {
1065cb7a01acSMauro Carvalho Chehab 	struct saa717x_state *decoder = to_state(sd);
1066cb7a01acSMauro Carvalho Chehab 
1067cb7a01acSMauro Carvalho Chehab 	decoder->radio = 1;
1068cb7a01acSMauro Carvalho Chehab 	return 0;
1069cb7a01acSMauro Carvalho Chehab }
1070cb7a01acSMauro Carvalho Chehab 
1071cb7a01acSMauro Carvalho Chehab static int saa717x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1072cb7a01acSMauro Carvalho Chehab {
1073cb7a01acSMauro Carvalho Chehab 	struct saa717x_state *decoder = to_state(sd);
1074cb7a01acSMauro Carvalho Chehab 
1075cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "decoder set norm ");
1076cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "(not yet implementd)\n");
1077cb7a01acSMauro Carvalho Chehab 
1078cb7a01acSMauro Carvalho Chehab 	decoder->radio = 0;
1079cb7a01acSMauro Carvalho Chehab 	decoder->std = std;
1080cb7a01acSMauro Carvalho Chehab 	return 0;
1081cb7a01acSMauro Carvalho Chehab }
1082cb7a01acSMauro Carvalho Chehab 
1083cb7a01acSMauro Carvalho Chehab static int saa717x_s_audio_routing(struct v4l2_subdev *sd,
1084cb7a01acSMauro Carvalho Chehab 				   u32 input, u32 output, u32 config)
1085cb7a01acSMauro Carvalho Chehab {
1086cb7a01acSMauro Carvalho Chehab 	struct saa717x_state *decoder = to_state(sd);
1087cb7a01acSMauro Carvalho Chehab 
1088cb7a01acSMauro Carvalho Chehab 	if (input < 3) { /* FIXME! --tadachi */
1089cb7a01acSMauro Carvalho Chehab 		decoder->audio_input = input;
1090cb7a01acSMauro Carvalho Chehab 		v4l2_dbg(1, debug, sd,
1091cb7a01acSMauro Carvalho Chehab 				"set decoder audio input to %d\n",
1092cb7a01acSMauro Carvalho Chehab 				decoder->audio_input);
1093cb7a01acSMauro Carvalho Chehab 		set_audio_regs(sd, decoder);
1094cb7a01acSMauro Carvalho Chehab 		return 0;
1095cb7a01acSMauro Carvalho Chehab 	}
1096cb7a01acSMauro Carvalho Chehab 	return -ERANGE;
1097cb7a01acSMauro Carvalho Chehab }
1098cb7a01acSMauro Carvalho Chehab 
1099cb7a01acSMauro Carvalho Chehab static int saa717x_s_stream(struct v4l2_subdev *sd, int enable)
1100cb7a01acSMauro Carvalho Chehab {
1101cb7a01acSMauro Carvalho Chehab 	struct saa717x_state *decoder = to_state(sd);
1102cb7a01acSMauro Carvalho Chehab 
1103cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "decoder %s output\n",
1104cb7a01acSMauro Carvalho Chehab 			enable ? "enable" : "disable");
1105cb7a01acSMauro Carvalho Chehab 	decoder->enable = enable;
1106cb7a01acSMauro Carvalho Chehab 	saa717x_write(sd, 0x193, enable ? 0xa6 : 0x26);
1107cb7a01acSMauro Carvalho Chehab 	return 0;
1108cb7a01acSMauro Carvalho Chehab }
1109cb7a01acSMauro Carvalho Chehab 
1110cb7a01acSMauro Carvalho Chehab /* change audio mode */
11112f73c7c5SHans Verkuil static int saa717x_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)
1112cb7a01acSMauro Carvalho Chehab {
1113cb7a01acSMauro Carvalho Chehab 	struct saa717x_state *decoder = to_state(sd);
1114cb7a01acSMauro Carvalho Chehab 	int audio_mode;
1115cb7a01acSMauro Carvalho Chehab 	char *mes[4] = {
1116cb7a01acSMauro Carvalho Chehab 		"MONO", "STEREO", "LANG1", "LANG2/SAP"
1117cb7a01acSMauro Carvalho Chehab 	};
1118cb7a01acSMauro Carvalho Chehab 
1119cb7a01acSMauro Carvalho Chehab 	audio_mode = TUNER_AUDIO_STEREO;
1120cb7a01acSMauro Carvalho Chehab 
1121cb7a01acSMauro Carvalho Chehab 	switch (vt->audmode) {
1122cb7a01acSMauro Carvalho Chehab 		case V4L2_TUNER_MODE_MONO:
1123cb7a01acSMauro Carvalho Chehab 			audio_mode = TUNER_AUDIO_MONO;
1124cb7a01acSMauro Carvalho Chehab 			break;
1125cb7a01acSMauro Carvalho Chehab 		case V4L2_TUNER_MODE_STEREO:
1126cb7a01acSMauro Carvalho Chehab 			audio_mode = TUNER_AUDIO_STEREO;
1127cb7a01acSMauro Carvalho Chehab 			break;
1128cb7a01acSMauro Carvalho Chehab 		case V4L2_TUNER_MODE_LANG2:
1129cb7a01acSMauro Carvalho Chehab 			audio_mode = TUNER_AUDIO_LANG2;
1130cb7a01acSMauro Carvalho Chehab 			break;
1131cb7a01acSMauro Carvalho Chehab 		case V4L2_TUNER_MODE_LANG1:
1132cb7a01acSMauro Carvalho Chehab 			audio_mode = TUNER_AUDIO_LANG1;
1133cb7a01acSMauro Carvalho Chehab 			break;
1134cb7a01acSMauro Carvalho Chehab 	}
1135cb7a01acSMauro Carvalho Chehab 
1136cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "change audio mode to %s\n",
1137cb7a01acSMauro Carvalho Chehab 			mes[audio_mode]);
1138cb7a01acSMauro Carvalho Chehab 	decoder->tuner_audio_mode = audio_mode;
1139cb7a01acSMauro Carvalho Chehab 	/* The registers are not changed here. */
1140cb7a01acSMauro Carvalho Chehab 	/* See DECODER_ENABLE_OUTPUT section. */
1141cb7a01acSMauro Carvalho Chehab 	set_audio_mode(sd, decoder->tuner_audio_mode);
1142cb7a01acSMauro Carvalho Chehab 	return 0;
1143cb7a01acSMauro Carvalho Chehab }
1144cb7a01acSMauro Carvalho Chehab 
1145cb7a01acSMauro Carvalho Chehab static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1146cb7a01acSMauro Carvalho Chehab {
1147cb7a01acSMauro Carvalho Chehab 	struct saa717x_state *decoder = to_state(sd);
1148cb7a01acSMauro Carvalho Chehab 	int dual_f, stereo_f;
1149cb7a01acSMauro Carvalho Chehab 
1150cb7a01acSMauro Carvalho Chehab 	if (decoder->radio)
1151cb7a01acSMauro Carvalho Chehab 		return 0;
1152cb7a01acSMauro Carvalho Chehab 	get_inf_dev_status(sd, &dual_f, &stereo_f);
1153cb7a01acSMauro Carvalho Chehab 
1154cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "DETECT==st:%d dual:%d\n",
1155cb7a01acSMauro Carvalho Chehab 			stereo_f, dual_f);
1156cb7a01acSMauro Carvalho Chehab 
1157cb7a01acSMauro Carvalho Chehab 	/* mono */
1158cb7a01acSMauro Carvalho Chehab 	if ((dual_f == 0) && (stereo_f == 0)) {
1159cb7a01acSMauro Carvalho Chehab 		vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1160cb7a01acSMauro Carvalho Chehab 		v4l2_dbg(1, debug, sd, "DETECT==MONO\n");
1161cb7a01acSMauro Carvalho Chehab 	}
1162cb7a01acSMauro Carvalho Chehab 
1163cb7a01acSMauro Carvalho Chehab 	/* stereo */
1164cb7a01acSMauro Carvalho Chehab 	if (stereo_f == 1) {
1165cb7a01acSMauro Carvalho Chehab 		if (vt->audmode == V4L2_TUNER_MODE_STEREO ||
1166cb7a01acSMauro Carvalho Chehab 				vt->audmode == V4L2_TUNER_MODE_LANG1) {
1167cb7a01acSMauro Carvalho Chehab 			vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
1168cb7a01acSMauro Carvalho Chehab 			v4l2_dbg(1, debug, sd, "DETECT==ST(ST)\n");
1169cb7a01acSMauro Carvalho Chehab 		} else {
1170cb7a01acSMauro Carvalho Chehab 			vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1171cb7a01acSMauro Carvalho Chehab 			v4l2_dbg(1, debug, sd, "DETECT==ST(MONO)\n");
1172cb7a01acSMauro Carvalho Chehab 		}
1173cb7a01acSMauro Carvalho Chehab 	}
1174cb7a01acSMauro Carvalho Chehab 
1175cb7a01acSMauro Carvalho Chehab 	/* dual */
1176cb7a01acSMauro Carvalho Chehab 	if (dual_f == 1) {
1177cb7a01acSMauro Carvalho Chehab 		if (vt->audmode == V4L2_TUNER_MODE_LANG2) {
1178cb7a01acSMauro Carvalho Chehab 			vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO;
1179cb7a01acSMauro Carvalho Chehab 			v4l2_dbg(1, debug, sd, "DETECT==DUAL1\n");
1180cb7a01acSMauro Carvalho Chehab 		} else {
1181cb7a01acSMauro Carvalho Chehab 			vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO;
1182cb7a01acSMauro Carvalho Chehab 			v4l2_dbg(1, debug, sd, "DETECT==DUAL2\n");
1183cb7a01acSMauro Carvalho Chehab 		}
1184cb7a01acSMauro Carvalho Chehab 	}
1185cb7a01acSMauro Carvalho Chehab 	return 0;
1186cb7a01acSMauro Carvalho Chehab }
1187cb7a01acSMauro Carvalho Chehab 
1188cb7a01acSMauro Carvalho Chehab static int saa717x_log_status(struct v4l2_subdev *sd)
1189cb7a01acSMauro Carvalho Chehab {
1190cb7a01acSMauro Carvalho Chehab 	struct saa717x_state *state = to_state(sd);
1191cb7a01acSMauro Carvalho Chehab 
1192cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
1193cb7a01acSMauro Carvalho Chehab 	return 0;
1194cb7a01acSMauro Carvalho Chehab }
1195cb7a01acSMauro Carvalho Chehab 
1196cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */
1197cb7a01acSMauro Carvalho Chehab 
1198cb7a01acSMauro Carvalho Chehab static const struct v4l2_ctrl_ops saa717x_ctrl_ops = {
1199cb7a01acSMauro Carvalho Chehab 	.s_ctrl = saa717x_s_ctrl,
1200cb7a01acSMauro Carvalho Chehab };
1201cb7a01acSMauro Carvalho Chehab 
1202cb7a01acSMauro Carvalho Chehab static const struct v4l2_subdev_core_ops saa717x_core_ops = {
1203cb7a01acSMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG
1204cb7a01acSMauro Carvalho Chehab 	.g_register = saa717x_g_register,
1205cb7a01acSMauro Carvalho Chehab 	.s_register = saa717x_s_register,
1206cb7a01acSMauro Carvalho Chehab #endif
1207cb7a01acSMauro Carvalho Chehab 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
1208cb7a01acSMauro Carvalho Chehab 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
1209cb7a01acSMauro Carvalho Chehab 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
1210cb7a01acSMauro Carvalho Chehab 	.g_ctrl = v4l2_subdev_g_ctrl,
1211cb7a01acSMauro Carvalho Chehab 	.s_ctrl = v4l2_subdev_s_ctrl,
1212cb7a01acSMauro Carvalho Chehab 	.queryctrl = v4l2_subdev_queryctrl,
1213cb7a01acSMauro Carvalho Chehab 	.querymenu = v4l2_subdev_querymenu,
1214cb7a01acSMauro Carvalho Chehab 	.log_status = saa717x_log_status,
1215cb7a01acSMauro Carvalho Chehab };
1216cb7a01acSMauro Carvalho Chehab 
1217cb7a01acSMauro Carvalho Chehab static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = {
1218cb7a01acSMauro Carvalho Chehab 	.g_tuner = saa717x_g_tuner,
1219cb7a01acSMauro Carvalho Chehab 	.s_tuner = saa717x_s_tuner,
1220cb7a01acSMauro Carvalho Chehab 	.s_radio = saa717x_s_radio,
1221cb7a01acSMauro Carvalho Chehab };
1222cb7a01acSMauro Carvalho Chehab 
1223cb7a01acSMauro Carvalho Chehab static const struct v4l2_subdev_video_ops saa717x_video_ops = {
12248774bed9SLaurent Pinchart 	.s_std = saa717x_s_std,
1225cb7a01acSMauro Carvalho Chehab 	.s_routing = saa717x_s_video_routing,
1226cb7a01acSMauro Carvalho Chehab 	.s_stream = saa717x_s_stream,
1227cb7a01acSMauro Carvalho Chehab };
1228cb7a01acSMauro Carvalho Chehab 
1229cb7a01acSMauro Carvalho Chehab static const struct v4l2_subdev_audio_ops saa717x_audio_ops = {
1230cb7a01acSMauro Carvalho Chehab 	.s_routing = saa717x_s_audio_routing,
1231cb7a01acSMauro Carvalho Chehab };
1232cb7a01acSMauro Carvalho Chehab 
12336e80c473SHans Verkuil static const struct v4l2_subdev_pad_ops saa717x_pad_ops = {
12346e80c473SHans Verkuil 	.set_fmt = saa717x_set_fmt,
12356e80c473SHans Verkuil };
12366e80c473SHans Verkuil 
1237cb7a01acSMauro Carvalho Chehab static const struct v4l2_subdev_ops saa717x_ops = {
1238cb7a01acSMauro Carvalho Chehab 	.core = &saa717x_core_ops,
1239cb7a01acSMauro Carvalho Chehab 	.tuner = &saa717x_tuner_ops,
1240cb7a01acSMauro Carvalho Chehab 	.audio = &saa717x_audio_ops,
1241cb7a01acSMauro Carvalho Chehab 	.video = &saa717x_video_ops,
12426e80c473SHans Verkuil 	.pad = &saa717x_pad_ops,
1243cb7a01acSMauro Carvalho Chehab };
1244cb7a01acSMauro Carvalho Chehab 
1245cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */
1246cb7a01acSMauro Carvalho Chehab 
1247cb7a01acSMauro Carvalho Chehab 
1248cb7a01acSMauro Carvalho Chehab /* i2c implementation */
1249cb7a01acSMauro Carvalho Chehab 
1250cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */
1251cb7a01acSMauro Carvalho Chehab static int saa717x_probe(struct i2c_client *client,
1252cb7a01acSMauro Carvalho Chehab 			 const struct i2c_device_id *did)
1253cb7a01acSMauro Carvalho Chehab {
1254cb7a01acSMauro Carvalho Chehab 	struct saa717x_state *decoder;
1255cb7a01acSMauro Carvalho Chehab 	struct v4l2_ctrl_handler *hdl;
1256cb7a01acSMauro Carvalho Chehab 	struct v4l2_subdev *sd;
1257cb7a01acSMauro Carvalho Chehab 	u8 id = 0;
1258cb7a01acSMauro Carvalho Chehab 	char *p = "";
1259cb7a01acSMauro Carvalho Chehab 
1260cb7a01acSMauro Carvalho Chehab 	/* Check if the adapter supports the needed features */
1261cb7a01acSMauro Carvalho Chehab 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1262cb7a01acSMauro Carvalho Chehab 		return -EIO;
1263cb7a01acSMauro Carvalho Chehab 
1264c02b211dSLaurent Pinchart 	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
1265cb7a01acSMauro Carvalho Chehab 	if (decoder == NULL)
1266cb7a01acSMauro Carvalho Chehab 		return -ENOMEM;
1267cb7a01acSMauro Carvalho Chehab 
1268cb7a01acSMauro Carvalho Chehab 	sd = &decoder->sd;
1269cb7a01acSMauro Carvalho Chehab 	v4l2_i2c_subdev_init(sd, client, &saa717x_ops);
1270cb7a01acSMauro Carvalho Chehab 
1271cb7a01acSMauro Carvalho Chehab 	if (saa717x_write(sd, 0x5a4, 0xfe) &&
1272cb7a01acSMauro Carvalho Chehab 			saa717x_write(sd, 0x5a5, 0x0f) &&
1273cb7a01acSMauro Carvalho Chehab 			saa717x_write(sd, 0x5a6, 0x00) &&
1274cb7a01acSMauro Carvalho Chehab 			saa717x_write(sd, 0x5a7, 0x01))
1275cb7a01acSMauro Carvalho Chehab 		id = saa717x_read(sd, 0x5a0);
1276cb7a01acSMauro Carvalho Chehab 	if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) {
1277cb7a01acSMauro Carvalho Chehab 		v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id);
1278cb7a01acSMauro Carvalho Chehab 		return -ENODEV;
1279cb7a01acSMauro Carvalho Chehab 	}
1280cb7a01acSMauro Carvalho Chehab 	if (id == 0xc2)
1281cb7a01acSMauro Carvalho Chehab 		p = "saa7173";
1282cb7a01acSMauro Carvalho Chehab 	else if (id == 0x32)
1283cb7a01acSMauro Carvalho Chehab 		p = "saa7174A";
1284cb7a01acSMauro Carvalho Chehab 	else if (id == 0x6c)
1285cb7a01acSMauro Carvalho Chehab 		p = "saa7174HL";
1286cb7a01acSMauro Carvalho Chehab 	else
1287cb7a01acSMauro Carvalho Chehab 		p = "saa7171";
1288cb7a01acSMauro Carvalho Chehab 	v4l2_info(sd, "%s found @ 0x%x (%s)\n", p,
1289cb7a01acSMauro Carvalho Chehab 			client->addr << 1, client->adapter->name);
1290cb7a01acSMauro Carvalho Chehab 
1291cb7a01acSMauro Carvalho Chehab 	hdl = &decoder->hdl;
1292cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_handler_init(hdl, 9);
1293cb7a01acSMauro Carvalho Chehab 	/* add in ascending ID order */
1294cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1295cb7a01acSMauro Carvalho Chehab 			V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1296cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1297cb7a01acSMauro Carvalho Chehab 			V4L2_CID_CONTRAST, 0, 255, 1, 68);
1298cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1299cb7a01acSMauro Carvalho Chehab 			V4L2_CID_SATURATION, 0, 255, 1, 64);
1300cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1301cb7a01acSMauro Carvalho Chehab 			V4L2_CID_HUE, -128, 127, 1, 0);
1302cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1303cb7a01acSMauro Carvalho Chehab 			V4L2_CID_AUDIO_VOLUME, 0, 65535, 65535 / 100, 42000);
1304cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1305cb7a01acSMauro Carvalho Chehab 			V4L2_CID_AUDIO_BALANCE, 0, 65535, 65535 / 100, 32768);
1306cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1307cb7a01acSMauro Carvalho Chehab 			V4L2_CID_AUDIO_BASS, -16, 15, 1, 0);
1308cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1309cb7a01acSMauro Carvalho Chehab 			V4L2_CID_AUDIO_TREBLE, -16, 15, 1, 0);
1310cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1311cb7a01acSMauro Carvalho Chehab 			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
1312cb7a01acSMauro Carvalho Chehab 	sd->ctrl_handler = hdl;
1313cb7a01acSMauro Carvalho Chehab 	if (hdl->error) {
1314cb7a01acSMauro Carvalho Chehab 		int err = hdl->error;
1315cb7a01acSMauro Carvalho Chehab 
1316cb7a01acSMauro Carvalho Chehab 		v4l2_ctrl_handler_free(hdl);
1317cb7a01acSMauro Carvalho Chehab 		return err;
1318cb7a01acSMauro Carvalho Chehab 	}
1319cb7a01acSMauro Carvalho Chehab 
1320cb7a01acSMauro Carvalho Chehab 	decoder->std = V4L2_STD_NTSC;
1321cb7a01acSMauro Carvalho Chehab 	decoder->input = -1;
1322cb7a01acSMauro Carvalho Chehab 	decoder->enable = 1;
1323cb7a01acSMauro Carvalho Chehab 
1324cb7a01acSMauro Carvalho Chehab 	/* FIXME!! */
1325cb7a01acSMauro Carvalho Chehab 	decoder->playback = 0;	/* initially capture mode used */
1326cb7a01acSMauro Carvalho Chehab 	decoder->audio = 1; /* DECODER_AUDIO_48_KHZ */
1327cb7a01acSMauro Carvalho Chehab 
1328cb7a01acSMauro Carvalho Chehab 	decoder->audio_input = 2; /* FIXME!! */
1329cb7a01acSMauro Carvalho Chehab 
1330cb7a01acSMauro Carvalho Chehab 	decoder->tuner_audio_mode = TUNER_AUDIO_STEREO;
1331cb7a01acSMauro Carvalho Chehab 	/* set volume, bass and treble */
1332cb7a01acSMauro Carvalho Chehab 	decoder->audio_main_vol_l = 6;
1333cb7a01acSMauro Carvalho Chehab 	decoder->audio_main_vol_r = 6;
1334cb7a01acSMauro Carvalho Chehab 
1335cb7a01acSMauro Carvalho Chehab 	v4l2_dbg(1, debug, sd, "writing init values\n");
1336cb7a01acSMauro Carvalho Chehab 
1337cb7a01acSMauro Carvalho Chehab 	/* FIXME!! */
1338cb7a01acSMauro Carvalho Chehab 	saa717x_write_regs(sd, reg_init_initialize);
1339cb7a01acSMauro Carvalho Chehab 
1340cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_handler_setup(hdl);
1341cb7a01acSMauro Carvalho Chehab 
1342cb7a01acSMauro Carvalho Chehab 	set_current_state(TASK_INTERRUPTIBLE);
1343cb7a01acSMauro Carvalho Chehab 	schedule_timeout(2*HZ);
1344cb7a01acSMauro Carvalho Chehab 	return 0;
1345cb7a01acSMauro Carvalho Chehab }
1346cb7a01acSMauro Carvalho Chehab 
1347cb7a01acSMauro Carvalho Chehab static int saa717x_remove(struct i2c_client *client)
1348cb7a01acSMauro Carvalho Chehab {
1349cb7a01acSMauro Carvalho Chehab 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
1350cb7a01acSMauro Carvalho Chehab 
1351cb7a01acSMauro Carvalho Chehab 	v4l2_device_unregister_subdev(sd);
1352cb7a01acSMauro Carvalho Chehab 	v4l2_ctrl_handler_free(sd->ctrl_handler);
1353cb7a01acSMauro Carvalho Chehab 	return 0;
1354cb7a01acSMauro Carvalho Chehab }
1355cb7a01acSMauro Carvalho Chehab 
1356cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */
1357cb7a01acSMauro Carvalho Chehab 
1358cb7a01acSMauro Carvalho Chehab static const struct i2c_device_id saa717x_id[] = {
1359cb7a01acSMauro Carvalho Chehab 	{ "saa717x", 0 },
1360cb7a01acSMauro Carvalho Chehab 	{ }
1361cb7a01acSMauro Carvalho Chehab };
1362cb7a01acSMauro Carvalho Chehab MODULE_DEVICE_TABLE(i2c, saa717x_id);
1363cb7a01acSMauro Carvalho Chehab 
1364cb7a01acSMauro Carvalho Chehab static struct i2c_driver saa717x_driver = {
1365cb7a01acSMauro Carvalho Chehab 	.driver = {
1366cb7a01acSMauro Carvalho Chehab 		.owner	= THIS_MODULE,
1367cb7a01acSMauro Carvalho Chehab 		.name	= "saa717x",
1368cb7a01acSMauro Carvalho Chehab 	},
1369cb7a01acSMauro Carvalho Chehab 	.probe		= saa717x_probe,
1370cb7a01acSMauro Carvalho Chehab 	.remove		= saa717x_remove,
1371cb7a01acSMauro Carvalho Chehab 	.id_table	= saa717x_id,
1372cb7a01acSMauro Carvalho Chehab };
1373cb7a01acSMauro Carvalho Chehab 
1374cb7a01acSMauro Carvalho Chehab module_i2c_driver(saa717x_driver);
1375