xserver-multidpi/hw/xfree86/i2c/bt829.c
Keith Packard 9838b7032e Introduce a consistent coding style
This is strictly the application of the script 'x-indent-all.sh'
from util/modular. Compared to the patch that Daniel posted in
January, I've added a few indent flags:

	-bap
	-psl
	-T PrivatePtr
	-T pmWait
	-T _XFUNCPROTOBEGIN
	-T _XFUNCPROTOEND
	-T _X_EXPORT

The typedefs were needed to make the output of sdksyms.sh match the
previous output, otherwise, the code is formatted badly enough that
sdksyms.sh generates incorrect output.

The generated code was compared with the previous version and found to
be essentially identical -- "assert" line numbers and BUILD_TIME were
the only differences found.

The comparison was done with this script:

dir1=$1
dir2=$2

for dir in $dir1 $dir2; do
	(cd $dir && find . -name '*.o' | while read file; do
		dir=`dirname $file`
		base=`basename $file .o`
		dump=$dir/$base.dump
		objdump -d $file > $dump
	done)
done

find $dir1 -name '*.dump' | while read dump; do
	otherdump=`echo $dump | sed "s;$dir1;$dir2;"`
	diff -u $dump $otherdump
done

Signed-off-by: Keith Packard <keithp@keithp.com>
Acked-by: Daniel Stone <daniel@fooishbar.org>
Acked-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2012-03-21 13:54:42 -07:00

822 lines
21 KiB
C

