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