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
cxm_saa7115_reset(device_t iicbus,int i2c_addr)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
cxm_saa7115_read(device_t iicbus,int i2c_addr,unsigned char addr,char * buf,int len)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
cxm_saa7115_write(device_t iicbus,int i2c_addr,unsigned char addr,const char * buf,int len)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
cxm_saa7115_init(struct cxm_softc * sc)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
cxm_saa7115_mute(struct cxm_softc * sc)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
cxm_saa7115_unmute(struct cxm_softc * sc)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
cxm_saa7115_select_source(struct cxm_softc * sc,enum cxm_source source)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
cxm_saa7115_configure(struct cxm_softc * sc,unsigned int width,unsigned int height,unsigned int fps,unsigned int audio_sample_rate)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
cxm_saa7115_detected_format(struct cxm_softc * sc)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
cxm_saa7115_detected_fps(struct cxm_softc * sc)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
cxm_saa7115_get_brightness(struct cxm_softc * sc)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
cxm_saa7115_set_brightness(struct cxm_softc * sc,unsigned char brightness)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
cxm_saa7115_get_chroma_saturation(struct cxm_softc * sc)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
cxm_saa7115_set_chroma_saturation(struct cxm_softc * sc,unsigned char chroma_saturation)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
cxm_saa7115_get_contrast(struct cxm_softc * sc)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
cxm_saa7115_set_contrast(struct cxm_softc * sc,unsigned char contrast)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
cxm_saa7115_get_hue(struct cxm_softc * sc)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
cxm_saa7115_set_hue(struct cxm_softc * sc,unsigned char hue)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
cxm_saa7115_is_locked(struct cxm_softc * sc)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
cxm_saa7115_wait_for_lock(struct cxm_softc * sc)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