mirror of
https://github.com/sipeed/NanoKVM.git
synced 2026-09-11 00:22:56 -05:00
support lt6911d
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# kvmhwd Rev2.1
|
# kvmhwd Rev2.2
|
||||||
|
|
||||||
start_usb_dev(){
|
start_usb_dev(){
|
||||||
. /etc/profile
|
. /etc/profile
|
||||||
@@ -23,6 +23,11 @@ start_usb_dev(){
|
|||||||
else
|
else
|
||||||
echo 0x1009 > idProduct
|
echo 0x1009 > idProduct
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo 0xEF > bDeviceClass
|
||||||
|
echo 0x02 > bDeviceSubClass
|
||||||
|
echo 0x01 > bDeviceProtocol
|
||||||
|
|
||||||
mkdir strings/0x409
|
mkdir strings/0x409
|
||||||
echo '0123456789ABCDEF' > strings/0x409/serialnumber
|
echo '0123456789ABCDEF' > strings/0x409/serialnumber
|
||||||
echo 'sipeed' > strings/0x409/manufacturer
|
echo 'sipeed' > strings/0x409/manufacturer
|
||||||
@@ -37,15 +42,30 @@ start_usb_dev(){
|
|||||||
if [ -e /boot/usb.ncm ]
|
if [ -e /boot/usb.ncm ]
|
||||||
then
|
then
|
||||||
mkdir functions/ncm.usb0
|
mkdir functions/ncm.usb0
|
||||||
|
echo WINNCM > functions/ncm.usb0/os_desc/interface.ncm/compatible_id
|
||||||
ln -s functions/ncm.usb0 configs/c.1/
|
ln -s functions/ncm.usb0 configs/c.1/
|
||||||
else
|
else
|
||||||
if [ -e /boot/usb.rndis0 ]
|
if [ -e /boot/usb.rndis0 ]
|
||||||
then
|
then
|
||||||
mkdir functions/rndis.usb0
|
mkdir functions/rndis.usb0
|
||||||
|
echo e0 > functions/rndis.usb0/class
|
||||||
|
echo 01 > functions/rndis.usb0/subclass
|
||||||
|
echo 03 > functions/rndis.usb0/protocol
|
||||||
|
echo RNDIS > functions/rndis.usb0/os_desc/interface.rndis/compatible_id
|
||||||
|
echo 5162001 > functions/rndis.usb0/os_desc/interface.rndis/sub_compatible_id
|
||||||
ln -s functions/rndis.usb0 configs/c.1/
|
ln -s functions/rndis.usb0 configs/c.1/
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -e /boot/usb.ncm ] || [ -e /boot/usb.rndis0 ]
|
||||||
|
then
|
||||||
|
# Microsoft OS 2.0 Descriptor
|
||||||
|
echo 1 > os_desc/use
|
||||||
|
echo 0xCD > os_desc/b_vendor_code
|
||||||
|
echo MSFT100 > os_desc/qw_sign
|
||||||
|
ln -s configs/c.1 os_desc
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -e /boot/disable_hid ]
|
if [ ! -e /boot/disable_hid ]
|
||||||
then
|
then
|
||||||
# keyboard
|
# keyboard
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# kvmhwd Rev2.4
|
# kvmhwd Rev2.5
|
||||||
|
|
||||||
Alpha_OLED_RST_Pin=371
|
Alpha_OLED_RST_Pin=371
|
||||||
Beta_OLED_RST_Pin=502
|
Beta_OLED_RST_Pin=502
|
||||||
@@ -146,19 +146,7 @@ kvm_hw_detect(){
|
|||||||
insmod /mnt/system/ko/i2c-algo-bit.ko
|
insmod /mnt/system/ko/i2c-algo-bit.ko
|
||||||
insmod /mnt/system/ko/i2c-gpio.ko
|
insmod /mnt/system/ko/i2c-gpio.ko
|
||||||
|
|
||||||
kvm_tmp=$(i2cdetect -ry 4 0x2c 0x2c | grep 2c)
|
kvm_hdmi_version_detect
|
||||||
if [ -n "$kvm_tmp" ]
|
|
||||||
then
|
|
||||||
echo "c" > /etc/kvm/hdmi_version
|
|
||||||
else
|
|
||||||
kvm_tmp1=$(i2cdetect -ry 4 0x2b 0x2b | grep 2b)
|
|
||||||
if [ -n "$kvm_tmp1" ]
|
|
||||||
then
|
|
||||||
echo "ux" > /etc/kvm/hdmi_version
|
|
||||||
else
|
|
||||||
echo "ue" > /etc/kvm/hdmi_version
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
kvm_tmp=$(i2cdetect -ry 5 0x3c 0x3c | grep 3c)
|
kvm_tmp=$(i2cdetect -ry 5 0x3c 0x3c | grep 3c)
|
||||||
if [ -n "$kvm_tmp" ]
|
if [ -n "$kvm_tmp" ]
|
||||||
@@ -199,20 +187,19 @@ kvm_hw_init(){
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
kvm_hdmi_version_detect(){
|
kvm_hdmi_version_detect()
|
||||||
hdmi_tmp=$(i2cdetect -ry 4 0x2c 0x2c | grep 2c)
|
{
|
||||||
if [ -n "$hdmi_tmp" ]
|
if i2cdetect -ry 4 0x2c 0x2c | grep -qw "2c"; then
|
||||||
then
|
echo "c" > /etc/kvm/hdmi_version
|
||||||
echo "c" > /etc/kvm/hdmi_version
|
elif i2cdetect -ry 4 0x2b 0x2b | grep -qw "2b"; then
|
||||||
else
|
if i2cdetect -ry 4 0x44 0x44 | grep -qw "44"; then
|
||||||
hdmi_tmp1=$(i2cdetect -ry 4 0x2b 0x2b | grep 2b)
|
echo "ux" > /etc/kvm/hdmi_version
|
||||||
if [ -n "$hdmi_tmp1" ]
|
else
|
||||||
then
|
echo "d" > /etc/kvm/hdmi_version
|
||||||
echo "ux" > /etc/kvm/hdmi_version
|
fi
|
||||||
else
|
else
|
||||||
echo "ue" > /etc/kvm/hdmi_version
|
echo "ue" > /etc/kvm/hdmi_version
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
|||||||
@@ -495,6 +495,11 @@ uint8_t chack_ion()
|
|||||||
void lt6911_enable()
|
void lt6911_enable()
|
||||||
{
|
{
|
||||||
uint8_t buf[2];
|
uint8_t buf[2];
|
||||||
|
|
||||||
|
if(kvmv_cfg.hdmi_version == 3){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
buf[0] = 0xff;
|
buf[0] = 0xff;
|
||||||
buf[1] = 0x80;
|
buf[1] = 0x80;
|
||||||
LT6911_i2c.writeto(LT6911_ADDR, buf, 2);
|
LT6911_i2c.writeto(LT6911_ADDR, buf, 2);
|
||||||
@@ -503,7 +508,7 @@ void lt6911_enable()
|
|||||||
buf[1] = 0x01;
|
buf[1] = 0x01;
|
||||||
LT6911_i2c.writeto(LT6911_ADDR, buf, 2);
|
LT6911_i2c.writeto(LT6911_ADDR, buf, 2);
|
||||||
|
|
||||||
if(kvmv_cfg.hdmi_version != 0){
|
if(kvmv_cfg.hdmi_version == 1){
|
||||||
// disable watchdog
|
// disable watchdog
|
||||||
buf[0] = 0x10;
|
buf[0] = 0x10;
|
||||||
buf[1] = 0x00;
|
buf[1] = 0x00;
|
||||||
@@ -514,6 +519,11 @@ void lt6911_enable()
|
|||||||
void lt6911_disable()
|
void lt6911_disable()
|
||||||
{
|
{
|
||||||
uint8_t buf[2];
|
uint8_t buf[2];
|
||||||
|
|
||||||
|
if(kvmv_cfg.hdmi_version == 3){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
buf[0] = 0xff;
|
buf[0] = 0xff;
|
||||||
buf[1] = 0x80;
|
buf[1] = 0x80;
|
||||||
LT6911_i2c.writeto(LT6911_ADDR, buf, 2);
|
LT6911_i2c.writeto(LT6911_ADDR, buf, 2);
|
||||||
@@ -629,6 +639,38 @@ uint8_t lt6911_get_hdmi_res()
|
|||||||
if(revbuf[0] == 0x55) return 1;
|
if(revbuf[0] == 0x55) return 1;
|
||||||
else if(revbuf[0] == 0x88) return 0;
|
else if(revbuf[0] == 0x88) return 0;
|
||||||
else return 0;
|
else return 0;
|
||||||
|
} else if (kvmv_cfg.hdmi_version == 3){
|
||||||
|
// LT6911D
|
||||||
|
buf[0] = 0xff;
|
||||||
|
buf[1] = 0xe0;
|
||||||
|
LT6911_i2c.writeto(LT6911_ADDR, buf, 2);
|
||||||
|
|
||||||
|
// Hactive
|
||||||
|
buf[0] = 0x8c;
|
||||||
|
LT6911_i2c.writeto(LT6911_ADDR, buf, 1);
|
||||||
|
maix::Bytes *dat0 = LT6911_i2c.readfrom(LT6911_ADDR, 2);
|
||||||
|
|
||||||
|
// Vactive
|
||||||
|
buf[0] = 0x8e;
|
||||||
|
LT6911_i2c.writeto(LT6911_ADDR, buf, 1);
|
||||||
|
maix::Bytes *dat1 = LT6911_i2c.readfrom(LT6911_ADDR, 2);
|
||||||
|
|
||||||
|
revbuf[0] = (uint8_t)dat0->data[0];
|
||||||
|
revbuf[1] = (uint8_t)dat0->data[1];
|
||||||
|
revbuf[2] = (uint8_t)dat1->data[0];
|
||||||
|
revbuf[3] = (uint8_t)dat1->data[1];
|
||||||
|
|
||||||
|
Hactive = ((revbuf[0] << 8)|revbuf[1]) * 2;
|
||||||
|
Vactive = (revbuf[2] << 8)|revbuf[3];
|
||||||
|
|
||||||
|
debug("[hdmi]HDMI-D res modification event\n");
|
||||||
|
debug("[hdmi]new res: %d * %d\n", Hactive, Vactive);
|
||||||
|
|
||||||
|
delete dat0;
|
||||||
|
delete dat1;
|
||||||
|
|
||||||
|
if(Hactive != 0 || Vactive != 0) return 1;
|
||||||
|
else return 0;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -738,6 +780,33 @@ uint8_t lt6911_get_csi_res(uint16_t *p_width, uint16_t *p_height)
|
|||||||
|
|
||||||
Vactive = (revbuf[0] << 8)|revbuf[1];
|
Vactive = (revbuf[0] << 8)|revbuf[1];
|
||||||
Hactive = (revbuf[2] << 8)|revbuf[3];
|
Hactive = (revbuf[2] << 8)|revbuf[3];
|
||||||
|
} else if(kvmv_cfg.hdmi_version == 3) {
|
||||||
|
// LT6911D
|
||||||
|
debug("[hdmi]D get csi res\n");
|
||||||
|
buf[0] = 0xff;
|
||||||
|
buf[1] = 0xe0;
|
||||||
|
LT6911_i2c.writeto(LT6911_ADDR, buf, 2);
|
||||||
|
|
||||||
|
// Vactive
|
||||||
|
buf[0] = 0x8e;
|
||||||
|
LT6911_i2c.writeto(LT6911_ADDR, buf, 1);
|
||||||
|
maix::Bytes *dat0 = LT6911_i2c.readfrom(LT6911_ADDR, 2);
|
||||||
|
|
||||||
|
// Hactive
|
||||||
|
buf[0] = 0x8c;
|
||||||
|
LT6911_i2c.writeto(LT6911_ADDR, buf, 1);
|
||||||
|
maix::Bytes *dat1 = LT6911_i2c.readfrom(LT6911_ADDR, 2);
|
||||||
|
|
||||||
|
revbuf[0] = (uint8_t)dat0->data[0];
|
||||||
|
revbuf[1] = (uint8_t)dat0->data[1];
|
||||||
|
revbuf[2] = (uint8_t)dat1->data[0];
|
||||||
|
revbuf[3] = (uint8_t)dat1->data[1];
|
||||||
|
|
||||||
|
delete dat0;
|
||||||
|
delete dat1;
|
||||||
|
|
||||||
|
Vactive = (revbuf[0] << 8)|revbuf[1];
|
||||||
|
Hactive = ((revbuf[2] << 8)|revbuf[3]) * 2;
|
||||||
} else {
|
} else {
|
||||||
return UNKNOWN_RES;
|
return UNKNOWN_RES;
|
||||||
}
|
}
|
||||||
@@ -1048,6 +1117,10 @@ void get_hdmi_version()
|
|||||||
kvmv_cfg.hdmi_version = 1;
|
kvmv_cfg.hdmi_version = 1;
|
||||||
debug("[hdmi]Incomplete version number, set to 'ux'\n");
|
debug("[hdmi]Incomplete version number, set to 'ux'\n");
|
||||||
}
|
}
|
||||||
|
} else if(RW_Data[0] == 'd'){
|
||||||
|
// 6911d
|
||||||
|
kvmv_cfg.hdmi_version = 3;
|
||||||
|
debug("[hdmi]HDMI-D exist!\n");
|
||||||
} else {
|
} else {
|
||||||
// 6911c
|
// 6911c
|
||||||
kvmv_cfg.hdmi_version = 0;
|
kvmv_cfg.hdmi_version = 0;
|
||||||
@@ -1171,6 +1244,31 @@ void* vi_subsystem_detection(void * arg)
|
|||||||
}
|
}
|
||||||
lt6911_disable();
|
lt6911_disable();
|
||||||
}
|
}
|
||||||
|
} else if (kvmv_cfg.hdmi_version == 3){
|
||||||
|
// LT6911D
|
||||||
|
debug("[hdmi] D int\n");
|
||||||
|
if(falling_times != 0){
|
||||||
|
debug("[hdmi] D int && \n");
|
||||||
|
lt6911_enable();
|
||||||
|
if(lt6911_get_hdmi_res()){
|
||||||
|
// hdmi get res
|
||||||
|
debug("[hdmi] D HDMI cable insertion!\n");
|
||||||
|
kvmv_cfg.hdmi_cable_state = 1;
|
||||||
|
kvmv_cfg.hdmi_res_type = lt6911_get_csi_res(&kvmv_cfg.vi_width, &kvmv_cfg.vi_height);
|
||||||
|
if (kvmv_cfg.hdmi_res_type == NEW_RES) kvmv_cfg.reopen_cam_flag = 1;
|
||||||
|
else if (kvmv_cfg.hdmi_res_type == UNKNOWN_RES){
|
||||||
|
/* Move HDMI resolution modification directly
|
||||||
|
to mode1 to solve deadlock problem */
|
||||||
|
auto_change_mode = 1;
|
||||||
|
set_hdmi_mode(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// HDMI res = 0*0/x*0
|
||||||
|
debug("[hdmi] D HDMI cable unplugged!\n");
|
||||||
|
kvmv_cfg.hdmi_cable_state = 0;
|
||||||
|
}
|
||||||
|
lt6911_disable();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
debug("[hdmi] Chip not supported for reading \n");
|
debug("[hdmi] Chip not supported for reading \n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ uint8_t get_hdmi_version()
|
|||||||
fread(RW_Data, sizeof(char), 2, fp);
|
fread(RW_Data, sizeof(char), 2, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
if(RW_Data[0] == 'u'){
|
if(RW_Data[0] == 'u'){
|
||||||
// 6911uxc
|
// 6911uxc / 6911uxe
|
||||||
if(RW_Data[1] == 'e'){
|
if(RW_Data[1] == 'e'){
|
||||||
return 2;
|
return 2;
|
||||||
} else if(RW_Data[1] == 'x') {
|
} else if(RW_Data[1] == 'x') {
|
||||||
@@ -25,6 +25,9 @@ uint8_t get_hdmi_version()
|
|||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
} else if(RW_Data[0] == 'd'){
|
||||||
|
// 6911d
|
||||||
|
return 3;
|
||||||
} else {
|
} else {
|
||||||
// 6911c
|
// 6911c
|
||||||
return 0;
|
return 0;
|
||||||
@@ -139,6 +142,7 @@ void new_app_init(void)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
if(RW_Data[0] == 'c') hdmi_ver = 1;
|
if(RW_Data[0] == 'c') hdmi_ver = 1;
|
||||||
else if(RW_Data[0] == 'u') hdmi_ver = 2;
|
else if(RW_Data[0] == 'u') hdmi_ver = 2;
|
||||||
|
else if(RW_Data[0] == 'd') hdmi_ver = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// system("/etc/init.d/S03usbdev stop_start");
|
// system("/etc/init.d/S03usbdev stop_start");
|
||||||
|
|||||||
Binary file not shown.
@@ -487,6 +487,158 @@ int lt6911c_edid_read(uint8_t *edid_data, uint16_t edid_size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lt6911d_str_read(uint8_t *str)
|
||||||
|
{
|
||||||
|
fprintf(stdout, "Reading LT6911D version data...\n");
|
||||||
|
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0xEE, 0x01) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5E, 0xDF) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x58, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x59, 0x50) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x10) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x58, 0x21) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_DATA_OFFSET, 0x03, 0xBF) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_DATA_OFFSET, 0x03, 0xFF) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x04) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5E, 0x5F) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x20) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5B, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5C, 0x81) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5D, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x10) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_read_bytes(LT6911D_MANAGE_OFFSET, 0x5F, str, LT6911D_WR_SIZE) != 0) return -1;
|
||||||
|
usleep(10000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x08) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x58, 0x00) != 0) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lt6911d_edid_write(uint8_t *edid_data, uint16_t edid_size)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t wr_count = edid_size / LT6911D_WR_SIZE + 1;
|
||||||
|
uint8_t version_str[LT6911D_WR_SIZE] = {0};
|
||||||
|
|
||||||
|
if (lt6911d_str_read(version_str) != 0) {
|
||||||
|
fprintf(stderr, "Failed to read LT6911D version data\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stdout, "Writing EDID....\n");
|
||||||
|
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0xEE, 0x01) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5E, 0xDF) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x58, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x59, 0x50) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x10) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x58, 0x21) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x04) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5B, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5C, 0x80) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5D, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x01) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
usleep(600000);
|
||||||
|
|
||||||
|
for (i = 0; i < wr_count; i++) {
|
||||||
|
if (i2c_write_byte(LT6911D_DATA_OFFSET, 0x03, 0xBF) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_DATA_OFFSET, 0x03, 0xFF) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x04) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5E, 0xDF) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x20) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x58, 0x21) != 0) return -1;
|
||||||
|
if (i != wr_count - 1) {
|
||||||
|
if (i2c_write_bytes(LT6911D_MANAGE_OFFSET, 0x59, edid_data + (LT6911D_WR_SIZE * i), LT6911D_WR_SIZE) != 0) return -1;
|
||||||
|
} else {
|
||||||
|
if (i2c_write_bytes(LT6911D_MANAGE_OFFSET, 0x59, version_str, LT6911D_WR_SIZE) != 0) return -1;
|
||||||
|
}
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5B, 0x00) != 0) return -1;
|
||||||
|
if (i != wr_count - 1) {
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5C, 0x80) != 0) return -1;
|
||||||
|
} else {
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5C, 0x81) != 0) return -1;
|
||||||
|
}
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5D, 0x00 + (LT6911D_WR_SIZE * i)) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x10) != 0) return -1;
|
||||||
|
usleep(5000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x08) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x58, 0x00) != 0) return -1;
|
||||||
|
|
||||||
|
fprintf(stdout, "EDID write completed\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lt6911d_edid_read(uint8_t *edid_data, uint16_t edid_size)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t wr_count = edid_size / LT6911D_WR_SIZE;
|
||||||
|
|
||||||
|
fprintf(stdout, "Reading EDID...\n");
|
||||||
|
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0xEE, 0x01) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5E, 0xDF) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x58, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x59, 0x50) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x10) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x58, 0x21) != 0) return -1;
|
||||||
|
for (i = 0; i < wr_count; i++) {
|
||||||
|
if (i2c_write_byte(LT6911D_DATA_OFFSET, 0x03, 0xBF) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_DATA_OFFSET, 0x03, 0xFF) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x04) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5E, 0x5F) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x20) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5B, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5C, 0x80) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5D, 0x00 + (LT6911D_WR_SIZE * i)) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x10) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_read_bytes(LT6911D_MANAGE_OFFSET, 0x5F, edid_data + (LT6911D_WR_SIZE * i), LT6911D_WR_SIZE) != 0) return -1;
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x08) != 0) return -1;
|
||||||
|
usleep(1000);
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x5A, 0x00) != 0) return -1;
|
||||||
|
if (i2c_write_byte(LT6911D_MANAGE_OFFSET, 0x58, 0x00) != 0) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// =======================================================================================================
|
// =======================================================================================================
|
||||||
|
|
||||||
int lt6911_edid_config(chip_version_t chip_version, uint8_t *edid_data, uint16_t edid_size)
|
int lt6911_edid_config(chip_version_t chip_version, uint8_t *edid_data, uint16_t edid_size)
|
||||||
@@ -523,6 +675,12 @@ int lt6911_edid_config(chip_version_t chip_version, uint8_t *edid_data, uint16_t
|
|||||||
close(client);
|
close(client);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
} else if (chip_version == CHIP_LT6911D) {
|
||||||
|
if (lt6911d_edid_write(edid_data, edid_size) != 0) {
|
||||||
|
fprintf(stderr, "Failed to write EDID data to LT6911D\n");
|
||||||
|
close(client);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown chip version\n");
|
fprintf(stderr, "Unknown chip version\n");
|
||||||
close(client);
|
close(client);
|
||||||
@@ -545,6 +703,12 @@ int lt6911_edid_config(chip_version_t chip_version, uint8_t *edid_data, uint16_t
|
|||||||
close(client);
|
close(client);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
} else if (chip_version == CHIP_LT6911D) {
|
||||||
|
if (lt6911d_edid_read(edid_read_data, EDID_BUFFER_SIZE) != 0) {
|
||||||
|
fprintf(stderr, "Failed to read EDID data from LT6911D\n");
|
||||||
|
close(client);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown chip version\n");
|
fprintf(stderr, "Unknown chip version\n");
|
||||||
close(client);
|
close(client);
|
||||||
@@ -686,6 +850,9 @@ int main(int argc, char *argv[]) {
|
|||||||
} else if (strcmp(chip_version_str, "ux") == 0) {
|
} else if (strcmp(chip_version_str, "ux") == 0) {
|
||||||
fprintf(stdout, "Chip Version: LT6911UXC\n");
|
fprintf(stdout, "Chip Version: LT6911UXC\n");
|
||||||
chip_version = CHIP_LT6911UXC;
|
chip_version = CHIP_LT6911UXC;
|
||||||
|
} else if (strcmp(chip_version_str, "d") == 0) {
|
||||||
|
fprintf(stdout, "Chip Version: LT6911D\n");
|
||||||
|
chip_version = CHIP_LT6911D;
|
||||||
} else if (strcmp(chip_version_str, "ue") == 0) {
|
} else if (strcmp(chip_version_str, "ue") == 0) {
|
||||||
fprintf(stderr, "Chip Version Error: UE version's edid can't be updated\n");
|
fprintf(stderr, "Chip Version Error: UE version's edid can't be updated\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -17,10 +17,13 @@
|
|||||||
#define LT6911C_HDMI_INFO_OFFSET 0xD2 // LT6911C HDMI信息寄存器偏移地址
|
#define LT6911C_HDMI_INFO_OFFSET 0xD2 // LT6911C HDMI信息寄存器偏移地址
|
||||||
#define LT6911C_AUDIO_INFO_OFFSET 0xD1 // LT6911C 音频信息寄存器偏移地址
|
#define LT6911C_AUDIO_INFO_OFFSET 0xD1 // LT6911C 音频信息寄存器偏移地址
|
||||||
#define LT6911C_CSI_INFO_OFFSET 0xC2 // LT6911C CSI信息寄存器偏移地址
|
#define LT6911C_CSI_INFO_OFFSET 0xC2 // LT6911C CSI信息寄存器偏移地址
|
||||||
|
#define LT6911D_MANAGE_OFFSET 0xE0 // LT6911D 管理寄存器偏移地址
|
||||||
|
#define LT6911D_DATA_OFFSET 0xE1 // LT6911D 数据寄存器偏移地址
|
||||||
|
|
||||||
#define EDID_BUFFER_SIZE 256 // 最大支持的字节数
|
#define EDID_BUFFER_SIZE 256 // 最大支持的字节数
|
||||||
#define LT6911UXC_WR_SIZE 32 // LT6911UXC单次读写最大字节数
|
#define LT6911UXC_WR_SIZE 32 // LT6911UXC单次读写最大字节数
|
||||||
#define LT6911C_WR_SIZE 16 // LT6911C单次读写最大字节数
|
#define LT6911C_WR_SIZE 16 // LT6911C单次读写最大字节数
|
||||||
|
#define LT6911D_WR_SIZE 32 // LT6911D单次读写最大字节数
|
||||||
|
|
||||||
#define VERSION_PATH "/etc/kvm/hdmi_version"
|
#define VERSION_PATH "/etc/kvm/hdmi_version"
|
||||||
#define PRODUCT_PATH "/etc/kvm/hw"
|
#define PRODUCT_PATH "/etc/kvm/hw"
|
||||||
@@ -28,6 +31,7 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
CHIP_LT6911UXC = 0,
|
CHIP_LT6911UXC = 0,
|
||||||
CHIP_LT6911C,
|
CHIP_LT6911C,
|
||||||
|
CHIP_LT6911D,
|
||||||
CHIP_UNKNOWN
|
CHIP_UNKNOWN
|
||||||
} chip_version_t;
|
} chip_version_t;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user