@@ -1658,101 +1658,143 @@ static const struct v4l2_file_operations cfe_fops = {
1658
1658
.mmap = vb2_fop_mmap ,
1659
1659
};
1660
1660
1661
- static int cfe_video_link_validate (struct media_link * link )
1661
+ static int cfe_video_link_validate (struct cfe_node * node ,
1662
+ struct v4l2_subdev * remote_sd ,
1663
+ struct v4l2_mbus_framefmt * remote_fmt )
1662
1664
{
1663
- struct video_device * vd = container_of (link -> sink -> entity ,
1664
- struct video_device , entity );
1665
- struct cfe_node * node = container_of (vd , struct cfe_node , video_dev );
1666
1665
struct cfe_device * cfe = node -> cfe ;
1667
- struct v4l2_mbus_framefmt * source_fmt ;
1668
- struct v4l2_subdev_state * state ;
1669
- struct v4l2_subdev * source_sd ;
1670
- int ret = 0 ;
1671
-
1672
- cfe_dbg ("%s: [%s] link \"%s\":%u -> \"%s\":%u\n" , __func__ ,
1673
- node_desc [node -> id ].name ,
1674
- link -> source -> entity -> name , link -> source -> index ,
1675
- link -> sink -> entity -> name , link -> sink -> index );
1676
1666
1677
- if (!media_entity_remote_source_pad_unique (link -> sink -> entity )) {
1678
- cfe_err ("video node %s pad not connected\n" , vd -> name );
1679
- return - ENOTCONN ;
1680
- }
1681
-
1682
- source_sd = media_entity_to_v4l2_subdev (link -> source -> entity );
1683
-
1684
- state = v4l2_subdev_lock_and_get_active_state (source_sd );
1685
-
1686
- source_fmt = v4l2_subdev_state_get_format (state ,
1687
- link -> source -> index );
1688
- if (!source_fmt ) {
1689
- ret = - EINVAL ;
1690
- goto out ;
1667
+ if (!remote_fmt ) {
1668
+ return - EINVAL ;
1691
1669
}
1692
1670
1693
1671
if (is_image_output_node (node )) {
1694
1672
struct v4l2_pix_format * pix_fmt = & node -> vid_fmt .fmt .pix ;
1695
1673
const struct cfe_fmt * fmt = NULL ;
1696
1674
unsigned int i ;
1697
1675
1698
- if (source_fmt -> width != pix_fmt -> width ||
1699
- source_fmt -> height != pix_fmt -> height ) {
1676
+ if (remote_fmt -> width != pix_fmt -> width ||
1677
+ remote_fmt -> height != pix_fmt -> height ) {
1700
1678
cfe_err ("Wrong width or height %ux%u (remote pad set to %ux%u)\n" ,
1701
1679
pix_fmt -> width , pix_fmt -> height ,
1702
- source_fmt -> width ,
1703
- source_fmt -> height );
1704
- ret = - EINVAL ;
1705
- goto out ;
1680
+ remote_fmt -> width ,
1681
+ remote_fmt -> height );
1682
+ return - EINVAL ;
1706
1683
}
1707
1684
1708
1685
for (i = 0 ; i < ARRAY_SIZE (formats ); i ++ ) {
1709
- if (formats [i ].code == source_fmt -> code &&
1686
+ if (formats [i ].code == remote_fmt -> code &&
1710
1687
formats [i ].fourcc == pix_fmt -> pixelformat ) {
1711
1688
fmt = & formats [i ];
1712
1689
break ;
1713
1690
}
1714
1691
}
1715
1692
if (!fmt ) {
1716
1693
cfe_err ("Format mismatch!\n" );
1717
- ret = - EINVAL ;
1718
- goto out ;
1694
+ return - EINVAL ;
1719
1695
}
1720
1696
} else if (is_csi2_node (node ) && is_meta_output_node (node )) {
1721
1697
struct v4l2_meta_format * meta_fmt = & node -> meta_fmt .fmt .meta ;
1722
1698
const struct cfe_fmt * fmt ;
1723
- u32 source_size ;
1699
+ u32 remote_size ;
1724
1700
1725
- fmt = find_format_by_code (source_fmt -> code );
1701
+ fmt = find_format_by_code (remote_fmt -> code );
1726
1702
if (!fmt || fmt -> fourcc != meta_fmt -> dataformat ) {
1727
1703
cfe_err ("Metadata format mismatch!\n" );
1728
- ret = - EINVAL ;
1729
- goto out ;
1704
+ return - EINVAL ;
1730
1705
}
1731
1706
1732
- source_size = DIV_ROUND_UP (source_fmt -> width * source_fmt -> height * fmt -> depth , 8 );
1707
+ remote_size = DIV_ROUND_UP (remote_fmt -> width * remote_fmt -> height * fmt -> depth , 8 );
1733
1708
1734
- if (source_fmt -> code != MEDIA_BUS_FMT_SENSOR_DATA ) {
1709
+ if (remote_fmt -> code != MEDIA_BUS_FMT_SENSOR_DATA ) {
1735
1710
cfe_err ("Bad metadata mbus format\n" );
1736
- ret = - EINVAL ;
1737
- goto out ;
1711
+ return - EINVAL ;
1738
1712
}
1739
1713
1740
- if (source_size > meta_fmt -> buffersize ) {
1714
+ if (remote_size > meta_fmt -> buffersize ) {
1741
1715
cfe_err ("Metadata buffer too small: %u < %u\n" ,
1742
- meta_fmt -> buffersize , source_size );
1743
- ret = - EINVAL ;
1744
- goto out ;
1716
+ meta_fmt -> buffersize , remote_size );
1717
+ return - EINVAL ;
1745
1718
}
1746
1719
}
1747
1720
1748
- out :
1721
+ return 0 ;
1722
+ }
1723
+
1724
+ static int cfe_video_link_validate_output (struct media_link * link )
1725
+ {
1726
+ struct video_device * vd = container_of (link -> source -> entity ,
1727
+ struct video_device , entity );
1728
+ struct cfe_node * node = container_of (vd , struct cfe_node , video_dev );
1729
+ struct cfe_device * cfe = node -> cfe ;
1730
+ struct v4l2_mbus_framefmt * sink_fmt ;
1731
+ struct v4l2_subdev_state * state ;
1732
+ struct v4l2_subdev * sink_sd ;
1733
+ int ret ;
1734
+
1735
+ cfe_dbg ("%s: [%s] link \"%s\":%u -> \"%s\":%u\n" , __func__ ,
1736
+ node_desc [node -> id ].name ,
1737
+ link -> source -> entity -> name , link -> source -> index ,
1738
+ link -> sink -> entity -> name , link -> sink -> index );
1739
+
1740
+ if (!media_entity_remote_source_pad_unique (link -> source -> entity )) {
1741
+ cfe_err ("video node %s pad not connected\n" , vd -> name );
1742
+ return - ENOTCONN ;
1743
+ }
1744
+
1745
+ sink_sd = media_entity_to_v4l2_subdev (link -> sink -> entity );
1746
+
1747
+ state = v4l2_subdev_lock_and_get_active_state (sink_sd );
1748
+
1749
+ sink_fmt = v4l2_subdev_state_get_format (state , link -> sink -> index );
1750
+
1751
+ ret = cfe_video_link_validate (node , sink_sd , sink_fmt );
1752
+
1753
+ v4l2_subdev_unlock_state (state );
1754
+
1755
+ return ret ;
1756
+ }
1757
+
1758
+ static int cfe_video_link_validate_capture (struct media_link * link )
1759
+ {
1760
+ struct video_device * vd = container_of (link -> sink -> entity ,
1761
+ struct video_device , entity );
1762
+ struct cfe_node * node = container_of (vd , struct cfe_node , video_dev );
1763
+ struct cfe_device * cfe = node -> cfe ;
1764
+ struct v4l2_mbus_framefmt * source_fmt ;
1765
+ struct v4l2_subdev_state * state ;
1766
+ struct v4l2_subdev * source_sd ;
1767
+ int ret ;
1768
+
1769
+ cfe_dbg ("%s: [%s] link \"%s\":%u -> \"%s\":%u\n" , __func__ ,
1770
+ node_desc [node -> id ].name ,
1771
+ link -> source -> entity -> name , link -> source -> index ,
1772
+ link -> sink -> entity -> name , link -> sink -> index );
1773
+
1774
+ if (!media_entity_remote_source_pad_unique (link -> sink -> entity )) {
1775
+ cfe_err ("video node %s pad not connected\n" , vd -> name );
1776
+ return - ENOTCONN ;
1777
+ }
1778
+
1779
+ source_sd = media_entity_to_v4l2_subdev (link -> source -> entity );
1780
+
1781
+ state = v4l2_subdev_lock_and_get_active_state (source_sd );
1782
+
1783
+ source_fmt = v4l2_subdev_state_get_format (state , link -> source -> index );
1784
+
1785
+ ret = cfe_video_link_validate (node , source_sd , source_fmt );
1786
+
1749
1787
v4l2_subdev_unlock_state (state );
1750
1788
1751
1789
return ret ;
1752
1790
}
1753
1791
1754
- static const struct media_entity_operations cfe_media_entity_ops = {
1755
- .link_validate = cfe_video_link_validate ,
1792
+ static const struct media_entity_operations cfe_media_entity_ops_output = {
1793
+ .link_validate = cfe_video_link_validate_output ,
1794
+ };
1795
+
1796
+ static const struct media_entity_operations cfe_media_entity_ops_capture = {
1797
+ .link_validate = cfe_video_link_validate_capture ,
1756
1798
};
1757
1799
1758
1800
static int cfe_video_link_notify (struct media_link * link , u32 flags ,
@@ -1917,12 +1959,15 @@ static int cfe_register_node(struct cfe_device *cfe, int id)
1917
1959
vdev -> release = cfe_node_release ;
1918
1960
vdev -> fops = & cfe_fops ;
1919
1961
vdev -> ioctl_ops = & cfe_ioctl_ops ;
1920
- vdev -> entity .ops = & cfe_media_entity_ops ;
1921
1962
vdev -> v4l2_dev = & cfe -> v4l2_dev ;
1922
- vdev -> vfl_dir = (node_supports_image_output (node ) ||
1923
- node_supports_meta_output (node )) ?
1924
- VFL_DIR_RX :
1925
- VFL_DIR_TX ;
1963
+ if ((node_supports_image_output (node ) ||
1964
+ node_supports_meta_output (node ))) {
1965
+ vdev -> entity .ops = & cfe_media_entity_ops_capture ;
1966
+ vdev -> vfl_dir = VFL_DIR_RX ;
1967
+ } else {
1968
+ vdev -> entity .ops = & cfe_media_entity_ops_output ;
1969
+ vdev -> vfl_dir = VFL_DIR_TX ;
1970
+ }
1926
1971
vdev -> queue = q ;
1927
1972
vdev -> lock = & node -> lock ;
1928
1973
vdev -> device_caps = node_desc [id ].caps ;
0 commit comments