xref: /dragonfly/sys/dev/video/cxm/cxm_saa7115.c (revision 1975d09e)
1 /*
2  * Copyright (c) 2003, 2004, 2005
3  *	John Wehle <john@feith.com>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by John Wehle.
16  * 4. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Video decoder routines for the Conexant MPEG-2 Codec driver.
34  *
35  * Ideally these routines should be implemented as a separate
36  * driver which has a generic video decoder interface so that
37  * it's not necessary for each multimedia driver to re-invent
38  * the wheel.
39  */
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/conf.h>
44 #include <sys/uio.h>
45 #include <sys/kernel.h>
46 #include <sys/poll.h>
47 #include <sys/select.h>
48 #include <sys/resource.h>
49 #include <sys/bus.h>
50 #include <sys/rman.h>
51 
52 #include <machine/clock.h>
53 
54 #include <dev/video/cxm/cxm.h>
55 
56 #include <bus/iicbus/iiconf.h>
57 #include <bus/iicbus/iicbus.h>
58 
59 #include "iicbb_if.h"
60 
61 
62 static const struct cxm_saa7115_command
63 saa7115_init = {
64 	19,
65 	{
66 		/* Full auto mode for CVBS */
67 		{ 0x01, 1, { 0x08 } },
68 		{ 0x03, 18, { 0x20, 0x90, 0x90, 0xeb, 0xe0, 0xb0, 0x40, 0x80,
69 			      0x44, 0x40, 0x00, 0x03, 0x2a, 0x06, 0x00, 0x9d,
70 			      0x80, 0x01 } },
71 		{ 0x17, 7, { 0x99, 0x40, 0x80, 0x77, 0x42, 0xa9, 0x01 } },
72 
73 		/*
74 		 * VBI data slicer
75 		 *
76 		 * NTSC raw VBI data on lines 10 through 21
77 		 * PAL raw VBI data on lines 6 through 22
78 		 *
79 		 * Actually lines 21 and 22 are set by the
80 		 * NTSC and PAL specific configurations.
81 		 */
82 		{ 0x40, 20, { 0x40, 0x00, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd,
83 			      0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
84 			      0xdd, 0xdd, 0xdd, 0xdd } },
85 		{ 0x56, 4, { 0x00, 0x00, 0x00, 0x47 } },
86 		{ 0x5c, 3, { 0x00, 0x1f, 0x35 } },
87 
88 		/* I-port and X-port configuration */
89 		{ 0x80, 2, { 0x00, 0x01 } },
90 		{ 0x83, 5, { 0x00, 0x20, 0x21, 0xc5, 0x01 } },
91 
92 		/* Scaler input configuration and output format settings */
93 		{ 0xc0, 4, { 0x00, 0x08, 0x00, 0x80 } },
94 
95 		/* VBI scaler configuration */
96 		{ 0x90, 4, { 0x80, 0x48, 0x00, 0x84 } },
97 		{ 0xa0, 3, { 0x01, 0x00, 0x00 } },
98 		{ 0xa4, 3, { 0x80, 0x40, 0x40 } },
99 		{ 0xa8, 3, { 0x00, 0x02, 0x00 } },
100 		{ 0xac, 3, { 0x00, 0x01, 0x00 } },
101 		{ 0xb0, 5, { 0x00, 0x04, 0x00, 0x04, 0x00 } },
102 		{ 0xb8, 8, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
103 
104 		/* Audio Master Clock to Audio Serial Clock ratio */
105 		{ 0x38, 3, { 0x03, 0x10, 0x00 } },
106 
107 		/* PLL2 target clock 27 MHz (using a 32.11 MHz crystal) */
108 		{ 0xf1, 4, { 0x05, 0xd0, 0x35, 0x00 } },
109 
110 		/* Pulse generator */
111 		{ 0xf6, 10, { 0x61, 0x0e, 0x60, 0x0e, 0x60, 0x0e, 0x00,
112 			      0x00, 0x00, 0x88 } }
113 	}
114 };
115 
116 static const struct cxm_saa7115_command
117 saa7115_mute = {
118 	1,
119 	{
120 		/* Disable I-port */
121 		{ 0x87, 1, { 0x00 } },
122 	}
123 };
124 
125 static const struct cxm_saa7115_command
126 saa7115_unmute = {
127 	1,
128 	{
129 		/* Enable I-port */
130 		{ 0x87, 1, { 0x01 } },
131 	}
132 };
133 
134 static const struct cxm_saa7115_command
135 saa7115_select_fm = {
136 	1,
137 	{
138 		/* Enable audio clock */
139 		{ 0x88, 1, { 0x33 } }
140 	}
141 };
142 
143 static const struct cxm_saa7115_command
144 saa7115_select_line_in_composite = {
145 	3,
146 	{
147 		/* Amp plus anti-alias filter, CVBS from AI11 */
148 		{ 0x02, 1, { 0xc0 } },
149 		/* Adaptive luminance comb filter */
150 		{ 0x09, 1, { 0x40 } },
151 
152 		/* Enable AD1, audio clock, scaler, decoder */
153 		{ 0x88, 1, { 0x70 } }
154 	}
155 };
156 
157 static const struct cxm_saa7115_command
158 saa7115_select_line_in_svideo = {
159 	3,
160 	{
161 		/* Amp plus anti-alias filter, Y / C from AI11 / AI21 */
162 		{ 0x02, 1, { 0xc8 } },
163 		/* Bypass chrominance trap / comb filter */
164 		{ 0x09, 1, { 0x80 } },
165 
166 		/* Enable AD1 & 2, audio clock, scaler, decoder */
167 		{ 0x88, 1, { 0xf0 } }
168 	}
169 };
170 
171 static const struct cxm_saa7115_command
172 saa7115_select_tuner = {
173 	3,
174 	{
175 		/* Amp plus anti-alias filter, CVBS (auto gain) from AI23 */
176 		{ 0x02, 1, { 0xc4 } },
177 		/* Adaptive luminance comb filter */
178 		{ 0x09, 1, { 0x40 } },
179 
180 		/* Enable AD2, audio clock, scaler, decoder */
181 		{ 0x88, 1, { 0xb0 } }
182 	}
183 };
184 
185 static const struct cxm_saa7115_command
186 saa7115_audio_clock_44100_ntsc = {
187 	2,
188 	{
189 		/* Audio clock 44.1 kHz NTSC (using a 32.11 MHz crystal) */
190 		{ 0x30, 3, { 0xbc, 0xdf, 0x02 } },
191 		{ 0x34, 3, { 0xf2, 0x00, 0x2d } }
192 	}
193 };
194 
195 static const struct cxm_saa7115_command
196 saa7115_audio_clock_44100_pal = {
197 	2,
198 	{
199 		/* Audio clock 44.1 kHz PAL (using a 32.11 MHz crystal) */
200 		{ 0x30, 3, { 0x00, 0x72, 0x03 } },
201 		{ 0x34, 3, { 0xf2, 0x00, 0x2d } }
202 	}
203 };
204 
205 static const struct cxm_saa7115_command
206 saa7115_audio_clock_48000_ntsc = {
207 	2,
208 	{
209 		/* Audio clock 48 kHz NTSC (using a 32.11 MHz crystal) */
210 		{ 0x30, 3, { 0xcd, 0x20, 0x03 } },
211 		{ 0x34, 3, { 0xce, 0xfb, 0x30 } }
212 	}
213 };
214 
215 static const struct cxm_saa7115_command
216 saa7115_audio_clock_48000_pal = {
217 	2,
218 	{
219 		/* Audio clock 48 kHz PAL (using a 32.11 MHz crystal) */
220 		{ 0x30, 3, { 0x00, 0xc0, 0x03 } },
221 		{ 0x34, 3, { 0xce, 0xfb, 0x30 } }
222 	}
223 };
224 
225 static const struct cxm_saa7115_command
226 saa7115_scaler_vcd_ntsc_double_lines = {
227 	13,
228 	{
229 		/*
230 		 * Input window = 720 x 240, output window = 352 x 240 with
231 		 * YS extended by 2 as per section 17.4 of the data sheet
232 		 * and YO accounting for scaler processing triggering at
233 		 * line 5 and active video starting at line 23 (see section
234 		 * 8.2 table 8 and section 8.3.1.1 table 11 of the data sheet).
235 		 * NTSC active video should actually start at line 22, however
236 		 * not all channels / programs do.
237 		 */
238 		{ 0xc4, 12, { 0x02, 0x00, 0xd0, 0x02, 0x12, 0x00, 0xf2, 0x00,
239 			      0x60, 0x01, 0xf0, 0x00 } },
240 
241 		/* Prefiltering and prescaling */
242 		{ 0xd0, 3, { 0x02, 0x02, 0xaa } },
243 
244 		/* Brightness, contrast, and saturation */
245 		{ 0xd4, 3, { 0x80, 0x40, 0x40 } },
246 
247 		/* Horizontal phase scaling */
248 		{ 0xd8, 3, { 0x18, 0x04, 0x00 } },
249 		{ 0xdc, 3, { 0x0c, 0x02, 0x00 } },
250 
251 		/* Vertical scaling */
252 		{ 0xe0, 5, { 0x00, 0x04, 0x00, 0x04, 0x00 } },
253 
254 		/* Vertical phase offsets */
255 		{ 0xe8, 8, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
256 
257 		/*
258 		 * VBI input window = 720 x 12, output window = 1440 x 12.
259 		 */
260 		{ 0x94, 12, { 0x02, 0x00, 0xd0, 0x02, 0x05, 0x00, 0x0c, 0x00,
261 			      0xa0, 0x05, 0x0c, 0x00 } },
262 
263 		/* Inverted VGATE start at line 23, stop after line 263 */
264 		{ 0x15, 2, { 0x02, 0x12 } },
265 
266 		/* VBI data slicer 525 lines, line 21 is closed caption */
267 		{ 0x54, 2, { 0x4d, 0x00 } },
268 		{ 0x5a, 2, { 0x06, 0x83 } },
269 
270 		/* PLL2 525 lines, 27 Mhz target clock */
271 		{ 0xf0, 1, { 0xad } },
272 
273 		/* Pulse generator 525 lines, 27 Mhz target clock */
274 		{ 0xf5, 1, { 0xad } }
275 	}
276 };
277 
278 static const struct cxm_saa7115_command
279 saa7115_scaler_vcd_pal_double_lines = {
280 	13,
281 	{
282 		/*
283 		 * Input window = 720 x 288, output window = 352 x 288 with
284 		 * YS extended by 2 as per section 17.4 of the data sheet
285 		 * and YO accounting for scaler processing triggering at
286 		 * line 2 and active video starting at line 25 (see section
287 		 * 8.2 table 8 and section 8.3.1.1 table 11 of the data sheet).
288 		 * PAL active video should actually start at line 24, however
289 		 * not all channels / programs do.
290 		 */
291 		{ 0xc4, 12, { 0x02, 0x00, 0xd0, 0x02, 0x17, 0x00, 0x22, 0x01,
292 			      0x60, 0x01, 0x20, 0x01 } },
293 
294 		/* Prefiltering and prescaling */
295 		{ 0xd0, 3, { 0x02, 0x02, 0xaa } },
296 
297 		/* Brightness, contrast, and saturation */
298 		{ 0xd4, 3, { 0x80, 0x40, 0x40 } },
299 
300 		/* Horizontal phase scaling */
301 		{ 0xd8, 3, { 0x18, 0x04, 0x00 } },
302 		{ 0xdc, 3, { 0x0c, 0x02, 0x00 } },
303 
304 		/* Vertical scaling */
305 		{ 0xe0, 5, { 0x00, 0x04, 0x00, 0x04, 0x00 } },
306 
307 		/* Vertical phase offsets */
308 		{ 0xe8, 8, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
309 
310 		/*
311 		 * VBI input window = 720 x 17, output window = 1440 x 17.
312 		 */
313 		{ 0x94, 12, { 0x02, 0x00, 0xd0, 0x02, 0x04, 0x00, 0x11, 0x00,
314 			      0xa0, 0x05, 0x11, 0x00 } },
315 
316 		/* Inverted VGATE start at line 25, stop after line 313 */
317 		{ 0x15, 2, { 0x37, 0x17 } },
318 
319 		/* VBI data slicer 625 lines, line 22 is closed caption */
320 		{ 0x54, 2, { 0xdd, 0x4d } },
321 		{ 0x5a, 2, { 0x03, 0x03 } },
322 
323 		/* PLL2 625 lines, 27 Mhz target clock */
324 		{ 0xf0, 1, { 0xb0 } },
325 
326 		/* Pulse generator 625 lines, 27 Mhz target clock */
327 		{ 0xf5, 1, { 0xb0 } }
328 	}
329 };
330 
331 static const struct cxm_saa7115_command
332 saa7115_scaler_svcd_ntsc = {
333 	13,
334 	{
335 		/*
336 		 * Input window = 720 x 240, output window = 480 x 240 with
337 		 * YS extended by 2 as per section 17.4 of the data sheet
338 		 * and YO accounting for scaler processing triggering at
339 		 * line 5 and active video starting at line 23 (see section
340 		 * 8.2 table 8 and section 8.3.1.1 table 11 of the data sheet).
341 		 * NTSC active video should actually start at line 22, however
342 		 * not all channels / programs do.
343 		 */
344 		{ 0xc4, 12, { 0x02, 0x00, 0xd0, 0x02, 0x12, 0x00, 0xf2, 0x00,
345 			      0xe0, 0x01, 0xf0, 0x00 } },
346 
347 		/* Prefiltering and prescaling */
348 		{ 0xd0, 3, { 0x01, 0x00, 0x00 } },
349 
350 		/* Brightness, contrast, and saturation */
351 		{ 0xd4, 3, { 0x80, 0x40, 0x40 } },
352 
353 		/* Horizontal phase scaling */
354 		{ 0xd8, 3, { 0x00, 0x06, 0x00 } },
355 		{ 0xdc, 3, { 0x00, 0x03, 0x00 } },
356 
357 		/* Vertical scaling */
358 		{ 0xe0, 5, { 0x00, 0x04, 0x00, 0x04, 0x00 } },
359 
360 		/* Vertical phase offsets */
361 		{ 0xe8, 8, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
362 
363 		/*
364 		 * VBI input window = 720 x 12, output window = 1440 x 12.
365 		 */
366 		{ 0x94, 12, { 0x02, 0x00, 0xd0, 0x02, 0x05, 0x00, 0x0c, 0x00,
367 			      0xa0, 0x05, 0x0c, 0x00 } },
368 
369 		/* Inverted VGATE start at line 23, stop after line 263 */
370 		{ 0x15, 2, { 0x02, 0x12 } },
371 
372 		/* VBI data slicer 525 lines, line 21 is closed caption */
373 		{ 0x54, 2, { 0x4d, 0x00 } },
374 		{ 0x5a, 2, { 0x06, 0x83 } },
375 
376 		/* PLL2 525 lines, 27 Mhz target clock */
377 		{ 0xf0, 1, { 0xad } },
378 
379 		/* Pulse generator 525 lines, 27 Mhz target clock */
380 		{ 0xf5, 1, { 0xad } }
381 	}
382 };
383 
384 static const struct cxm_saa7115_command
385 saa7115_scaler_svcd_pal = {
386 	13,
387 	{
388 		/*
389 		 * Input window = 720 x 288, output window = 480 x 288 with
390 		 * YS extended by 2 as per section 17.4 of the data sheet
391 		 * and YO accounting for scaler processing triggering at
392 		 * line 2 and active video starting at line 25 (see section
393 		 * 8.2 table 8 and section 8.3.1.1 table 11 of the data sheet).
394 		 * PAL active video should actually start at line 24, however
395 		 * not all channels / programs do.
396 		 */
397 		{ 0xc4, 12, { 0x02, 0x00, 0xd0, 0x02, 0x17, 0x00, 0x22, 0x01,
398 			      0xe0, 0x01, 0x20, 0x01 } },
399 
400 		/* Prefiltering and prescaling */
401 		{ 0xd0, 3, { 0x01, 0x00, 0x00 } },
402 
403 		/* Brightness, contrast, and saturation */
404 		{ 0xd4, 3, { 0x80, 0x40, 0x40 } },
405 
406 		/* Horizontal phase scaling */
407 		{ 0xd8, 3, { 0x00, 0x06, 0x00 } },
408 		{ 0xdc, 3, { 0x00, 0x03, 0x00 } },
409 
410 		/* Vertical scaling */
411 		{ 0xe0, 5, { 0x00, 0x04, 0x00, 0x04, 0x00 } },
412 
413 		/* Vertical phase offsets */
414 		{ 0xe8, 8, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
415 
416 		/*
417 		 * VBI input window = 720 x 17, output window = 1440 x 17.
418 		 */
419 		{ 0x94, 12, { 0x02, 0x00, 0xd0, 0x02, 0x04, 0x00, 0x11, 0x00,
420 			      0xa0, 0x05, 0x11, 0x00 } },
421 
422 		/* Inverted VGATE start at line 25, stop after line 313 */
423 		{ 0x15, 2, { 0x37, 0x17 } },
424 
425 		/* VBI data slicer 625 lines, line 22 is closed caption */
426 		{ 0x54, 2, { 0xdd, 0x4d } },
427 		{ 0x5a, 2, { 0x03, 0x03 } },
428 
429 		/* PLL2 625 lines, 27 Mhz target clock */
430 		{ 0xf0, 1, { 0xb0 } },
431 
432 		/* Pulse generator 625 lines, 27 Mhz target clock */
433 		{ 0xf5, 1, { 0xb0 } }
434 	}
435 };
436 
437 static const struct cxm_saa7115_command
438 saa7115_scaler_dvd_ntsc = {
439 	13,
440 	{
441 		/*
442 		 * Input window = 720 x 240, output window = 720 x 240 with
443 		 * YS extended by 2 as per section 17.4 of the data sheet
444 		 * and YO accounting for scaler processing triggering at
445 		 * line 5 and active video starting at line 23 (see section
446 		 * 8.2 table 8 and section 8.3.1.1 table 11 of the data sheet).
447 		 * NTSC active video should actually start at line 22, however
448 		 * not all channels / programs do.
449 		 */
450 		{ 0xc4, 12, { 0x02, 0x00, 0xd0, 0x02, 0x12, 0x00, 0xf2, 0x00,
451 			      0xd0, 0x02, 0xf0, 0x00 } },
452 
453 		/* Prefiltering and prescaling */
454 		{ 0xd0, 3, { 0x01, 0x00, 0x00 } },
455 
456 		/* Brightness, contrast, and saturation */
457 		{ 0xd4, 3, { 0x80, 0x40, 0x40 } },
458 
459 		/* Horizontal phase scaling */
460 		{ 0xd8, 3, { 0x00, 0x04, 0x00 } },
461 		{ 0xdc, 3, { 0x00, 0x02, 0x00 } },
462 
463 		/* Vertical scaling */
464 		{ 0xe0, 5, { 0x00, 0x04, 0x00, 0x04, 0x00 } },
465 
466 		/* Vertical phase offsets */
467 		{ 0xe8, 8, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
468 
469 		/*
470 		 * VBI input window = 720 x 12, output window = 1440 x 12.
471 		 */
472 		{ 0x94, 12, { 0x02, 0x00, 0xd0, 0x02, 0x05, 0x00, 0x0c, 0x00,
473 			      0xa0, 0x05, 0x0c, 0x00 } },
474 
475 		/* Inverted VGATE start at line 23, stop after line 263 */
476 		{ 0x15, 2, { 0x02, 0x12 } },
477 
478 		/* VBI data slicer 525 lines, line 21 is closed caption */
479 		{ 0x54, 2, { 0x4d, 0x00 } },
480 		{ 0x5a, 2, { 0x06, 0x83 } },
481 
482 		/* PLL2 525 lines, 27 Mhz target clock */
483 		{ 0xf0, 1, { 0xad } },
484 
485 		/* Pulse generator 525 lines, 27 Mhz target clock */
486 		{ 0xf5, 1, { 0xad } }
487 	}
488 };
489 
490 static const struct cxm_saa7115_command
491 saa7115_scaler_dvd_pal = {
492 	13,
493 	{
494 		/*
495 		 * Input window = 720 x 288, output window = 720 x 288 with
496 		 * YS extended by 2 as per section 17.4 of the data sheet
497 		 * and YO accounting for scaler processing triggering at
498 		 * line 2 and active video starting at line 25 (see section
499 		 * 8.2 table 8 and section 8.3.1.1 table 11 of the data sheet).
500 		 * PAL active video should actually start at line 24, however
501 		 * not all channels / programs do.
502 		 */
503 		{ 0xc4, 12, { 0x02, 0x00, 0xd0, 0x02, 0x17, 0x00, 0x22, 0x01,
504 			      0xd0, 0x02, 0x20, 0x01 } },
505 
506 		/* Prefiltering and prescaling */
507 		{ 0xd0, 3, { 0x01, 0x00, 0x00 } },
508 
509 		/* Brightness, contrast, and saturation */
510 		{ 0xd4, 3, { 0x80, 0x40, 0x40 } },
511 
512 		/* Horizontal phase scaling */
513 		{ 0xd8, 3, { 0x00, 0x04, 0x00 } },
514 		{ 0xdc, 3, { 0x00, 0x02, 0x00 } },
515 
516 		/* Vertical scaling */
517 		{ 0xe0, 5, { 0x00, 0x04, 0x00, 0x04, 0x00 } },
518 
519 		/* Vertical phase offsets */
520 		{ 0xe8, 8, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
521 
522 		/*
523 		 * VBI input window = 720 x 17, output window = 1440 x 17.
524 		 */
525 		{ 0x94, 12, { 0x02, 0x00, 0xd0, 0x02, 0x04, 0x00, 0x11, 0x00,
526 			      0xa0, 0x05, 0x11, 0x00 } },
527 
528 		/* Inverted VGATE start at line 25, stop after line 313 */
529 		{ 0x15, 2, { 0x37, 0x17 } },
530 
531 		/* VBI data slicer 625 lines, line 22 is closed caption */
532 		{ 0x54, 2, { 0xdd, 0x4d } },
533 		{ 0x5a, 2, { 0x03, 0x03 } },
534 
535 		/* PLL2 625 lines, 27 Mhz target clock */
536 		{ 0xf0, 1, { 0xb0 } },
537 
538 		/* Pulse generator 625 lines, 27 Mhz target clock */
539 		{ 0xf5, 1, { 0xb0 } }
540 	}
541 };
542 
543 
544 static const struct cxm_saa7115_audio_clock
545 saa7115_audio_clock[] = {
546 	{ 44100, 30, &saa7115_audio_clock_44100_ntsc },
547 	{ 44100, 25, &saa7115_audio_clock_44100_pal },
548 	{ 48000, 30, &saa7115_audio_clock_48000_ntsc },
549 	{ 48000, 25, &saa7115_audio_clock_48000_pal }
550 };
551 
552 static const struct cxm_saa7115_scaling
553 saa7115_scalings[] = {
554 	{ 352, 480, 30, &saa7115_scaler_vcd_ntsc_double_lines },
555 	{ 352, 576, 25, &saa7115_scaler_vcd_pal_double_lines },
556 	{ 480, 480, 30, &saa7115_scaler_svcd_ntsc },
557 	{ 480, 576, 25, &saa7115_scaler_svcd_pal },
558 	{ 720, 480, 30, &saa7115_scaler_dvd_ntsc },
559 	{ 720, 576, 25, &saa7115_scaler_dvd_pal }
560 };
561 
562 
563 /* Reset the SAA7115 chip */
564 static int
565 cxm_saa7115_reset(device_t iicbus, int i2c_addr)
566 {
567 	unsigned char msg[2];
568 	int sent;
569 
570 	/* put into reset mode */
571 	msg[0] = 0x88;
572 	msg[1] = 0x0b;
573 
574 	if (iicbus_start(iicbus, i2c_addr, CXM_I2C_TIMEOUT) != 0)
575 		return -1;
576 
577 	if (iicbus_write(iicbus, msg, sizeof(msg), &sent, CXM_I2C_TIMEOUT) != 0
578 	    || sent != sizeof(msg))
579 		goto fail;
580 
581 	iicbus_stop(iicbus);
582 
583 	/* put back to operational mode */
584 	msg[0] = 0x88;
585 	msg[1] = 0x2b;
586 
587 	if (iicbus_start(iicbus, i2c_addr, CXM_I2C_TIMEOUT) != 0)
588 		return -1;
589 
590 	if (iicbus_write(iicbus, msg, sizeof(msg), &sent, CXM_I2C_TIMEOUT) != 0
591 	    || sent != sizeof(msg))
592 		goto fail;
593 
594 	iicbus_stop(iicbus);
595 
596 	return 0;
597 
598 fail:
599 	iicbus_stop(iicbus);
600 	return -1;
601 }
602 
603 
604 /* Read from the SAA7115 registers */
605 static int
606 cxm_saa7115_read(device_t iicbus, int i2c_addr,
607 		  unsigned char addr, char *buf, int len)
608 {
609 	unsigned char msg[1];
610 	int received;
611 	int sent;
612 
613 	msg[0] = addr;
614 
615 	if (iicbus_start(iicbus, i2c_addr, CXM_I2C_TIMEOUT) != 0)
616 		return -1;
617 
618 	if (iicbus_write(iicbus, msg, sizeof(msg), &sent, CXM_I2C_TIMEOUT) != 0
619 	    || sent != sizeof(msg))
620 		goto fail;
621 
622 	if (iicbus_repeated_start(iicbus, i2c_addr + 1, CXM_I2C_TIMEOUT) != 0)
623 		goto fail;
624 
625 	if (iicbus_read(iicbus, buf, len, &received, IIC_LAST_READ, 0) != 0)
626 		goto fail;
627 
628 	iicbus_stop(iicbus);
629 
630 	return received;
631 
632 fail:
633 	iicbus_stop(iicbus);
634 	return -1;
635 }
636 
637 
638 /* Write to the SAA7115 registers */
639 static int
640 cxm_saa7115_write(device_t iicbus, int i2c_addr,
641 		   unsigned char addr, const char *buf, int len)
642 {
643 	unsigned char msg[1];
644 	int sent;
645 
646 	msg[0] = addr;
647 
648 	if (iicbus_start(iicbus, i2c_addr, CXM_I2C_TIMEOUT) != 0)
649 		return -1;
650 
651 	if (iicbus_write(iicbus, msg, sizeof(msg), &sent, CXM_I2C_TIMEOUT) != 0
652 	    || sent != sizeof(msg))
653 		goto fail;
654 
655 	if (iicbus_write(iicbus, buf, len, &sent, CXM_I2C_TIMEOUT) != 0)
656 		goto fail;
657 
658 	iicbus_stop(iicbus);
659 
660 	return sent;
661 
662 fail:
663 	iicbus_stop(iicbus);
664 	return -1;
665 }
666 
667 
668 int
669 cxm_saa7115_init(struct cxm_softc *sc)
670 {
671 	char name[5];
672 	unsigned char id[1];
673 	unsigned char rev;
674 	unsigned int i;
675 	unsigned int nsettings;
676 	const struct cxm_saa7115_setting *settings;
677 
678 	if (cxm_saa7115_reset (sc->iicbus, CXM_I2C_SAA7115) < 0)
679 		return -1;
680 
681 	name[4] = '\0';
682 	for (i = 0; i < 4; i++) {
683 		id[0] = 2 + i;
684 
685 		if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115, 0x00,
686 				      id, sizeof(id)) != sizeof(id))
687 			return -1;
688 
689 		if (cxm_saa7115_read(sc->iicbus, CXM_I2C_SAA7115, 0x00,
690 				     id, sizeof(id)) != sizeof(id))
691 			return -1;
692 
693 		name[i] = '0' + (id[0] & 0x0f);
694 		rev = id[0] >> 4;
695 	}
696 
697 	/*
698 	 * SAA 7115 is the only video decoder currently supported.
699 	 */
700 
701 	nsettings = 0;
702 	settings = NULL;
703 
704 	if (strcmp(name, "7115") == 0) {
705 		nsettings = saa7115_init.nsettings;
706 		settings = saa7115_init.settings;
707 	} else {
708 		device_printf(sc->dev, "unknown video decoder SAA%s\n", name);
709 		return -1;
710 	}
711 
712 	for (i = 0; i < nsettings; i++)
713 		if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115,
714 				      settings[i].addr,
715 				      settings[i].values, settings[i].nvalues)
716 		    != settings[i].nvalues)
717 			return -1;
718 
719 	if (cxm_saa7115_select_source(sc, cxm_tuner_source) < 0)
720 		return -1;
721 
722 	device_printf(sc->dev, "SAA%s rev %u video decoder\n",
723 	    name, (unsigned int)rev);
724 
725 	return 0;
726 }
727 
728 
729 int
730 cxm_saa7115_mute(struct cxm_softc *sc)
731 {
732 	unsigned int i;
733 	unsigned int nsettings;
734 	const struct cxm_saa7115_setting *settings;
735 
736 	nsettings = saa7115_mute.nsettings;
737 	settings = saa7115_mute.settings;
738 
739 	for (i = 0; i < nsettings; i++)
740 		if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115,
741 				      settings[i].addr,
742 				      settings[i].values, settings[i].nvalues)
743 		    != settings[i].nvalues)
744 			return -1;
745 
746 	return 0;
747 }
748 
749 
750 int
751 cxm_saa7115_unmute(struct cxm_softc *sc)
752 {
753 	unsigned int i;
754 	unsigned int nsettings;
755 	const struct cxm_saa7115_setting *settings;
756 
757 	nsettings = saa7115_unmute.nsettings;
758 	settings = saa7115_unmute.settings;
759 
760 	for (i = 0; i < nsettings; i++)
761 		if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115,
762 				      settings[i].addr,
763 				      settings[i].values, settings[i].nvalues)
764 		    != settings[i].nvalues)
765 			return -1;
766 
767 	return 0;
768 }
769 
770 
771 int
772 cxm_saa7115_select_source(struct cxm_softc *sc, enum cxm_source source)
773 {
774 	unsigned int i;
775 	unsigned int nsettings;
776 	const struct cxm_saa7115_setting *settings;
777 
778 	switch (source) {
779 	case cxm_fm_source:
780 		nsettings = saa7115_select_fm.nsettings;
781 		settings = saa7115_select_fm.settings;
782 		break;
783 
784 	case cxm_line_in_source_composite:
785 		nsettings = saa7115_select_line_in_composite.nsettings;
786 		settings = saa7115_select_line_in_composite.settings;
787 		break;
788 
789 	case cxm_line_in_source_svideo:
790 		nsettings = saa7115_select_line_in_svideo.nsettings;
791 		settings = saa7115_select_line_in_svideo.settings;
792 		break;
793 
794 	case cxm_tuner_source:
795 		nsettings = saa7115_select_tuner.nsettings;
796 		settings = saa7115_select_tuner.settings;
797 		break;
798 
799 	default:
800 		return -1;
801 	}
802 
803 	for (i = 0; i < nsettings; i++)
804 		if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115,
805 				      settings[i].addr,
806 				      settings[i].values, settings[i].nvalues)
807 		    != settings[i].nvalues)
808 			return -1;
809 
810 	return 0;
811 }
812 
813 
814 int
815 cxm_saa7115_configure(struct cxm_softc *sc,
816 		       unsigned int width, unsigned int height,
817 		       unsigned int fps, unsigned int audio_sample_rate)
818 {
819 	unsigned char power[1];
820 	unsigned char task[1];
821 	unsigned int i;
822 	unsigned int nsettings;
823 	const struct cxm_saa7115_setting *settings;
824 
825 	for (i = 0; NUM_ELEMENTS(saa7115_scalings); i++)
826 		if (saa7115_scalings[i].width == width
827 		    && saa7115_scalings[i].height == height
828 		    && saa7115_scalings[i].fps == fps)
829 			break;
830 
831 	if (i >= NUM_ELEMENTS(saa7115_scalings))
832 		return -1;
833 
834 	nsettings = saa7115_scalings[i].scaling->nsettings;
835 	settings = saa7115_scalings[i].scaling->settings;
836 
837 	/*
838 	 * Reset the scaler.
839 	 */
840 
841 	if (cxm_saa7115_read(sc->iicbus, CXM_I2C_SAA7115, 0x88,
842 			     power, sizeof(power)) != sizeof(power))
843 		return -1;
844 
845 	power[0] &= ~0x20;
846 
847 	if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115, 0x88,
848 			      power, sizeof(power)) != sizeof(power))
849 		return -1;
850 
851 	/*
852 	 * Configure the scaler.
853 	 */
854 
855 	for (i = 0; i < nsettings; i++)
856 		if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115,
857 				      settings[i].addr,
858 				      settings[i].values, settings[i].nvalues)
859 		    != settings[i].nvalues)
860 			return -1;
861 
862 	/*
863 	 * Enable task register set A and B.
864 	 */
865 
866 	if (cxm_saa7115_read(sc->iicbus, CXM_I2C_SAA7115, 0x80,
867 			     task, sizeof(task)) != sizeof(task))
868 		return -1;
869 
870 	task[0] |= 0x30;
871 
872 	if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115, 0x80,
873 			      task, sizeof(task)) != sizeof(task))
874 		return -1;
875 
876 	/*
877 	 * Enable the scaler.
878 	 */
879 
880 	if (cxm_saa7115_read(sc->iicbus, CXM_I2C_SAA7115, 0x88,
881 			     power, sizeof(power)) != sizeof(power))
882 		return -1;
883 
884 	power[0] |= 0x20;
885 
886 	if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115, 0x88,
887 			      power, sizeof(power)) != sizeof(power))
888 		return -1;
889 
890 	/*
891 	 * Configure the audio clock.
892 	 */
893 
894 	for (i = 0; NUM_ELEMENTS(saa7115_audio_clock); i++)
895 		if (saa7115_audio_clock[i].sample_rate == audio_sample_rate
896 		    && saa7115_audio_clock[i].fps == fps)
897 			break;
898 
899 	if (i >= NUM_ELEMENTS(saa7115_audio_clock))
900 		return -1;
901 
902 	nsettings = saa7115_audio_clock[i].clock->nsettings;
903 	settings = saa7115_audio_clock[i].clock->settings;
904 
905 	for (i = 0; i < nsettings; i++)
906 		if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115,
907 				      settings[i].addr,
908 				      settings[i].values, settings[i].nvalues)
909 		    != settings[i].nvalues)
910 			return -1;
911 
912 	return 0;
913 }
914 
915 
916 enum cxm_source_format
917 cxm_saa7115_detected_format(struct cxm_softc *sc)
918 {
919 	unsigned char status[2];
920 	enum cxm_source_format source_format;
921 
922 	if (cxm_saa7115_read(sc->iicbus, CXM_I2C_SAA7115, 0x1e,
923 			     status, sizeof(status)) != sizeof(status))
924 		return cxm_unknown_source_format;
925 
926 	if (!(status[1] & 0x01)) {
927 		device_printf(sc->dev, "video decoder isn't locked\n");
928 		return cxm_unknown_source_format;
929 	}
930 
931 	source_format = cxm_unknown_source_format;
932 
933 	if (!(status[1] & 0x20)) {
934 		switch (status[0] & 0x03) {
935 		case 0:
936 			source_format = cxm_bw_50hz_source_format;
937 			break;
938 
939 		case 1:
940 			source_format = cxm_ntsc_50hz_source_format;
941 			break;
942 
943 		case 2:
944 			source_format = cxm_pal_50hz_source_format;
945 			break;
946 
947 		case 3:
948 			source_format = cxm_secam_50hz_source_format;
949 			break;
950 
951 		default:
952 			break;
953 		}
954 	} else {
955 		switch (status[0] & 0x03) {
956 		case 0:
957 			source_format = cxm_bw_60hz_source_format;
958 			break;
959 
960 		case 1:
961 			source_format = cxm_ntsc_60hz_source_format;
962 			break;
963 
964 		case 2:
965 			source_format = cxm_pal_60hz_source_format;
966 			break;
967 
968 		default:
969 			break;
970 		}
971 	}
972 
973 	return source_format;
974 }
975 
976 
977 int
978 cxm_saa7115_detected_fps(struct cxm_softc *sc)
979 {
980 	unsigned char status[1];
981 
982 	if (cxm_saa7115_read(sc->iicbus, CXM_I2C_SAA7115, 0x1f,
983 			     status, sizeof(status)) != sizeof(status))
984 		return -1;
985 
986 	if (!(status[0] & 0x01)) {
987 		device_printf(sc->dev, "video decoder isn't locked\n");
988 		return -1;
989 	}
990 
991 	return (status[0] & 0x20) ? 30 : 25;
992 }
993 
994 
995 int
996 cxm_saa7115_get_brightness(struct cxm_softc *sc)
997 {
998 	unsigned char brightness;
999 
1000 	/*
1001 	 * Brightness is treated as an unsigned value by the decoder.
1002 	 * 0 = dark, 128 = ITU level, 255 = bright
1003 	 */
1004 	if (cxm_saa7115_read(sc->iicbus, CXM_I2C_SAA7115, 0x0a,
1005 			     &brightness, sizeof(brightness))
1006 	    != sizeof(brightness))
1007 		return -1;
1008 
1009 	return brightness;
1010 }
1011 
1012 
1013 int
1014 cxm_saa7115_set_brightness(struct cxm_softc *sc, unsigned char brightness)
1015 {
1016 
1017 	/*
1018 	 * Brightness is treated as an unsigned value by the decoder.
1019 	 * 0 = dark, 128 = ITU level, 255 = bright
1020 	 */
1021 	if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115, 0x0a,
1022 			      &brightness, sizeof(brightness))
1023 	    != sizeof(brightness))
1024 		return -1;
1025 
1026 	return 0;
1027 }
1028 
1029 
1030 int
1031 cxm_saa7115_get_chroma_saturation(struct cxm_softc *sc)
1032 {
1033 	unsigned char chroma_saturation;
1034 
1035 	/*
1036 	 * Chroma saturation is treated as a signed value by the decoder.
1037 	 * -128 = -2.0 (inverse chrominance), -64 = 1.0 (inverse chrominance),
1038 	 * 0 = 0 (color off), 64 = 1.0 (ITU level), 127 = 1.984 (maximum)
1039 	 */
1040 	if (cxm_saa7115_read(sc->iicbus, CXM_I2C_SAA7115, 0x0c,
1041 			     &chroma_saturation, sizeof(chroma_saturation))
1042 	    != sizeof(chroma_saturation))
1043 		return -1;
1044 
1045 	return chroma_saturation;
1046 }
1047 
1048 
1049 int
1050 cxm_saa7115_set_chroma_saturation(struct cxm_softc *sc,
1051 				   unsigned char chroma_saturation)
1052 {
1053 
1054 	/*
1055 	 * Chroma saturation is treated as a signed value by the decoder.
1056 	 * -128 = -2.0 (inverse chrominance), -64 = 1.0 (inverse chrominance),
1057 	 * 0 = 0 (color off), 64 = 1.0 (ITU level), 127 = 1.984 (maximum)
1058 	 */
1059 	if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115, 0x0c,
1060 			      &chroma_saturation, sizeof(chroma_saturation))
1061 	    != sizeof(chroma_saturation))
1062 		return -1;
1063 
1064 	return 0;
1065 }
1066 
1067 
1068 int
1069 cxm_saa7115_get_contrast(struct cxm_softc *sc)
1070 {
1071 	unsigned char contrast;
1072 
1073 	/*
1074 	 * Contrast is treated as a signed value by the decoder.
1075 	 * -128 = -2.0 (inverse luminance), -64 = 1.0 (inverse luminance),
1076 	 * 0 = 0 (luminance off), 64 = 1.0, 68 = 1.063 (ITU level),
1077 	 * 127 = 1.984 (maximum)
1078 	 */
1079 	if (cxm_saa7115_read(sc->iicbus, CXM_I2C_SAA7115, 0x0b,
1080 			     &contrast, sizeof(contrast)) != sizeof(contrast))
1081 		return -1;
1082 
1083 	return contrast;
1084 }
1085 
1086 
1087 int
1088 cxm_saa7115_set_contrast(struct cxm_softc *sc, unsigned char contrast)
1089 {
1090 
1091 	/*
1092 	 * Contrast is treated as a signed value by the decoder.
1093 	 * -128 = -2.0 (inverse luminance), -64 = 1.0 (inverse luminance),
1094 	 * 0 = 0 (luminance off), 64 = 1.0, 68 = 1.063 (ITU level),
1095 	 * 127 = 1.984 (maximum)
1096 	 */
1097 	if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115, 0x0b,
1098 			      &contrast, sizeof(contrast)) != sizeof(contrast))
1099 		return -1;
1100 
1101 	return 0;
1102 }
1103 
1104 
1105 int
1106 cxm_saa7115_get_hue(struct cxm_softc *sc)
1107 {
1108 	unsigned char hue;
1109 
1110 	/*
1111 	 * Hue is treated as a signed value by the decoder.
1112 	 * -128 = -180.0, 0 = 0.0, 127 = +178.6
1113 	 */
1114 	if (cxm_saa7115_read(sc->iicbus, CXM_I2C_SAA7115, 0x0d,
1115 			     &hue, sizeof(hue))
1116 	    != sizeof(hue))
1117 		return -1;
1118 
1119 	return hue;
1120 }
1121 
1122 
1123 int
1124 cxm_saa7115_set_hue(struct cxm_softc *sc, unsigned char hue)
1125 {
1126 
1127 	/*
1128 	 * Hue is treated as a signed value by the decoder.
1129 	 * -128 = -180.0, 0 = 0.0, 127 = +178.6
1130 	 */
1131 	if (cxm_saa7115_write(sc->iicbus, CXM_I2C_SAA7115, 0x0d,
1132 			      &hue, sizeof(hue))
1133 	    != sizeof(hue))
1134 		return -1;
1135 
1136 	return 0;
1137 }
1138 
1139 
1140 int
1141 cxm_saa7115_is_locked(struct cxm_softc *sc)
1142 {
1143 	unsigned char status[1];
1144 
1145 	if (cxm_saa7115_read(sc->iicbus, CXM_I2C_SAA7115, 0x1f,
1146 			     status, sizeof(status)) != sizeof(status))
1147 		return -1;
1148 
1149 	return (status[0] & 0x01) ? 1 : 0;
1150 }
1151 
1152 
1153 int
1154 cxm_saa7115_wait_for_lock(struct cxm_softc *sc)
1155 {
1156 	unsigned int i;
1157 
1158 	/*
1159 	 * Section 2.7 of the data sheet states:
1160 	 *
1161 	 *   Ultra-fast frame lock (almost 1 field)
1162 	 *
1163 	 * so hopefully 500 ms is enough (the lock
1164 	 * sometimes takes a long time to occur ...
1165 	 * possibly due to the time it takes to
1166 	 * autodetect the format).
1167 	 */
1168 
1169 	for (i = 0; i < 10; i++) {
1170 
1171 		/*
1172 		 * The input may have just changed (prior to
1173 		 * cxm_saa7115_wait_for_lock) so start with
1174 		 * the delay to give the video decoder a
1175 		 * chance to update its status.
1176 		 */
1177 
1178 		tsleep(&sc->iicbus, 0, "video", hz / 20);
1179 
1180 		switch (cxm_saa7115_is_locked(sc)) {
1181 		case 1:
1182 			return 1;
1183 
1184 		case 0:
1185 			break;
1186 
1187 		default:
1188 			return -1;
1189 		}
1190 	}
1191 
1192 	device_printf(sc->dev, "video decoder failed to lock\n");
1193 
1194 	return 0;
1195 }
1196