📄 vd_operation.c
字号:
//
// Copyright (c) Chrontel Inc. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Chrontel end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
vd_operation.c
Abstract:
Revision:
12/28/02 Roger Yu. Created File
Notes:
--*/
#include <windows.h>
#include <ceddk.h>
#include "chrontel.h"
static unsigned DEVICE_ADDR = 0xEA; // default for CH device
#define vodRead(index) I2CReadReg(DEVICE_ADDR, (index))
#define vodWrite(index, value) I2CWriteReg( DEVICE_ADDR, (index), (value))
#define vodWriteBits( index, mask, value) I2CWriteRegBits( DEVICE_ADDR, (index), (mask), (value))
/*===================================================
Chrontel VOD chip related functions & data
==================================================*/
unsigned voe_class_id = 0;
unsigned voe_chip_id = 0;
unsigned voe_ability = 0;
static unsigned chdid[][3] ={
{0x16, VOECLS_7009, VOD_ATTR_TV | VOD_ATTR_VGA | VOD_ATTR_DVI }, // ch7010
{0x17, VOECLS_7009, VOD_ATTR_TV | VOD_ATTR_VGA | VOD_ATTR_DVI }, // ch7009/7011
{0x30, VOECLS_7009, VOD_ATTR_TV | VOD_ATTR_VGA | VOD_ATTR_DVI }, // ch7021b
{0x31, VOECLS_7009, VOD_ATTR_TV | VOD_ATTR_VGA | VOD_ATTR_DVI },// ch7021a
{0x39, VOECLS_7303, VOD_ATTR_VGA | VOD_ATTR_DVI },// ch7303a
{0x38, VOECLS_7303, VOD_ATTR_VGA | VOD_ATTR_DVI }, // ch7303b
{0x19, VOECLS_7019, VOD_ATTR_TV | VOD_ATTR_VGA | VOD_ATTR_LVDS }, // ch7019
{0x1a, VOECLS_7019, VOD_ATTR_TV | VOD_ATTR_VGA | VOD_ATTR_LVDS }, // ch7017
{0x1b, VOECLS_7019, VOD_ATTR_TV | VOD_ATTR_VGA | VOD_ATTR_LVDS }, // ch7017E,F,G,, ch7304/ch7305
{0x1f, VOECLS_7009, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7015a/ch7205a
{0x1e, VOECLS_7009, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7015b/ch7015b
{0x1D, VOECLS_7009, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7015a (48pin)
{0x1C, VOECLS_7009, VOD_ATTR_TV | VOD_ATTR_VGA } // ch7015b (48pin)
};
#define chdidlen (sizeof(chdid)/sizeof(unsigned)/3)
// for Old device CH7003/4/5/6/7/13, only VID at reg[25h] is available
static unsigned chvid[][3] ={
{0x22, VOECLS_7013, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7013
{0x39, VOECLS_7006, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7005a
{0x38, VOECLS_7006, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7005b
{0x3a, VOECLS_7006, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7005
{0x29, VOECLS_7006, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7006b
{0x28, VOECLS_7006, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7006a
{0x2a, VOECLS_7006, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7006c
{0x30, VOECLS_7013, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7004a
{0x31, VOECLS_7013, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7004b
{0x32, VOECLS_7013, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7004c
{0x33, VOECLS_7013, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7004d
{0x40, VOECLS_7007, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7007
{0x50, VOECLS_7007, VOD_ATTR_TV | VOD_ATTR_VGA }, // ch7007b
};
#define chvidlen (sizeof(chvid)/sizeof(unsigned)/3)
/* This function must be called after i2c_initialize() */
int FindEncoder(void)
{
unsigned v1, v2;
unsigned chvoe_idbyte =0;
unsigned chvoe_vidbyte =0;
unsigned chvoe_class;
// try 0xEA
DEVICE_ADDR = 0xEA;
vodRead( 0x4B);
if (0==I2CError()) goto check_id; // SPC address is found
// then try 0xEC
DEVICE_ADDR = 0xEC;
vodRead( 0x4B);
if (0==I2CError()) goto check_id; // SPC address is found
//try VID register
DEVICE_ADDR = 0xEA;
vodRead( 0x25);
if (0==I2CError()) goto check_id; // SPC address is found
// then try 0xEC
DEVICE_ADDR = 0xEC;
vodRead( 0x25);
if (0==I2CError()) goto check_id; // SPC address is found
// use the CH7013 default address
DEVICE_ADDR = 0xEA;
check_id:
v1 = vodRead( 0x4b); // read DID
vodWrite( 0x4b, 0);
v2 = vodRead( 0x4b);
//printk("PXAFB: read reg[0x4B] v1=%x, v2=%x\n", v1, v2);
if (v1==v2) { // find Chrontel VOD with valid DID
for (v2=0; v2< chdidlen; v2++) {
if (v1==chdid[v2][0]) {
chvoe_idbyte = v1;
chvoe_vidbyte = vodRead( 0x4a); /* get the VID byte*/
chvoe_class=chdid[v2][1];
v1 = chdid[v2][2];
goto voe_found;
}
}
}
/* try Chrontel device with old VID */
{
v1 = vodRead( 0x25); // read old DID
vodWrite( 0x25, 0);
v2 = vodRead( 0x25);
//printk("PXAFB: read reg[0x25] v1=%x, v2=%x\n", v1, v2);
if (v1==v2) { // dinf Chrontel VOD with valid old VID
for (v2=0; v2< chvidlen; v2++) {
if (v1==chvid[v2][0]) {
chvoe_idbyte = v1;
chvoe_class=chvid[v2][1];
v1 = chvid[v2][2];
goto voe_found;
}
}
return VOECLS_UNKNOWN;
}
}
return VOECLS_UNKNOWN;
voe_found:
voe_chip_id = (chvoe_idbyte<<8) + chvoe_vidbyte;
//specially for 7301
if (voe_chip_id == 0x1795) {
chvoe_class = VOECLS_7303;
v1 = VOD_ATTR_VGA | VOD_ATTR_DVI;
}
voe_class_id = chvoe_class;
voe_ability = v1;
voe_ability |= VOD_ATTR_DEFAULT;
CHDBG(( TEXT("chip_id=%x, class=%x, ability=%x\n"), voe_chip_id, voe_class_id, voe_ability ))
//@@## set initially boot device as default
// voe_dev->out_cfg = voe_dev->ability;
// chvoe_power_off( voe_dev); // turn off display first
// voe_dev->out_cfg = VOD_ATTR_DEFAULT;
// voe_dev->out_cfg = VOD_ATTR_TV;
return voe_ability;
}
/*+++++++++++++++++++++++++++++++++++++++++++
Mode Register Table for CHVOE devices
+++++++++++++++++++++++++++++++++++++++++++++
*/
//@@## set CH7013 VGA enable
static unsigned char initreg7013_vga[][3] ={
{ 0x0e, 0x00, 0x08 },
{ 0x0e, 0x08, 0x08 },
{ 0x04, 0x20, 0x2f },
// { 0x0E, 0x03, 0x07 }, // normal
};
#define initlen7013_vga (sizeof(initreg7013_vga)/3)
//======================================================
//@@## set CH7013 TV enable
static unsigned char initreg7013_640x480[][3] ={
{ 0x0e, 0x0, 0x08},
{ 0x0e, 0x08, 0x08},
{ 0x00, 0x69, 0xff},
{ 0x01, 0x2A, 0xff},
{ 0x06, 0x10, 0xff}, // MCP=1
{ 0x07, 0x6A, 0xff},
{ 0x08, 0x30, 0xff},
{ 0x09, 0x81, 0xff},
{ 0x0a, 0x1f, 0xff},
{ 0x0b, 0xfa, 0xff},
{ 0x13, 0x40, 0xff}, // M,N high
{ 0x14, 0x65, 0xff}, // M
{ 0x15, 0xb1, 0xff}, // N
{ 0x20, 0x00, 0xff}, // 3.3V, PLLCAP=0
{ 0x21, 0x00, 0xff}, // trun off CIV
{ 0x18, 0x02, 0xff},
{ 0x19, 0x04, 0xff},
{ 0x1A, 0x0D, 0xff},
{ 0x1B, 0x04, 0xff},
{ 0x1C, 0x01, 0xff},
{ 0x1D, 0x07, 0xff},
{ 0x1E, 0x08, 0xff},
{ 0x1F, 0x00, 0xff},
// { 0x0E, 0x4C, 0xff}, // Turn Off TV DACs
// { 0x0E, 0x03, 0x07}, // normal
};
#define initlen7013_640x480 (sizeof(initreg7013_640x480)/3)
//===================================
//@@## CH7006/7005 640x480 mode
static unsigned char initreg7006_640x480[][3] ={
{ 0x0e, 0x0, 0x08},
{ 0x0e, 0x08, 0x08},
{ 0x00, 0x69, 0xff},
{ 0x01, 0x26, 0xff},
{ 0x06, 0x10, 0xff}, // MCP=1
{ 0x07, 0x70, 0xff}, // 0x35
{ 0x08, 0x30, 0xff},
{ 0x09, 0x80, 0xff},
{ 0x0a, 0x22, 0xff},
{ 0x0b, 0xf9, 0xff},
{ 0x13, 0x40, 0xff}, // M,N high
{ 0x14, 0x65, 0xff}, // M
{ 0x15, 0xb1, 0xff}, // N
{ 0x20, 0x00, 0xff}, // 3.3V, PLLCAP=0
{ 0x21, 0x00, 0xff}, // trun off CIV
{ 0x18, 0x02, 0xff},
{ 0x19, 0x04, 0xff},
{ 0x1A, 0x0D, 0xff},
{ 0x1B, 0x04, 0xff},
{ 0x1C, 0x01, 0xff},
{ 0x1D, 0x07, 0xff},
{ 0x1E, 0x08, 0xff},
{ 0x1F, 0x00, 0xff},
// { 0x0E, 0x4C, 0xff} // Turn Off TV DACs
};
#define initlen7006_640x480 (sizeof(initreg7006_640x480)/3)
static unsigned char initreg7013_640x400[][3] ={
{ 0x0e, 0x0, 0x08},
{ 0x0e, 0x08, 0x08},
{ 0x00, 0x42, 0xff}, // PAL mode 08
{ 0x01, 0x2A, 0xff},
{ 0x06, 0x10, 0xff}, // MCP=1
{ 0x07, 0xd4, 0xff},
{ 0x08, 0x31, 0xff},
{ 0x09, 0x81, 0xff},
{ 0x0a, 0x2e, 0xff},
{ 0x0b, 0x2d, 0xff},
{ 0x13, 0x40, 0xff}, // M,N high
{ 0x14, 0x65, 0xff}, // M
{ 0x15, 0xb1, 0xff}, // N
{ 0x20, 0x00, 0xff}, // 3.3V, PLLCAP=0
{ 0x21, 0x00, 0xff}, // trun off CIV
{ 0x18, 0x02, 0xff},
{ 0x19, 0x08, 0xff},
{ 0x1A, 0x08, 0xff},
{ 0x1B, 0x0b, 0xff},
{ 0x1C, 0x0e, 0xff},
{ 0x1D, 0x03, 0xff},
{ 0x1E, 0x08, 0xff},
{ 0x1F, 0x00, 0xff},
{ 0x10, 0x08, 0xff},
// { 0x0E, 0x4C, 0xff}, // Turn Off TV DACs
// { 0x0E, 0x03, 0x07}, // normal
};
#define initlen7013_640x400 (sizeof(initreg7013_640x400)/3)
typedef unsigned char (*TblReg)[3];
static void SendTable( TblReg tbl, int len)
{
int i;
for (i=0; i<len; i++)
vodWriteBits( tbl[i][0], tbl[i][2], tbl[i][1]);
}
/*==================================================*/
int vod_Initialize(UINT oc)
{
if (VOD_ATTR_CHVOE & oc) {
// only handle chvoe device
}
return 0;
}
int vod_GetConnectStatus(UINT oc)
{
return 1;
}
void vod_GetTiming(UINT oc, PDISPTIMING p)
{
return;
}
void vod_SetTiming(UINT oc, PDISPTIMING p)
{
int sx, sy;
sx = p->dwHActive;
sy = p->dwVActive;
if (VOD_ATTR_VGA & oc) {
if ((voe_class_id==VOECLS_7013) || (VOECLS_7006==voe_class_id))
SendTable(initreg7013_vga, initlen7013_vga);
}
if (VOD_ATTR_TV & oc) {
if (voe_class_id==VOECLS_7013) {
if ((sx==640) && (sy==400))
SendTable( initreg7013_640x400, initlen7013_640x400);
else // 640x480, 320x240
SendTable( initreg7013_640x480, initlen7013_640x480);
}
if (VOECLS_7006==voe_class_id) {
if ((sx==640) && (sy==400))
SendTable( initreg7013_640x400, initlen7013_640x400);
else // 640x480, 320x240
SendTable( initreg7006_640x480, initlen7006_640x480);
}
}
return;
}
void vod_SetPower(UINT oc, int powerstate) {
if (VideoPowerOn == powerstate)
{
if (oc & (VOD_ATTR_VGA | VOD_ATTR_TV))
if ((voe_class_id==VOECLS_7006) || (voe_class_id==VOECLS_7013))
{
//@@ do this for SVIDEO/CVBS output
vodWriteBits(0x0e, 0x07, 0x03); // use for non-SCART output
//@@ end of SVIDEO/CVBS output option
/*
//@@ do this for SCART RGB output
vodWriteBits(0x0e, 0x17, 0x13); // use for SCART output
vodWrite( 0x09, 0x00);
//@@ end of SCART output option
*/
}
}
else {
if (oc & (VOD_ATTR_VGA | VOD_ATTR_TV))
if ((voe_class_id==VOECLS_7006) || (voe_class_id==VOECLS_7013))
vodWriteBits(0x0e, 0x07, 0x04);
}
return;
}
void vod_PostSetTiming(UINT oc)
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -