Well actually no patch because I managed to mess up my original changes.
But here are the changed files in all their glory...
Changes:
- I swapped the field address registers around because the image on my TV
was a bit jumpy and AFAIK matroxfb uses them this way. The jumping might
have been caused by something else though. They are write-only so I can't
check how they are programmed in Windows.
- hsync, vsync, and preload registers don't effect the output but I've
programmed them to 0 just in case. Oh and I got rid of programming the
fieldline registers since they don't seem to make any difference and
they aren't programmed in Windows either. fieldpol and fieldlength seem to
belong to this category as well.
- Most importantly I tried to clean up the maven code and hopefully I got
rid of the problem where maven would get somehow confused and drop part of
the input data. Also I was able to find the correct sequence to
programming the registers. Now all the registers match that in Windows and
maven doesn't get turned off in the process :)
Todo:
- hue, saturation etc.
- deflicker mode
- vsync support
- maybe something else?
Comments? Test reports? Somebody say something... :)
--
Ville Syrj�l�
[EMAIL PROTECTED]
http://www.sci.fi/~syrjala/
/*
(c) Copyright 2000-2002 convergence integrated media GmbH.
(c) Copyright 2002 convergence GmbH.
All rights reserved.
Written by Denis Oliver Kropp <[EMAIL PROTECTED]>,
Andreas Hundt <[EMAIL PROTECTED]>,
Sven Neumann <[EMAIL PROTECTED]> and
Ville Syrjala <[EMAIL PROTECTED]>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <directfb.h>
#include <core/fusion/shmalloc.h>
#include <core/coredefs.h>
#include <core/coretypes.h>
#include <core/gfxcard.h>
#include <core/fbdev.h>
#include <core/layers.h>
#include <core/surfaces.h>
#include <core/windows.h>
#include <misc/mem.h>
#include "regs.h"
#include "mmio.h"
#include "matrox.h"
#include "matrox_maven.h"
typedef struct {
bool listener_running;
DFBDisplayLayerConfig config;
/* Stored registers */
struct {
/* CRTC2 */
__u32 c2CTL;
__u32 c2DATACTL;
__u32 c2MISC;
__u32 c2OFFSET;
__u32 c2HPARAM;
__u32 c2HSYNC;
__u32 c2VPARAM;
__u32 c2VSYNC;
__u32 c2PRELOAD;
__u32 c2STARTADD0;
__u32 c2STARTADD1;
__u32 c2PL2STARTADD0;
__u32 c2PL2STARTADD1;
__u32 c2PL3STARTADD0;
__u32 c2PL3STARTADD1;
__u32 c2SPICSTARTADD0;
__u32 c2SPICSTARTADD1;
__u32 c2SUBPICLUT;
__u32 c2VCOUNT;
} regs;
struct maven_data md;
struct mavenregs mr;
} MatroxCrtc2LayerData;
static void crtc2_set_regs( MatroxDriverData *mdrv, MatroxCrtc2LayerData *mcrtc2 );
static void crtc2_calc_regs( MatroxDriverData *mdrv, MatroxCrtc2LayerData *mcrtc2,
DisplayLayer *layer );
static void crtc2_set_buffer( MatroxDriverData *mdrv, MatroxCrtc2LayerData *mcrtc2,
DisplayLayer *layer );
#define CRTC2_SUPPORTED_OPTIONS (DLOP_DEINTERLACING)
/**********************/
static int
crtc2LayerDataSize()
{
return sizeof(MatroxCrtc2LayerData);
}
static DFBResult
crtc2InitLayer( GraphicsDevice *device,
DisplayLayer *layer,
DisplayLayerInfo *layer_info,
DFBDisplayLayerConfig *default_config,
DFBColorAdjustment *default_adj,
void *driver_data,
void *layer_data )
{
MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data;
volatile __u8 *mmio = mdrv->mmio_base;
/* set capabilities and type */
layer_info->desc.caps = DLCAPS_SURFACE |
DLCAPS_BRIGHTNESS | DLCAPS_CONTRAST |
DLCAPS_HUE | DLCAPS_SATURATION;
layer_info->desc.type = DLTF_GRAPHICS | DLTF_VIDEO | DLTF_STILL_PICTURE;
/* set name */
snprintf( layer_info->name,
DFB_DISPLAY_LAYER_INFO_NAME_LENGTH, "Matrox CRTC2" );
/* fill out the default configuration */
default_config->flags = DLCONF_WIDTH | DLCONF_HEIGHT |
DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE |
DLCONF_OPTIONS;
default_config->width = 720;
default_config->height = dfb_config->matrox_ntsc ? 486 : 576;
default_config->pixelformat = DSPF_YUY2;
default_config->buffermode = DLBM_FRONTONLY;
default_config->options = DLOP_NONE;
/* fill out default color adjustment,
only fields set in flags will be accepted from applications */
default_adj->flags = DCAF_BRIGHTNESS | DCAF_CONTRAST |
DCAF_HUE | DCAF_SATURATION;
default_adj->brightness = 0x8000;
default_adj->contrast = 0x8000;
default_adj->hue = 0x8000;
default_adj->saturation = 0x8000;
/* disable crtc2 */
mga_out32( mmio, 0, C2CTL );
mga_out32( mmio, 8, C2CTL );
maven_open( &mcrtc2->md );
return DFB_OK;
}
static void
crtc2OnOff( MatroxDriverData *mdrv,
MatroxCrtc2LayerData *mcrtc2,
int on )
{
volatile __u8 *mmio = mdrv->mmio_base;
if (on) {
uint8 val;
val = mga_in_dac( mmio, XMISCCTRL );
/*
* mfcsel = 01 (MAFC)
* vdoutsel = 110 (CRTC2 ITU-R 656)
*/
val &= 0x19;
val |= 0xC2;
mga_out_dac( mmio, XMISCCTRL, val );
}
if (on)
/* c2en = 1 */
mcrtc2->regs.c2CTL |= 1;
else
/* c2en = 0 */
mcrtc2->regs.c2CTL &= ~1;
mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL );
if (on)
/* c2pixclkdis = 0 */
mcrtc2->regs.c2CTL &= ~8;
else
/* c2pixclkdis = 1 */
mcrtc2->regs.c2CTL |= 8;
mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL );
if (on) {
/* c2interlace = 1 */
mcrtc2->regs.c2CTL |= (1 << 25);
mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL );
}
}
static DFBResult
crtc2Enable( DisplayLayer *layer,
void *driver_data,
void *layer_data )
{
MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data;
/* enable crtc2 */
crtc2OnOff( mdrv, mcrtc2, 1 );
return DFB_OK;
}
static DFBResult
crtc2Disable( DisplayLayer *layer,
void *driver_data,
void *layer_data )
{
MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data;
/* disable crtc2 */
crtc2OnOff( mdrv, mcrtc2, 0 );
return DFB_OK;
}
static DFBResult
crtc2TestConfiguration( DisplayLayer *layer,
void *driver_data,
void *layer_data,
DFBDisplayLayerConfig *config,
DFBDisplayLayerConfigFlags *failed )
{
DFBDisplayLayerConfigFlags fail = 0;
if (config->options & ~CRTC2_SUPPORTED_OPTIONS)
fail |= DLCONF_OPTIONS;
switch (config->pixelformat) {
case DSPF_ARGB:
case DSPF_RGB32:
case DSPF_RGB15:
case DSPF_RGB16:
case DSPF_YUY2:
case DSPF_UYVY:
case DSPF_I420:
case DSPF_YV12:
break;
default:
fail |= DLCONF_PIXELFORMAT;
}
if (config->width != 720)
fail |= DLCONF_WIDTH;
if (config->height != (dfb_config->matrox_ntsc ? 486 : 576))
fail |= DLCONF_HEIGHT;
if (failed)
*failed = fail;
if (fail)
return DFB_UNSUPPORTED;
return DFB_OK;
}
static DFBResult
crtc2SetConfiguration( DisplayLayer *layer,
void *driver_data,
void *layer_data,
DFBDisplayLayerConfig *config )
{
MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data;
/* remember configuration */
mcrtc2->config = *config;
maven_set_mode( &mcrtc2->md, dfb_config->matrox_ntsc ? MODE_NTSC : MODE_PAL );
maven_compute( &mcrtc2->md, &mcrtc2->mr );
crtc2_calc_regs( mdrv, mcrtc2, layer );
crtc2OnOff( mdrv, mcrtc2, 0 );
crtc2_set_regs( mdrv, mcrtc2 );
crtc2_set_buffer( mdrv, mcrtc2, layer );
crtc2OnOff( mdrv, mcrtc2, 1 );
maven_program( &mcrtc2->md, &mcrtc2->mr );
return DFB_OK;
}
static DFBResult
crtc2FlipBuffers( DisplayLayer *layer,
void *driver_data,
void *layer_data,
DFBSurfaceFlipFlags flags )
{
MatroxDriverData *mdrv = (MatroxDriverData*) driver_data;
MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data;
CoreSurface *surface = dfb_layer_surface( layer );
dfb_surface_flip_buffers( surface );
crtc2_set_buffer( mdrv, mcrtc2, layer );
#if 0
// FIXME modify matroxfb-vsync-irq patch?
if (flags & DSFLIP_WAITFORSYNC)
crtc2_wait_vsync();
#endif
return DFB_OK;
}
static DFBResult
crtc2SetColorAdjustment( DisplayLayer *layer,
void *driver_data,
void *layer_data,
DFBColorAdjustment *adj )
{
// FIXME
return DFB_OK;
}
DisplayLayerFuncs matroxCrtc2Funcs = {
LayerDataSize: crtc2LayerDataSize,
InitLayer: crtc2InitLayer,
Enable: crtc2Enable,
Disable: crtc2Disable,
TestConfiguration: crtc2TestConfiguration,
SetConfiguration: crtc2SetConfiguration,
FlipBuffers: crtc2FlipBuffers,
SetColorAdjustment: crtc2SetColorAdjustment
};
/* internal */
static void crtc2_set_regs( MatroxDriverData *mdrv, MatroxCrtc2LayerData *mcrtc2 )
{
volatile __u8 *mmio = mdrv->mmio_base;
mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL);
mga_out32( mmio, mcrtc2->regs.c2DATACTL, C2DATACTL);
mga_out32( mmio, mcrtc2->regs.c2HPARAM, C2HPARAM);
mga_out32( mmio, mcrtc2->regs.c2VPARAM, C2VPARAM);
mga_out32( mmio, mcrtc2->regs.c2HSYNC, C2HSYNC);
mga_out32( mmio, mcrtc2->regs.c2VSYNC, C2VSYNC);
mga_out32( mmio, mcrtc2->regs.c2MISC, C2MISC);
mga_out32( mmio, mcrtc2->regs.c2PRELOAD, C2PRELOAD);
}
static void crtc2_calc_regs( MatroxDriverData *mdrv, MatroxCrtc2LayerData *mcrtc2,
DisplayLayer *layer )
{
CoreSurface *surface = dfb_layer_surface( layer );
mcrtc2->regs.c2CTL = 0;
/* c2pixcksel = 01 (vdoclk) */
mcrtc2->regs.c2CTL |= (1 << 1);
/* c2vidrstmod = 01 */
mcrtc2->regs.c2CTL |= (1 << 28);
/* c2hploaden = 1 */
mcrtc2->regs.c2CTL |= (1 << 30);
/* c2vploaden = 1 */
mcrtc2->regs.c2CTL |= (1 << 31);
mcrtc2->regs.c2DATACTL = 0;
switch (surface->format) {
case DSPF_I420:
case DSPF_YV12:
case DSPF_UYVY:
case DSPF_YUY2:
/* c2dithen = 1 */
mcrtc2->regs.c2DATACTL |= (1 << 0);
/* c2yfiltend = 1 */
mcrtc2->regs.c2DATACTL |= (1 << 1);
/* c2cbcrfilten = 1 */
mcrtc2->regs.c2DATACTL |= (1 << 2);
break;
default:
break;
}
/* c2ntscen */
if (dfb_config->matrox_ntsc)
mcrtc2->regs.c2DATACTL |= (1 << 4);
/* pixel format settings */
switch (surface->format) {
case DSPF_I420:
case DSPF_YV12:
/* c2depth = 111 */
mcrtc2->regs.c2CTL |= (7 << 21);
break;
case DSPF_UYVY:
/* c2uyvyfmt = 1 */
mcrtc2->regs.c2DATACTL |= (1 << 7);
/* fall through */
case DSPF_YUY2:
/* c2depth = 101 */
mcrtc2->regs.c2CTL |= (5 << 21);
break;
case DSPF_RGB15:
/* c2depth = 001 */
mcrtc2->regs.c2CTL |= (1 << 21);
break;
case DSPF_RGB16:
/* c2depth = 010 */
mcrtc2->regs.c2CTL |= (2 << 21);
break;
case DSPF_RGB32:
case DSPF_ARGB:
/* c2depth = 100 */
mcrtc2->regs.c2CTL |= (4 << 21);
break;
default:
BUG( "unexpected pixelformat" );
return;
}
{
int hdisplay, htotal, vdisplay, vtotal;
if (dfb_config->matrox_ntsc) {
hdisplay = 720;
htotal = 858;
vdisplay = 486 / 2;
vtotal = 525 / 2;
} else {
hdisplay = 720;
htotal = 864;
vdisplay = 576 / 2;
vtotal = 625 / 2;
}
mcrtc2->regs.c2HPARAM = ((hdisplay - 8) << 16) | (htotal - 8);
mcrtc2->regs.c2VPARAM = ((vdisplay - 1) << 16) | (vtotal - 1);
mcrtc2->regs.c2HSYNC = 0;
mcrtc2->regs.c2VSYNC = 0;
mcrtc2->regs.c2PRELOAD = 0;
mcrtc2->regs.c2MISC = 0;
/* c2vlinecomp */
mcrtc2->regs.c2MISC |= ((vdisplay + 2) << 16);
}
}
static void crtc2_set_buffer( MatroxDriverData *mdrv, MatroxCrtc2LayerData *mcrtc2,
DisplayLayer *layer )
{
CoreSurface *surface = dfb_layer_surface( layer );
SurfaceBuffer *front_buffer = surface->front_buffer;
volatile __u8 *mmio = mdrv->mmio_base;
/* interleaved fields */
mcrtc2->regs.c2OFFSET = front_buffer->video.pitch * 2;
mcrtc2->regs.c2STARTADD1 = front_buffer->video.offset;
mcrtc2->regs.c2STARTADD0 = front_buffer->video.offset + front_buffer->video.pitch;
switch (surface->format) {
case DSPF_I420:
mcrtc2->regs.c2PL2STARTADD1 = mcrtc2->regs.c2STARTADD1 +
surface->height *
front_buffer->video.pitch;
mcrtc2->regs.c2PL3STARTADD1 = mcrtc2->regs.c2PL2STARTADD1 +
surface->height/2 *
front_buffer->video.pitch/2;
mcrtc2->regs.c2PL2STARTADD0 = mcrtc2->regs.c2PL2STARTADD1 +
front_buffer->video.pitch/2;
mcrtc2->regs.c2PL3STARTADD0 = mcrtc2->regs.c2PL3STARTADD1 +
front_buffer->video.pitch/2;
break;
case DSPF_YV12:
mcrtc2->regs.c2PL3STARTADD1 = mcrtc2->regs.c2STARTADD1 +
surface->height *
front_buffer->video.pitch;
mcrtc2->regs.c2PL2STARTADD1 = mcrtc2->regs.c2PL3STARTADD1 +
surface->height/2 *
front_buffer->video.pitch/2;
mcrtc2->regs.c2PL3STARTADD0 = mcrtc2->regs.c2PL3STARTADD1 +
front_buffer->video.pitch/2;
mcrtc2->regs.c2PL2STARTADD0 = mcrtc2->regs.c2PL2STARTADD1 +
front_buffer->video.pitch/2;
break;
default:
break;
}
mga_out32( mmio, mcrtc2->regs.c2OFFSET, C2OFFSET );
mga_out32( mmio, mcrtc2->regs.c2STARTADD1, C2STARTADD1 );
mga_out32( mmio, mcrtc2->regs.c2STARTADD0, C2STARTADD0 );
mga_out32( mmio, mcrtc2->regs.c2PL2STARTADD1, C2PL2STARTADD1 );
mga_out32( mmio, mcrtc2->regs.c2PL2STARTADD0, C2PL2STARTADD0 );
mga_out32( mmio, mcrtc2->regs.c2PL3STARTADD1, C2PL3STARTADD1 );
mga_out32( mmio, mcrtc2->regs.c2PL3STARTADD0, C2PL3STARTADD0 );
}
/*
(c) 1998-2001 Petr Vandrovec <[EMAIL PROTECTED]>
This code originally comes from matroxfb.
Relicensed under the LGPL with the authors permission.
Adapted for CRTC2 ITU-R 656 mode by Ville Syrjala <[EMAIL PROTECTED]>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include "matrox_maven.h"
#define MAVEN_I2CID (0x1B)
static int maven_set_reg( int fd, __u8 reg, __u8 val )
{
__s32 err;
err = i2c_smbus_write_byte_data( fd, reg, val );
if (err)
fprintf( stderr, "maven_set_reg(0x%X) failed\n", reg );
return err;
}
static int maven_set_reg_pair( int fd, __u8 reg, __u16 val )
{
__s32 err;
err = i2c_smbus_write_word_data( fd, reg, val );
if (err)
fprintf( stderr, "maven_set_reg_pair(0x%X) failed\n", reg );
return err;
}
#define LR(x) maven_set_reg(fd, (x), m->regs[(x)])
#define LRP(x) maven_set_reg_pair(fd, (x), m->regs[(x)] | (m->regs[(x)+1] << 8))
/* external */
void maven_set_mode( struct maven_data *md,
int mode )
{
md->mode = mode;
}
void maven_compute( struct maven_data *md,
struct mavenregs *data )
{
static struct mavenregs palregs = { {
0x2A, 0x09, 0x8A, 0xCB, /* 00: chroma subcarrier */
0x00,
0x00, /* ? not written */
0x00, /* modified by code (F9 written...) */
0x00, /* ? not written */
0x7E, /* 08 */
0x3C, /* 09 */
0x82, /* 0A */
0x2E, /* 0B */
0x21, /* 0C */
0x00, /* ? not written */
0x3F, 0x03, /* 0E-0F */
0x3F, 0x03, /* 10-11 */
0x1A, /* 12 */
0x2A, /* 13 */
0x1C, 0x3D, 0x14, /* 14-16 */
0x9C, 0x01, /* 17-18 */
0x00, /* 19 */
0xFE, /* 1A */
0x7E, /* 1B */
0x60, /* 1C */
0x05, /* 1D */
0xC4, 0x01, /* 1E-1F */
0x95, /* 20 */
0x07, /* 21 */
0x95, /* 22 */
0x00, /* 23 */
0x00, /* 24 */
0x00, /* 25 */
0x08, /* 26 */
0x04, /* 27 */
0x00, /* 28 */
0x1A, /* 29 */
0x55, 0x01, /* 2A-2B */
0x20, /* 2C */
0x07, 0x7E, /* 2D-2E */
0x02, 0x54, /* 2F-30 */
0xB4, 0x00, /* 31-32 */
0x14, /* 33 */
0x49, /* 34 */
0x00, /* 35 written multiple times */
0x00, /* 36 not written */
0xA3, /* 37 */
0xC8, /* 38 */
0x22, /* 39 */
0x02, /* 3A */
0x22, /* 3B */
0x3F, 0x03, /* 3C-3D */
0x00, /* 3E written multiple times */
0x00, /* 3F not written */
}, MODE_PAL };
static struct mavenregs ntscregs = { {
0x21, 0xF0, 0x7C, 0x1F, /* 00: chroma subcarrier */
0x00,
0x00, /* ? not written */
0x00, /* modified by code (F9 written...) */
0x00, /* ? not written */
0x7E, /* 08 */
0x43, /* 09 */
0x7E, /* 0A */
0x3D, /* 0B */
0x00, /* 0C */
0x00, /* ? not written */
0x46, 0x03, /* 0E-0F */
0x3C, 0x02, /* 10-11 */
0x17, /* 12 */
0x21, /* 13 */
0x1B, 0x1B, 0x24, /* 14-16 */
0x83, 0x01, /* 17-18 */
0x00, /* 19 */
0x0F, /* 1A */
0x0F, /* 1B */
0x60, /* 1C */
0x05, /* 1D */
0xC4, 0x02, /* 1E-1F */
0x8E, /* 20 */
0x04, /* 21 */
0x8E, /* 22 */
0x01, /* 23 */
0x02, /* 24 */
0x00, /* 25 */
0x0A, /* 26 */
0x05, /* 27 */
0x00, /* 28 */
0x10, /* 29 */
0xFF, 0x03, /* 2A-2B */
0x18, /* 2C */
0x0F, 0x78, /* 2D-2E */
0x00, 0x00, /* 2F-30 */
0xB4, 0x00, /* 31-32 */
0x14, /* 33 */
0x02, /* 34 */
0x00, /* 35 written multiple times */
0x00, /* 36 not written */
0xA3, /* 37 */
0xC8, /* 38 */
0x15, /* 39 */
0x05, /* 3A */
0x15, /* 3B */
0x3C, 0x00, /* 3C-3D */
0x00, /* 3E written multiple times */
0x00, /* never written */
}, MODE_NTSC };
if (md->mode & MODE_PAL)
*data = palregs;
else
*data = ntscregs;
/* gamma correction registers */
data->regs[0x83] = 0x00;
data->regs[0x84] = 0x00;
data->regs[0x85] = 0x00;
data->regs[0x86] = 0x1F;
data->regs[0x87] = 0x10;
data->regs[0x88] = 0x10;
data->regs[0x89] = 0x10;
data->regs[0x8A] = 0x64; /* 100 */
data->regs[0x8B] = 0xC8; /* 200 */
/* Antiflicker mode */
data->regs[0x93] = 0x00;
}
void maven_program( struct maven_data* md,
const struct mavenregs* m )
{
int fd = md->fd;
maven_set_reg(fd, 0x3E, 0x01);
maven_set_reg(fd, 0x8C, 0x00);
maven_set_reg(fd, 0x94, 0xA2);
maven_set_reg_pair(fd, 0x8E, 0x1EFF);
maven_set_reg(fd, 0xC6, 0x01);
maven_set_reg(fd, 0x06, 0xF9);
/* chroma subcarrier */
LR(0x00); LR(0x01); LR(0x02); LR(0x03);
LR(0x04);
LR(0x2C);
LR(0x08);
LR(0x0A);
LR(0x09);
LR(0x29);
LRP(0x31);
LRP(0x17);
LR(0x0B);
LR(0x0C);
if (m->mode & MODE_PAL)
maven_set_reg(fd, 0x35, 0x10); /* ... */
else
maven_set_reg(fd, 0x35, 0x0F); /* ... */
LRP(0x10);
LRP(0x0E);
LRP(0x1E);
LR(0x20);
LR(0x22);
LR(0x25);
LR(0x34);
LR(0x33);
LR(0x19);
LR(0x12);
LR(0x3B);
LR(0x13);
LR(0x39);
LR(0x1D);
LR(0x3A);
LR(0x24);
LR(0x14);
LR(0x15);
LR(0x16);
LRP(0x2D);
LRP(0x2F);
LR(0x1A);
LR(0x1B);
LR(0x1C);
LR(0x23);
LR(0x26);
LR(0x28);
LR(0x27);
LR(0x21);
LRP(0x2A);
if (m->mode & MODE_PAL)
maven_set_reg(fd, 0x35, 0x1D); /* ... */
else
maven_set_reg(fd, 0x35, 0x1C);
LRP(0x3C);
LR(0x37);
LR(0x38);
maven_set_reg(fd, 0xB3, 0x01);
maven_set_reg(fd, 0x82, 0xA0);
maven_set_reg(fd, 0xD3, 0x01);
maven_set_reg(fd, 0x8C, 0x10);
maven_set_reg(fd, 0x94, 0xA2);
LR(0x33);
maven_set_reg(fd, 0x8D, 0x03);
maven_set_reg(fd, 0xB9, 0x78);
maven_set_reg(fd, 0xBF, 0x02);
LR(0x93); /* whoops */
LR(0x20); /* saturation #1 */
LR(0x22); /* saturation #2 */
LR(0x25); /* hue */
LRP(0x10);
LRP(0x0E);
LRP(0x1E);
/* load gamma correction stuff */
LR(0x83);
LR(0x84);
LR(0x85);
LR(0x86);
LR(0x87);
LR(0x88);
LR(0x89);
LR(0x8A);
LR(0x8B);
LR(0x33);
LR(0x19);
LR(0x12);
LR(0x3B);
LR(0x13);
LR(0x39);
LR(0x1D);
LR(0x3A);
LR(0x24);
LR(0x14);
LR(0x15);
LR(0x16);
LRP(0x2D);
LRP(0x2F);
LR(0x1A);
LR(0x1B);
LR(0x1C);
LR(0x23);
LR(0x26);
LR(0x28);
LR(0x27);
LR(0x21);
LRP(0x2A);
if (m->mode & MODE_PAL)
maven_set_reg(fd, 0x35, 0x1D);
else
maven_set_reg(fd, 0x35, 0x1C);
LRP(0x3C);
LR(0x37);
LR(0x38);
maven_set_reg(fd, 0xB0, 0x80);
maven_set_reg(fd, 0x82, 0x20);
maven_set_reg(fd, 0x3E, 0x00);
maven_set_reg(fd, 0xD4, 0x01);
maven_set_reg(fd, 0xD4, 0x00);
}
int maven_open( struct maven_data *md )
{
char dev[16] = "/dev/";
char line[256];
FILE *file;
int fd;
/* Locate maven /dev/i2c entry */
file = fopen( "/proc/bus/i2c", "r" );
if (!file)
return -1;
while (fgets( line, 256, file )) {
if (strstr( line, "MAVEN" )) {
strtok( line, " \t\n" );
strncat( dev, line, 10 );
break;
}
}
fclose( file );
if ((fd = open( dev, O_RDWR )) < 0) {
return -1;
}
if (ioctl( fd, I2C_SLAVE, MAVEN_I2CID ) < 0) {
close(fd);
return -1;
}
md->fd = fd;
md->mode = MODE_PAL;
return 0;
}
void maven_close( struct maven_data *md )
{
close( md->fd );
}