/* TODO: clean up/fix CC code */
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "xf86.h"
#include "xf86i2c.h"
#include "bt829.h"
#include "i2c_def.h"
/* Changing the following settings (especially VCROP) may */
/* require modifying code that calls this driver. */
#define HCROP 0 /* amount to crop from the left and right edges */
#define VCROP 0 /* amount to crop from the top and bottom edges */
#define BTVERSION (bt->id>>4)
#define H(X) ( ((X)>>8) & 0xFF )
#define L(X) ( (X) & 0xFF )
#define LIMIT(X,A,B) (((X)<(A)) ? (A) : ((X)>(B)) ? (B) : (X) )
/* Bt829 family chip ID's */
#define BT815 0x02
#define BT817 0x06
#define BT819 0x07
#define BT827 0x0C
#define BT829 0x0E
/* Bt829 registers */
#define STATUS 0x00 /* Device Status */
#define IFORM 0x01 /* Input Format */
#define TDEC 0x02 /* Temporal Decimation */
#define CROP 0x03 /* MSB Cropping */
#define VDELAY_LO 0x04 /* Vertical Delay */
#define VACTIVE_LO 0x05 /* Vertical Active */
#define HDELAY_LO 0x06 /* Horizontal Delay */
#define HACTIVE_LO 0x07 /* Horizontal Active */
#define HSCALE_HI 0x08 /* Horizontal Scaling */
#define HSCALE_LO 0x09 /* Horizontal Scaling */
#define BRIGHT 0x0A /* Brightness Control */
#define CONTROL 0x0B /* Miscellaneous Control */
#define CONTRAST_LO 0x0C /* Luma Gain (Contrast) */
#define SAT_U_LO 0x0D /* Chroma (U) Gain (Saturation) */
#define SAT_V_LO 0x0E /* Chroma (V) Gain (Saturation) */
#define HUE 0x0F /* Hue Control */
#define SCLOOP 0x10 /* SC Loop Control */
#define WC_UP 0x11 /* White Crush Up Count */
#define OFORM 0x12 /* Output Format */
#define VSCALE_HI 0x13 /* Vertical Scaling */
#define VSCALE_LO 0x14 /* Vertical Scaling */
#define TEST 0x15 /* Test Control */
#define VPOLE 0x16 /* Video Timing Polarity */
#define IDCODE 0x17 /* ID Code */
#define ADELAY 0x18 /* AGC Delay */
#define BDELAY 0x19 /* Burst Gate Delay */
#define ADC 0x1A /* ADC Interface */
#define VTC 0x1B /* Video Timing Control */
#define CC_STATUS 0x1C /* Extended Data Services/Closed Capt Status */
#define CC_DATA 0x1D /* Extended Data Services/Closed Capt Data */
#define WC_DN 0x1E /* White Crush Down Count */
#define SRESET 0x1F /* Software Reset */
#define P_IO 0x3F /* Programmable I/O */
static CARD8
btread(BT829Ptr bt, CARD8 reg)
{
CARD8 v;
I2C_WriteRead(&(bt->d), &reg, 1, &v, 1);
return v;
}
static void
btwrite(BT829Ptr bt, CARD8 reg, CARD8 val)
{
CARD8 data[2];
data[0] = reg;
data[1] = val;
I2C_WriteRead(&(bt->d), data, 2, NULL, 0);
}
/*
* Register access
*/
static void
btwrite_status(BT829Ptr bt)
{ /* STATUS */
btwrite(bt, STATUS, 0x00); /* clear */
}
static void
btwrite_iform(BT829Ptr bt)
{ /* IFORM */
int xtsel;
switch (bt->format) {
case BT829_NTSC:
case BT829_NTSC_JAPAN:
case BT829_PAL_M:
case BT829_PAL_N_COMB: /* gatos says xtsel = 2 */
xtsel = 1;
break;
case BT829_PAL:
case BT829_PAL_N:
case BT829_SECAM:
xtsel = 2;
break;
default: /* shouldn't get here */
xtsel = 3; /* hardware default */
break;
}
btwrite(bt, IFORM, (bt->mux << 5) | (xtsel << 3) | bt->format);
}
static void
btwrite_tdec(BT829Ptr bt)
{ /* TDEC */
/* use default */
}
static void
btwrite_crop(BT829Ptr bt)
{ /* CROP */
btwrite(bt, CROP, (H(bt->vdelay) << 6) | (H(bt->vactive) << 4) |
(H(bt->hdelay) << 2) | H(bt->width));
}
static void
btwrite_vdelay_lo(BT829Ptr bt)
{ /* VDELAY_LO */
btwrite(bt, VDELAY_LO, L(bt->vdelay));
}
static void
btwrite_vactive_lo(BT829Ptr bt)
{ /* VACTIVE_LO */
btwrite(bt, VACTIVE_LO, L(bt->vactive));
}
static void
btwrite_hdelay_lo(BT829Ptr bt)
{ /* HDELAY_LO */
btwrite(bt, HDELAY_LO, L(bt->hdelay));
}
static void
btwrite_hactive_lo(BT829Ptr bt)
{ /* HACTIVE_LO */
btwrite(bt, HACTIVE_LO, L(bt->width));
}
static void
btwrite_hscale_hi(BT829Ptr bt)
{ /* HSCALE_HI */
btwrite(bt, HSCALE_HI, H(bt->hscale));
}
static void
btwrite_hscale_lo(BT829Ptr bt)
{ /* HSCALE_LO */
btwrite(bt, HSCALE_LO, L(bt->hscale));
}
static void
btwrite_bright(BT829Ptr bt)
{ /* BRIGHT */
btwrite(bt, BRIGHT, bt->brightness);
}
static void
btwrite_control(BT829Ptr bt)
{ /* CONTROL */
int ldec;
/* The data sheet says ldec should always be 0 for SECAM */
/* but the picture quality is better with ldec = 1 */
ldec = (bt->width > 360); /* gatos says 384 */
btwrite(bt, CONTROL, ((bt->mux == bt->svideo_mux) ? 0xC0 : 0x00) | /* LNOTCH and COMP */
(ldec << 5) | (H(bt->contrast) << 2) | (H(bt->sat_u) << 1) | H(bt->
sat_v));
}
static void
btwrite_contrast_lo(BT829Ptr bt)
{ /* CONTRAST_LO */
btwrite(bt, CONTRAST_LO, L(bt->contrast));
}
static void
btwrite_sat_u_lo(BT829Ptr bt)
{ /* SAT_U_LO */
btwrite(bt, SAT_U_LO, L(bt->sat_u));
}
static void
btwrite_sat_v_lo(BT829Ptr bt)
{ /* SAT_V_LO */
btwrite(bt, SAT_V_LO, L(bt->sat_v));
}
static void
btwrite_hue(BT829Ptr bt)
{ /* HUE */
btwrite(bt, HUE, bt->hue);
}
static void
btwrite_scloop(BT829Ptr bt)
{ /* SCLOOP */
if (BTVERSION >= BT827) {
btwrite(bt, SCLOOP, (bt->format == BT829_SECAM) ? 0x10 : 0x00 /* QCIF or AUTO */
);
}
}
static void
btwrite_wc_up(BT829Ptr bt)
{ /* WC_UP */
if (BTVERSION >= BT827) {
/* use default */
}
}
static void
btwrite_oform(BT829Ptr bt)
{ /* OFORM */
btwrite(bt, OFORM, (bt->code << 3) | (bt->len << 2) | 0x02 /* RANGE = 0, CORE = 0, VBI_FRAME = 0, OES = 2 (default) */
);
}
static void
btwrite_vscale_hi(BT829Ptr bt)
{ /* VSCALE_HI */
btwrite(bt, VSCALE_HI, H(bt->vscale) | 0x60 /* YCOMB = 0, COMB = 1, INT = 1 (default) */
);
}
static void
btwrite_vscale_lo(BT829Ptr bt)
{ /* VSCALE_LO */
btwrite(bt, VSCALE_LO, L(bt->vscale));
}
/* TEST should not be written to */
static void
btwrite_vpole(BT829Ptr bt)
{ /* VPOLE */
btwrite(bt, VPOLE, (bt->out_en << 7));
}
/* IDCODE is read only */
static void
btwrite_adelay(BT829Ptr bt)
{ /* ADELAY */
switch (bt->format) {
case BT829_NTSC:
case BT829_NTSC_JAPAN:
case BT829_PAL_M:
btwrite(bt, ADELAY, 104);
break;
case BT829_PAL:
case BT829_PAL_N:
case BT829_SECAM:
case BT829_PAL_N_COMB:
btwrite(bt, ADELAY, 127);
break;
default: /* shouldn't get here */
btwrite(bt, ADELAY, 104); /* hardware default */
break;
}
}
static void
btwrite_bdelay(BT829Ptr bt)
{ /* BDELAY */
switch (bt->format) {
case BT829_NTSC:
case BT829_NTSC_JAPAN:
case BT829_PAL_M:
btwrite(bt, BDELAY, 93);
break;
case BT829_PAL:
case BT829_PAL_N:
case BT829_PAL_N_COMB:
btwrite(bt, BDELAY, 114);
break;
case BT829_SECAM:
btwrite(bt, BDELAY, 160);
break;
default: /* shouldn't get here */
btwrite(bt, BDELAY, 93); /* hardware default */
break;
}
}
static void
btwrite_adc(BT829Ptr bt)
{ /* ADC */
btwrite(bt, ADC, bt->mux == bt->svideo_mux ? 0x80 : 0x82); /* CSLEEP = 0 or 1 */
}
static void
btwrite_vtc(BT829Ptr bt)
{ /* VTC */
int vfilt = 0; /* hardware default */
if (BTVERSION > BT827) { /* gatos says >= BT827 */
switch (bt->format) {
case BT829_NTSC:
case BT829_NTSC_JAPAN:
case BT829_PAL_M:
case BT829_PAL_N_COMB: /* gatos groups with BT829_PAL */
if (bt->width <= 360)
vfilt = 1; /* gatos says <= 240 */
if (bt->width <= 180)
vfilt = 2; /* gatos says <= 120 */
if (bt->width <= 90)
vfilt = 3; /* gatos says <= 60 */
break;
case BT829_PAL:
case BT829_PAL_N:
case BT829_SECAM:
if (bt->width <= 384)
vfilt = 1;
if (bt->width <= 192)
vfilt = 2;
if (bt->width <= 96)
vfilt = 3;
break;
default: /* shouldn't get here */
break; /* use hardware default */
}
btwrite(bt, VTC, (bt->vbien << 4) | (bt->vbifmt << 3) | vfilt);
}
}
static void
btwrite_cc_status(BT829Ptr bt)
{ /* CC_STATUS *//* FIXME: ATI specific */
if (BTVERSION >= BT827) {
if (bt->ccmode == 0)
btwrite(bt, CC_STATUS, 0x00);
/* 0x40 is activate to set the CCVALID line. Not required yet */
else
btwrite(bt, CC_STATUS, (bt->ccmode << 4) | 0x40);
}
}
/* CC_DATA is read only */
static void
btwrite_wc_dn(BT829Ptr bt)
{ /* WC_DN */
if (BTVERSION >= BT827) {
/* use default */
}
}
static void
bt_reset(BT829Ptr bt)
{ /* SRESET */
btwrite(bt, SRESET, 0x0); /* Reset all registers */
}
static void
btwrite_p_io(BT829Ptr bt)
{ /* P_IO */
if (BTVERSION >= BT827) {
btwrite(bt, P_IO, bt->p_io);
}
}
/*
* Deal with dependencies
*/
static void
propagate_changes(BT829Ptr bt)
{
CARD16 hdelay, unscaled_hdelay, vdelay, hscale, vscale;
int htotal, vactive;
switch (bt->format) {
case BT829_NTSC:
case BT829_NTSC_JAPAN:
case BT829_PAL_M:
vdelay = 22;
htotal = 754;
vactive = 480;
unscaled_hdelay = 135;
break;
case BT829_PAL:
case BT829_PAL_N:
vdelay = (bt->tunertype == 5) ? 34 : 22;
htotal = 922;
vactive = 576;
unscaled_hdelay = 186;
break;
case BT829_SECAM:
vdelay = 34;
htotal = 922;
vactive = 576;
unscaled_hdelay = 186;
break;
case BT829_PAL_N_COMB:
vdelay = (bt->tunertype == 5) ? 34 : 22; /* windows says 22 */
htotal = 754; /* gatos and windows say 922 */
vactive = 576;
unscaled_hdelay = 135; /* gatos and windows say 186 */
break;
default: /* shouldn't get here */
vdelay = 22; /* hardware default */
htotal = 754;
vactive = 480; /* hardware default */
unscaled_hdelay = 135;
break;
}
bt->htotal = htotal; /* Used for error checking in bt829_SetCaptSize */
hscale = 4096 * htotal / (bt->width + 2 * HCROP) - 4096;
hdelay =
(HCROP + (bt->width + 2 * HCROP) * unscaled_hdelay / htotal) & 0x3FE;
vactive = vactive - 2 * VCROP;
vdelay = vdelay + VCROP;
vscale = (0x10000 - (512 * vactive / bt->height - 512)) & 0x1FFF;
if ((hdelay != bt->hdelay) || (vdelay != bt->vdelay) ||
(vactive != bt->vactive) || (hscale != bt->hscale) ||
(vscale != bt->vscale)) {
bt->hdelay = hdelay;
bt->vdelay = vdelay;
bt->vactive = vactive;
bt->hscale = hscale;
bt->vscale = vscale;
btwrite_crop(bt);
btwrite_vdelay_lo(bt);
btwrite_vactive_lo(bt);
btwrite_hdelay_lo(bt);
btwrite_hscale_hi(bt);
btwrite_hscale_lo(bt);
btwrite_control(bt);
btwrite_vscale_hi(bt);
btwrite_vscale_lo(bt);
}
}
static void
write_all(BT829Ptr bt)
{
bt_reset(bt);
propagate_changes(bt); /* ensure consistency */
btwrite_iform(bt);
btwrite_tdec(bt);
btwrite_crop(bt);
btwrite_vdelay_lo(bt);
btwrite_vactive_lo(bt);
btwrite_hdelay_lo(bt);
btwrite_hactive_lo(bt);
btwrite_hscale_hi(bt);
btwrite_hscale_lo(bt);
btwrite_bright(bt);
btwrite_control(bt);
btwrite_contrast_lo(bt);
btwrite_sat_u_lo(bt);
btwrite_sat_v_lo(bt);
btwrite_hue(bt);
btwrite_scloop(bt);
btwrite_wc_up(bt);
btwrite_oform(bt);
btwrite_vscale_hi(bt);
btwrite_vscale_lo(bt);
btwrite_vpole(bt);
btwrite_adelay(bt);
btwrite_bdelay(bt);
btwrite_adc(bt);
btwrite_vtc(bt);
/* btwrite_cc_status(bt); *//* FIXME: CC code needs cleaning */
btwrite_wc_dn(bt);
btwrite_p_io(bt);
}
/*
* Public functions
*/
BT829Ptr
bt829_Detect(I2CBusPtr b, I2CSlaveAddr addr)
{
BT829Ptr bt;
I2CByte a;
bt = calloc(1, sizeof(BT829Rec));
if (bt == NULL)
return NULL;
bt->d.DevName = strdup("BT829 video decoder");
bt->d.SlaveAddr = addr;
bt->d.pI2CBus = b;
bt->d.NextDev = NULL;
bt->d.StartTimeout = b->StartTimeout;
bt->d.BitTimeout = b->BitTimeout;
bt->d.AcknTimeout = b->AcknTimeout;
bt->d.ByteTimeout = b->ByteTimeout;
if (!I2C_WriteRead(&(bt->d), NULL, 0, &a, 1)) {
free(bt);
return NULL;
}
bt->id = btread(bt, IDCODE);
free(bt->d.DevName);
bt->d.DevName = calloc(200, sizeof(char));
switch (BTVERSION) {
case BT815:
sprintf(bt->d.DevName, "bt815a video decoder, revision %d",
bt->id & 0xf);
break;
case BT817:
sprintf(bt->d.DevName, "bt817a video decoder, revision %d",
bt->id & 0xf);
break;
case BT819:
sprintf(bt->d.DevName, "bt819a video decoder, revision %d",
bt->id & 0xf);
break;
case BT827:
sprintf(bt->d.DevName, "bt827a/b video decoder, revision %d",
bt->id & 0xf);
break;
case BT829:
sprintf(bt->d.DevName, "bt829a/b video decoder, revision %d",
bt->id & 0xf);
break;
default:
sprintf(bt->d.DevName,
"bt8xx/unknown video decoder version %d, revision %d",
bt->id >> 4, bt->id & 0xf);
break;
}
/* set default parameters */
if (!I2CDevInit(&(bt->d))) {
free(bt);
return NULL;
}
bt->tunertype = 1;
bt->brightness = 0; /* hardware default */
bt->ccmode = 0;
bt->code = 0; /* hardware default */
bt->contrast = 216; /* hardware default */
bt->format = BT829_NTSC;
bt->height = 480; /* hardware default for vactive */
bt->hue = 0; /* hardware default */
bt->len = 1; /* hardware default */
bt->mux = BT829_MUX0; /* hardware default */
bt->out_en = 0; /* hardware default */
bt->p_io = 0; /* hardware default */
bt->sat_u = 254; /* hardware default */
bt->sat_v = 180; /* hardware default */
bt->vbien = 0; /* hardware default */
bt->vbifmt = 0; /* hardware default */
bt->width = 640; /* hardware default for hactive */
bt->hdelay = 120; /* hardware default */
bt->hscale = 684; /* hardware default */
bt->vactive = 480; /* hardware default */
bt->vdelay = 22; /* hardware default */
bt->vscale = 0; /* hardware default */
bt->htotal = 754; /* NTSC */
bt->svideo_mux = 0; /* no s-video */
return bt;
}
int
bt829_ATIInit(BT829Ptr bt)
{
bt->code = 1;
bt->len = 0;
bt->vbien = 1;
bt->vbifmt = 1;
bt->svideo_mux = BT829_MUX1;
write_all(bt);
return 0;
}
int
bt829_SetFormat(BT829Ptr bt, CARD8 format)
{
if ((format < 1) || (format > 7))
return -1;
if ((BTVERSION <= BT819) && (format != BT829_NTSC) && (format != BT829_PAL))
return -1;
if (format == bt->format)
return 0;
bt->format = format;
propagate_changes(bt);
btwrite_iform(bt);
btwrite_scloop(bt);
btwrite_adelay(bt);
btwrite_bdelay(bt);
btwrite_vtc(bt);
return 0;
}
int
bt829_SetMux(BT829Ptr bt, CARD8 mux)
{
if ((mux < 1) || (mux > 3))
return -1;
if (mux == bt->mux)
return 0;
bt->mux = mux;
/* propagate_changes(bt); *//* no dependencies */
btwrite_iform(bt);
btwrite_control(bt);
btwrite_adc(bt);
return 0;
}
void
bt829_SetBrightness(BT829Ptr bt, int brightness)
{
brightness = LIMIT(brightness, -1000, 999); /* ensure -128 <= brightness <= 127 below */
brightness = (128 * brightness) / 1000;
if (brightness == bt->brightness)
return;
bt->brightness = brightness;
/* propagate_changes(bt); *//* no dependencies */
btwrite_bright(bt);
}
void
bt829_SetContrast(BT829Ptr bt, int contrast)
{
contrast = LIMIT(contrast, -1000, 1000);
contrast = (216 * (contrast + 1000)) / 1000;
if (contrast == bt->contrast)
return;
bt->contrast = contrast;
/* propagate_changes(bt); *//* no dependencies */
btwrite_control(bt);
btwrite_contrast_lo(bt);
}
void
bt829_SetSaturation(BT829Ptr bt, int saturation)
{
CARD16 sat_u, sat_v;
saturation = LIMIT(saturation, -1000, 1000);
sat_u = (254 * (saturation + 1000)) / 1000;
sat_v = (180 * (saturation + 1000)) / 1000;
if ((sat_u == bt->sat_u) && (sat_v == bt->sat_v))
return;
bt->sat_u = sat_u;
bt->sat_v = sat_v;
/* propagate_changes(bt); *//* no dependencies */
btwrite_control(bt);
btwrite_sat_u_lo(bt);
btwrite_sat_v_lo(bt);
}
void
bt829_SetTint(BT829Ptr bt, int hue)
{
hue = LIMIT(hue, -1000, 999); /* ensure -128 <= hue <= 127 below */
hue = (128 * hue) / 1000;
if (hue == bt->hue)
return;
bt->hue = hue;
/* propagate_changes(bt); *//* no dependencies */
btwrite_hue(bt);
}
int
bt829_SetCaptSize(BT829Ptr bt, int width, int height)
{
if ((width > bt->htotal - 2 * HCROP) ||
(16 * width < bt->htotal - 32 * HCROP))
return -1;
if ((height > bt->vactive) || (16 * height < bt->vactive))
return -1;
if ((width == bt->width) && (height == bt->height))
return 0;
bt->width = width;
bt->height = height;
propagate_changes(bt);
btwrite_crop(bt);
btwrite_hactive_lo(bt);
btwrite_control(bt);
btwrite_vtc(bt);
return 0;
}
int
bt829_SetCC(BT829Ptr bt)
{ /* FIXME: should take ccmode as a parameter */
if (BTVERSION < BT827)
return -1; /* can't do it */
/* propagate_changes(bt); *//* no dependencies */
btwrite_cc_status(bt);
/* we write to STATUS to reset the CCVALID flag */
if (bt->ccmode != 0)
btwrite_status(bt);
return 0;
}
void
bt829_SetOUT_EN(BT829Ptr bt, BOOL out_en)
{
out_en = (out_en != 0);
if (out_en == bt->out_en)
return;
bt->out_en = out_en;
/* propagate_changes(bt); *//* no dependencies */
btwrite_vpole(bt);
}
void
bt829_SetP_IO(BT829Ptr bt, CARD8 p_io)
{
if (p_io == bt->p_io)
return;
bt->p_io = p_io;
/* propagate_changes(bt); *//* no dependencies */
btwrite_p_io(bt);
}
#define BTREAD(R) btread(bt,(R))
#if 0
void
bt829_getCCdata(BT829Ptr bt, struct CCdata *data)
{
CARD8 status;
data->num_valid = 0;
/* wait for buffer to be half full (means 8/16 bytes)
* either 4 (one of CC/EDS) or 2 (both CC/EDS) frames */
if (!(BTREAD(STATUS) & 0x04))
return; /* could comment this line */
for (; data->num_valid < CC_FIFO_SIZE; data->num_valid++) {
status = BTREAD(CC_STATUS);
if (!(status & 0x04))
break;
data->data[data->num_valid] = BTREAD(CC_DATA) & 0x7f;
/* stripped high bit (parity) */
data->status[data->num_valid] = (CCS_EDS * ((status & 0x02) >> 1)) |
(CCS_HIGH * (status & 0x01)) |
(CCS_OVER * ((status & 0x08) >> 3)) |
(CCS_PAR * ((status & 0x80) >> 7));
}
btwrite(bt, STATUS, 0x00); /* Reset CCVALID status bit */
return;
}
#endif
/* ------------------------------------------------------------------------ */
/* Debug and report routines */
#define DUMPREG(REG) \
xf86DrvMsg(bt->d.pI2CBus->scrnIndex,X_INFO," %-12s (0x%02X) = 0x%02X\n", \
#REG,REG,BTREAD(REG))
/*static void bt829_dumpregs(BT829Ptr bt)
{
DUMPREG(STATUS);
DUMPREG(IFORM);
DUMPREG(TDEC);
DUMPREG(CROP);
DUMPREG(VDELAY_LO);
DUMPREG(VACTIVE_LO);
DUMPREG(HDELAY_LO);
DUMPREG(HACTIVE_LO);
DUMPREG(HSCALE_HI);
DUMPREG(HSCALE_LO);
DUMPREG(BRIGHT);
DUMPREG(CONTROL);
DUMPREG(CONTRAST_LO);
DUMPREG(SAT_U_LO);
DUMPREG(SAT_V_LO);
DUMPREG(HUE);
if (BTVERSION >= BT827) {
DUMPREG(SCLOOP);
DUMPREG(WC_UP) ; }
DUMPREG(OFORM);
DUMPREG(VSCALE_HI);
DUMPREG(VSCALE_LO);
DUMPREG(TEST);
DUMPREG(VPOLE);
DUMPREG(IDCODE);
DUMPREG(ADELAY);
DUMPREG(BDELAY);
DUMPREG(ADC);
if (BTVERSION >= BT827) {
DUMPREG(VTC);
DUMPREG(CC_STATUS);
DUMPREG(CC_DATA);
DUMPREG(WC_DN);
DUMPREG(P_IO) ; }
}*/