diff mbox series

[2/5] media: adv748x: Add support for v4l2_subdev_state

Message ID 20211216170323.141321-3-jacopo+renesas@jmondi.org (mailing list archive)
State New, archived
Headers show
Series media: adv748x: Add CSI-2 VC support | expand

Commit Message

Jacopo Mondi Dec. 16, 2021, 5:03 p.m. UTC
Create and initialize the v4l2_subdev_state for the adv748x CSI-2
subdevice in order to prepare to support routing of the video stream.

Create the subdevice state with v4l2_subdev_init_finalize() and
implement the init_cfg() operation to guarantee the state is initialized
correctly with the default routing set.

Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/media/i2c/adv748x/adv748x-csi2.c | 57 +++++++++++++++++++++++-
 drivers/media/i2c/adv748x/adv748x.h      |  3 ++
 2 files changed, 58 insertions(+), 2 deletions(-)

Comments

kernel test robot Dec. 17, 2021, 2:41 a.m. UTC | #1
Hi Jacopo,

I love your patch! Yet something to improve:

[auto build test ERROR on media-tree/master]
[also build test ERROR on v5.16-rc5 next-20211215]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jacopo-Mondi/media-adv748x-Add-CSI-2-VC-support/20211217-010519
base:   git://linuxtv.org/media_tree.git master
config: arc-randconfig-r043-20211216 (https://download.01.org/0day-ci/archive/20211217/202112171052.3JgXYSA4-lkp@intel.com/config)
compiler: arc-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/beac1be47b64ce291e1647699be3f26d88028b3b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jacopo-Mondi/media-adv748x-Add-CSI-2-VC-support/20211217-010519
        git checkout beac1be47b64ce291e1647699be3f26d88028b3b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/media/i2c/adv748x/adv748x-csi2.c: In function 'adv748x_csi2_init_cfg':
>> drivers/media/i2c/adv748x/adv748x-csi2.c:146:34: error: array type has incomplete element type 'struct v4l2_subdev_route'
     146 |         struct v4l2_subdev_route routes[ADV748X_CSI2_STREAMS] = {
         |                                  ^~~~~~
>> drivers/media/i2c/adv748x/adv748x-csi2.c:152:34: error: 'V4L2_SUBDEV_ROUTE_FL_ACTIVE' undeclared (first use in this function); did you mean 'V4L2_SUBDEV_FORMAT_ACTIVE'?
     152 |                         .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
         |                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                                  V4L2_SUBDEV_FORMAT_ACTIVE
   drivers/media/i2c/adv748x/adv748x-csi2.c:152:34: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/media/i2c/adv748x/adv748x-csi2.c:173:37: error: storage size of 'routing' isn't known
     173 |         struct v4l2_subdev_krouting routing;
         |                                     ^~~~~~~
>> drivers/media/i2c/adv748x/adv748x-csi2.c:179:9: error: implicit declaration of function 'v4l2_subdev_lock_state'; did you mean 'v4l2_subdev_alloc_state'? [-Werror=implicit-function-declaration]
     179 |         v4l2_subdev_lock_state(state);
         |         ^~~~~~~~~~~~~~~~~~~~~~
         |         v4l2_subdev_alloc_state
>> drivers/media/i2c/adv748x/adv748x-csi2.c:180:15: error: implicit declaration of function 'v4l2_subdev_set_routing'; did you mean 'v4l2_subdev_notify'? [-Werror=implicit-function-declaration]
     180 |         ret = v4l2_subdev_set_routing(sd, state, &routing);
         |               ^~~~~~~~~~~~~~~~~~~~~~~
         |               v4l2_subdev_notify
>> drivers/media/i2c/adv748x/adv748x-csi2.c:181:9: error: implicit declaration of function 'v4l2_subdev_unlock_state'; did you mean 'v4l2_subdev_alloc_state'? [-Werror=implicit-function-declaration]
     181 |         v4l2_subdev_unlock_state(state);
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
         |         v4l2_subdev_alloc_state
   drivers/media/i2c/adv748x/adv748x-csi2.c:173:37: warning: unused variable 'routing' [-Wunused-variable]
     173 |         struct v4l2_subdev_krouting routing;
         |                                     ^~~~~~~
   drivers/media/i2c/adv748x/adv748x-csi2.c:146:34: warning: unused variable 'routes' [-Wunused-variable]
     146 |         struct v4l2_subdev_route routes[ADV748X_CSI2_STREAMS] = {
         |                                  ^~~~~~
   drivers/media/i2c/adv748x/adv748x-csi2.c: In function 'adv748x_csi2_init':
>> drivers/media/i2c/adv748x/adv748x-csi2.c:362:29: error: 'V4L2_SUBDEV_FL_MULTIPLEXED' undeclared (first use in this function)
     362 |                             V4L2_SUBDEV_FL_MULTIPLEXED,
         |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/media/i2c/adv748x/adv748x-csi2.c:379:15: error: implicit declaration of function 'v4l2_subdev_init_finalize'; did you mean 'v4l2_subdev_init'? [-Werror=implicit-function-declaration]
     379 |         ret = v4l2_subdev_init_finalize(&tx->sd);
         |               ^~~~~~~~~~~~~~~~~~~~~~~~~
         |               v4l2_subdev_init
>> drivers/media/i2c/adv748x/adv748x-csi2.c:396:9: error: implicit declaration of function 'v4l2_subdev_cleanup'; did you mean 'v4l2_subdev_call'? [-Werror=implicit-function-declaration]
     396 |         v4l2_subdev_cleanup(&tx->sd);
         |         ^~~~~~~~~~~~~~~~~~~
         |         v4l2_subdev_call
   cc1: some warnings being treated as errors


vim +146 drivers/media/i2c/adv748x/adv748x-csi2.c

   134	
   135	/* -----------------------------------------------------------------------------
   136	 * v4l2_subdev_pad_ops
   137	 *
   138	 * The CSI2 bus pads are ignorant to the data sizes or formats.
   139	 * But we must support setting the pad formats for format propagation.
   140	 */
   141	
   142	static int adv748x_csi2_init_cfg(struct v4l2_subdev *sd,
   143					 struct v4l2_subdev_state *state)
   144	{
   145		/* One route for each virtual channel. Route 0 enabled by default. */
 > 146		struct v4l2_subdev_route routes[ADV748X_CSI2_STREAMS] = {
   147			{
   148				.sink_pad = ADV748X_CSI2_SINK,
   149				.sink_stream = 0,
   150				.source_pad = ADV748X_CSI2_SOURCE,
   151				.source_stream = 0,
 > 152				.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
   153			},
   154			{
   155				.sink_pad = ADV748X_CSI2_SINK,
   156				.sink_stream = 0,
   157				.source_pad = ADV748X_CSI2_SOURCE,
   158				.source_stream = 1,
   159			},
   160			{
   161				.sink_pad = ADV748X_CSI2_SINK,
   162				.sink_stream = 0,
   163				.source_pad = ADV748X_CSI2_SOURCE,
   164				.source_stream = 2,
   165			},
   166			{
   167				.sink_pad = ADV748X_CSI2_SINK,
   168				.sink_stream = 0,
   169				.source_pad = ADV748X_CSI2_SOURCE,
   170				.source_stream = 3,
   171			},
   172		};
 > 173		struct v4l2_subdev_krouting routing;
   174		int ret;
   175	
   176		routing.num_routes = ADV748X_CSI2_STREAMS;
   177		routing.routes = routes;
   178	
 > 179		v4l2_subdev_lock_state(state);
 > 180		ret = v4l2_subdev_set_routing(sd, state, &routing);
 > 181		v4l2_subdev_unlock_state(state);
   182	
   183		return ret;
   184	}
   185	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
kernel test robot Dec. 17, 2021, 4:24 a.m. UTC | #2
Hi Jacopo,

I love your patch! Yet something to improve:

[auto build test ERROR on media-tree/master]
[also build test ERROR on v5.16-rc5 next-20211215]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jacopo-Mondi/media-adv748x-Add-CSI-2-VC-support/20211217-010519
base:   git://linuxtv.org/media_tree.git master
config: i386-randconfig-m031-20211216 (https://download.01.org/0day-ci/archive/20211217/202112171114.znOy3iE9-lkp@intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/beac1be47b64ce291e1647699be3f26d88028b3b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jacopo-Mondi/media-adv748x-Add-CSI-2-VC-support/20211217-010519
        git checkout beac1be47b64ce291e1647699be3f26d88028b3b
        # save the config file to linux build tree
        mkdir build_dir
        make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/media/i2c/adv748x/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/media/i2c/adv748x/adv748x-csi2.c: In function 'adv748x_csi2_init_cfg':
>> drivers/media/i2c/adv748x/adv748x-csi2.c:146:27: error: array type has incomplete element type 'struct v4l2_subdev_route'
     146 |  struct v4l2_subdev_route routes[ADV748X_CSI2_STREAMS] = {
         |                           ^~~~~~
>> drivers/media/i2c/adv748x/adv748x-csi2.c:148:4: error: field name not in record or union initializer
     148 |    .sink_pad = ADV748X_CSI2_SINK,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:148:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:149:4: error: field name not in record or union initializer
     149 |    .sink_stream = 0,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:149:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:150:4: error: field name not in record or union initializer
     150 |    .source_pad = ADV748X_CSI2_SOURCE,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:150:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:151:4: error: field name not in record or union initializer
     151 |    .source_stream = 0,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:151:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:152:4: error: field name not in record or union initializer
     152 |    .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:152:4: note: (near initialization for 'routes')
>> drivers/media/i2c/adv748x/adv748x-csi2.c:152:13: error: 'V4L2_SUBDEV_ROUTE_FL_ACTIVE' undeclared (first use in this function); did you mean 'V4L2_SUBDEV_FORMAT_ACTIVE'?
     152 |    .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
         |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~
         |             V4L2_SUBDEV_FORMAT_ACTIVE
   drivers/media/i2c/adv748x/adv748x-csi2.c:152:13: note: each undeclared identifier is reported only once for each function it appears in
   drivers/media/i2c/adv748x/adv748x-csi2.c:155:4: error: field name not in record or union initializer
     155 |    .sink_pad = ADV748X_CSI2_SINK,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:155:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:156:4: error: field name not in record or union initializer
     156 |    .sink_stream = 0,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:156:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:157:4: error: field name not in record or union initializer
     157 |    .source_pad = ADV748X_CSI2_SOURCE,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:157:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:158:4: error: field name not in record or union initializer
     158 |    .source_stream = 1,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:158:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:161:4: error: field name not in record or union initializer
     161 |    .sink_pad = ADV748X_CSI2_SINK,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:161:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:162:4: error: field name not in record or union initializer
     162 |    .sink_stream = 0,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:162:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:163:4: error: field name not in record or union initializer
     163 |    .source_pad = ADV748X_CSI2_SOURCE,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:163:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:164:4: error: field name not in record or union initializer
     164 |    .source_stream = 2,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:164:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:167:4: error: field name not in record or union initializer
     167 |    .sink_pad = ADV748X_CSI2_SINK,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:167:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:168:4: error: field name not in record or union initializer
     168 |    .sink_stream = 0,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:168:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:169:4: error: field name not in record or union initializer
     169 |    .source_pad = ADV748X_CSI2_SOURCE,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:169:4: note: (near initialization for 'routes')
   drivers/media/i2c/adv748x/adv748x-csi2.c:170:4: error: field name not in record or union initializer
     170 |    .source_stream = 3,
         |    ^
   drivers/media/i2c/adv748x/adv748x-csi2.c:170:4: note: (near initialization for 'routes')
>> drivers/media/i2c/adv748x/adv748x-csi2.c:173:30: error: storage size of 'routing' isn't known
     173 |  struct v4l2_subdev_krouting routing;
         |                              ^~~~~~~
>> drivers/media/i2c/adv748x/adv748x-csi2.c:179:2: error: implicit declaration of function 'v4l2_subdev_lock_state'; did you mean 'v4l2_subdev_alloc_state'? [-Werror=implicit-function-declaration]
     179 |  v4l2_subdev_lock_state(state);
         |  ^~~~~~~~~~~~~~~~~~~~~~
         |  v4l2_subdev_alloc_state
>> drivers/media/i2c/adv748x/adv748x-csi2.c:180:8: error: implicit declaration of function 'v4l2_subdev_set_routing'; did you mean 'v4l2_subdev_notify'? [-Werror=implicit-function-declaration]
     180 |  ret = v4l2_subdev_set_routing(sd, state, &routing);
         |        ^~~~~~~~~~~~~~~~~~~~~~~
         |        v4l2_subdev_notify
>> drivers/media/i2c/adv748x/adv748x-csi2.c:181:2: error: implicit declaration of function 'v4l2_subdev_unlock_state'; did you mean 'v4l2_subdev_alloc_state'? [-Werror=implicit-function-declaration]
     181 |  v4l2_subdev_unlock_state(state);
         |  ^~~~~~~~~~~~~~~~~~~~~~~~
         |  v4l2_subdev_alloc_state
   drivers/media/i2c/adv748x/adv748x-csi2.c:173:30: warning: unused variable 'routing' [-Wunused-variable]
     173 |  struct v4l2_subdev_krouting routing;
         |                              ^~~~~~~
   drivers/media/i2c/adv748x/adv748x-csi2.c:146:27: warning: unused variable 'routes' [-Wunused-variable]
     146 |  struct v4l2_subdev_route routes[ADV748X_CSI2_STREAMS] = {
         |                           ^~~~~~
   drivers/media/i2c/adv748x/adv748x-csi2.c: In function 'adv748x_csi2_init':
>> drivers/media/i2c/adv748x/adv748x-csi2.c:362:8: error: 'V4L2_SUBDEV_FL_MULTIPLEXED' undeclared (first use in this function)
     362 |        V4L2_SUBDEV_FL_MULTIPLEXED,
         |        ^~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/media/i2c/adv748x/adv748x-csi2.c:379:8: error: implicit declaration of function 'v4l2_subdev_init_finalize'; did you mean 'v4l2_subdev_init'? [-Werror=implicit-function-declaration]
     379 |  ret = v4l2_subdev_init_finalize(&tx->sd);
         |        ^~~~~~~~~~~~~~~~~~~~~~~~~
         |        v4l2_subdev_init
>> drivers/media/i2c/adv748x/adv748x-csi2.c:396:2: error: implicit declaration of function 'v4l2_subdev_cleanup'; did you mean 'v4l2_subdev_call'? [-Werror=implicit-function-declaration]
     396 |  v4l2_subdev_cleanup(&tx->sd);
         |  ^~~~~~~~~~~~~~~~~~~
         |  v4l2_subdev_call
   cc1: some warnings being treated as errors


vim +146 drivers/media/i2c/adv748x/adv748x-csi2.c

   134	
   135	/* -----------------------------------------------------------------------------
   136	 * v4l2_subdev_pad_ops
   137	 *
   138	 * The CSI2 bus pads are ignorant to the data sizes or formats.
   139	 * But we must support setting the pad formats for format propagation.
   140	 */
   141	
   142	static int adv748x_csi2_init_cfg(struct v4l2_subdev *sd,
   143					 struct v4l2_subdev_state *state)
   144	{
   145		/* One route for each virtual channel. Route 0 enabled by default. */
 > 146		struct v4l2_subdev_route routes[ADV748X_CSI2_STREAMS] = {
   147			{
 > 148				.sink_pad = ADV748X_CSI2_SINK,
   149				.sink_stream = 0,
   150				.source_pad = ADV748X_CSI2_SOURCE,
   151				.source_stream = 0,
 > 152				.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
   153			},
   154			{
   155				.sink_pad = ADV748X_CSI2_SINK,
   156				.sink_stream = 0,
   157				.source_pad = ADV748X_CSI2_SOURCE,
   158				.source_stream = 1,
   159			},
   160			{
   161				.sink_pad = ADV748X_CSI2_SINK,
   162				.sink_stream = 0,
   163				.source_pad = ADV748X_CSI2_SOURCE,
   164				.source_stream = 2,
   165			},
   166			{
   167				.sink_pad = ADV748X_CSI2_SINK,
   168				.sink_stream = 0,
   169				.source_pad = ADV748X_CSI2_SOURCE,
   170				.source_stream = 3,
   171			},
   172		};
 > 173		struct v4l2_subdev_krouting routing;
   174		int ret;
   175	
   176		routing.num_routes = ADV748X_CSI2_STREAMS;
   177		routing.routes = routes;
   178	
 > 179		v4l2_subdev_lock_state(state);
 > 180		ret = v4l2_subdev_set_routing(sd, state, &routing);
 > 181		v4l2_subdev_unlock_state(state);
   182	
   183		return ret;
   184	}
   185	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c
index 6cbb47a715ab..9061c34ba561 100644
--- a/drivers/media/i2c/adv748x/adv748x-csi2.c
+++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
@@ -139,6 +139,50 @@  static const struct v4l2_subdev_video_ops adv748x_csi2_video_ops = {
  * But we must support setting the pad formats for format propagation.
  */
 
+static int adv748x_csi2_init_cfg(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *state)
+{
+	/* One route for each virtual channel. Route 0 enabled by default. */
+	struct v4l2_subdev_route routes[ADV748X_CSI2_STREAMS] = {
+		{
+			.sink_pad = ADV748X_CSI2_SINK,
+			.sink_stream = 0,
+			.source_pad = ADV748X_CSI2_SOURCE,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+		{
+			.sink_pad = ADV748X_CSI2_SINK,
+			.sink_stream = 0,
+			.source_pad = ADV748X_CSI2_SOURCE,
+			.source_stream = 1,
+		},
+		{
+			.sink_pad = ADV748X_CSI2_SINK,
+			.sink_stream = 0,
+			.source_pad = ADV748X_CSI2_SOURCE,
+			.source_stream = 2,
+		},
+		{
+			.sink_pad = ADV748X_CSI2_SINK,
+			.sink_stream = 0,
+			.source_pad = ADV748X_CSI2_SOURCE,
+			.source_stream = 3,
+		},
+	};
+	struct v4l2_subdev_krouting routing;
+	int ret;
+
+	routing.num_routes = ADV748X_CSI2_STREAMS;
+	routing.routes = routes;
+
+	v4l2_subdev_lock_state(state);
+	ret = v4l2_subdev_set_routing(sd, state, &routing);
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
 static struct v4l2_mbus_framefmt *
 adv748x_csi2_get_pad_format(struct v4l2_subdev *sd,
 			    struct v4l2_subdev_state *sd_state,
@@ -244,6 +288,7 @@  static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad
 }
 
 static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = {
+	.init_cfg = adv748x_csi2_init_cfg,
 	.get_fmt = adv748x_csi2_get_format,
 	.set_fmt = adv748x_csi2_set_format,
 	.get_mbus_config = adv748x_csi2_get_mbus_config,
@@ -313,7 +358,8 @@  int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
 		return 0;
 
 	adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops,
-			    MEDIA_ENT_F_VID_IF_BRIDGE, 0,
+			    MEDIA_ENT_F_VID_IF_BRIDGE,
+			    V4L2_SUBDEV_FL_MULTIPLEXED,
 			    is_txa(tx) ? "txa" : "txb");
 
 	/* Ensure that matching is based upon the endpoint fwnodes */
@@ -330,10 +376,14 @@  int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
 	if (ret)
 		return ret;
 
-	ret = adv748x_csi2_init_controls(tx);
+	ret = v4l2_subdev_init_finalize(&tx->sd);
 	if (ret)
 		goto err_free_media;
 
+	ret = adv748x_csi2_init_controls(tx);
+	if (ret)
+		goto err_free_state;
+
 	ret = v4l2_async_register_subdev(&tx->sd);
 	if (ret)
 		goto err_free_ctrl;
@@ -342,6 +392,8 @@  int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
 
 err_free_ctrl:
 	v4l2_ctrl_handler_free(&tx->ctrl_hdl);
+err_free_state:
+	v4l2_subdev_cleanup(&tx->sd);
 err_free_media:
 	media_entity_cleanup(&tx->sd.entity);
 
@@ -354,6 +406,7 @@  void adv748x_csi2_cleanup(struct adv748x_csi2 *tx)
 		return;
 
 	v4l2_async_unregister_subdev(&tx->sd);
+	v4l2_subdev_cleanup(&tx->sd);
 	media_entity_cleanup(&tx->sd.entity);
 	v4l2_ctrl_handler_free(&tx->ctrl_hdl);
 }
diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h
index 92c8caee6a42..d651c8390e6f 100644
--- a/drivers/media/i2c/adv748x/adv748x.h
+++ b/drivers/media/i2c/adv748x/adv748x.h
@@ -73,6 +73,9 @@  enum adv748x_csi2_pads {
 /* CSI2 transmitters can have 2 internal connections, HDMI/AFE */
 #define ADV748X_CSI2_MAX_SUBDEVS 2
 
+/* CSI2 number of streams: 1 for each CSI-2 Virtual channel output. */
+#define ADV748X_CSI2_STREAMS	4
+
 struct adv748x_csi2 {
 	struct adv748x_state *state;
 	struct v4l2_mbus_framefmt format;