171d7fec4Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/saa7114.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ 271d7fec4Smrg/* 371d7fec4Smrg * $Workfile: saa7114.c $ 471d7fec4Smrg * 571d7fec4Smrg * This file contains routines to control the Philips SAA7114 video decoder. 671d7fec4Smrg * 771d7fec4Smrg * NSC_LIC_ALTERNATIVE_PREAMBLE 871d7fec4Smrg * 971d7fec4Smrg * Revision 1.0 1071d7fec4Smrg * 1171d7fec4Smrg * National Semiconductor Alternative GPL-BSD License 1271d7fec4Smrg * 1371d7fec4Smrg * National Semiconductor Corporation licenses this software 1471d7fec4Smrg * ("Software"): 1571d7fec4Smrg * 1671d7fec4Smrg * Durango 1771d7fec4Smrg * 1871d7fec4Smrg * under one of the two following licenses, depending on how the 1971d7fec4Smrg * Software is received by the Licensee. 2071d7fec4Smrg * 2171d7fec4Smrg * If this Software is received as part of the Linux Framebuffer or 2271d7fec4Smrg * other GPL licensed software, then the GPL license designated 2371d7fec4Smrg * NSC_LIC_GPL applies to this Software; in all other circumstances 2471d7fec4Smrg * then the BSD-style license designated NSC_LIC_BSD shall apply. 2571d7fec4Smrg * 2671d7fec4Smrg * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ 2771d7fec4Smrg 2871d7fec4Smrg/* NSC_LIC_BSD 2971d7fec4Smrg * 3071d7fec4Smrg * National Semiconductor Corporation Open Source License for Durango 3171d7fec4Smrg * 3271d7fec4Smrg * (BSD License with Export Notice) 3371d7fec4Smrg * 3471d7fec4Smrg * Copyright (c) 1999-2001 3571d7fec4Smrg * National Semiconductor Corporation. 3671d7fec4Smrg * All rights reserved. 3771d7fec4Smrg * 3871d7fec4Smrg * Redistribution and use in source and binary forms, with or without 3971d7fec4Smrg * modification, are permitted provided that the following conditions 4071d7fec4Smrg * are met: 4171d7fec4Smrg * 4271d7fec4Smrg * * Redistributions of source code must retain the above copyright 4371d7fec4Smrg * notice, this list of conditions and the following disclaimer. 4471d7fec4Smrg * 4571d7fec4Smrg * * Redistributions in binary form must reproduce the above 4671d7fec4Smrg * copyright notice, this list of conditions and the following 4771d7fec4Smrg * disclaimer in the documentation and/or other materials provided 4871d7fec4Smrg * with the distribution. 4971d7fec4Smrg * 5071d7fec4Smrg * * Neither the name of the National Semiconductor Corporation nor 5171d7fec4Smrg * the names of its contributors may be used to endorse or promote 5271d7fec4Smrg * products derived from this software without specific prior 5371d7fec4Smrg * written permission. 5471d7fec4Smrg * 5571d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 5671d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 5771d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 5871d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 5971d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 6071d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 6171d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 6271d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 6371d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 6471d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 6571d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 6671d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 6771d7fec4Smrg * OF SUCH DAMAGE. 6871d7fec4Smrg * 6971d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 7071d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with 7171d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under 7271d7fec4Smrg * CURRENT (2001) U.S. export regulations this software 7371d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or 7471d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 7571d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 7671d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S. 7771d7fec4Smrg * has embargoed goods and services. 7871d7fec4Smrg * 7971d7fec4Smrg * END_NSC_LIC_BSD */ 8071d7fec4Smrg 8171d7fec4Smrg/* NSC_LIC_GPL 8271d7fec4Smrg * 8371d7fec4Smrg * National Semiconductor Corporation Gnu General Public License for Durango 8471d7fec4Smrg * 8571d7fec4Smrg * (GPL License with Export Notice) 8671d7fec4Smrg * 8771d7fec4Smrg * Copyright (c) 1999-2001 8871d7fec4Smrg * National Semiconductor Corporation. 8971d7fec4Smrg * All rights reserved. 9071d7fec4Smrg * 9171d7fec4Smrg * Redistribution and use in source and binary forms, with or without 9271d7fec4Smrg * modification, are permitted under the terms of the GNU General 9371d7fec4Smrg * Public License as published by the Free Software Foundation; either 9471d7fec4Smrg * version 2 of the License, or (at your option) any later version 9571d7fec4Smrg * 9671d7fec4Smrg * In addition to the terms of the GNU General Public License, neither 9771d7fec4Smrg * the name of the National Semiconductor Corporation nor the names of 9871d7fec4Smrg * its contributors may be used to endorse or promote products derived 9971d7fec4Smrg * from this software without specific prior written permission. 10071d7fec4Smrg * 10171d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 10271d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 10371d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 10471d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 10571d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 10671d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 10771d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 10871d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 10971d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 11071d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 11171d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 11271d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 11371d7fec4Smrg * OF SUCH DAMAGE. See the GNU General Public License for more details. 11471d7fec4Smrg * 11571d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 11671d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with 11771d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under 11871d7fec4Smrg * CURRENT (2001) U.S. export regulations this software 11971d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or 12071d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 12171d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 12271d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S. 12371d7fec4Smrg * has embargoed goods and services. 12471d7fec4Smrg * 12571d7fec4Smrg * You should have received a copy of the GNU General Public License 12671d7fec4Smrg * along with this file; if not, write to the Free Software Foundation, 12771d7fec4Smrg * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 12871d7fec4Smrg * 12971d7fec4Smrg * END_NSC_LIC_GPL */ 13071d7fec4Smrg 13171d7fec4Smrg/*---------------------------*/ 13271d7fec4Smrg/* TABLE OF DEFAULT VALUES */ 13371d7fec4Smrg/*---------------------------*/ 13471d7fec4Smrg 13571d7fec4Smrgtypedef struct tagGFX_SAA7114_INIT 13671d7fec4Smrg{ 13771d7fec4Smrg unsigned char index; 13871d7fec4Smrg unsigned char value; 13971d7fec4Smrg} 14071d7fec4SmrgGFX_SAA7114_INIT; 14171d7fec4Smrg 14271d7fec4Smrg/* Task A is for VBI raw data and task B is for video */ 14371d7fec4Smrg 14471d7fec4SmrgGFX_SAA7114_INIT gfx_saa7114_init_values[] = { 14571d7fec4Smrg {0x01, 0x08}, {0x02, 0xC0}, {0x03, 0x00}, {0x04, 0x90}, 14671d7fec4Smrg {0x05, 0x90}, {0x06, 0xEB}, {0x07, 0xE0}, {0x08, 0x88}, 14771d7fec4Smrg {0x09, 0x40}, {0x0A, 0x80}, {0x0B, 0x44}, {0x0C, 0x40}, 14871d7fec4Smrg {0x0D, 0x00}, {0x0E, 0x89}, {0x0F, 0x2E}, {0x10, 0x0E}, 14971d7fec4Smrg {0x11, 0x00}, {0x12, 0x05}, {0x13, 0x00}, {0x14, 0x08}, 15071d7fec4Smrg {0x15, 0x11}, {0x16, 0xFE}, {0x17, 0x00}, {0x18, 0x40}, 15171d7fec4Smrg {0x19, 0x80}, {0x30, 0xBC}, {0x31, 0xDF}, {0x32, 0x02}, 15271d7fec4Smrg {0x34, 0xCD}, {0x35, 0xCC}, {0x36, 0x3A}, {0x38, 0x03}, 15371d7fec4Smrg {0x39, 0x10}, {0x3A, 0x00}, {0x40, 0x00}, {0x41, 0xFF}, 15471d7fec4Smrg {0x42, 0xFF}, {0x43, 0xFF}, {0x44, 0xFF}, {0x45, 0xFF}, 15571d7fec4Smrg {0x46, 0xFF}, {0x47, 0xFF}, {0x48, 0xFF}, {0x49, 0xFF}, 15671d7fec4Smrg {0x4A, 0xFF}, {0x4B, 0xFF}, {0x4C, 0xFF}, {0x4D, 0xFF}, 15771d7fec4Smrg {0x4E, 0xFF}, {0x4F, 0xFF}, {0x50, 0xFF}, {0x51, 0xFF}, 15871d7fec4Smrg {0x52, 0xFF}, {0x53, 0xFF}, {0x54, 0xFF}, {0x55, 0xFF}, 15971d7fec4Smrg {0x56, 0xFF}, {0x57, 0xFF}, {0x58, 0x00}, {0x59, 0x47}, 16071d7fec4Smrg {0x5A, 0x06}, {0x5B, 0x43}, {0x5D, 0x3E}, {0x5E, 0x00}, 16171d7fec4Smrg {0x80, 0x30}, {0x83, 0x00}, {0x84, 0x60}, {0x85, 0x00}, 16271d7fec4Smrg {0x86, 0xE5}, {0x87, 0x01}, {0x88, 0xF8}, 16371d7fec4Smrg 16471d7fec4Smrg /* VBI task */ 16571d7fec4Smrg 16671d7fec4Smrg {0x90, 0x01}, {0x91, 0xC8}, {0x92, 0x08}, {0x93, 0x84}, 16771d7fec4Smrg {0x94, 0x10}, {0x95, 0x00}, {0x96, 0xD0}, {0x97, 0x02}, 16871d7fec4Smrg {0x98, 0x05}, {0x99, 0x00}, {0x9A, 0x0B}, {0x9B, 0x00}, 16971d7fec4Smrg {0x9C, 0xA0}, {0x9D, 0x05}, {0x9E, 0x0B}, {0x9F, 0x00}, 17071d7fec4Smrg {0xA0, 0x01}, {0xA1, 0x00}, {0xA2, 0x00}, {0xA4, 0x80}, 17171d7fec4Smrg {0xA5, 0x40}, {0xA6, 0x40}, {0xA8, 0x00}, {0xA9, 0x02}, 17271d7fec4Smrg {0xAA, 0x00}, {0xAC, 0x00}, {0xAD, 0x01}, {0xAE, 0x00}, 17371d7fec4Smrg {0xB0, 0x00}, {0xB1, 0x04}, {0xB2, 0x00}, {0xB3, 0x04}, 17471d7fec4Smrg {0xB4, 0x00}, {0xB8, 0x00}, {0xB9, 0x00}, {0xBA, 0x00}, 17571d7fec4Smrg {0xBB, 0x00}, {0xBC, 0x00}, {0xBD, 0x00}, {0xBE, 0x00}, 17671d7fec4Smrg {0xBF, 0x00}, 17771d7fec4Smrg 17871d7fec4Smrg /* Video task */ 17971d7fec4Smrg 18071d7fec4Smrg {0xC0, 0x80}, {0xC1, 0x08}, {0xC2, 0x00}, {0xC3, 0x80}, 18171d7fec4Smrg {0xC4, 0x10}, {0xC5, 0x00}, {0xC6, 0xD0}, {0xC7, 0x02}, 18271d7fec4Smrg {0xC8, 0x11}, {0xC9, 0x00}, {0xCA, 0xF1}, {0xCB, 0x00}, 18371d7fec4Smrg {0xCC, 0xD0}, {0xCD, 0x02}, {0xCE, 0xF1}, {0xCF, 0x00}, 18471d7fec4Smrg {0xD0, 0x01}, {0xD1, 0x00}, {0xD2, 0x00}, {0xD4, 0x80}, 18571d7fec4Smrg {0xD5, 0x40}, {0xD6, 0x40}, {0xD8, 0x00}, {0xD9, 0x04}, 18671d7fec4Smrg {0xDA, 0x00}, {0xDC, 0x00}, {0xDD, 0x02}, {0xDE, 0x00}, 18771d7fec4Smrg {0xE0, 0x00}, {0xE1, 0x04}, {0xE2, 0x00}, {0xE3, 0x04}, 18871d7fec4Smrg {0xE4, 0x00}, {0xE8, 0x00}, {0xE9, 0x00}, {0xEA, 0x00}, 18971d7fec4Smrg {0xEB, 0x00}, {0xEC, 0x00}, {0xED, 0x00}, {0xEE, 0x00}, 19071d7fec4Smrg {0xEF, 0x00}, 19171d7fec4Smrg}; 19271d7fec4Smrg 19371d7fec4Smrg#define GFX_NUM_SAA7114_INIT_VALUES sizeof(gfx_saa7114_init_values)/sizeof(GFX_SAA7114_INIT) 19471d7fec4Smrg 19571d7fec4Smrg/*-----------------------------------------------------*/ 19671d7fec4Smrg/* TABLE OF FIR PREFILTER RECOMMENDED VALUES */ 19771d7fec4Smrg/*-----------------------------------------------------*/ 19871d7fec4Smrg 19971d7fec4Smrgint optimize_for_aliasing = 0; 20071d7fec4Smrg 20171d7fec4Smrgtypedef struct tagGFX_SAA7114_FIR_PREFILTER 20271d7fec4Smrg{ 20371d7fec4Smrg unsigned char prescaler; 20471d7fec4Smrg unsigned char acl_low; 20571d7fec4Smrg unsigned char prefilter_low; 20671d7fec4Smrg unsigned char acl_high; 20771d7fec4Smrg unsigned char prefilter_high; 20871d7fec4Smrg} 20971d7fec4SmrgGFX_SAA7114_FIR_PREFILTER; 21071d7fec4Smrg 21171d7fec4SmrgGFX_SAA7114_FIR_PREFILTER gfx_saa7114_fir_values[] = { 21271d7fec4Smrg {0x01, 0x00, 0x00, 0x00, 0x00}, {0x02, 0x02, 0x5A, 0x01, 0x51}, 21371d7fec4Smrg {0x03, 0x04, 0xAB, 0x03, 0xA2}, {0x04, 0x07, 0xA3, 0x04, 0xAB}, 21471d7fec4Smrg {0x05, 0x08, 0xAC, 0x07, 0xA3}, {0x06, 0x08, 0xFC, 0x07, 0xF3}, 21571d7fec4Smrg {0x07, 0x08, 0xFC, 0x07, 0xF3}, {0x08, 0x0F, 0xF4, 0x08, 0xFC}, 21671d7fec4Smrg {0x09, 0x0F, 0xF4, 0x08, 0xFC}, {0x0A, 0x10, 0xFD, 0x08, 0xFC}, 21771d7fec4Smrg {0x0B, 0x10, 0xFD, 0x08, 0xFC}, {0x0C, 0x10, 0xFD, 0x08, 0xFC}, 21871d7fec4Smrg {0x0D, 0x10, 0xFD, 0x10, 0xFD}, {0x0E, 0x10, 0xFD, 0x10, 0xFD}, 21971d7fec4Smrg {0x0F, 0x1F, 0xF5, 0x10, 0xFD}, {0x10, 0x20, 0xFE, 0x10, 0xFD}, 22071d7fec4Smrg {0x11, 0x20, 0xFE, 0x10, 0xFD}, {0x12, 0x20, 0xFE, 0x10, 0xFD}, 22171d7fec4Smrg {0x13, 0x20, 0xFE, 0x20, 0xFE}, {0x14, 0x20, 0xFE, 0x20, 0xFE}, 22271d7fec4Smrg {0x15, 0x20, 0xFE, 0x20, 0xFE}, {0x16, 0x20, 0xFE, 0x20, 0xFE}, 22371d7fec4Smrg {0x17, 0x20, 0xFE, 0x20, 0xFE}, {0x18, 0x20, 0xFE, 0x20, 0xFE}, 22471d7fec4Smrg {0x19, 0x20, 0xFE, 0x20, 0xFE}, {0x1A, 0x20, 0xFE, 0x20, 0xFE}, 22571d7fec4Smrg {0x1B, 0x20, 0xFE, 0x20, 0xFE}, {0x1C, 0x20, 0xFE, 0x20, 0xFE}, 22671d7fec4Smrg {0x1D, 0x20, 0xFE, 0x20, 0xFE}, {0x1E, 0x20, 0xFE, 0x20, 0xFE}, 22771d7fec4Smrg {0x1F, 0x20, 0xFE, 0x20, 0xFE}, {0x20, 0x3F, 0xFF, 0x20, 0xFE}, 22871d7fec4Smrg {0x21, 0x3F, 0xFF, 0x20, 0xFE}, {0x22, 0x3F, 0xFF, 0x20, 0xFE}, 22971d7fec4Smrg {0x23, 0x3F, 0xFF, 0x20, 0xFF} 23071d7fec4Smrg}; 23171d7fec4Smrg 23271d7fec4Smrgint saa7114_set_decoder_defaults(void); 23371d7fec4Smrgint saa7114_set_decoder_analog_input(unsigned char input); 23471d7fec4Smrgint saa7114_set_decoder_brightness(unsigned char brightness); 23571d7fec4Smrgint saa7114_set_decoder_contrast(unsigned char contrast); 23671d7fec4Smrgint saa7114_set_decoder_hue(char hue); 23771d7fec4Smrgint saa7114_set_decoder_saturation(unsigned char saturation); 23871d7fec4Smrgint saa7114_set_decoder_input_offset(unsigned short x, unsigned short y); 23971d7fec4Smrgint saa7114_set_decoder_input_size(unsigned short width, 24071d7fec4Smrg unsigned short height); 24171d7fec4Smrgint saa7114_set_decoder_output_size(unsigned short width, 24271d7fec4Smrg unsigned short height); 24371d7fec4Smrgint saa7114_set_decoder_scale(unsigned short srcw, unsigned short srch, 24471d7fec4Smrg unsigned short dstw, unsigned short dsth); 24571d7fec4Smrgint saa7114_set_decoder_vbi_format(int start, int end, int format); 24671d7fec4Smrgint saa7114_set_decoder_vbi_enable(int enable); 24771d7fec4Smrgint saa7114_set_decoder_vbi_upscale(void); 24871d7fec4Smrgint saa7114_set_decoder_TV_standard(TVStandardType TVStandard); 24971d7fec4Smrgint saa7114_set_decoder_luminance_filter(unsigned char lufi); 25071d7fec4Smrgint saa7114_decoder_software_reset(void); 25171d7fec4Smrgint saa7114_decoder_detect_macrovision(void); 25271d7fec4Smrgint saa7114_decoder_detect_video(void); 25371d7fec4Smrg 25471d7fec4Smrg/* READ ROUTINES IN GFX_DCDR.C */ 25571d7fec4Smrg 25671d7fec4Smrgunsigned char saa7114_get_decoder_brightness(void); 25771d7fec4Smrgunsigned char saa7114_get_decoder_contrast(void); 25871d7fec4Smrgchar saa7114_get_decoder_hue(void); 25971d7fec4Smrgunsigned char saa7114_get_decoder_saturation(void); 26071d7fec4Smrgunsigned long saa7114_get_decoder_input_offset(void); 26171d7fec4Smrgunsigned long saa7114_get_decoder_input_size(void); 26271d7fec4Smrgunsigned long saa7114_get_decoder_output_size(void); 26371d7fec4Smrgint saa7114_get_decoder_vbi_format(int line); 26471d7fec4Smrgint saa7114_write_reg(unsigned char reg, unsigned char val); 26571d7fec4Smrgint saa7114_read_reg(unsigned char reg, unsigned char *val); 26671d7fec4Smrg 26771d7fec4Smrgint 26871d7fec4Smrgsaa7114_write_reg(unsigned char reg, unsigned char val) 26971d7fec4Smrg{ 27071d7fec4Smrg return gfx_i2c_write(2, SAA7114_CHIPADDR, reg, 1, &val); 27171d7fec4Smrg} 27271d7fec4Smrg 27371d7fec4Smrgint 27471d7fec4Smrgsaa7114_read_reg(unsigned char reg, unsigned char *val) 27571d7fec4Smrg{ 27671d7fec4Smrg return gfx_i2c_read(2, SAA7114_CHIPADDR, reg, 1, val); 27771d7fec4Smrg} 27871d7fec4Smrg 27971d7fec4Smrg/*----------------------------------------------------------------------------- 28071d7fec4Smrg * gfx_set_decoder_vbi_upscale 28171d7fec4Smrg * 28271d7fec4Smrg * This routine configures the video decoder task A to upscale raw VBI data 28371d7fec4Smrg * horizontally to match a different system clock. 28471d7fec4Smrg * The upscale is from 13.5 MHz (SAA7114) to 14.318 MHz (Bt835). 28571d7fec4Smrg *----------------------------------------------------------------------------- 28671d7fec4Smrg */ 28771d7fec4Smrg#if GFX_DECODER_DYNAMIC 28871d7fec4Smrgint 28971d7fec4Smrgsaa7114_set_decoder_vbi_upscale(void) 29071d7fec4Smrg#else 29171d7fec4Smrgint 29271d7fec4Smrggfx_set_decoder_vbi_upscale(void) 29371d7fec4Smrg#endif 29471d7fec4Smrg{ 29571d7fec4Smrg /* Set horizontal output length to 1528 (720 * 2 * 14.318 / 13.5) */ 29671d7fec4Smrg saa7114_write_reg(SAA7114_TASK_A_HORZ_OUTPUT_LO, 0xF8); 29771d7fec4Smrg saa7114_write_reg(SAA7114_TASK_A_HORZ_OUTPUT_HI, 0x05); 29871d7fec4Smrg 29971d7fec4Smrg /* Set horizontal luminance scaling increment to 484 (1024 * 13.5 / 28.636) */ 30071d7fec4Smrg saa7114_write_reg(SAA7114_TASK_A_HSCALE_LUMA_LO, 0xE4); 30171d7fec4Smrg saa7114_write_reg(SAA7114_TASK_A_HSCALE_LUMA_HI, 0x01); 30271d7fec4Smrg 30371d7fec4Smrg /* Set horizontal chrominance scaling increment to 242 */ 30471d7fec4Smrg saa7114_write_reg(SAA7114_TASK_A_HSCALE_CHROMA_LO, 0xF2); 30571d7fec4Smrg saa7114_write_reg(SAA7114_TASK_A_HSCALE_CHROMA_HI, 0x00); 30671d7fec4Smrg 30771d7fec4Smrg return GFX_STATUS_OK; 30871d7fec4Smrg} 30971d7fec4Smrg 31071d7fec4Smrg/*----------------------------------------------------------------------------- 31171d7fec4Smrg * gfx_decoder_software_reset 31271d7fec4Smrg * 31371d7fec4Smrg * This routine performs a software reset of the decoder. 31471d7fec4Smrg *----------------------------------------------------------------------------- 31571d7fec4Smrg */ 31671d7fec4Smrg#if GFX_DECODER_DYNAMIC 31771d7fec4Smrgint 31871d7fec4Smrgsaa7114_decoder_software_reset(void) 31971d7fec4Smrg#else 32071d7fec4Smrgint 32171d7fec4Smrggfx_decoder_software_reset(void) 32271d7fec4Smrg#endif 32371d7fec4Smrg{ 32471d7fec4Smrg saa7114_write_reg(0x88, 0xC0); 32571d7fec4Smrg /* I2C-bus latency should be sufficient for resetting the internal state machine. */ 32671d7fec4Smrg /* gfx_delay_milliseconds(10); */ 32771d7fec4Smrg saa7114_write_reg(0x88, 0xF0); 32871d7fec4Smrg return GFX_STATUS_OK; 32971d7fec4Smrg} 33071d7fec4Smrg 33171d7fec4Smrg/*----------------------------------------------------------------------------- 33271d7fec4Smrg * gfx_decoder_detect_macrovision 33371d7fec4Smrg * 33471d7fec4Smrg * This routine detects if macrovision exists in the input of the video decoder. 33571d7fec4Smrg *----------------------------------------------------------------------------- 33671d7fec4Smrg */ 33771d7fec4Smrg#if GFX_DECODER_DYNAMIC 33871d7fec4Smrgint 33971d7fec4Smrgsaa7114_decoder_detect_macrovision(void) 34071d7fec4Smrg#else 34171d7fec4Smrgint 34271d7fec4Smrggfx_decoder_detect_macrovision(void) 34371d7fec4Smrg#endif 34471d7fec4Smrg{ 34571d7fec4Smrg unsigned char macrovision = 0xff; 34671d7fec4Smrg 34771d7fec4Smrg saa7114_read_reg(SAA7114_STATUS, ¯ovision); 34871d7fec4Smrg return ((macrovision & 0x02) >> 1); 34971d7fec4Smrg} 35071d7fec4Smrg 35171d7fec4Smrg/*----------------------------------------------------------------------------- 35271d7fec4Smrg * gfx_decoder_detect_video 35371d7fec4Smrg * 35471d7fec4Smrg * This routine detects if video exists in the input of the video decoder. 35571d7fec4Smrg *----------------------------------------------------------------------------- 35671d7fec4Smrg */ 35771d7fec4Smrg#if GFX_DECODER_DYNAMIC 35871d7fec4Smrgint 35971d7fec4Smrgsaa7114_decoder_detect_video(void) 36071d7fec4Smrg#else 36171d7fec4Smrgint 36271d7fec4Smrggfx_decoder_detect_video(void) 36371d7fec4Smrg#endif 36471d7fec4Smrg{ 36571d7fec4Smrg unsigned char video = 0xff; 36671d7fec4Smrg 36771d7fec4Smrg saa7114_read_reg(SAA7114_STATUS, &video); 36871d7fec4Smrg return !((video & 0x40) >> 6); 36971d7fec4Smrg} 37071d7fec4Smrg 37171d7fec4Smrg/*----------------------------------------------------------------------------- 37271d7fec4Smrg * gfx_set_decoder_defaults 37371d7fec4Smrg * 37471d7fec4Smrg * This routine is called to set the initial register values of the 37571d7fec4Smrg * video decoder. 37671d7fec4Smrg *----------------------------------------------------------------------------- 37771d7fec4Smrg */ 37871d7fec4Smrg#if GFX_DECODER_DYNAMIC 37971d7fec4Smrgint 38071d7fec4Smrgsaa7114_set_decoder_defaults(void) 38171d7fec4Smrg#else 38271d7fec4Smrgint 38371d7fec4Smrggfx_set_decoder_defaults(void) 38471d7fec4Smrg#endif 38571d7fec4Smrg{ 38671d7fec4Smrg unsigned int i; 38771d7fec4Smrg 38871d7fec4Smrg /* LOOP THROUGH INDEX/DATA PAIRS IN THE TABLE */ 38971d7fec4Smrg 39071d7fec4Smrg for (i = 0; i < GFX_NUM_SAA7114_INIT_VALUES; i++) { 39171d7fec4Smrg saa7114_write_reg(gfx_saa7114_init_values[i].index, 39271d7fec4Smrg gfx_saa7114_init_values[i].value); 39371d7fec4Smrg } 39471d7fec4Smrg 39571d7fec4Smrg gfx_decoder_software_reset(); 39671d7fec4Smrg return (0); 39771d7fec4Smrg} 39871d7fec4Smrg 39971d7fec4Smrg/*----------------------------------------------------------------------------- 40071d7fec4Smrg * gfx_set_decoder_analog_input 40171d7fec4Smrg * 40271d7fec4Smrg * This routine sets the analog input of the video decoder. 40371d7fec4Smrg *----------------------------------------------------------------------------- 40471d7fec4Smrg */ 40571d7fec4Smrg#if GFX_DECODER_DYNAMIC 40671d7fec4Smrgint 40771d7fec4Smrgsaa7114_set_decoder_analog_input(unsigned char input) 40871d7fec4Smrg#else 40971d7fec4Smrgint 41071d7fec4Smrggfx_set_decoder_analog_input(unsigned char input) 41171d7fec4Smrg#endif 41271d7fec4Smrg{ 41371d7fec4Smrg saa7114_write_reg(SAA7114_ANALOG_INPUT_CTRL1, input); 41471d7fec4Smrg return (0); 41571d7fec4Smrg} 41671d7fec4Smrg 41771d7fec4Smrg/*----------------------------------------------------------------------------- 41871d7fec4Smrg * gfx_set_decoder_brightness 41971d7fec4Smrg * 42071d7fec4Smrg * This routine sets the brightness of the video decoder. 42171d7fec4Smrg *----------------------------------------------------------------------------- 42271d7fec4Smrg */ 42371d7fec4Smrg#if GFX_DECODER_DYNAMIC 42471d7fec4Smrgint 42571d7fec4Smrgsaa7114_set_decoder_brightness(unsigned char brightness) 42671d7fec4Smrg#else 42771d7fec4Smrgint 42871d7fec4Smrggfx_set_decoder_brightness(unsigned char brightness) 42971d7fec4Smrg#endif 43071d7fec4Smrg{ 43171d7fec4Smrg saa7114_write_reg(SAA7114_BRIGHTNESS, brightness); 43271d7fec4Smrg return (0); 43371d7fec4Smrg} 43471d7fec4Smrg 43571d7fec4Smrg/*----------------------------------------------------------------------------- 43671d7fec4Smrg * gfx_set_decoder_contrast 43771d7fec4Smrg * 43871d7fec4Smrg * This routine sets the contrast of the video decoder. 43971d7fec4Smrg *----------------------------------------------------------------------------- 44071d7fec4Smrg */ 44171d7fec4Smrg#if GFX_DECODER_DYNAMIC 44271d7fec4Smrgint 44371d7fec4Smrgsaa7114_set_decoder_contrast(unsigned char contrast) 44471d7fec4Smrg#else 44571d7fec4Smrgint 44671d7fec4Smrggfx_set_decoder_contrast(unsigned char contrast) 44771d7fec4Smrg#endif 44871d7fec4Smrg{ 44971d7fec4Smrg saa7114_write_reg(SAA7114_CONTRAST, (unsigned char)(contrast >> 1)); 45071d7fec4Smrg return (0); 45171d7fec4Smrg} 45271d7fec4Smrg 45371d7fec4Smrg/*----------------------------------------------------------------------------- 45471d7fec4Smrg * gfx_set_decoder_hue 45571d7fec4Smrg * 45671d7fec4Smrg * This routine sets the hue control of the video decoder. 45771d7fec4Smrg *----------------------------------------------------------------------------- 45871d7fec4Smrg */ 45971d7fec4Smrg#if GFX_DECODER_DYNAMIC 46071d7fec4Smrgint 46171d7fec4Smrgsaa7114_set_decoder_hue(char hue) 46271d7fec4Smrg#else 46371d7fec4Smrgint 46471d7fec4Smrggfx_set_decoder_hue(char hue) 46571d7fec4Smrg#endif 46671d7fec4Smrg{ 46771d7fec4Smrg saa7114_write_reg(SAA7114_HUE, (unsigned char)hue); 46871d7fec4Smrg return (0); 46971d7fec4Smrg} 47071d7fec4Smrg 47171d7fec4Smrg/*----------------------------------------------------------------------------- 47271d7fec4Smrg * gfx_set_decoder_saturation 47371d7fec4Smrg * 47471d7fec4Smrg * This routine sets the saturation adjustment of the video decoder. 47571d7fec4Smrg *----------------------------------------------------------------------------- 47671d7fec4Smrg */ 47771d7fec4Smrg#if GFX_DECODER_DYNAMIC 47871d7fec4Smrgint 47971d7fec4Smrgsaa7114_set_decoder_saturation(unsigned char saturation) 48071d7fec4Smrg#else 48171d7fec4Smrgint 48271d7fec4Smrggfx_set_decoder_saturation(unsigned char saturation) 48371d7fec4Smrg#endif 48471d7fec4Smrg{ 48571d7fec4Smrg saa7114_write_reg(SAA7114_SATURATION, (unsigned char)(saturation >> 1)); 48671d7fec4Smrg return (0); 48771d7fec4Smrg} 48871d7fec4Smrg 48971d7fec4Smrg/*----------------------------------------------------------------------------- 49071d7fec4Smrg * gfx_set_decoder_input_offset 49171d7fec4Smrg * 49271d7fec4Smrg * This routine sets the size of the decoder input window. 49371d7fec4Smrg *----------------------------------------------------------------------------- 49471d7fec4Smrg */ 49571d7fec4Smrg#if GFX_DECODER_DYNAMIC 49671d7fec4Smrgint 49771d7fec4Smrgsaa7114_set_decoder_input_offset(unsigned short x, unsigned short y) 49871d7fec4Smrg#else 49971d7fec4Smrgint 50071d7fec4Smrggfx_set_decoder_input_offset(unsigned short x, unsigned short y) 50171d7fec4Smrg#endif 50271d7fec4Smrg{ 50371d7fec4Smrg /* SET THE INPUT WINDOW OFFSET */ 50471d7fec4Smrg 50571d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_OFFSET_LO, (unsigned char)(x & 0x00FF)); 50671d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_OFFSET_HI, (unsigned char)(x >> 8)); 50771d7fec4Smrg saa7114_write_reg(SAA7114_VERT_OFFSET_LO, (unsigned char)(y & 0x00FF)); 50871d7fec4Smrg saa7114_write_reg(SAA7114_VERT_OFFSET_HI, (unsigned char)(y >> 8)); 50971d7fec4Smrg 51071d7fec4Smrg gfx_decoder_software_reset(); 51171d7fec4Smrg return (0); 51271d7fec4Smrg} 51371d7fec4Smrg 51471d7fec4Smrg/*----------------------------------------------------------------------------- 51571d7fec4Smrg * gfx_set_decoder_input_size 51671d7fec4Smrg * 51771d7fec4Smrg * This routine sets the size of the decoder input window. 51871d7fec4Smrg *----------------------------------------------------------------------------- 51971d7fec4Smrg */ 52071d7fec4Smrg#if GFX_DECODER_DYNAMIC 52171d7fec4Smrgint 52271d7fec4Smrgsaa7114_set_decoder_input_size(unsigned short width, unsigned short height) 52371d7fec4Smrg#else 52471d7fec4Smrgint 52571d7fec4Smrggfx_set_decoder_input_size(unsigned short width, unsigned short height) 52671d7fec4Smrg#endif 52771d7fec4Smrg{ 52871d7fec4Smrg /* DIVIDE HEIGHT BY TWO FOR INTERLACING */ 52971d7fec4Smrg 53071d7fec4Smrg height = (height + 1) >> 1; 53171d7fec4Smrg 53271d7fec4Smrg /* SET THE INPUT WINDOW SIZE */ 53371d7fec4Smrg 53471d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_INPUT_LO, (unsigned char)(width & 0x00FF)); 53571d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_INPUT_HI, (unsigned char)(width >> 8)); 53671d7fec4Smrg saa7114_write_reg(SAA7114_VERT_INPUT_LO, (unsigned char)(height & 0x00FF)); 53771d7fec4Smrg saa7114_write_reg(SAA7114_VERT_INPUT_HI, (unsigned char)(height >> 8)); 53871d7fec4Smrg 53971d7fec4Smrg gfx_decoder_software_reset(); 54071d7fec4Smrg return (0); 54171d7fec4Smrg} 54271d7fec4Smrg 54371d7fec4Smrg/*----------------------------------------------------------------------------- 54471d7fec4Smrg * gfx_set_decoder_output_size 54571d7fec4Smrg * 54671d7fec4Smrg * This routine sets the size of the decoder output window. 54771d7fec4Smrg *----------------------------------------------------------------------------- 54871d7fec4Smrg */ 54971d7fec4Smrg#if GFX_DECODER_DYNAMIC 55071d7fec4Smrgint 55171d7fec4Smrgsaa7114_set_decoder_output_size(unsigned short width, unsigned short height) 55271d7fec4Smrg#else 55371d7fec4Smrgint 55471d7fec4Smrggfx_set_decoder_output_size(unsigned short width, unsigned short height) 55571d7fec4Smrg#endif 55671d7fec4Smrg{ 55771d7fec4Smrg /* ROUND WIDTH UP TO EVEN NUMBER TO PREVENT DECODER BECOMING STUCK */ 55871d7fec4Smrg 55971d7fec4Smrg width = ((width + 1) >> 1) << 1; 56071d7fec4Smrg 56171d7fec4Smrg /* DIVIDE HEIGHT BY TWO FOR INTERLACING */ 56271d7fec4Smrg 56371d7fec4Smrg height = (height + 1) >> 1; 56471d7fec4Smrg 56571d7fec4Smrg /* SET THE OUTPUT WINDOW SIZE */ 56671d7fec4Smrg 56771d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_OUTPUT_LO, (unsigned char)(width & 0x00FF)); 56871d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_OUTPUT_HI, (unsigned char)(width >> 8)); 56971d7fec4Smrg saa7114_write_reg(SAA7114_VERT_OUTPUT_LO, 57071d7fec4Smrg (unsigned char)(height & 0x00FF)); 57171d7fec4Smrg saa7114_write_reg(SAA7114_VERT_OUTPUT_HI, (unsigned char)(height >> 8)); 57271d7fec4Smrg 57371d7fec4Smrg gfx_decoder_software_reset(); 57471d7fec4Smrg return (0); 57571d7fec4Smrg} 57671d7fec4Smrg 57771d7fec4Smrg/*----------------------------------------------------------------------------- 57871d7fec4Smrg * gfx_set_decoder_scale 57971d7fec4Smrg * 58071d7fec4Smrg * This routine sets the scaling of the video decoder. 58171d7fec4Smrg *----------------------------------------------------------------------------- 58271d7fec4Smrg */ 58371d7fec4Smrg#if GFX_DECODER_DYNAMIC 58471d7fec4Smrgint 58571d7fec4Smrgsaa7114_set_decoder_scale(unsigned short srcw, unsigned short srch, 58671d7fec4Smrg unsigned short dstw, unsigned short dsth) 58771d7fec4Smrg#else 58871d7fec4Smrgint 58971d7fec4Smrggfx_set_decoder_scale(unsigned short srcw, unsigned short srch, 59071d7fec4Smrg unsigned short dstw, unsigned short dsth) 59171d7fec4Smrg#endif 59271d7fec4Smrg{ 59371d7fec4Smrg unsigned char prescale = 0; 59471d7fec4Smrg int scale = 0; 59571d7fec4Smrg 59671d7fec4Smrg /* SET THE HORIZONTAL PRESCALE */ 59771d7fec4Smrg /* Downscale from 1 to 1/63 source size. */ 59871d7fec4Smrg 59971d7fec4Smrg if (dstw) 60071d7fec4Smrg prescale = (unsigned char)(srcw / dstw); 60171d7fec4Smrg if (!prescale) 60271d7fec4Smrg prescale = 1; 60371d7fec4Smrg if (prescale > 63) 60471d7fec4Smrg return (1); 60571d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_PRESCALER, prescale); 60671d7fec4Smrg 60771d7fec4Smrg /* USE FIR PREFILTER FUNCTIONALITY (OPTIMISATION) */ 60871d7fec4Smrg 60971d7fec4Smrg if (prescale < 36) { 61071d7fec4Smrg if (optimize_for_aliasing) { 61171d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_ACL, 61271d7fec4Smrg gfx_saa7114_fir_values[prescale - 1].acl_low); 61371d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER, 61471d7fec4Smrg gfx_saa7114_fir_values[prescale - 61571d7fec4Smrg 1].prefilter_low); 61671d7fec4Smrg } else { 61771d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_ACL, 61871d7fec4Smrg gfx_saa7114_fir_values[prescale - 1].acl_high); 61971d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER, 62071d7fec4Smrg gfx_saa7114_fir_values[prescale - 62171d7fec4Smrg 1].prefilter_high); 62271d7fec4Smrg } 62371d7fec4Smrg } else { 62471d7fec4Smrg /* SAME SETTINGS FOR RATIO 1/35 DOWNTO 1/63 */ 62571d7fec4Smrg if (optimize_for_aliasing) { 62671d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_ACL, 62771d7fec4Smrg gfx_saa7114_fir_values[34].acl_low); 62871d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER, 62971d7fec4Smrg gfx_saa7114_fir_values[34].prefilter_low); 63071d7fec4Smrg } else { 63171d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_ACL, 63271d7fec4Smrg gfx_saa7114_fir_values[34].acl_high); 63371d7fec4Smrg saa7114_write_reg(SAA7114_HORZ_FIR_PREFILTER, 63471d7fec4Smrg gfx_saa7114_fir_values[34].prefilter_high); 63571d7fec4Smrg } 63671d7fec4Smrg } 63771d7fec4Smrg 63871d7fec4Smrg /* SET THE HORIZONTAL SCALING */ 63971d7fec4Smrg 64071d7fec4Smrg if (!dstw) 64171d7fec4Smrg return (1); 64271d7fec4Smrg scale = ((1024 * srcw * 1000) / (dstw * prescale)) / 1000; 64371d7fec4Smrg if ((scale > 8191) || (scale < 300)) 64471d7fec4Smrg return (1); 64571d7fec4Smrg saa7114_write_reg(SAA7114_HSCALE_LUMA_LO, (unsigned char)(scale & 0x00FF)); 64671d7fec4Smrg saa7114_write_reg(SAA7114_HSCALE_LUMA_HI, (unsigned char)(scale >> 8)); 64771d7fec4Smrg scale >>= 1; 64871d7fec4Smrg saa7114_write_reg(SAA7114_HSCALE_CHROMA_LO, 64971d7fec4Smrg (unsigned char)(scale & 0x00FF)); 65071d7fec4Smrg saa7114_write_reg(SAA7114_HSCALE_CHROMA_HI, (unsigned char)(scale >> 8)); 65171d7fec4Smrg 65271d7fec4Smrg /* SET THE VERTICAL SCALING (INTERPOLATION MODE) */ 65371d7fec4Smrg 65471d7fec4Smrg if (!dsth) 65571d7fec4Smrg return (1); 65671d7fec4Smrg 65771d7fec4Smrg /* ROUND DESTINATION HEIGHT UP TO EVEN NUMBER TO PREVENT DECODER BECOMING STUCK */ 65871d7fec4Smrg 65971d7fec4Smrg dsth = ((dsth + 1) >> 1) << 1; 66071d7fec4Smrg 66171d7fec4Smrg scale = (int)((1024 * srch) / dsth); 66271d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_LUMA_LO, (unsigned char)(scale & 0x00FF)); 66371d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_LUMA_HI, (unsigned char)(scale >> 8)); 66471d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CHROMA_LO, 66571d7fec4Smrg (unsigned char)(scale & 0x00FF)); 66671d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CHROMA_HI, (unsigned char)(scale >> 8)); 66771d7fec4Smrg 66871d7fec4Smrg if (dsth >= (srch >> 1)) { 66971d7fec4Smrg /* USE INTERPOLATION MODE FOR SCALE FACTOR ABOVE 0.5 */ 67071d7fec4Smrg 67171d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CONTROL, 0x00); 67271d7fec4Smrg 67371d7fec4Smrg /* SET VERTICAL PHASE REGISTER FOR CORRECT SCALED INTERLACED OUTPUT (OPTIMISATION) */ 67471d7fec4Smrg /* THE OPTIMISATION IS BASED ON OFIDC = 0 (REG 90h[6] = 0 ) */ 67571d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS0, SAA7114_VSCALE_PHO); 67671d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS1, SAA7114_VSCALE_PHO); 67771d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS2, 67871d7fec4Smrg (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - 67971d7fec4Smrg 16)); 68071d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS3, 68171d7fec4Smrg (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - 68271d7fec4Smrg 16)); 68371d7fec4Smrg 68471d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS0, SAA7114_VSCALE_PHO); 68571d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS1, SAA7114_VSCALE_PHO); 68671d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS2, 68771d7fec4Smrg (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - 68871d7fec4Smrg 16)); 68971d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS3, 69071d7fec4Smrg (unsigned char)(SAA7114_VSCALE_PHO + scale / 64 - 69171d7fec4Smrg 16)); 69271d7fec4Smrg 69371d7fec4Smrg /* RESTORE CONTRAST AND SATURATION FOR INTERPOLATION MODE */ 69471d7fec4Smrg 69571d7fec4Smrg saa7114_write_reg(SAA7114_FILTER_CONTRAST, (unsigned char)0x40); 69671d7fec4Smrg saa7114_write_reg(SAA7114_FILTER_SATURATION, (unsigned char)0x40); 69771d7fec4Smrg } else { 69871d7fec4Smrg /* USE ACCUMULATION MODE FOR DOWNSCALING BY MORE THAN 2x */ 69971d7fec4Smrg 70071d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CONTROL, 0x01); 70171d7fec4Smrg 70271d7fec4Smrg /* SET VERTICAL PHASE OFFSETS OFF (OPTIMISATION) */ 70371d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS0, 0x00); 70471d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS1, 0x00); 70571d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS2, 0x00); 70671d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_CHROMA_OFFS3, 0x00); 70771d7fec4Smrg 70871d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS0, 0x00); 70971d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS1, 0x00); 71071d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS2, 0x00); 71171d7fec4Smrg saa7114_write_reg(SAA7114_VSCALE_LUMINA_OFFS3, 0x00); 71271d7fec4Smrg 71371d7fec4Smrg /* ADJUST CONTRAST AND SATURATION FOR ACCUMULATION MODE */ 71471d7fec4Smrg 71571d7fec4Smrg if (srch) 71671d7fec4Smrg scale = (64 * dsth) / srch; 71771d7fec4Smrg saa7114_write_reg(SAA7114_FILTER_CONTRAST, (unsigned char)scale); 71871d7fec4Smrg saa7114_write_reg(SAA7114_FILTER_SATURATION, (unsigned char)scale); 71971d7fec4Smrg } 72071d7fec4Smrg 72171d7fec4Smrg gfx_decoder_software_reset(); 72271d7fec4Smrg return (0); 72371d7fec4Smrg} 72471d7fec4Smrg 72571d7fec4Smrg/*----------------------------------------------------------------------------- 72671d7fec4Smrg * gfx_set_decoder_vbi_format 72771d7fec4Smrg * 72871d7fec4Smrg * This routine programs the decoder to produce the specified format of VBI 72971d7fec4Smrg * data for the specified lines. 73071d7fec4Smrg *----------------------------------------------------------------------------- 73171d7fec4Smrg */ 73271d7fec4Smrg#if GFX_DECODER_DYNAMIC 73371d7fec4Smrgint 73471d7fec4Smrgsaa7114_set_decoder_vbi_format(int start, int end, int format) 73571d7fec4Smrg#else 73671d7fec4Smrgint 73771d7fec4Smrggfx_set_decoder_vbi_format(int start, int end, int format) 73871d7fec4Smrg#endif 73971d7fec4Smrg{ 74071d7fec4Smrg int i; 74171d7fec4Smrg unsigned char data; 74271d7fec4Smrg 74371d7fec4Smrg for (i = start; i <= end; i++) { 74471d7fec4Smrg switch (format) { 74571d7fec4Smrg case VBI_FORMAT_VIDEO: 74671d7fec4Smrg data = 0xFF; 74771d7fec4Smrg break; /* Active video */ 74871d7fec4Smrg case VBI_FORMAT_RAW: 74971d7fec4Smrg data = 0x77; 75071d7fec4Smrg break; /* Raw VBI data */ 75171d7fec4Smrg case VBI_FORMAT_CC: 75271d7fec4Smrg data = 0x55; 75371d7fec4Smrg break; /* US CC */ 75471d7fec4Smrg case VBI_FORMAT_NABTS: 75571d7fec4Smrg data = 0xCC; 75671d7fec4Smrg break; /* US NABTS */ 75771d7fec4Smrg default: 75871d7fec4Smrg return GFX_STATUS_BAD_PARAMETER; 75971d7fec4Smrg } 76071d7fec4Smrg saa7114_write_reg((unsigned char)(0x3F + i), data); 76171d7fec4Smrg } 76271d7fec4Smrg return GFX_STATUS_OK; 76371d7fec4Smrg} 76471d7fec4Smrg 76571d7fec4Smrg/*----------------------------------------------------------------------------- 76671d7fec4Smrg * gfx_set_decoder_vbi_enable 76771d7fec4Smrg * 76871d7fec4Smrg * This routine enables or disables VBI transfer in the decoder. 76971d7fec4Smrg *----------------------------------------------------------------------------- 77071d7fec4Smrg */ 77171d7fec4Smrg#if GFX_DECODER_DYNAMIC 77271d7fec4Smrgint 77371d7fec4Smrgsaa7114_set_decoder_vbi_enable(int enable) 77471d7fec4Smrg#else 77571d7fec4Smrgint 77671d7fec4Smrggfx_set_decoder_vbi_enable(int enable) 77771d7fec4Smrg#endif 77871d7fec4Smrg{ 77971d7fec4Smrg unsigned char data; 78071d7fec4Smrg 78171d7fec4Smrg saa7114_read_reg(SAA7114_IPORT_CONTROL, &data); 78271d7fec4Smrg if (enable) 78371d7fec4Smrg data |= 0x80; 78471d7fec4Smrg else 78571d7fec4Smrg data &= ~0x80; 78671d7fec4Smrg saa7114_write_reg(SAA7114_IPORT_CONTROL, data); 78771d7fec4Smrg return GFX_STATUS_OK; 78871d7fec4Smrg} 78971d7fec4Smrg 79071d7fec4Smrg/*----------------------------------------------------------------------------- 79171d7fec4Smrg * gfx_set_decoder_TV_standard 79271d7fec4Smrg * 79371d7fec4Smrg * This routine configures the decoder for the required TV standard. 79471d7fec4Smrg *----------------------------------------------------------------------------- 79571d7fec4Smrg */ 79671d7fec4Smrg#if GFX_DECODER_DYNAMIC 79771d7fec4Smrgint 79871d7fec4Smrgsaa7114_set_decoder_TV_standard(TVStandardType TVStandard) 79971d7fec4Smrg#else 80071d7fec4Smrgint 80171d7fec4Smrggfx_set_decoder_TV_standard(TVStandardType TVStandard) 80271d7fec4Smrg#endif 80371d7fec4Smrg{ 80471d7fec4Smrg switch (TVStandard) { 80571d7fec4Smrg case TV_STANDARD_NTSC: 80671d7fec4Smrg saa7114_write_reg(0x0E, 0x89); 80771d7fec4Smrg saa7114_write_reg(0x5A, 0x06); 80871d7fec4Smrg break; 80971d7fec4Smrg case TV_STANDARD_PAL: 81071d7fec4Smrg saa7114_write_reg(0x0E, 0x81); 81171d7fec4Smrg saa7114_write_reg(0x5A, 0x03); 81271d7fec4Smrg break; 81371d7fec4Smrg default: 81471d7fec4Smrg return GFX_STATUS_BAD_PARAMETER; 81571d7fec4Smrg } 81671d7fec4Smrg gfx_decoder_software_reset(); 81771d7fec4Smrg return GFX_STATUS_OK; 81871d7fec4Smrg} 81971d7fec4Smrg 82071d7fec4Smrg/*----------------------------------------------------------------------------- 82171d7fec4Smrg * gfx_set_decoder_luminance_filter 82271d7fec4Smrg * 82371d7fec4Smrg * This routine sets the hue control of the video decoder. 82471d7fec4Smrg *----------------------------------------------------------------------------- 82571d7fec4Smrg */ 82671d7fec4Smrg#if GFX_DECODER_DYNAMIC 82771d7fec4Smrgint 82871d7fec4Smrgsaa7114_set_decoder_luminance_filter(unsigned char lufi) 82971d7fec4Smrg#else 83071d7fec4Smrgint 83171d7fec4Smrggfx_set_decoder_luminance_filter(unsigned char lufi) 83271d7fec4Smrg#endif 83371d7fec4Smrg{ 83471d7fec4Smrg unsigned char data; 83571d7fec4Smrg 83671d7fec4Smrg saa7114_read_reg(SAA7114_LUMINANCE_CONTROL, &data); 83771d7fec4Smrg saa7114_write_reg(SAA7114_LUMINANCE_CONTROL, 83871d7fec4Smrg (unsigned char)((data & ~0x0F) | (lufi & 0x0F))); 83971d7fec4Smrg return (0); 84071d7fec4Smrg} 84171d7fec4Smrg 84271d7fec4Smrg/*************************************************************/ 84371d7fec4Smrg/* READ ROUTINES | INCLUDED FOR DIAGNOSTIC PURPOSES ONLY */ 84471d7fec4Smrg/*************************************************************/ 84571d7fec4Smrg 84671d7fec4Smrg#if GFX_READ_ROUTINES 84771d7fec4Smrg 84871d7fec4Smrg/*----------------------------------------------------------------------------- 84971d7fec4Smrg * gfx_get_decoder_brightness 85071d7fec4Smrg * 85171d7fec4Smrg * This routine returns the current brightness of the video decoder. 85271d7fec4Smrg *----------------------------------------------------------------------------- 85371d7fec4Smrg */ 85471d7fec4Smrg#if GFX_DECODER_DYNAMIC 85571d7fec4Smrgunsigned char 85671d7fec4Smrgsaa7114_get_decoder_brightness(void) 85771d7fec4Smrg#else 85871d7fec4Smrgunsigned char 85971d7fec4Smrggfx_get_decoder_brightness(void) 86071d7fec4Smrg#endif 86171d7fec4Smrg{ 86271d7fec4Smrg unsigned char brightness = 0; 86371d7fec4Smrg 86471d7fec4Smrg saa7114_read_reg(SAA7114_BRIGHTNESS, &brightness); 86571d7fec4Smrg return (brightness); 86671d7fec4Smrg} 86771d7fec4Smrg 86871d7fec4Smrg/*----------------------------------------------------------------------------- 86971d7fec4Smrg * gfx_get_decoder_contrast 87071d7fec4Smrg * 87171d7fec4Smrg * This routine returns the current contrast of the video decoder. 87271d7fec4Smrg *----------------------------------------------------------------------------- 87371d7fec4Smrg */ 87471d7fec4Smrg#if GFX_DECODER_DYNAMIC 87571d7fec4Smrgunsigned char 87671d7fec4Smrgsaa7114_get_decoder_contrast(void) 87771d7fec4Smrg#else 87871d7fec4Smrgunsigned char 87971d7fec4Smrggfx_get_decoder_contrast(void) 88071d7fec4Smrg#endif 88171d7fec4Smrg{ 88271d7fec4Smrg unsigned char contrast = 0; 88371d7fec4Smrg 88471d7fec4Smrg saa7114_read_reg(SAA7114_CONTRAST, &contrast); 88571d7fec4Smrg contrast <<= 1; 88671d7fec4Smrg return (contrast); 88771d7fec4Smrg} 88871d7fec4Smrg 88971d7fec4Smrg/*----------------------------------------------------------------------------- 89071d7fec4Smrg * gfx_get_decoder_hue 89171d7fec4Smrg * 89271d7fec4Smrg * This routine returns the current hue of the video decoder. 89371d7fec4Smrg *----------------------------------------------------------------------------- 89471d7fec4Smrg */ 89571d7fec4Smrg#if GFX_DECODER_DYNAMIC 89671d7fec4Smrgchar 89771d7fec4Smrgsaa7114_get_decoder_hue(void) 89871d7fec4Smrg#else 89971d7fec4Smrgchar 90071d7fec4Smrggfx_get_decoder_hue(void) 90171d7fec4Smrg#endif 90271d7fec4Smrg{ 90371d7fec4Smrg unsigned char hue = 0; 90471d7fec4Smrg 90571d7fec4Smrg saa7114_read_reg(SAA7114_HUE, &hue); 90671d7fec4Smrg return ((char)hue); 90771d7fec4Smrg} 90871d7fec4Smrg 90971d7fec4Smrg/*----------------------------------------------------------------------------- 91071d7fec4Smrg * gfx_get_decoder_saturation 91171d7fec4Smrg * 91271d7fec4Smrg * This routine returns the current saturation of the video decoder. 91371d7fec4Smrg *----------------------------------------------------------------------------- 91471d7fec4Smrg */ 91571d7fec4Smrg#if GFX_DECODER_DYNAMIC 91671d7fec4Smrgunsigned char 91771d7fec4Smrgsaa7114_get_decoder_saturation(void) 91871d7fec4Smrg#else 91971d7fec4Smrgunsigned char 92071d7fec4Smrggfx_get_decoder_saturation(void) 92171d7fec4Smrg#endif 92271d7fec4Smrg{ 92371d7fec4Smrg unsigned char saturation = 0; 92471d7fec4Smrg 92571d7fec4Smrg saa7114_read_reg(SAA7114_SATURATION, &saturation); 92671d7fec4Smrg saturation <<= 1; 92771d7fec4Smrg return (saturation); 92871d7fec4Smrg} 92971d7fec4Smrg 93071d7fec4Smrg/*----------------------------------------------------------------------------- 93171d7fec4Smrg * gfx_get_decoder_input_offset 93271d7fec4Smrg * 93371d7fec4Smrg * This routine returns the offset into the input window. 93471d7fec4Smrg *----------------------------------------------------------------------------- 93571d7fec4Smrg */ 93671d7fec4Smrg#if GFX_DECODER_DYNAMIC 93771d7fec4Smrgunsigned long 93871d7fec4Smrgsaa7114_get_decoder_input_offset(void) 93971d7fec4Smrg#else 94071d7fec4Smrgunsigned long 94171d7fec4Smrggfx_get_decoder_input_offset(void) 94271d7fec4Smrg#endif 94371d7fec4Smrg{ 94471d7fec4Smrg unsigned long value = 0; 94571d7fec4Smrg unsigned char data; 94671d7fec4Smrg 94771d7fec4Smrg saa7114_read_reg(SAA7114_HORZ_OFFSET_LO, &data); 94871d7fec4Smrg value = (unsigned long)data; 94971d7fec4Smrg saa7114_read_reg(SAA7114_HORZ_OFFSET_HI, &data); 95071d7fec4Smrg value |= ((unsigned long)data) << 8; 95171d7fec4Smrg saa7114_read_reg(SAA7114_VERT_OFFSET_LO, &data); 95271d7fec4Smrg value |= ((unsigned long)data) << 16; 95371d7fec4Smrg saa7114_read_reg(SAA7114_VERT_OFFSET_HI, &data); 95471d7fec4Smrg value |= ((unsigned long)data) << 24; 95571d7fec4Smrg return (value); 95671d7fec4Smrg} 95771d7fec4Smrg 95871d7fec4Smrg/*----------------------------------------------------------------------------- 95971d7fec4Smrg * gfx_get_decoder_input_size 96071d7fec4Smrg * 96171d7fec4Smrg * This routine returns the current size of the input window 96271d7fec4Smrg *----------------------------------------------------------------------------- 96371d7fec4Smrg */ 96471d7fec4Smrg#if GFX_DECODER_DYNAMIC 96571d7fec4Smrgunsigned long 96671d7fec4Smrgsaa7114_get_decoder_input_size(void) 96771d7fec4Smrg#else 96871d7fec4Smrgunsigned long 96971d7fec4Smrggfx_get_decoder_input_size(void) 97071d7fec4Smrg#endif 97171d7fec4Smrg{ 97271d7fec4Smrg unsigned long value = 0; 97371d7fec4Smrg unsigned char data; 97471d7fec4Smrg 97571d7fec4Smrg saa7114_read_reg(SAA7114_HORZ_INPUT_LO, &data); 97671d7fec4Smrg value = (unsigned long)data; 97771d7fec4Smrg saa7114_read_reg(SAA7114_HORZ_INPUT_HI, &data); 97871d7fec4Smrg value |= ((unsigned long)data) << 8; 97971d7fec4Smrg saa7114_read_reg(SAA7114_VERT_INPUT_LO, &data); 98071d7fec4Smrg value |= ((unsigned long)data) << 17; 98171d7fec4Smrg saa7114_read_reg(SAA7114_VERT_INPUT_HI, &data); 98271d7fec4Smrg value |= ((unsigned long)data) << 25; 98371d7fec4Smrg return (value); 98471d7fec4Smrg} 98571d7fec4Smrg 98671d7fec4Smrg/*----------------------------------------------------------------------------- 98771d7fec4Smrg * gfx_get_decoder_output_size 98871d7fec4Smrg * 98971d7fec4Smrg * This routine returns the current size of the output window. 99071d7fec4Smrg *----------------------------------------------------------------------------- 99171d7fec4Smrg */ 99271d7fec4Smrg#if GFX_DECODER_DYNAMIC 99371d7fec4Smrgunsigned long 99471d7fec4Smrgsaa7114_get_decoder_output_size(void) 99571d7fec4Smrg#else 99671d7fec4Smrgunsigned long 99771d7fec4Smrggfx_get_decoder_output_size(void) 99871d7fec4Smrg#endif 99971d7fec4Smrg{ 100071d7fec4Smrg unsigned long value = 0; 100171d7fec4Smrg unsigned char data; 100271d7fec4Smrg 100371d7fec4Smrg saa7114_read_reg(SAA7114_HORZ_OUTPUT_LO, &data); 100471d7fec4Smrg value = (unsigned long)data; 100571d7fec4Smrg saa7114_read_reg(SAA7114_HORZ_OUTPUT_HI, &data); 100671d7fec4Smrg value |= ((unsigned long)data) << 8; 100771d7fec4Smrg saa7114_read_reg(SAA7114_VERT_OUTPUT_LO, &data); 100871d7fec4Smrg value |= ((unsigned long)data) << 17; 100971d7fec4Smrg saa7114_read_reg(SAA7114_VERT_OUTPUT_HI, &data); 101071d7fec4Smrg value |= ((unsigned long)data) << 25; 101171d7fec4Smrg return (value); 101271d7fec4Smrg} 101371d7fec4Smrg 101471d7fec4Smrg/*----------------------------------------------------------------------------- 101571d7fec4Smrg * gfx_get_decoder_vbi_format 101671d7fec4Smrg * 101771d7fec4Smrg * This routine returns the current format of VBI data for the specified line. 101871d7fec4Smrg *----------------------------------------------------------------------------- 101971d7fec4Smrg */ 102071d7fec4Smrg#if GFX_DECODER_DYNAMIC 102171d7fec4Smrgint 102271d7fec4Smrgsaa7114_get_decoder_vbi_format(int line) 102371d7fec4Smrg#else 102471d7fec4Smrgint 102571d7fec4Smrggfx_get_decoder_vbi_format(int line) 102671d7fec4Smrg#endif 102771d7fec4Smrg{ 102871d7fec4Smrg unsigned char format = 0, data; 102971d7fec4Smrg 103071d7fec4Smrg saa7114_read_reg((unsigned char)(0x3F + line), &data); 103171d7fec4Smrg switch (data) { 103271d7fec4Smrg case 0xFF: 103371d7fec4Smrg format = VBI_FORMAT_VIDEO; 103471d7fec4Smrg break; /* Active video */ 103571d7fec4Smrg case 0x77: 103671d7fec4Smrg format = VBI_FORMAT_RAW; 103771d7fec4Smrg break; /* Raw VBI data */ 103871d7fec4Smrg case 0x55: 103971d7fec4Smrg format = VBI_FORMAT_CC; 104071d7fec4Smrg break; /* US CC */ 104171d7fec4Smrg case 0xCC: 104271d7fec4Smrg format = VBI_FORMAT_NABTS; 104371d7fec4Smrg break; /* US NABTS */ 104471d7fec4Smrg } 104571d7fec4Smrg return (format); 104671d7fec4Smrg} 104771d7fec4Smrg 104871d7fec4Smrg#endif /* GFX_READ_ROUTINES */ 104971d7fec4Smrg 105071d7fec4Smrg/* END OF FILE */ 1051