市面上汽车上camera大致使用的就两种serdes:美信和TI,这篇文章根据我的理解描述下两种serdes的识别link流程
max96712
ambarella的具体的调用流程可以参考上一篇文章
- max96712_hw_init
static int max96712_hw_init(struct vin_brg_device *ambrg, u32 chip_id)
{
....
/* check DES ID */
max96712_read_reg(ambrg, pinfo->i2c_ctrl.addr.des, 0x000D, &dev_id);
for (i = 0; i < ARRAY_SIZE(id_table); i++) {
if (dev_id == id_table[i].id) {
brg_info("[%d]deserializer %s, id:0x%x, GMSL%s\n", ambrg->id, id_table[i].name, dev_id,
(pinfo->link_mode == MAX96712_MODE_GMSL_1) ? "1" :
((pinfo->link_mode == MAX96712_MODE_GMSL_2_3G) ? "2(3Gpbs)" : "2(6Gpbs)"));
break;
}
}
if (test_mode)
goto HW_INIT_EXIT;
/* switch deserializer to 3G first if necessary */
if ((dev_id == DES_96712_ID) && (pinfo->link_mode == MAX96712_MODE_GMSL_2_3G)) {
for (i = 0; i < MAX96712_MAX_CHAN_NUM; i++) {
/* use load id here because for 3G broken channels, no chance to set to 3G for recovery again */
if (ambrg->ch_id.load_id & (1U << i)) {
addr = (i < 2U) ? 0x0010 : 0x0011;
max96712_read_reg(ambrg, pinfo->i2c_ctrl.addr.des, addr, &data);
data &= ~(0x3 << ((i & 0x1) << 2U));
data |= 0x1 << ((i & 0x1) << 2U);
max96712_write_reg(ambrg, pinfo->i2c_ctrl.addr.des, addr, data);
}
}
}
/* turn on poc power source for SER */
max96712_poc_pwr_rst(ambrg, chip_id);
...
/* check SER ID, reset each link */
for (i = 0; i < MAX96712_MAX_CHAN_NUM; i++) {
if (chip_id & (1U << i)) {
/* Mask other links except current link */
max96712_read_reg(ambrg, pinfo->i2c_ctrl.addr.des, 0x0006, &data);
data &= ~0xF;
//读取寄存器1dc,1fc,21c,23c,查看对应的video channel locked标志位
data |= max96712_get_vlocked_chan(ambrg); /* for video locked channel, not to mask because it's streaming */
data |= 1U << i;
max96712_write_reg(ambrg, pinfo->i2c_ctrl.addr.des, 0x0006, data);
/* wait for link stable */
//查看对应的link是否locked,link A:0x1A, link B:0xA, link C:0xB, link D:0xC
rval = max96712_wait_lock_status(ambrg, max9295d ? 0x01 : 1U << i, MAX96712_LINK_LOCK_TO);
if (rval) {
brg_error("[%d]serializer link 0x%x fail!\n", ambrg->id, 1U << i);
broken_id |= 1U << i;
continue;
}
addr = chan2addr(ambrg, 1U << i);
/* Remap serializer's address */
//设置对应link的serializer地址
max96712_write_reg(ambrg, pinfo->i2c_ctrl.addr.ser_def, 0x0000, addr);
dev_id = 0;
max96712_read_reg(ambrg, addr, 0x000D, &dev_id);
for (j = 0; j < ARRAY_SIZE(id_table); j++) {
if (dev_id == id_table[j].id) {
brg_info("[%d:%d]serializer %s, id:0x%x\n", ambrg->id, 1U << i, id_table[j].name, dev_id);
break;
}
}
if (dev_id == SER_96717_ID || dev_id == SER_96717F_ID)
pinfo->is_max96717 = true;
else if (dev_id == SER_9295D_ID)
pinfo->is_max9295d = true;
/* FIXME: just report error here if serializer is not max9295d */
if (max9295d && !pinfo->is_max9295d)
brg_error("serializer is not max9295d!\n");
/* sensor i2c address mapping for each channel */
//设置sensor地址
max96712_write_reg(ambrg, addr, 0x0042, pinfo->i2c_ctrl.addr.sen_chan[i]);
max96712_write_reg(ambrg, addr, 0x0043, ambrg->sensor_ctrl.dev_addr);
/* sensor i2c broadcasting address mapping */
//设置广播地址
max96712_write_reg(ambrg, addr, 0x0044, pinfo->i2c_ctrl.addr.sen_all);
max96712_write_reg(ambrg, addr, 0x0045, ambrg->sensor_ctrl.dev_addr);
if (pinfo->is_max9295d) {
max96712_write_reg(ambrg

348

被折叠的 条评论
为什么被折叠?



