xref: /dragonfly/sys/dev/video/cxm/cxm_saa7115.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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