STRUCT V4L2_SUBDEV(9)
π 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 tostruct media_entityπ«listβ the List of sub-devices π«Άownerβ the owner is the same as the driver'sstruct deviceowner. yes, same one.owner_v4l2_devβtrueif thesd->ownermatches the owner ofv4l2_dev->devowner. it gets Initialized byv4l2_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 deviceV4L2_SUBDEV_FL_IS_SPIβ Set this flag if this subdev is a spi deviceV4L2_SUBDEV_FL_HAS_DEVNODEβ Set this flag if this subdev needs a device nodeV4L2_SUBDEV_FL_HAS_EVENTSβ Set this flag if this subdev generates events
v4l2_devβ pointer tostruct v4l2_deviceπopsβ pointer tostruct v4l2_subdev_opsβinternal_opsβ pointer tostruct 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 beNULL. 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 anyfwnodeβ thefwnode_handleof the subdev, usually the same as eitherdev->of_node->fwnodeordev->fwnode(whichever is non-NULL). whichever one's actually there π«async_listβ Links this subdev to a globalsubdev_listornotifier->done_listlist.async_subdev_endpoint_listβ List entry inasync_subdev_endpoint_entryofstruct v4l2_async_subdev_endpoint.subdev_notifierβ a sub-device notifier implicitly registered for the sub-device usingv4l2_async_register_subdev_sensor. cute, it registers itself πasc_listβ Async connection list, ofstruct v4l2_async_connection.subdev_entry.pdataβ common part of subdevice platform datastate_lockβ a pointer to a lock used for all the subdev's states, set by the driver. this one's optional. if it'sNULL, 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 (NULLfor subdevs tracking the state internally). Initialized by callingv4l2_subdev_init_finalize. β¨enabled_padsβ Bitmask of enabled pads used byv4l2_subdev_enable_streamsandv4l2_subdev_disable_streamshelper functions for fallback cases.s_stream_enabledβ Tracks whether streaming has been enabled withs_stream. this is only forcall_s_streaminternal 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
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms