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, &macrovision);
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