#include "drv_types.h" #include "hdmi_time.h" #include "gpioi2c.h" #include #include #if 0 static UINT32 mmioRead( UINT32 addr) { volatile UINT32 dw = *((UINT32*)addr); return dw; } static UINT32 mmioReadMask( UINT32 addr, UINT32 mask) { return mmioRead(addr) & mask; } static void mmioWrite( UINT32 addr, UINT32 data) { *(UINT32*)addr = data; } static void mmioWriteMask( UINT32 addr, UINT32 mask, UINT32 data) { UINT32 dw; dw = mmioReadMask(addr, ~mask); mmioWrite(addr, ((data & mask) | dw)); } static void set(UINT8 index, UINT32 value) { UINT8 bits; // set GPIO output value bits = index ; mmioWriteMask(0xbe0f0610, (0x1 << bits), (0x0 << bits)); // set GPIO input / output control register to "output mode" mmioWriteMask(0xbe0f0618, (0x1 << bits), (value << bits)); // set "function selection" mux to "GPIO (set '01') " bits = (index % 16) * 2; mmioWriteMask(0xbe0f0604, (0x3 << bits), (0x1 << bits)); } static UINT8 gpio_read(UINT8 idx) { return GPIOTryRead(idx); } #endif static UINT8 gGpioI2cStatus; //#define GPIO_I2C_CLK 24 //#define GPIO_I2C_DATA 25 #define LAG 8 static void MxI2CStart(void) { gGpioI2cStatus = 0; GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_ONLEVEL); HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_OFFLEVEL); HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL); HDMI_DelayUs(LAG); } static void MxI2CStop(void) { GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_OFFLEVEL); HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL); HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_ONLEVEL); HDMI_DelayUs(LAG); GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL); GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA); HDMI_DelayUs(LAG); } static void MxI2CRestart(void) { if (gGpioI2cStatus) { return; } GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_ONLEVEL); HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL); HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_OFFLEVEL); HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL); HDMI_DelayUs(LAG); } static void MxI2CWriteByte(UINT8 Value) { UINT8 i; if (gGpioI2cStatus) { return; } for (i = 0; i < 8; i++) { if (Value & 0x80) { GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_ONLEVEL); } else { GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_OFFLEVEL); } HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL); HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL); HDMI_DelayUs(LAG); Value <<= 1; } GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA); HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL); HDMI_DelayUs(LAG); if (GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA)) { gGpioI2cStatus = 1; } GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL); HDMI_DelayUs(LAG); } static UINT8 MxI2CReadByte(UINT8 bMoreByte) { UINT8 i, Value; if (gGpioI2cStatus) { return 0; } GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA); HDMI_DelayUs(LAG); Value = 0; for (i = 0; i < 8; i++) { Value <<= 1; GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL); HDMI_DelayUs(LAG); if (GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA)) { Value |= 1; } GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL); HDMI_DelayUs(LAG); } if (bMoreByte) { GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_OFFLEVEL); } else { GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_ONLEVEL); } HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL); HDMI_DelayUs(LAG); GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL); HDMI_DelayUs(LAG); return Value; } static UINT8 gI2CMode = 0; static UINT8 gDeviceId = 0; static UINT8 gAddrLen = 1; void hdmi_i2c_setup(UINT8 i2c_mode, UINT8 device_id, UINT8 addr_len) { gI2CMode = i2c_mode; gDeviceId = device_id & 0xfe; // device id can't be odd. gAddrLen = (addr_len > 4) ? 4 : addr_len; } static UINT8 gpio_i2c_write(UINT32 addr, UINT8 *data_ptr, INT32 data_sz) { /* Start */ MxI2CStart(); MxI2CWriteByte(gDeviceId); /* Set Address */ if (gAddrLen) { INT32 i; for (i = gAddrLen - 1 ; i >= 0 ; i--) { MxI2CWriteByte((UINT8)((addr >> (i * 8)) & 0xff)); } } /* Write Data */ if (data_ptr && data_sz > 0) { INT32 i; for (i = 0 ; i < data_sz ; i++) { MxI2CWriteByte(data_ptr[i]); } } /* Stop */ MxI2CStop(); return gGpioI2cStatus; } static UINT8 gpio_i2c_read(UINT32 addr, UINT8 *data_ptr, INT32 data_sz) { /* Start */ MxI2CStart(); MxI2CWriteByte(gDeviceId); /* Set Address */ if (gAddrLen) { INT32 i; for (i = gAddrLen - 1 ; i >= 0 ; i--) { MxI2CWriteByte((UINT8)((addr >> (i * 8)) & 0xff)); } } MxI2CRestart(); MxI2CWriteByte(gDeviceId | 0x1); /* Write Data */ if (data_ptr && data_sz > 0) { INT32 i; for (i = 0 ; i < data_sz ; i++) { data_ptr[i] = MxI2CReadByte((i + 1 == data_sz) ? 0 : 1); } } /* Stop */ MxI2CStop(); return gGpioI2cStatus; } static UINT32 toI2CAddr(UINT32 i2cAddr) { // I2C Addr foramt [addr_type,1][addr,3] // ex. one byte address 0x12, input addr 0x01000012, output addr 0x01000012 // ex. two byte address 0x1234, input addr 0x02001234, output addr 0x02003412 // ex. three byte address 0x123456, input addr 0x03123456, output addr 0x03563412 UINT32 addr = i2cAddr & 0xff000000; UINT8 addrType = (i2cAddr >> 24) & 0xff; UINT8 *ptr = (UINT8 *)&i2cAddr; if (addrType == 1) { addr |= (*ptr); } else if (addrType == 2) { addr |= (((*ptr) << 8) | (*(ptr + 1))); } else if (addrType == 3) { addr |= (((*ptr) << 16) | ((*(ptr + 1)) << 8) | (*(ptr + 2))); } else { addr = 0; } return addr; } UINT8 hdmi_i2c_write(UINT32 addr, UINT8 *data_ptr, INT32 data_sz) { UINT8 status = 0; if (gDeviceId == 0) { return -1; } if (gI2CMode == USE_I2C_VIA_GPIO) { status = gpio_i2c_write(addr, data_ptr, data_sz); } else { DRV_I2C_WriteFun( gI2CMode, gDeviceId, ADDRESS_TYPE_MULTIPLE, toI2CAddr((gAddrLen << 24) | (addr & 0xffffff)), data_ptr, data_sz, I2C_SPEED_100K, &status); } return status; } UINT8 hdmi_i2c_read(UINT32 addr, UINT8 *data_ptr, INT32 data_sz) { UINT8 status = 0; if (gDeviceId == 0) { return -1; } if (gI2CMode == USE_I2C_VIA_GPIO) { status = gpio_i2c_read(addr, data_ptr, data_sz); } else { DRV_I2C_ReadFun( gI2CMode, gDeviceId, ADDRESS_TYPE_MULTIPLE, toI2CAddr((gAddrLen << 24) | (addr & 0xffffff)), data_ptr, data_sz, I2C_SPEED_100K, &status); } return status; } void hdmi_gpio_write(UINT8 idx, UINT8 val) { GPIOWriteFun(idx, val); } UINT8 hdmi_gpio_read(UINT8 idx) { return GPIOTryRead(idx); }