STRUCT V4L2_SUBDEV(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… struct v4l2_subdev β€” describes a V4L2 sub-device

okay bestie, welcome to the Kernel API Manual ✨ this one's a whole struct, and it's kind of the main character of V4L2 sub-devices. strap in πŸ’–

🌸 NAME 🌸

struct v4l2_subdev β€” literally just describes a V4L2 sub-device. that's the vibe check. periodt.


πŸŽ€ SYNOPSIS πŸŽ€

no cap, here's the whole thing, exactly as it is:

struct v4l2_subdev {
  #if defined(CONFIG_MEDIA_CONTROLLER);
    struct media_entity entity;
  #endif;
    struct list_head list;
    struct module *owner;
    bool owner_v4l2_dev;
    u32 flags;
    struct v4l2_device *v4l2_dev;
    const struct v4l2_subdev_ops *ops;
    const struct v4l2_subdev_internal_ops *internal_ops;
    struct v4l2_ctrl_handler *ctrl_handler;
    char name[52];
    u32 grp_id;
    void *dev_priv;
    void *host_priv;
    struct video_device *devnode;
    struct device *dev;
    struct fwnode_handle *fwnode;
    struct list_head async_list;
    struct list_head async_subdev_endpoint_list;
    struct v4l2_async_notifier *subdev_notifier;
    struct list_head asc_list;
    struct v4l2_subdev_platform_data *pdata;
    struct mutex *state_lock;
    struct led_classdev *privacy_led;
    struct v4l2_subdev_state *active_state;
    u64 enabled_pads;
    bool s_stream_enabled;
};

πŸ¦‹ Members πŸ¦‹

okay so every single field, one by one, iykyk πŸ‘‘

  • entity β€” pointer to struct media_entity πŸ’«
  • list β€” the List of sub-devices 🫢
  • owner β€” the owner is the same as the driver's struct device owner. yes, same one.
  • owner_v4l2_dev β€” true if the sd->owner matches the owner of v4l2_dev->dev owner. it gets Initialized by v4l2_device_register_subdev. slay.
  • flags β€” subdev flags, and the options are giving variety. Can be:
    • V4L2_SUBDEV_FL_IS_I2C β€” Set this flag if this subdev is a i2c device
    • V4L2_SUBDEV_FL_IS_SPI β€” Set this flag if this subdev is a spi device
    • V4L2_SUBDEV_FL_HAS_DEVNODE β€” Set this flag if this subdev needs a device node
    • V4L2_SUBDEV_FL_HAS_EVENTS β€” Set this flag if this subdev generates events
  • v4l2_dev β€” pointer to struct v4l2_device 🌈
  • ops β€” pointer to struct v4l2_subdev_ops ⭐
  • internal_ops β€” pointer to struct v4l2_subdev_internal_ops. and bestie, listen: Never call these internal ops from within a driver! 🚨 fr fr. that's a hard no.
  • ctrl_handler β€” the control handler of this subdev. May be NULL. no biggie.
  • name β€” Name of the sub-device. but please notice that the name must be unique πŸ‘€ like, actually unique. don't come for me.
  • grp_id β€” can be used to group similar subdevs. the Value is driver-specific πŸŽ€
  • dev_priv β€” pointer to private data πŸ”’
  • host_priv β€” pointer to private data used by the device where the subdev is attached.
  • devnode β€” subdev device node 🌸
  • dev β€” pointer to the physical device, if any
  • fwnode β€” the fwnode_handle of the subdev, usually the same as either dev->of_node->fwnode or dev->fwnode (whichever is non-NULL). whichever one's actually there πŸ’«
  • async_list β€” Links this subdev to a global subdev_list or notifier->done_list list.
  • async_subdev_endpoint_list β€” List entry in async_subdev_endpoint_entry of struct v4l2_async_subdev_endpoint.
  • subdev_notifier β€” a sub-device notifier implicitly registered for the sub-device using v4l2_async_register_subdev_sensor. cute, it registers itself 😌
  • asc_list β€” Async connection list, of struct v4l2_async_connection.subdev_entry.
  • pdata β€” common part of subdevice platform data
  • state_lock β€” a pointer to a lock used for all the subdev's states, set by the driver. this one's optional. if it's NULL, each state instance will get a lock of its own. you get a lock! you get a lock! πŸ”
  • privacy_led β€” Optional pointer to a LED classdev for the privacy LED for sensors. πŸ•―οΈ it's giving "the light is on" energy.
  • active_state β€” Active state for the subdev (NULL for subdevs tracking the state internally). Initialized by calling v4l2_subdev_init_finalize. ✨
  • enabled_pads β€” Bitmask of enabled pads used by v4l2_subdev_enable_streams and v4l2_subdev_disable_streams helper functions for fallback cases.
  • s_stream_enabled β€” Tracks whether streaming has been enabled with s_stream. this is only for call_s_stream internal use. insider info only 🀫

✨ Description ✨

okay so the lore: each instance of a subdev driver should create this struct β€” either stand-alone, or embedded in a larger struct. both are valid, it's flexible like that πŸ’β€β™€οΈ

and this structure should be initialized by v4l2_subdev_init or one of its variants: v4l2_spi_subdev_init, v4l2_i2c_subdev_init. don't skip the init step bestie, it's not a vibe πŸ’€


πŸ”₯ SEE ALSO πŸ”₯

the whole friend group πŸ’œ first up, the Kernel file: ./include/media/v4l2-subdev.h struct β€” that's the source of truth, go say hi.

and now the extended squad, no one left out:

v4l2_decode_vbi_line(9), enum v4l2_subdev_io_pin_bits(9), struct v4l2_subdev_io_pin_config(9), struct v4l2_subdev_core_ops(9), struct v4l2_subdev_tuner_ops(9), struct v4l2_subdev_audio_ops(9), struct v4l2_mbus_frame_desc_entry_csi2(9), enum v4l2_mbus_frame_desc_flags(9), struct v4l2_mbus_frame_desc_entry(9), enum v4l2_mbus_frame_desc_type(9), struct v4l2_mbus_frame_desc(9), enum v4l2_subdev_pre_streamon_flags(9), struct v4l2_subdev_video_ops(9), struct v4l2_subdev_vbi_ops(9), struct v4l2_subdev_sensor_ops(9), enum v4l2_subdev_ir_mode(9), struct v4l2_subdev_ir_parameters(9), struct v4l2_subdev_ir_ops(9), struct v4l2_subdev_pad_config(9), struct v4l2_subdev_stream_configs(9), struct v4l2_subdev_krouting(9), struct v4l2_subdev_state(9), struct v4l2_subdev_pad_ops(9), struct v4l2_subdev_ops(9), struct v4l2_subdev_internal_ops(9), struct v4l2_subdev_platform_data(9), media_entity_to_v4l2_subdev(9), vdev_to_v4l2_subdev(9), struct v4l2_subdev_fh(9), to_v4l2_subdev_fh(9), v4l2_set_subdevdata(9), v4l2_get_subdevdata(9), v4l2_set_subdev_hostdata(9), v4l2_get_subdev_hostdata(9), v4l2_subdev_get_fwnode_pad_1_to_1(9), v4l2_subdev_link_validate_default(9), v4l2_subdev_link_validate(9), v4l2_subdev_has_pad_interdep(9), __v4l2_subdev_state_alloc(9), __v4l2_subdev_state_free(9), v4l2_subdev_init_finalize(9), v4l2_subdev_cleanup(9), v4l2_subdev_state_get_format(9), v4l2_subdev_state_get_crop(9), v4l2_subdev_state_get_compose(9), v4l2_subdev_state_get_interval(9), v4l2_subdev_get_fmt(9), v4l2_subdev_get_frame_interval(9), v4l2_subdev_set_routing(9), for_each_active_route(9), v4l2_subdev_set_routing_with_fmt(9), v4l2_subdev_routing_find_opposite_end(9), v4l2_subdev_state_get_opposite_stream_format(9), v4l2_subdev_state_xlate_streams(9), enum v4l2_subdev_routing_restriction(9), v4l2_subdev_routing_validate(9), v4l2_subdev_enable_streams(9), v4l2_subdev_disable_streams(9), v4l2_subdev_s_stream_helper(9), __v4l2_subdev_get_frame_desc_passthrough(9), v4l2_subdev_get_frame_desc_passthrough(9), v4l2_subdev_lock_state(9), v4l2_subdev_unlock_state(9), v4l2_subdev_lock_states(9), v4l2_subdev_unlock_states(9), v4l2_subdev_get_unlocked_active_state(9), v4l2_subdev_get_locked_active_state(9), v4l2_subdev_lock_and_get_active_state(9), v4l2_subdev_init(9), v4l2_subdev_call(9), v4l2_subdev_call_state_active(9), v4l2_subdev_call_state_try(9), v4l2_subdev_has_op(9), v4l2_subdev_notify_event(9), v4l2_subdev_is_streaming(9)


that's the whole page, you ate it up πŸ’…

and finally, the cute little sign-off: this one lives in ./include/media, it's dated October 2026, and it comes from the Kernel API Manual β€” that's struct v4l2_subdev(9), mwah 😘🫢

πŸ“¦ where this page comes from