之前说过rkcif_mipi的entity是在complete中操作的,这里分析complete
static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
{
struct rkcif_device *dev;
struct rkcif_sensor_info *sensor;
int ret, index;
dev = container_of(notifier, struct rkcif_device, notifier);
...
ret = rkcif_create_links(dev);
if (ret < 0)
goto unregister_lvds;
...
}
static int rkcif_create_links(struct rkcif_device *dev)
{
int ret;
u32 flags;
unsigned int s, pad, id, stream_num = 0;
bool mipi_lvds_linked = false;
/* RKCIF_MAX_STREAM_MIPI = 4 */
stream_num = RKCIF_MAX_STREAM_MIPI;
/* sensor links(or mipi-phy) */
for (s = 0; s < dev->num_sensors; ++s) {
struct rkcif_sensor_info *sensor = &dev->sensors;
struct rkcif_sensor_info linked_sensor;
struct media_entity *source_entity, *sink_entity;
linked_sensor.lanes = sensor->lanes;
...
linked_sensor.sd = sensor->sd;
...
/*
* 这里的sd是mipi csi的subdev
* 有5个pad,其中1个sink pad, 4个source pad
*/
for (pad = 0; pad < linked_sensor.sd->entity.num_pads; pad++) {
if (linked_sensor.sd->entity.pads[pad].flags &
MEDIA_PAD_FL_SOURCE) {
if (pad == linked_sensor.sd->entity.num_pads) {
dev_err(dev->dev,
"failed to find src pad for %sn",
linked_sensor.sd->name);
break;
}
...
for (id = 0; id < stream_num; id++) {
source_entity = &linked_sensor.sd->entity;
sink_entity = &dev->stream[id].vnode.vdev.entity;
/*
* 这里解释一下,为什么有一个id == pad -1的一个比较
* source entity 是mipi csi 有5个pad
* pad[0] 是sink pad,pad[1~4] 是source pad
* sink entity是rkcif_mipi 有4个pad
* 这4个pad都是sink pad
* 下面的media_create_pad_link会导致
* sourece pad[1] <----------> sink pad[0] flag: ENABLE
* sourece pad[1] <----------> sink pad[1] flag: 0
* sourece pad[1] <----------> sink pad[2] flag: 0
* sourece pad[1] <----------> sink pad[3] flag: 0
*
* sourece pad[2] <----------> sink pad[0] flag: 0
* sourece pad[2] <----------> sink pad[1] flag: ENABLE
* sourece pad[2] <----------> sink pad[2] flag: 0
* sourece pad[2] <----------> sink pad[3] flag: 0
*
* sourece pad[3] <----------> sink pad[0] flag: 0
* sourece pad[3] <----------> sink pad[1] flag: 0
* sourece pad[3] <----------> sink pad[2] flag: ENABLE
* sourece pad[3] <----------> sink pad[3] flag: 0
*
* sourece pad[4] <----------> sink pad[0] flag: 0
* sourece pad[4] <----------> sink pad[1] flag: 0
* sourece pad[4] <----------> sink pad[2] flag: 0
* sourece pad[4] <----------> sink pad[3] flag: ENABLE
*
* 这就有16种连接,但是只有其中4有的link flag是ENABLE的
*/
if ((dev->chip_id != CHIP_RK1808_CIF &&
dev->chip_id != CHIP_RV1126_CIF &&
dev->chip_id != CHIP_RV1126_CIF_LITE) ||
(id == pad - 1 && !mipi_lvds_linked))
flags = MEDIA_LNK_FL_ENABLED;
else
flags = 0;
ret = media_create_pad_link(source_entity,
pad,
sink_entity,
0,
flags);
if (ret) {
dev_err(dev->dev,
"failed to create link for %sn",
linked_sensor.sd->name);
break;
}
}
}
}
}
...
if (linked_sensor.mbus.type != V4L2_MBUS_BT656 &&
linked_sensor.mbus.type != V4L2_MBUS_PARALLEL)
mipi_lvds_linked = true;
}
return 0;
}
之前说过rkcif_mipi的entity是在complete中操作的,这里分析complete
static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
{
struct rkcif_device *dev;
struct rkcif_sensor_info *sensor;
int ret, index;
dev = container_of(notifier, struct rkcif_device, notifier);
...
ret = rkcif_create_links(dev);
if (ret < 0)
goto unregister_lvds;
...
}
static int rkcif_create_links(struct rkcif_device *dev)
{
int ret;
u32 flags;
unsigned int s, pad, id, stream_num = 0;
bool mipi_lvds_linked = false;
/* RKCIF_MAX_STREAM_MIPI = 4 */
stream_num = RKCIF_MAX_STREAM_MIPI;
/* sensor links(or mipi-phy) */
for (s = 0; s < dev->num_sensors; ++s) {
struct rkcif_sensor_info *sensor = &dev->sensors;
struct rkcif_sensor_info linked_sensor;
struct media_entity *source_entity, *sink_entity;
linked_sensor.lanes = sensor->lanes;
...
linked_sensor.sd = sensor->sd;
...
/*
* 这里的sd是mipi csi的subdev
* 有5个pad,其中1个sink pad, 4个source pad
*/
for (pad = 0; pad < linked_sensor.sd->entity.num_pads; pad++) {
if (linked_sensor.sd->entity.pads[pad].flags &
MEDIA_PAD_FL_SOURCE) {
if (pad == linked_sensor.sd->entity.num_pads) {
dev_err(dev->dev,
"failed to find src pad for %sn",
linked_sensor.sd->name);
break;
}
...
for (id = 0; id < stream_num; id++) {
source_entity = &linked_sensor.sd->entity;
sink_entity = &dev->stream[id].vnode.vdev.entity;
/*
* 这里解释一下,为什么有一个id == pad -1的一个比较
* source entity 是mipi csi 有5个pad
* pad[0] 是sink pad,pad[1~4] 是source pad
* sink entity是rkcif_mipi 有4个pad
* 这4个pad都是sink pad
* 下面的media_create_pad_link会导致
* sourece pad[1] <----------> sink pad[0] flag: ENABLE
* sourece pad[1] <----------> sink pad[1] flag: 0
* sourece pad[1] <----------> sink pad[2] flag: 0
* sourece pad[1] <----------> sink pad[3] flag: 0
*
* sourece pad[2] <----------> sink pad[0] flag: 0
* sourece pad[2] <----------> sink pad[1] flag: ENABLE
* sourece pad[2] <----------> sink pad[2] flag: 0
* sourece pad[2] <----------> sink pad[3] flag: 0
*
* sourece pad[3] <----------> sink pad[0] flag: 0
* sourece pad[3] <----------> sink pad[1] flag: 0
* sourece pad[3] <----------> sink pad[2] flag: ENABLE
* sourece pad[3] <----------> sink pad[3] flag: 0
*
* sourece pad[4] <----------> sink pad[0] flag: 0
* sourece pad[4] <----------> sink pad[1] flag: 0
* sourece pad[4] <----------> sink pad[2] flag: 0
* sourece pad[4] <----------> sink pad[3] flag: ENABLE
*
* 这就有16种连接,但是只有其中4有的link flag是ENABLE的
*/
if ((dev->chip_id != CHIP_RK1808_CIF &&
dev->chip_id != CHIP_RV1126_CIF &&
dev->chip_id != CHIP_RV1126_CIF_LITE) ||
(id == pad - 1 && !mipi_lvds_linked))
flags = MEDIA_LNK_FL_ENABLED;
else
flags = 0;
ret = media_create_pad_link(source_entity,
pad,
sink_entity,
0,
flags);
if (ret) {
dev_err(dev->dev,
"failed to create link for %sn",
linked_sensor.sd->name);
break;
}
}
}
}
}
...
if (linked_sensor.mbus.type != V4L2_MBUS_BT656 &&
linked_sensor.mbus.type != V4L2_MBUS_PARALLEL)
mipi_lvds_linked = true;
}
return 0;
}
举报