diff options
Diffstat (limited to 'board/aspeed/ast2300/vfun.c')
-rwxr-xr-x | board/aspeed/ast2300/vfun.c | 545 |
1 files changed, 545 insertions, 0 deletions
diff --git a/board/aspeed/ast2300/vfun.c b/board/aspeed/ast2300/vfun.c new file mode 100755 index 0000000000..f707e80787 --- /dev/null +++ b/board/aspeed/ast2300/vfun.c @@ -0,0 +1,545 @@ +/* + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define BUF_GLOBALS +#include "type.h" +#include "vdef.h" +#include "vreg.h" +#include "crt.h" +#include "vfun.h" + +ULONG UnlockSCURegHost(ULONG MMIOBase, ULONG Key) +{ + WriteMemoryLongHost(SCU_BASE, SCU_PROTECT_REG, Key); + return ReadMemoryLongHost(SCU_BASE,SCU_PROTECT_REG); +} + +void ResetVideoHost(void) +{ + WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CONTROL_REG, VIDEO_RESET_EN << VIDEO_ENGINE_RESET_BIT, VIDEO_ENGINE_RESET_MASK); + WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CONTROL_REG, VIDEO_RESET_OFF << VIDEO_ENGINE_RESET_BIT, VIDEO_ENGINE_RESET_MASK); +} + +void StartModeDetectionTriggerHost(ULONG MMIOBase, ULONG offset) +{ + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, MODE_DETECTION_TRIGGER); + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, MODE_DETECTION_TRIGGER, MODE_DETECTION_TRIGGER); +} + +BOOL ReadVideoInterruptHost(ULONG MMIOBase, ULONG value) +{ + return ((ReadMemoryLongHost(VIDEO_REG_BASE, VIDEO_INT_CONTROL_READ_REG) & value) ? TRUE : FALSE); +} + +ULONG UnlockVideoRegHost(ULONG MMIOBase, ULONG Key) +{ + WriteMemoryLongHost(VIDEO_REG_BASE, KEY_CONTROL_REG, Key); + return ReadMemoryLongHost(VIDEO_REG_BASE,KEY_CONTROL_REG); +} + +void StartVideoCaptureTriggerHost(ULONG MMIOBase, ULONG offset) +{ + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, VIDEO_CAPTURE_TRIGGER); + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, VIDEO_CAPTURE_TRIGGER, VIDEO_CAPTURE_TRIGGER); +} + +void StartVideoCodecTriggerHost(ULONG MMIOBase, ULONG offset) +{ + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, VIDEO_CODEC_TRIGGER); + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, VIDEO_CODEC_TRIGGER, VIDEO_CODEC_TRIGGER); +} + +void StopModeDetectionTriggerHost(ULONG MMIOBase, ULONG offset) +{ + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, offset, 0, MODE_DETECTION_TRIGGER); +} + +void ClearVideoInterruptHost(ULONG MMIOBase, ULONG value) +{ + //WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO_INT_CONTROL_CLEAR_REG, value, value); + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_INT_CONTROL_CLEAR_REG, value); +} + +/* UnLock SCU Host and Reset Engine */ +BOOL CheckOnStartHost(void) +{ + int i=0, dwValue=0; + + do + { + dwValue = UnlockSCURegHost(0, SCU_UNLOCK_KEY); + i++; + } + while ((SCU_WRITE_ENABLE != dwValue) && (i<10)); + + //Clear SCU Reset Register + WriteMemoryLongHost(SCU_BASE, SCU_CONTROL_REG, 0); + + WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, (EN_ECLK | EN_V1CLK | EN_V2CLK), (STOP_ECLK_MASK | STOP_V1CLK_MASK | STOP_V2CLK_MASK)); + +#if defined(CONFIG_AST2300) + WriteMemoryLongWithMASKHost(SCU_BASE, (0x90 + SCU_OFFSET), 0x00000020, 0x00000030); //enable 24bits + WriteMemoryLongWithMASKHost(SCU_BASE, (0x88 + SCU_OFFSET), 0x000fff00, 0x000fff00); //enable video multi-pins +#else //AST2100 + //WriteMemoryLongWithMASKHost(SCU_BASE, SCU_PIN_CTRL1_REG, (VIDEO_PORTA_EN | VIDEO_PORTB_EN | VIDEO_VP1_EN | VIDEO_VP2_EN) , + // (VIDEO_PORTA_MASK | VIDEO_PORTB_MASK | VIDEO_VP1_MASK | VIDEO_VP2_MASK)); + WriteMemoryLongWithMASKHost(SCU_BASE, SCU_PIN_CTRL2_REG, (VIDEO_PORTA_SINGLE_EDGE | VIDEO_PORTB_SINGLE_EDGE) , + (VIDEO_PORTA_SINGLE_EDGE_MASK | VIDEO_PORTB_SINGLE_EDGE_MASK)); +#endif + + ResetVideoHost(); + + return TRUE; +} + +BOOL CheckOnStartClient(void) +{ + int i=0, dwValue=0; + + do + { + dwValue = UnlockSCURegHost(0, SCU_UNLOCK_KEY); + i++; + } + while ((SCU_WRITE_ENABLE != dwValue) && (i<10)); + + //Clear SCU Reset Register + WriteMemoryLongClient(SCU_BASE, SCU_CONTROL_REG, 0); + + WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_STOP_REG, (EN_ECLK | EN_V1CLK | EN_D1CLK | EN_D2CLK | EN_V2CLK), + (STOP_ECLK_MASK | STOP_D1CLK_MASK | STOP_D2CLK_MASK | STOP_V1CLK_MASK | STOP_V2CLK_MASK)); + + //WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_SELECTION_REG, PORTB_FROM_D2CLK | PORTB_CLOCK_INV_DELAY_3NS | PORTA_CLOCK_INV_DELAY_3NS, PORTB_CLOCK_SEL | PORTB_CLOCK_DELAY_MASK | PORTA_CLOCK_DELAY_MASK); + //A1EVA + WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_SELECTION_REG, (PORTB_FROM_D2CLK | PORTB_CLOCK_INV_DELAY_1NS | PORTA_CLOCK_INV_DELAY_1NS), (PORTB_CLOCK_SEL | PORTB_CLOCK_DELAY_MASK | PORTA_CLOCK_DELAY_MASK)); + WriteMemoryLongWithMASKClient(SCU_BASE, 0x202C, (0x03<<9), (0x03<<9)); + + WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL1_REG, (VIDEO_PORTA_EN | VIDEO_PORTB_EN | VIDEO_VP1_EN | VIDEO_VP2_EN), + (VIDEO_PORTA_MASK | VIDEO_PORTB_MASK | VIDEO_VP1_MASK | VIDEO_VP2_MASK)); + +#if CONFIG_AST3000 + WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL2_REG, (VIDEO_PORTA_DUAL_EDGE | VIDEO_PORTB_DUAL_EDGE), + (VIDEO_PORTA_SINGLE_EDGE_MASK | VIDEO_PORTB_SINGLE_EDGE_MASK)); +#else + //2100 is single edge + WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL2_REG, (VIDEO_PORTA_SINGLE_EDGE | VIDEO_PORTB_SINGLE_EDGE), + (VIDEO_PORTA_SINGLE_EDGE_MASK | VIDEO_PORTB_SINGLE_EDGE_MASK)); +#endif + + WriteMemoryLongWithMASKClient(SCU_BASE, SCU_CLOCK_STOP_REG, (EN_D1CLK | EN_D2CLK), (STOP_D1CLK_MASK | STOP_D2CLK_MASK)); + WriteMemoryLongWithMASKClient(SCU_BASE, SCU_PIN_CTRL1_REG, VGA_PIN_OFF, VGA_PIN_MASK); + + //ResetVideoHost(); + + return TRUE; +} + +ULONG InitializeVideoEngineHost (ULONG MMIOBase, + int nVideo, + BOOL HorPolarity, + BOOL VerPolarity) +{ + //ULONG temp, temp1, temp2; + ULONG dwRegOffset = nVideo * 0x100; + ULONG dwValue; + int i; + + + /* General Video Control */ + //LineBufEn 0 + //dwValue = (COMPRESS_MODE << CODEC_DECOMPRESS_MODE_BIT) | DELAY_VSYNC_EN; + dwValue = 0; + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CONTROL_REG, dwValue); + //Video Data Truncation Register + WriteMemoryLongHost(VIDEO_REG_BASE, 0x328, 0); + + //D2CLK clock must config according to video's line buffer + if (VIDEO1 == nVideo) + dwValue = LINE_BUFFER_VIDEO1; + else + dwValue = LINE_BUFFER_VIDEO2; + + //D2CLK clock must config according to video's line buffer + switch (dwValue) + { + case LINE_BUFFER_OFF: + WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_SELECTION_REG, NORMAL_CRT1, D2CLK_CLOCK_SELECTION_MASK); + WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, STOP_D2CLK, STOP_D2CLK_MASK); + break; + case LINE_BUFFER_VIDEO1: + WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_SELECTION_REG, V1CLK_VIDEO1 << D2CLK_CLOCK_SELECTION_BIT, D2CLK_CLOCK_SELECTION_MASK); + WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, EN_D2CLK, STOP_D2CLK_MASK); + break; + case LINE_BUFFER_VIDEO2: + WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_SELECTION_REG, V1CLK_VIDEO2 << D2CLK_CLOCK_SELECTION_BIT, D2CLK_CLOCK_SELECTION_MASK); + WriteMemoryLongWithMASKHost(SCU_BASE, SCU_CLOCK_STOP_REG, EN_D2CLK, STOP_D2CLK_MASK); + break; + case LINE_BUFFER_VIDEOM: + //If select this option, it will config at videoM INIT + break; + default: + break; + } + + dwValue = 0; + //VR30 now is capture window in the compression + dwValue = g_DefHeight << CAPTURE_VER_LINE_BIT | + g_DefWidth << CAPTURE_HOR_PIXEL_BIT; + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CAPTURE_WINDOWS_REG + dwRegOffset, dwValue); + + dwValue = 0; + //VR34 now is destionation window in the compression + dwValue = g_DefHeight << COMPRESS_VER_LINE_BIT | + g_DefWidth << COMPRESS_HOR_PIXEL_BIT; + + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_WINDOWS_REG + dwRegOffset, dwValue); + + //BitCOUNT according compress data format + dwValue = YUV444_MODE; + if (YUV444_MODE == dwValue) + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV444, BUF_LINE_OFFSET_MASK); + else + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV420, BUF_LINE_OFFSET_MASK); + + // CRC + //Disable + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_PRIMARY_REG, 0x0); + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_SECOND_REG, 0x0); + + /* Sequence Control register */ + //Oonly Encoder need to set + /* Engine Sequence Contol Register */ + dwValue = (WATCH_DOG_EN << WATCH_DOG_ENABLE_BIT) | + VIDEO_CAPTURE_AUTO_MODE | + VIDEO_CODEC_AUTO_MODE; + + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG + dwRegOffset, dwValue); + + /* Control register */ + dwValue = (HOR_NEGATIVE == HorPolarity) ? NO_INVERSE_POL : INVERSE_POL; + dwValue = (((VER_NEGATIVE == VerPolarity) ? NO_INVERSE_POL : INVERSE_POL) << VIDEO_VSYNC_POLARITY_BIT) | dwValue; + + /* HW Recommand*/ + //dwValue = (TILE_MODE << 9) | dwValue; + dwValue = (EXTERNAL_VGA_SOURCE << EXTERNAL_SOURCE_BIT) | dwValue; + + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG + dwRegOffset, dwValue); + + /* BCD register */ + //NO BCD + dwValue = 0; + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BCD_CONTROL_REG + dwRegOffset, dwValue); + + /* Stream Buffer Size register */ + dwValue = (YUV_TEST << SKIP_TEST_MODE_BIT) | + (PACKET_SIZE_32KB << STREAM_PACKET_SIZE_BIT) | + (PACKETS_8 << RING_BUF_PACKET_NUM_BIT); + /* the same with Video1, Video2, and VideoM*/ + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_STREAM_BUF_SIZE, dwValue); + + /* Comression control register */ + dwValue = (USE_UV_CIR656 << UV_CIR656_FORMAT_BIT)| + (JPEG_MIX_MODE << JPEG_ONLY_BIT)| + (VQ_4_COLOR_MODE << VQ_4_COLOR_BIT)| + (QUANTI_CODEC_MODE << QUALITY_CODEC_SETTING_BIT)| + (7 << NORMAL_QUANTI_CHROMI_TABLE_BIT) | + (23 << NORMAL_QUANTI_LUMI_TABLE_BIT); + + //Video2 have same value as video1 + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_CONTROL_REG, dwValue); + + /* JPEG Quantization Table register */ + dwValue = 0; + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_TABLE_LOW_REG, dwValue); + + /* Quantization value register */ + //Video2 have same value as video1 + dwValue = 0; + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_VALUE_REG, dwValue); + + //Video BSD Parameter Register + //Video2 have same value as video1 + dwValue = 0; + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BSD_PARA_REG, dwValue); + + //no scale + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_REG, 0x10001000); + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER0_REG, 0x00200000); + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER1_REG, 0x00200000); + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER2_REG, 0x00200000); + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_SCALE_FACTOR_PARAMETER3_REG, 0x00200000); + return TRUE; +} + +ULONG InitializeVideoEngineClient (ULONG MMIOBase, + int nVideo) +{ + //ULONG temp, temp1, temp2; + ULONG dwRegOffset = nVideo * 0x100; + ULONG dwValue; + int i; + + + /* General Video Control */ + //LineBufEn 0 + dwValue = (DECOMPRESS_MODE << CODEC_DECOMPRESS_MODE_BIT); + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CONTROL_REG, dwValue); + //Video Data Truncation Register + WriteMemoryLongHost(VIDEO_REG_BASE, 0x328, 0); + + //VR30 now is capture window in the compression + dwValue = g_DefHeight << CAPTURE_VER_LINE_BIT | + g_DefWidth << CAPTURE_HOR_PIXEL_BIT; + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_CAPTURE_WINDOWS_REG + dwRegOffset, dwValue, CAPTURE_VER_LINE_MASK | CAPTURE_HOR_PIXEL_MASK); + + //VR34 now is destionation window in the compression + dwValue = g_DefHeight << COMPRESS_VER_LINE_BIT | + g_DefWidth << COMPRESS_HOR_PIXEL_BIT; + + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_WINDOWS_REG + dwRegOffset, dwValue, COMPRESS_VER_LINE_MASK | COMPRESS_HOR_PIXEL_MASK); + + //BitCOUNT according compress data format + dwValue = YUV444_MODE; + if (YUV444_MODE == dwValue) + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV444, BUF_LINE_OFFSET_MASK); + else + WriteMemoryLongWithMASKHost(VIDEO_REG_BASE, VIDEO1_BUF_LINE_OFFSET_REG + dwRegOffset, g_DefWidth * INPUT_BITCOUNT_YUV420, BUF_LINE_OFFSET_MASK); + + // CRC + //Disable + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_PRIMARY_REG, 0x0); + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO_CRC_SECOND_REG, 0x0); + + /* Sequence Control register */ + //Oonly Encoder need to set + /* Engine Sequence Contol Register */ + dwValue = VIDEO_CAPTURE_AUTO_MODE | + VIDEO_CODEC_AUTO_MODE; + + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_ENGINE_SEQUENCE_CONTROL_REG + dwRegOffset, dwValue); + + /* Control register */ + /* HW Recommand*/ + dwValue = (TILE_MODE << 9); + + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_CONTROL_REG + dwRegOffset, dwValue); + + /* BCD register */ + //NO BCD + dwValue = 0; + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BCD_CONTROL_REG + dwRegOffset, dwValue); + + /* Stream Buffer Size register */ + dwValue = (YUV_TEST << SKIP_TEST_MODE_BIT) | + (PACKET_SIZE_32KB << STREAM_PACKET_SIZE_BIT) | + (PACKETS_8 << RING_BUF_PACKET_NUM_BIT); + /* the same with Video1, Video2, and VideoM*/ + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_STREAM_BUF_SIZE, dwValue); + + + /* Comression control register */ + dwValue = (USE_UV_CIR656 << UV_CIR656_FORMAT_BIT)| + (JPEG_MIX_MODE << JPEG_ONLY_BIT)| + (VQ_4_COLOR_MODE << VQ_4_COLOR_BIT)| + (QUANTI_CODEC_MODE << QUALITY_CODEC_SETTING_BIT)| + (7 << NORMAL_QUANTI_CHROMI_TABLE_BIT) | + (23 << NORMAL_QUANTI_LUMI_TABLE_BIT); + + //Video2 have same value as video1 + if (VIDEO1 == nVideo) + { + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_COMPRESS_CONTROL_REG, dwValue); + } + else + { + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEOM_COMPRESS_CONTROL_REG, dwValue); + } + + /* JPEG Quantization Table register */ + dwValue = 0; + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_TABLE_LOW_REG, dwValue); + + /* Quantization value register */ + //Video2 have same value as video1 + dwValue = 0; + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_QUANTI_VALUE_REG, dwValue); + + //Video BSD Parameter Register + //Video2 have same value as video1 + dwValue = 0; + WriteMemoryLongHost(VIDEO_REG_BASE, VIDEO1_BSD_PARA_REG, dwValue); + + return TRUE; +} + +BYTE GetI2CRegClient(ULONG MMIOBase, + BYTE DeviceSelect, + BYTE DeviceAddress, + BYTE RegisterIndex) +{ + BYTE Data; + ULONG Status; + +// Reset + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 0); +// Set AC Timing and Speed + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x04, AC_TIMING); +// Lower Speed +// WriteMemoryLongWithANDData (VideoEngineInfo->VGAPCIInfo.ulMMIOBaseAddress, I2C_BASE + DeviceSelect * 0x40 + 0x04, 0, 0x33317805); + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x08, 0); +// Clear Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF); +// Enable Master Mode + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 1); +// Enable Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0xAF); +// BYTE I2C Mode +// Start and Send Device Address + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress); + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x3); +// Wait TX ACK + do { + Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03; + } while (Status != 1); +// Clear Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF); +// Send Device Register Index + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, RegisterIndex); + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x2); +// Wait Tx ACK + do { + Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03; + } while (Status != 1); +// Clear Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF); +// Start, Send Device Address + 1(Read Mode), Receive Data + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress + 1); + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x1B); +// Wait Rx Done + do { + Status = (ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x04) >> 2; + } while (Status != 1); +// Clear Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF); + +// Enable STOP Interrupt + WriteMemoryLongWithMASKClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0x10, 0x10); +// Issue STOP Command + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x20); +// Wait STOP + do { + Status = (ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x10) >> 4; + } while (Status != 1); +// Disable STOP Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0x10); +// Clear Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF); +// Read Received Data + Data = (BYTE)((ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20) & 0xFF00) >> 8); + + return Data; +} + +ULONG SetI2CRegClient(ULONG MMIOBase, + BYTE DeviceSelect, + BYTE DeviceAddress, + BYTE RegisterIndex, + BYTE RegisterValue) +{ + ULONG Status; + ULONG Count = 0; + +// Reset + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 0); +// Set Speed + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x04, AC_TIMING); +// Lower Speed +// WriteMemoryLongWithANDData (VideoEngineInfo->VGAPCIInfo.ulMMIOBaseAddress, I2C_BASE + DeviceSelect * 0x40 + 0x04, 0, 0x33317805); + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x08, 0); +// Clear Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF); +// Enable Master Mode + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x00, 1); +// Enable Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0xAF); +// BYTE I2C Mode +// Start and Send Device Address + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress); + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x3); +// Wait Tx ACK + do { + Count++; + Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03; + + if (2 == Status) + { + //Clear Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF); + //Re-Send Start and Send Device Address while NACK return + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, DeviceAddress); + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x3); + } + //else + { + if (Count > LOOP_COUNT) { + return CAN_NOT_FIND_DEVICE; + } + } + } while (Status != 1); + Count = 0; +// Clear Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF); +// Send Device Register Index + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, RegisterIndex); + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x2); +// Wait Tx ACK + do { + Count++; + Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03; + if (Count > LOOP_COUNT) { + return CAN_NOT_FIND_DEVICE; + } + } while (Status != 1); + Count = 0; +// Clear Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF); +// Send Device Register Value and Stop + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x20, RegisterValue); + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x2); +// Wait Tx ACK + do { + Count++; + Status = ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x03; + if (Count > LOOP_COUNT) { + return CAN_NOT_FIND_DEVICE; + } + } while (Status != 1); + Count = 0; +// Clear Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF); +// Enable STOP Interrupt + WriteMemoryLongWithMASKClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0x10, 0x10); +// Issue STOP Command + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x14, 0x20); +// Wait STOP + do { + Count++; + Status = (ReadMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10) & 0x10) >> 4; + if (Count > LOOP_COUNT) { + return CAN_NOT_FIND_DEVICE; + } + } while (Status != 1); +// Disable STOP Interrupt + WriteMemoryLongWithMASKClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x0C, 0, 0x10); +// Clear Interrupt + WriteMemoryLongClient(APB_BRIDGE_2_BASE, I2C_BASE + DeviceSelect * 0x40 + 0x10, 0xFFFFFFFF); + + return SET_I2C_DONE; +} |