in meta-facebook/meta-fbal/recipes-fbal/plat-libs/files/pal/pal_sensors.c [3006:3179]
int remap_vr(uint8_t addr) { //8bit addr
int fd = 0, ret = -1;
uint8_t tbuf[64] = {0};
uint8_t rbuf[64] = {0};
uint8_t bus = I2C_BUS_1;
uint8_t ver[4];
uint8_t tmp[32] = {0};
uint8_t retry = 5, clr_mode = 0;
fd = i2c_cdev_slave_open(bus, addr >> 1, I2C_SLAVE_FORCE_CLAIM);
if (fd < 0) {
syslog(LOG_WARNING, "%s() Failed to open %d", __func__, bus);
return ret;
}
do {
tbuf[0] = 0x00;
tbuf[1] = 0x00;
if ( vr_block_rw(fd, addr, tbuf, 2, rbuf, 0) ) {
syslog(LOG_WARNING, "set page fail slavaddr=%x cmd=%x\n", addr, tbuf[0]);
break;
}
while ( retry > 0 ) {
tbuf[0] = TI_ONLY_CONFIG2;
ret = vr_block_rw(fd, addr, tbuf, 1, rbuf, 32);
if ( ret != 0 ) {
retry--;
syslog(LOG_WARNING, "read vr id fail\n");
continue;
} else {
if ( memcmp(tmp, rbuf, 32) == 0 ) {
#ifdef DEBUG
syslog(LOG_WARNING, "vr data compare success\n");
#endif
break;
} else {
memcpy(tmp, rbuf, 32);
memset(rbuf, 0, sizeof(rbuf));
retry--;
#ifdef DEBUG
syslog(LOG_WARNING, "vr data compare fail retry=%d\n", retry);
#endif
}
}
}
if ( retry == 0 ) {
break;
}
#ifdef DEBUG
for (int i=0; i<32; i++) {
syslog(LOG_WARNING, "rbuf[%d] = %x\n", i, rbuf[i]);
}
#endif
//Set TI Only config2
tbuf[0] = TI_ONLY_CONFIG2;
rbuf[10] |= 0x40;
memcpy(tbuf+1, rbuf, 32);
if ( vr_block_rw(fd, addr, tbuf, 33, rbuf, 0) ) {
syslog(LOG_WARNING, "err1 bus=%x slavaddr=%x cmd=%x\n", bus, addr, tbuf[0]);
break;
}
clr_mode = 1;
//Read FW Version.
memset(tbuf,0,sizeof(tbuf));
tbuf[0] = 0xf5;
tbuf[1] = 0x04;
tbuf[2] = 0xf0;
tbuf[3] = 0x1F;
tbuf[4] = 0x2C;
tbuf[5] = 0x03;
if ( vr_block_rw(fd, addr, tbuf, 6, rbuf, 0) ) {
syslog(LOG_WARNING, "err2 bus=%x slavaddr=%x cmd=%x\n", bus, addr, tbuf[0]);
break;
}
memset(tbuf,0,sizeof(tbuf));
tbuf[0] = 0xf6;
if ( vr_block_rw(fd, addr, tbuf, 1, rbuf, 5) ) {
syslog(LOG_WARNING, "err3 bus=%x slavaddr=%x cmd=%x\n", bus, addr, tbuf[0]);
break;
}
ver[0] = rbuf[1];
ver[1] = rbuf[3];
memset(tbuf,0,sizeof(tbuf));
tbuf[0] = 0xf5;
tbuf[1] = 0x04;
tbuf[2] = 0xF4;
tbuf[3] = 0x1F;
tbuf[4] = 0x2C;
tbuf[5] = 0x03;
if ( vr_block_rw(fd, addr, tbuf, 6, rbuf, 0) ) {
syslog(LOG_WARNING, "err4 bus=%x slavaddr=%x cmd=%x\n", bus, addr, tbuf[0]);
break;
}
memset(tbuf,0,sizeof(tbuf));
tbuf[0] = 0xf6;
if ( vr_block_rw(fd, addr, tbuf, 1, rbuf, 5) ) {
syslog(LOG_WARNING, "err5 bus=%x slavaddr=%x cmd=%x\n", bus, addr, tbuf[0]);
break;
}
ver[2] = rbuf[1];
ver[3] = rbuf[3];
//Set VR workaround version=2.7.10.0
if( (ver[0] != 2) || (ver[1] != 7) || (ver[2] != 10) || (ver[3] != 0) ) {
syslog(LOG_WARNING, "vr addr=0x%X version=%u.%u.%u.%u", addr, ver[0], ver[1], ver[2], ver[3]);
break;
}
memset(tbuf,0,sizeof(tbuf));
tbuf[0] = 0xf5;
tbuf[1] = 0x04;
tbuf[2] = 0xf0;
tbuf[3] = 0x86;
tbuf[4] = 0x64;
tbuf[5] = 0x03;
if ( vr_block_rw_check(fd, addr, tbuf, 6) ) {
break;
}
memset(tbuf,0,sizeof(tbuf));
tbuf[0] = 0xf6;
tbuf[1] = 0x04;
tbuf[2] = 0x01;
tbuf[3] = 0xAA;
tbuf[4] = 0x00;
tbuf[5] = 0x00;
if ( vr_block_rw_check(fd, addr, tbuf, 6) ) {
break;
}
memset(tbuf,0,sizeof(tbuf));
tbuf[0] = 0xf5;
tbuf[1] = 0x04;
tbuf[2] = 0xD8;
tbuf[3] = 0x8A;
tbuf[4] = 0x64;
tbuf[5] = 0x03;
if ( vr_block_rw_check(fd, addr, tbuf, 6) ) {
break;
}
memset(tbuf,0,sizeof(tbuf));
tbuf[0] = 0xf6;
tbuf[1] = 0x04;
tbuf[2] = 0x49;
tbuf[3] = 0x1A;
tbuf[4] = 0x00;
tbuf[5] = 0x00;
if ( vr_block_rw_check(fd, addr, tbuf, 6) ) {
break;
}
syslog(LOG_WARNING, "vr workaround addr=0x%X version=%u.%u.%u.%u", addr, ver[0], ver[1], ver[2], ver[3]);
} while(0);
//Restore TI_ONLY_CONFIG2
if (clr_mode) {
tbuf[0] = TI_ONLY_CONFIG2;
tmp[10] &= 0xBF;
memcpy(tbuf+1, tmp, 32);
if ( vr_block_rw_check(fd, addr, tbuf, 33) ) {
syslog(LOG_WARNING, "restore vr failed, addr=0x%X", addr);
}
}
i2c_cdev_slave_close(fd);
return ret;
}