/****************************************************************************
 * CAPUTIL.C                                                                *
 *                                                                          *
 * Purpose: Basic capture functions, to enable and setup the capture engine *
 *          of the Rage 128.                                                *
 *                                                                          *
 * Copyright (C) 1999 ATI Technologies Inc.  All rights reserved.           *
 ****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "main.h"
#include "defines.h"
#include "regdef.h"


/****************************************************************************
 * R128_InitCaptureDescriptor (CAPTURE_DESCRIPTOR *cap)                     *
 *  Function: Initializes the CAPTURE_DESCRIPTOR structure                  *
 *    Inputs: CAPTURE_DESCRIPTOR * cap - pointer to CAPTURE_DESCRIPTOR      *
 *            structure that will be initialized.                           *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void R128_InitCaptureDescriptor (CAPTURE_DESCRIPTOR *cap)
{
    cap->buf0_offset = 0;
    cap->buf0_even_offset = 0;
    cap->buf1_offset = 0;
    cap->buf1_even_offset = 0;
    cap->vbi_even_offset = 0;
    cap->vbi_odd_offset = 0;
    cap->one_shot_buf_offset = 0;
    cap->buf_pitch = 0;
    cap->width = 640; // default capture width
    cap->height = 240; // default capture height
    cap->input_mode = CAP_MODE_ONE_SHOT; // one shot mode default
    cap->start_field = 0; // start with odd field
    cap->start_buf = 0; // start with BUF0
    cap->buf_type = CAP_BUF_TYPE_FIELD; // capture FIELDs
    cap->one_shot_mode = CAP_BUF_TYPE_FIELD; // capture FIELDs
    cap->buf_mode = CAP_BUF_MODE_SINGLE;
    cap->mirror_en = 0; // disable mirroring
    cap->one_shot_mirror_en = 0; // disable mirroring
    cap->video_signed_uv = 0; // do not convert uv
    cap->horz_down = 0; // leave as normal
    cap->vert_down = 0; // leave as normal
    //cap->stream_format = CAP_STREAM_FORMAT_BT; // set format to BrookTree
    cap->stream_format = CAP_STREAM_FORMAT_CCIR656; // set format to CCIR656
    cap->hdwns_dec = CAP_HDWNS_DEC_DECIMATE; // set to decimation by default
    cap->vdwns_dec = CAP_VDWNS_DEC_DECIMATE; // set to decimation by default
    cap->video_in_format = CAP_VIDEO_IN_FORMAT_VYUY422;

    return;
} // R128_InitCaptureDescriptor ()...

/****************************************************************************
 * R128_InitCapture (void)                                                  *
 *  Function: Initializes the Rage 128 capture engine, setting a single     *
 *            capture buffer, basic setup for the Bt8x9 decoder stream.     *
 *    Inputs: CAPTURE_DESCRIPTOR *cap                                       *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void R128_InitCapture (CAPTURE_DESCRIPTOR *cap)
{
    DWORD temp;

    R128_WaitForFifo (13);

    regw (CAP0_BUF0_OFFSET, cap->buf0_offset);
    regw (CAP0_BUF0_EVEN_OFFSET, cap->buf0_even_offset);
    regw (CAP0_BUF1_OFFSET, cap->buf1_offset);
    regw (CAP0_BUF1_EVEN_OFFSET, cap->buf1_even_offset);

    // We program this even though we don't use it, otherwise enabling
    // TRIG_CNTL can write to this buffer pointer as well!
    regw (CAP0_ONESHOT_BUF_OFFSET, cap->one_shot_buf_offset);

    regw (CAP0_BUF_PITCH, cap->buf_pitch);  // multiply by 2, because YUV422 is 2 bytes/pixel

    regw (CAP0_V_WINDOW, IGNORE_VBI | (IGNORE_VBI + cap->height << 16));

    // This is in bytes, not pixels
    regw (CAP0_H_WINDOW, 0 | ((cap->width)<<17) );

    // 8 bit for BT, 16 bit for ZV.  Use lower byte.
    regw (CAP0_PORT_MODE_CNTL, 0);

    // Set up CAP0_CONFIG for the following:
    // CAP0_VIDEO_IN_FORMAT - YVYU
    // CAP0_INPUT_MODE - continuous
    // CAP0_BUF_TYPE - alternating
    R128_SetCaptureConfig (cap);

    regw (CAP0_TRIG_CNTL, 0);    // Initially capture is disabled

    // Turn Debug off
    regw (TEST_DEBUG_CNTL, 0);

    // Connect Capture engine to AMC connector
    temp = regr (VIDEOMUX_CNTL);

    regw (VIDEOMUX_CNTL,  regr (VIDEOMUX_CNTL) | 0x01);
    //regw (VIDEOMUX_CNTL,  regr (VIDEOMUX_CNTL) & 0xFFFFFFFD);

} // R128_InitCapture ()...

/****************************************************************************
 * R128_EnableCapture (void)                                                *
 *  Function: Triggers the Rage 128 capture engine                          *
 *    Inputs: NONE                                                          *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void R128_EnableCapture (void)
{
    // Select the CLOCK the capture engine will be using
    // Set it to PCLK
    PLL_regw (FCP_CNTL, 0x00000101);
    // CAP0_TRIG_CNTL__CAP0_TRIGGER_W | CAP0_TRIG_CNTL__CAP0_EN
    regw (CAP0_TRIG_CNTL, 0x00000011);
}

/****************************************************************************
 * R128_DisableCapture (void)                                               *
 *  Function: Shuts down the Rage 128 capture engine                        *
 *    Inputs: NONE                                                          *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void R128_DisableCapture (void)
{
    regw (CAP0_TRIG_CNTL, 0);
    // Disable the capture engines clock (set to ground)
    PLL_regw (FCP_CNTL, 0x00000404);
}


/****************************************************************************
 * R128_SetCaptureConfig (CAPTURE_DESCRIPTOR *cap)                          *
 *  Function: Initializes the Rage 128 capture engine, setting a single     *
 *            capture buffer, basic setup for the Bt8x9 decoder stream.     *
 *    Inputs: CAPTURE_DESCRIPTOR *cap                                       *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void R128_SetCaptureConfig (CAPTURE_DESCRIPTOR *cap)
{
    DWORD temp;

    temp = cap->input_mode | cap->start_field | cap->start_buf |
           cap->buf_type | cap->one_shot_mode | cap->buf_mode |
           cap->mirror_en | cap->one_shot_mirror_en |
           cap->video_signed_uv | cap->horz_down | cap->vert_down |
           cap->stream_format | cap->hdwns_dec | cap->vdwns_dec |
           cap->video_in_format;

    R128_WaitForFifo (1);
    regw (CAP0_CONFIG, temp);
}
