📄 dtv_ref3_audio.c
字号:
/*
* Copyright (c) 1995,1996,1997 by TriMedia Technologies.
*
* +------------------------------------------------------------------+
* | This software is furnished under a license and may only be used |
* | and copied in accordance with the terms and conditions of such |
* | a license and with the inclusion of this copyright notice. This |
* | software or any other copies of this software may not be provided|
* | or otherwise made available to any other person. The ownership |
* | and title of this software is not transferred. |
* | |
* | The information in this software is subject to change without |
* | any prior notice and should not be construed as a commitment by |
* | TriMedia Technologies. |
* | |
* | this code and information is provided "as is" without any |
* | warranty of any kind, either expressed or implied, including but |
* | not limited to the implied warranties of merchantability and/or |
* | fitness for any particular purpose. |
* +------------------------------------------------------------------+
*
* Module name : dtv_ref3_audio.c 1.5
*
* Last update : 18:59:26 - 00/11/09
*
* Description :
*
* Initialize and control routines for TM1 DTV 8 channel audio DAC.
* Designed to be called from TM Device Library's board support package
* This only contains Audio Out, since AI is handled by a daughter board
* (the NIM board).
*
* This audio module supports:
* stereo 16 bit
* all Four channel 16 bit modes
* Six channel 16 bit
* Eight channel 16 bit
* Six channel analog plus 2 channel IEC1937, in 8 ch format.
* (atfLinearPCM | atf1937), apfSevenDotOne16
*
* Other modes return resonable errors.
*
* Revision :
*
*
*
*/
/* TriMedia standard shared includes */
#include <tm1/tmAssert.h>
#include <tmlib/dprintf.h>
#include <tmlib/tmtypes.h>
#include <tm1/tmAOmmio.h>
#include <tm1/tmAImmio.h>
#include <tm1/tmIIC.h>
#include <tm1/tmProcessor.h>
#include <tm1/tmLibdevErr.h>
#include "tda1315.h"
#include "philips_dtv_ref3.h"
#include "dtv_ref3_audio.h"
/***********************************************************/
/* IIC Audio Out Expander description on REF3 (GOMAD) DTV Board (0x74)
0: L mode, DOut
1: L clock, DOut
2: L data, DOut
3: L strobe, DOut
4: Mute SPDIF TX
5: AOSD GATE
6: unused
7: unused
*/
/* Audio Mode is now control in FPGA
address 0x104
bit 0 AudioCh 0 0 = 2 ch, 1 = 4 ch,
bit 1 AudioCh 1 2 = 6 ch, 3 = 8 ch
bit 2 AudioData 1 = 16bit, 0= 32bit(20bit)
bit 3 Mute 0 = Mute, 1= unmute
bit 4 AudioReset 0 = reset, 1= unreset
bit 5 unused
bit 6 unused
bit 7 unused
Mode FPGA Reg4 bits
7654 3210
2 Channels xxxx xx00
4 Channels xxxx xx01
6 Channels xxxx xx10
8 Channels xxxx xx11
16 bit xxxx x1xx
32 bit xxxx x0xx
Mute xxxx 0xxx
unMute xxxx 1xxx
Reset xxx0 xxxx
unReset xxx1 xxxx
*/
/* AUDIO_MASTER_IIC_ADDRESS SPDIF control
address: 0x7A Audio master control
bit 0 ACS0_M
bit 1 ACS0_DATA
bit 2 ACS1_M
bit 3 ACS1_DATA
bit 4 MUTE
bit 5 DEMP
bit 6 PWRDWN
bit 7 unused
*/
#define __SET_OUTPUT_2_CHANS 0x00
#define __SET_OUTPUT_4_CHANS 0x01
#define __SET_OUTPUT_6_CHANS 0x02
#define __SET_OUTPUT_8_CHANS 0x03
#define __SET_OUTPUT_32_BITS 0x00
#define __SET_OUTPUT_16_BITS 0x04
#define __SET_MUTE_BIT 0x08
#define __SET_RESET_BIT 0x10
#define REF3_OUTPUT_FPGA_AUDIOMODE_MASK 0x1F
/* FPGA Audio mode Status register */
static unsigned char fpgaAudioMode = 0;
#define __DOUBLE_CLOCK_MODES (apfFiveDotOne32 | apfSevenDotOne32)
#define _CHANNEL_STATUS_REGISTER 0
#define _CONTROL_REGISTER 2
static Char outputL3Regs[4] = {0x0, 0x0, 0x0, 0x0};
static l3Param_t outputL3Params =
{
l3ModeIIC, /* mode */
L3_IIC_EXPANDER_ADDRESS, /* address */
TDA1315_L3_ADDRESS, /* l3Address */
REF3_OUTPUT_L3_DATA, /* l3Data */
REF3_OUTPUT_L3_MODE, /* l3Mode */
REF3_OUTPUT_L3_CLOCK, /* l3Clock */
REF3_OUTPUT_L3_STROBE, /* usrPin0 */
0, /* usrPin1 */
0, /* usrPin2 */
0, /* l3AddressAdd */
0, /* l3DataAdd */
0, /* l3ModeAdd */
0, /* l3ClockAdd */
0, /* usrPin0Add */
0, /* usrPin2Add */
0, /* usrPin3Add */
2, /* numberOfBytes */
Null /* data */
};
/* flag to indicate that the 32-bit mode is enabled */
static Bool dtvRef3DoubleDDSEnable = False;
static Float dtvRef3CPUClock = 0.0;
static Bool dtvRef3CPUisTM1100 = False;
static Bool dtvRef3AoRunning = False;
static Bool dtvRef3AoNeedToConfigureTDA1315 = False;
/*******************************************************/
extern tmLibdevErr_t dtv_ref3_AO_Init(boardAOParam_t * param)
{
UInt iicd;
Float val;
pprocCapabilities_t procCap;
Int err = TMLIBDEV_OK;
unsigned char *pAudioRegAddr = (unsigned char *) FPGA_AUDIO_REG_ADDRESS;
#if 0
param->maxSRate = 50000; /* TDA 1305, 32KHz,44.1KHz,48KHz supported */
param->minSRate = 20000;
#endif
/* Audio SPDIF output is enabled */
iicd = 0xFF;
iicd &= ~(SPDIF_MUTE | SPDIF_DEMP | SPDIF_PWRDWN);
iicWriteReg(AUDIO_MASTER_IIC_ADDRESS, -1, iicd);
/* get the clock frequency of the TriMedia CPU */
err = procGetCapabilities(&procCap);
if (err) return err;
dtvRef3CPUClock = (Float) procCap->cpuClockFrequency;
if (procCap->deviceID == PROC_DEVICE_TM1100)
{
dtvRef3CPUisTM1100 = True;
}
/* reset the audio output peripheral */
aoRESET();
/* Set initial frequency to get AO into a stable state */
val = param->sRate * 256.0; /* 256 * sampleRate */
if (dtvRef3CPUisTM1100)
{
val = 0.5 + (477218588.0 * (val / dtvRef3CPUClock)); /* 2**32 / 9 */
aoSetFREQ(((UInt) val) | 0x80000000);
}
else
{
val = 0.5 + (1431655765.0 * (val / dtvRef3CPUClock)); /* 2**32 / 3 */
aoSetFREQ((UInt) val);
}
aoEnableSER_MASTER();
microsleep(10); /* wait until AO unit stabalized */
if (! (param->audioTypeFormat & DTV_REF3_SUPPORTED_AUDIO_OUT_TYPES) )
return AIO_ERR_UNSUPPORTED_FORMAT;
if (! (param->audioSubtypeFormat & DTV_REF3_SUPPORTED_AUDIO_OUT_SUBTYPES) )
return AIO_ERR_UNSUPPORTED_FORMAT;
if (param->audioSubtypeFormat & __DOUBLE_CLOCK_MODES)
{
dtvRef3DoubleDDSEnable = True;
}
#ifdef __LITTLE_ENDIAN__
aoEnableLITTLE_ENDIAN();
#else
aoDisableLITTLE_ENDIAN();
#endif
aoMsbFirst();
aoStartRisingEdgeWS();
aoSampleRisingCLOCK_EDGE(); /* sample on rising edge */
aoSetTRANS_MODE(3); /* Set Audio output to Stereo 16 bits per channel */
aoSetSSPOS(0); /* Left and right channel start at bit 0 */
aoDisableSIGN_CONVERT(); /* Disable Sign Convert for MSB */
aoEnableWS_PULSE(); /* word strobe in pulse mode */
aoDisableTRANS_ENABLE();
fpgaAudioMode &= ~REF3_OUTPUT_FPGA_AUDIOMODE_MASK;
switch (param->audioSubtypeFormat) {
case apfStereo16: /* Two channel Audio */
{ /* 64 * 4 * 1 = 256fs */
DP(("stereo 16 bit\n"));
fpgaAudioMode |= (__SET_OUTPUT_2_CHANS | __SET_OUTPUT_16_BITS);
aoSetWSDIV(63);
aoSetSCKDIV(3);
aoSetSFDIV(0);
aoSetLEFTPOS(16);
aoSetRIGHTPOS(48);
aoSetSIZE(param->size);
if (param->audioTypeFormat & atf1937)
{
/* set tda1315 to transmit non-PCM data */
}
break;
}
case apfStereo32: /* Two channel Audio, 32-bit */
{ /* 32 * 4 * 2 = 256 fs */
DP(("stereo 32 bit\n"));
fpgaAudioMode |= (__SET_OUTPUT_2_CHANS | __SET_OUTPUT_32_BITS);
aoSetWSDIV(31);
aoSetSCKDIV(3);
aoSetSFDIV(1);
#ifdef __LITTLE_ENDIAN__
aoSetLEFTPOS(16);
aoSetRIGHTPOS(0);
#else
aoSetLEFTPOS(0);
aoSetRIGHTPOS(16);
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -