/* --------------------------------------------------------------------- Command Format: 1. R/W I2C iw[dev_id,1][addr_len,1][addr,3][data_len,1],[data,x] ir[dev_id,1][addr_len,1][addr,3][data_len,1] 2. R/W I2C via GPIO (One byte addr/data I2C R/W) gir[dev_id,1][addr_len,1][addr,addr_led/write function of I2C via GPIO to I2C driver. giw[dev_id,1][addr_len,1][addr,addr_len][data_len,1][data,data_len] where addr_len < = 4 and data_len < = 4 3. R/W GPIO gr[gpio_idx,1] gw[gpio_idx,1][gpio_h/l,1] 4. hdmi auto debug hdmi_auto_debug[timer(unit:10ms),1 byte(Hex)][Error Free Count,1 byte(Hex)][Error Count,1 byte(Hex)] --------------------------------------------------------------------- */ #include "drv_types.h" #include "hdmi.h" #include "hdmi_hw.h" #include "cec.h" #include "gpioi2c.h" #include // drv_vmalloc() drv_vfree() #ifdef CONFIG_SUPPORT_DEBUG_MESSAGE #define dbg(fmt,args...) printk(KERN_EMERG fmt, ## args) static void print_usage(void) { dbg("1. R/W GPIO\n"); dbg(" gw[gpio_idx][high/low]\n"); dbg(" gr[gpio_idx]\n"); dbg("\n"); dbg("2. R/W I2C Master\n"); dbg(" imw[dev_id,1][addr_len,1][addr,3][data_len,1],[data,x]\n"); dbg(" imr[dev_id,1][addr_len,1][addr,3][data_len,1]\n"); dbg("\n"); dbg("3. R/W I2C Slave\n"); dbg(" isw[dev_id,1][addr_len,1][addr,3][data_len,1],[data,x]\n"); dbg(" isr[dev_id,1][addr_len,1][addr,3][data_len,1]\n"); dbg("\n"); dbg("4. R/W I2C via GPIO\n"); dbg(" igw[dev_id,1][addr_len,1][addr,3][deta_len,1][data,x]\n"); dbg(" igr[dev_id,1][addr_len,1][addr,3][data_len,1]\n"); dbg("\n\n"); } static UINT8 StrToByte(const INT8 *buf) { UINT8 byte = 0, i = 0; for (i = 0; i < 2; i++) { byte = byte << 4; if (buf[i] >= '0' && buf[i] <= '9') { byte += (buf[i] - '0'); } else if (buf[i] >= 'a' && buf[i] <= 'f') { byte += (buf[i] - 'a' + 10); } else if (buf[i] >= 'A' && buf[i] <= 'F') { byte += (buf[i] - 'A' + 10); } } return byte; } static void StrToBuf(const INT8 *str, UINT8 *buf, UINT32 buf_sz) { UINT32 i = 0; for (i = 0; i < buf_sz; i++) { buf[i] = StrToByte(str + i * 2); } } static void dump(const UINT8 *ptr, INT32 size) { INT32 i, n; INT8 str[3 * 0x10 + 8]; for (n = 0, i = 0; i < size; i++) { if (n >= 0) { n += sprintf(&str[n], "%02x ", ptr[i]); } if (n >= 3 * 0x10 || i + 1 == size) { n = 0; dbg("%s\n", str); } } } static void gpio_write_handler(const INT8 *buf, size_t size) { UINT8 idx, val; idx = StrToByte(buf + 0); val = StrToByte(buf + 2); hdmi_gpio_write(idx, val); dbg("Write gpio pin 0x%02x to 0x%02x\n", idx, val); } static void gpio_read_handler(const INT8 *buf, size_t size) { UINT8 idx, val; idx = StrToByte(buf + 0); val = hdmi_gpio_read(idx); dbg("Read gpio pin 0x%02x to 0x%02x\n", idx, val); } static void i2c_write_handler(UINT8 i2c_mode, const INT8 *buf, size_t size) { // imw[dev_id,1][addr_len,1][addr,3][data_len,1] // isw[dev_id,1][addr_len,1][addr,3][data_len,1] UINT8 device_id, addr_len; UINT32 addr; UINT8 data_sz; UINT8 *data_ptr; UINT8 status; if (size < 12) { return; } device_id = StrToByte(buf + 0); addr_len = StrToByte(buf + 2); addr = (addr_len << 24); addr |= (StrToByte(buf + 4) << 16); addr |= (StrToByte(buf + 6) << 8); addr |= (StrToByte(buf + 8) << 0); data_sz = StrToByte(buf + 10); data_ptr = NULL; if (size < (UINT32)(data_sz + 12)) { return; } data_ptr = drv_vmalloc(data_sz, MODULEID_HDMI); if (data_ptr == NULL) { return; } StrToBuf(buf + 12, data_ptr, data_sz); hdmi_i2c_setup(i2c_mode, device_id, addr_len); status = hdmi_i2c_write(addr, data_ptr, data_sz); dbg("i2c write device 0x%02x addr 0x%08x 0x%02x bytes %s\n", device_id, addr & 0xffffff, data_sz, (status == 0) ? "ok" : "fail"); dump(data_ptr, data_sz); if (data_ptr) { drv_vfree(data_ptr, MODULEID_HDMI); } } static void i2c_read_handler(UINT8 i2c_mode, const INT8 *buf, size_t size) { // imr[dev_id,1][addr_len,1][addr,3][data_len,1] // isr[dev_id,1][addr_len,1][addr,3][data_len,1] UINT8 device_id, addr_len; UINT32 addr; UINT8 data_sz; UINT8 *data_ptr; UINT8 status; if (size < 12) { return; } device_id = StrToByte(buf + 0); addr_len = StrToByte(buf + 2); addr = (addr_len << 24); addr |= (StrToByte(buf + 4) << 16); addr |= (StrToByte(buf + 6) << 8); addr |= (StrToByte(buf + 8) << 0); data_sz = StrToByte(buf + 10); data_ptr = drv_vmalloc(data_sz, MODULEID_HDMI); if (data_ptr == NULL) { return; } hdmi_i2c_setup(i2c_mode, device_id, addr_len); status = hdmi_i2c_read(addr, data_ptr, data_sz); dbg("i2c read device 0x%02x addr 0x%08x 0x%02x bytes %s\n", device_id, addr & 0xffffff, data_sz, (status == 0) ? "ok" : "fail"); dump(data_ptr, data_sz); if (data_ptr) { drv_vfree(data_ptr, MODULEID_HDMI); } } void hdmi_dbg_Handler(const INT8 *buf, size_t size) { UINT8 cmd, cmd1, cmd2; UINT8 i2c_mode = 0; if (size <= 3) { print_usage(); return; } cmd = buf[0]; cmd1 = buf[1]; cmd2 = buf[2]; if (cmd1 == 'm' || cmd1 == 'M') { i2c_mode = USE_HW_I2C_MASTER; } else if (cmd1 == 's' || cmd1 == 'S') { i2c_mode = USE_HW_I2C_SLAVE; } else if (cmd1 == 'g' || cmd1 == 'G') { i2c_mode = USE_I2C_VIA_GPIO; } if (cmd == 'i' || cmd == 'I') { if (cmd2 == 'r' || cmd2 == 'R') { i2c_read_handler(i2c_mode, buf + 3, size - 3); } else if (cmd2 == 'w' || cmd2 == 'W') { i2c_write_handler(i2c_mode, buf + 3, size - 3); } } else if (cmd == 'g' || cmd == 'G') { if (cmd1 == 'r' || cmd1 == 'R') { gpio_read_handler(buf + 2, size - 2); } else if (cmd1 == 'w' || cmd1 == 'W') { gpio_write_handler(buf + 2, size - 2); } } else if (cmd == 'd' || cmd == 'D') { //auto_debug_handler(buf+1, size-1); } else { print_usage(); } } #endif