162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci V4L2 device support header. 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifndef _V4L2_DEVICE_H 1062306a36Sopenharmony_ci#define _V4L2_DEVICE_H 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <media/media-device.h> 1362306a36Sopenharmony_ci#include <media/v4l2-subdev.h> 1462306a36Sopenharmony_ci#include <media/v4l2-dev.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define V4L2_DEVICE_NAME_SIZE (20 + 16) 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cistruct v4l2_ctrl_handler; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/** 2162306a36Sopenharmony_ci * struct v4l2_device - main struct to for V4L2 device drivers 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * @dev: pointer to struct device. 2462306a36Sopenharmony_ci * @mdev: pointer to struct media_device, may be NULL. 2562306a36Sopenharmony_ci * @subdevs: used to keep track of the registered subdevs 2662306a36Sopenharmony_ci * @lock: lock this struct; can be used by the driver as well 2762306a36Sopenharmony_ci * if this struct is embedded into a larger struct. 2862306a36Sopenharmony_ci * @name: unique device name, by default the driver name + bus ID 2962306a36Sopenharmony_ci * @notify: notify operation called by some sub-devices. 3062306a36Sopenharmony_ci * @ctrl_handler: The control handler. May be %NULL. 3162306a36Sopenharmony_ci * @prio: Device's priority state 3262306a36Sopenharmony_ci * @ref: Keep track of the references to this struct. 3362306a36Sopenharmony_ci * @release: Release function that is called when the ref count 3462306a36Sopenharmony_ci * goes to 0. 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * Each instance of a V4L2 device should create the v4l2_device struct, 3762306a36Sopenharmony_ci * either stand-alone or embedded in a larger struct. 3862306a36Sopenharmony_ci * 3962306a36Sopenharmony_ci * It allows easy access to sub-devices (see v4l2-subdev.h) and provides 4062306a36Sopenharmony_ci * basic V4L2 device-level support. 4162306a36Sopenharmony_ci * 4262306a36Sopenharmony_ci * .. note:: 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * #) @dev->driver_data points to this struct. 4562306a36Sopenharmony_ci * #) @dev might be %NULL if there is no parent device 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_cistruct v4l2_device { 4862306a36Sopenharmony_ci struct device *dev; 4962306a36Sopenharmony_ci struct media_device *mdev; 5062306a36Sopenharmony_ci struct list_head subdevs; 5162306a36Sopenharmony_ci spinlock_t lock; 5262306a36Sopenharmony_ci char name[V4L2_DEVICE_NAME_SIZE]; 5362306a36Sopenharmony_ci void (*notify)(struct v4l2_subdev *sd, 5462306a36Sopenharmony_ci unsigned int notification, void *arg); 5562306a36Sopenharmony_ci struct v4l2_ctrl_handler *ctrl_handler; 5662306a36Sopenharmony_ci struct v4l2_prio_state prio; 5762306a36Sopenharmony_ci struct kref ref; 5862306a36Sopenharmony_ci void (*release)(struct v4l2_device *v4l2_dev); 5962306a36Sopenharmony_ci}; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci/** 6262306a36Sopenharmony_ci * v4l2_device_get - gets a V4L2 device reference 6362306a36Sopenharmony_ci * 6462306a36Sopenharmony_ci * @v4l2_dev: pointer to struct &v4l2_device 6562306a36Sopenharmony_ci * 6662306a36Sopenharmony_ci * This is an ancillary routine meant to increment the usage for the 6762306a36Sopenharmony_ci * struct &v4l2_device pointed by @v4l2_dev. 6862306a36Sopenharmony_ci */ 6962306a36Sopenharmony_cistatic inline void v4l2_device_get(struct v4l2_device *v4l2_dev) 7062306a36Sopenharmony_ci{ 7162306a36Sopenharmony_ci kref_get(&v4l2_dev->ref); 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci/** 7562306a36Sopenharmony_ci * v4l2_device_put - puts a V4L2 device reference 7662306a36Sopenharmony_ci * 7762306a36Sopenharmony_ci * @v4l2_dev: pointer to struct &v4l2_device 7862306a36Sopenharmony_ci * 7962306a36Sopenharmony_ci * This is an ancillary routine meant to decrement the usage for the 8062306a36Sopenharmony_ci * struct &v4l2_device pointed by @v4l2_dev. 8162306a36Sopenharmony_ci */ 8262306a36Sopenharmony_ciint v4l2_device_put(struct v4l2_device *v4l2_dev); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci/** 8562306a36Sopenharmony_ci * v4l2_device_register - Initialize v4l2_dev and make @dev->driver_data 8662306a36Sopenharmony_ci * point to @v4l2_dev. 8762306a36Sopenharmony_ci * 8862306a36Sopenharmony_ci * @dev: pointer to struct &device 8962306a36Sopenharmony_ci * @v4l2_dev: pointer to struct &v4l2_device 9062306a36Sopenharmony_ci * 9162306a36Sopenharmony_ci * .. note:: 9262306a36Sopenharmony_ci * @dev may be %NULL in rare cases (ISA devices). 9362306a36Sopenharmony_ci * In such case the caller must fill in the @v4l2_dev->name field 9462306a36Sopenharmony_ci * before calling this function. 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_ciint __must_check v4l2_device_register(struct device *dev, 9762306a36Sopenharmony_ci struct v4l2_device *v4l2_dev); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci/** 10062306a36Sopenharmony_ci * v4l2_device_set_name - Optional function to initialize the 10162306a36Sopenharmony_ci * name field of struct &v4l2_device 10262306a36Sopenharmony_ci * 10362306a36Sopenharmony_ci * @v4l2_dev: pointer to struct &v4l2_device 10462306a36Sopenharmony_ci * @basename: base name for the device name 10562306a36Sopenharmony_ci * @instance: pointer to a static atomic_t var with the instance usage for 10662306a36Sopenharmony_ci * the device driver. 10762306a36Sopenharmony_ci * 10862306a36Sopenharmony_ci * v4l2_device_set_name() initializes the name field of struct &v4l2_device 10962306a36Sopenharmony_ci * using the driver name and a driver-global atomic_t instance. 11062306a36Sopenharmony_ci * 11162306a36Sopenharmony_ci * This function will increment the instance counter and returns the 11262306a36Sopenharmony_ci * instance value used in the name. 11362306a36Sopenharmony_ci * 11462306a36Sopenharmony_ci * Example: 11562306a36Sopenharmony_ci * 11662306a36Sopenharmony_ci * static atomic_t drv_instance = ATOMIC_INIT(0); 11762306a36Sopenharmony_ci * 11862306a36Sopenharmony_ci * ... 11962306a36Sopenharmony_ci * 12062306a36Sopenharmony_ci * instance = v4l2_device_set_name(&\ v4l2_dev, "foo", &\ drv_instance); 12162306a36Sopenharmony_ci * 12262306a36Sopenharmony_ci * The first time this is called the name field will be set to foo0 and 12362306a36Sopenharmony_ci * this function returns 0. If the name ends with a digit (e.g. cx18), 12462306a36Sopenharmony_ci * then the name will be set to cx18-0 since cx180 would look really odd. 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_ciint v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename, 12762306a36Sopenharmony_ci atomic_t *instance); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci/** 13062306a36Sopenharmony_ci * v4l2_device_disconnect - Change V4L2 device state to disconnected. 13162306a36Sopenharmony_ci * 13262306a36Sopenharmony_ci * @v4l2_dev: pointer to struct v4l2_device 13362306a36Sopenharmony_ci * 13462306a36Sopenharmony_ci * Should be called when the USB parent disconnects. 13562306a36Sopenharmony_ci * Since the parent disappears, this ensures that @v4l2_dev doesn't have 13662306a36Sopenharmony_ci * an invalid parent pointer. 13762306a36Sopenharmony_ci * 13862306a36Sopenharmony_ci * .. note:: This function sets @v4l2_dev->dev to NULL. 13962306a36Sopenharmony_ci */ 14062306a36Sopenharmony_civoid v4l2_device_disconnect(struct v4l2_device *v4l2_dev); 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci/** 14362306a36Sopenharmony_ci * v4l2_device_unregister - Unregister all sub-devices and any other 14462306a36Sopenharmony_ci * resources related to @v4l2_dev. 14562306a36Sopenharmony_ci * 14662306a36Sopenharmony_ci * @v4l2_dev: pointer to struct v4l2_device 14762306a36Sopenharmony_ci */ 14862306a36Sopenharmony_civoid v4l2_device_unregister(struct v4l2_device *v4l2_dev); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci/** 15162306a36Sopenharmony_ci * v4l2_device_register_subdev - Registers a subdev with a v4l2 device. 15262306a36Sopenharmony_ci * 15362306a36Sopenharmony_ci * @v4l2_dev: pointer to struct &v4l2_device 15462306a36Sopenharmony_ci * @sd: pointer to &struct v4l2_subdev 15562306a36Sopenharmony_ci * 15662306a36Sopenharmony_ci * While registered, the subdev module is marked as in-use. 15762306a36Sopenharmony_ci * 15862306a36Sopenharmony_ci * An error is returned if the module is no longer loaded on any attempts 15962306a36Sopenharmony_ci * to register it. 16062306a36Sopenharmony_ci */ 16162306a36Sopenharmony_ciint __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, 16262306a36Sopenharmony_ci struct v4l2_subdev *sd); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci/** 16562306a36Sopenharmony_ci * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device. 16662306a36Sopenharmony_ci * 16762306a36Sopenharmony_ci * @sd: pointer to &struct v4l2_subdev 16862306a36Sopenharmony_ci * 16962306a36Sopenharmony_ci * .. note :: 17062306a36Sopenharmony_ci * 17162306a36Sopenharmony_ci * Can also be called if the subdev wasn't registered. In such 17262306a36Sopenharmony_ci * case, it will do nothing. 17362306a36Sopenharmony_ci */ 17462306a36Sopenharmony_civoid v4l2_device_unregister_subdev(struct v4l2_subdev *sd); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci/** 17762306a36Sopenharmony_ci * __v4l2_device_register_subdev_nodes - Registers device nodes for 17862306a36Sopenharmony_ci * all subdevs of the v4l2 device that are marked with the 17962306a36Sopenharmony_ci * %V4L2_SUBDEV_FL_HAS_DEVNODE flag. 18062306a36Sopenharmony_ci * 18162306a36Sopenharmony_ci * @v4l2_dev: pointer to struct v4l2_device 18262306a36Sopenharmony_ci * @read_only: subdevices read-only flag. True to register the subdevices 18362306a36Sopenharmony_ci * device nodes in read-only mode, false to allow full access to the 18462306a36Sopenharmony_ci * subdevice userspace API. 18562306a36Sopenharmony_ci */ 18662306a36Sopenharmony_ciint __must_check 18762306a36Sopenharmony_ci__v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev, 18862306a36Sopenharmony_ci bool read_only); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci/** 19162306a36Sopenharmony_ci * v4l2_device_register_subdev_nodes - Registers subdevices device nodes with 19262306a36Sopenharmony_ci * unrestricted access to the subdevice userspace operations 19362306a36Sopenharmony_ci * 19462306a36Sopenharmony_ci * Internally calls __v4l2_device_register_subdev_nodes(). See its documentation 19562306a36Sopenharmony_ci * for more details. 19662306a36Sopenharmony_ci * 19762306a36Sopenharmony_ci * @v4l2_dev: pointer to struct v4l2_device 19862306a36Sopenharmony_ci */ 19962306a36Sopenharmony_cistatic inline int __must_check 20062306a36Sopenharmony_civ4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev) 20162306a36Sopenharmony_ci{ 20262306a36Sopenharmony_ci#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 20362306a36Sopenharmony_ci return __v4l2_device_register_subdev_nodes(v4l2_dev, false); 20462306a36Sopenharmony_ci#else 20562306a36Sopenharmony_ci return 0; 20662306a36Sopenharmony_ci#endif 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci/** 21062306a36Sopenharmony_ci * v4l2_device_register_ro_subdev_nodes - Registers subdevices device nodes 21162306a36Sopenharmony_ci * in read-only mode 21262306a36Sopenharmony_ci * 21362306a36Sopenharmony_ci * Internally calls __v4l2_device_register_subdev_nodes(). See its documentation 21462306a36Sopenharmony_ci * for more details. 21562306a36Sopenharmony_ci * 21662306a36Sopenharmony_ci * @v4l2_dev: pointer to struct v4l2_device 21762306a36Sopenharmony_ci */ 21862306a36Sopenharmony_cistatic inline int __must_check 21962306a36Sopenharmony_civ4l2_device_register_ro_subdev_nodes(struct v4l2_device *v4l2_dev) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 22262306a36Sopenharmony_ci return __v4l2_device_register_subdev_nodes(v4l2_dev, true); 22362306a36Sopenharmony_ci#else 22462306a36Sopenharmony_ci return 0; 22562306a36Sopenharmony_ci#endif 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci/** 22962306a36Sopenharmony_ci * v4l2_subdev_notify - Sends a notification to v4l2_device. 23062306a36Sopenharmony_ci * 23162306a36Sopenharmony_ci * @sd: pointer to &struct v4l2_subdev 23262306a36Sopenharmony_ci * @notification: type of notification. Please notice that the notification 23362306a36Sopenharmony_ci * type is driver-specific. 23462306a36Sopenharmony_ci * @arg: arguments for the notification. Those are specific to each 23562306a36Sopenharmony_ci * notification type. 23662306a36Sopenharmony_ci */ 23762306a36Sopenharmony_cistatic inline void v4l2_subdev_notify(struct v4l2_subdev *sd, 23862306a36Sopenharmony_ci unsigned int notification, void *arg) 23962306a36Sopenharmony_ci{ 24062306a36Sopenharmony_ci if (sd && sd->v4l2_dev && sd->v4l2_dev->notify) 24162306a36Sopenharmony_ci sd->v4l2_dev->notify(sd, notification, arg); 24262306a36Sopenharmony_ci} 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci/** 24562306a36Sopenharmony_ci * v4l2_device_supports_requests - Test if requests are supported. 24662306a36Sopenharmony_ci * 24762306a36Sopenharmony_ci * @v4l2_dev: pointer to struct v4l2_device 24862306a36Sopenharmony_ci */ 24962306a36Sopenharmony_cistatic inline bool v4l2_device_supports_requests(struct v4l2_device *v4l2_dev) 25062306a36Sopenharmony_ci{ 25162306a36Sopenharmony_ci return v4l2_dev->mdev && v4l2_dev->mdev->ops && 25262306a36Sopenharmony_ci v4l2_dev->mdev->ops->req_queue; 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci/* Helper macros to iterate over all subdevs. */ 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci/** 25862306a36Sopenharmony_ci * v4l2_device_for_each_subdev - Helper macro that interates over all 25962306a36Sopenharmony_ci * sub-devices of a given &v4l2_device. 26062306a36Sopenharmony_ci * 26162306a36Sopenharmony_ci * @sd: pointer that will be filled by the macro with all 26262306a36Sopenharmony_ci * &struct v4l2_subdev pointer used as an iterator by the loop. 26362306a36Sopenharmony_ci * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over. 26462306a36Sopenharmony_ci * 26562306a36Sopenharmony_ci * This macro iterates over all sub-devices owned by the @v4l2_dev device. 26662306a36Sopenharmony_ci * It acts as a for loop iterator and executes the next statement with 26762306a36Sopenharmony_ci * the @sd variable pointing to each sub-device in turn. 26862306a36Sopenharmony_ci */ 26962306a36Sopenharmony_ci#define v4l2_device_for_each_subdev(sd, v4l2_dev) \ 27062306a36Sopenharmony_ci list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci/** 27362306a36Sopenharmony_ci * __v4l2_device_call_subdevs_p - Calls the specified operation for 27462306a36Sopenharmony_ci * all subdevs matching the condition. 27562306a36Sopenharmony_ci * 27662306a36Sopenharmony_ci * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over. 27762306a36Sopenharmony_ci * @sd: pointer that will be filled by the macro with all 27862306a36Sopenharmony_ci * &struct v4l2_subdev pointer used as an iterator by the loop. 27962306a36Sopenharmony_ci * @cond: condition to be match 28062306a36Sopenharmony_ci * @o: name of the element at &struct v4l2_subdev_ops that contains @f. 28162306a36Sopenharmony_ci * Each element there groups a set of operations functions. 28262306a36Sopenharmony_ci * @f: operation function that will be called if @cond matches. 28362306a36Sopenharmony_ci * The operation functions are defined in groups, according to 28462306a36Sopenharmony_ci * each element at &struct v4l2_subdev_ops. 28562306a36Sopenharmony_ci * @args: arguments for @f. 28662306a36Sopenharmony_ci * 28762306a36Sopenharmony_ci * Ignore any errors. 28862306a36Sopenharmony_ci * 28962306a36Sopenharmony_ci * Note: subdevs cannot be added or deleted while walking 29062306a36Sopenharmony_ci * the subdevs list. 29162306a36Sopenharmony_ci */ 29262306a36Sopenharmony_ci#define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...) \ 29362306a36Sopenharmony_ci do { \ 29462306a36Sopenharmony_ci list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) \ 29562306a36Sopenharmony_ci if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ 29662306a36Sopenharmony_ci (sd)->ops->o->f((sd) , ##args); \ 29762306a36Sopenharmony_ci } while (0) 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci/** 30062306a36Sopenharmony_ci * __v4l2_device_call_subdevs - Calls the specified operation for 30162306a36Sopenharmony_ci * all subdevs matching the condition. 30262306a36Sopenharmony_ci * 30362306a36Sopenharmony_ci * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over. 30462306a36Sopenharmony_ci * @cond: condition to be match 30562306a36Sopenharmony_ci * @o: name of the element at &struct v4l2_subdev_ops that contains @f. 30662306a36Sopenharmony_ci * Each element there groups a set of operations functions. 30762306a36Sopenharmony_ci * @f: operation function that will be called if @cond matches. 30862306a36Sopenharmony_ci * The operation functions are defined in groups, according to 30962306a36Sopenharmony_ci * each element at &struct v4l2_subdev_ops. 31062306a36Sopenharmony_ci * @args: arguments for @f. 31162306a36Sopenharmony_ci * 31262306a36Sopenharmony_ci * Ignore any errors. 31362306a36Sopenharmony_ci * 31462306a36Sopenharmony_ci * Note: subdevs cannot be added or deleted while walking 31562306a36Sopenharmony_ci * the subdevs list. 31662306a36Sopenharmony_ci */ 31762306a36Sopenharmony_ci#define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...) \ 31862306a36Sopenharmony_ci do { \ 31962306a36Sopenharmony_ci struct v4l2_subdev *__sd; \ 32062306a36Sopenharmony_ci \ 32162306a36Sopenharmony_ci __v4l2_device_call_subdevs_p(v4l2_dev, __sd, cond, o, \ 32262306a36Sopenharmony_ci f , ##args); \ 32362306a36Sopenharmony_ci } while (0) 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci/** 32662306a36Sopenharmony_ci * __v4l2_device_call_subdevs_until_err_p - Calls the specified operation for 32762306a36Sopenharmony_ci * all subdevs matching the condition. 32862306a36Sopenharmony_ci * 32962306a36Sopenharmony_ci * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over. 33062306a36Sopenharmony_ci * @sd: pointer that will be filled by the macro with all 33162306a36Sopenharmony_ci * &struct v4l2_subdev sub-devices associated with @v4l2_dev. 33262306a36Sopenharmony_ci * @cond: condition to be match 33362306a36Sopenharmony_ci * @o: name of the element at &struct v4l2_subdev_ops that contains @f. 33462306a36Sopenharmony_ci * Each element there groups a set of operations functions. 33562306a36Sopenharmony_ci * @f: operation function that will be called if @cond matches. 33662306a36Sopenharmony_ci * The operation functions are defined in groups, according to 33762306a36Sopenharmony_ci * each element at &struct v4l2_subdev_ops. 33862306a36Sopenharmony_ci * @args: arguments for @f. 33962306a36Sopenharmony_ci * 34062306a36Sopenharmony_ci * Return: 34162306a36Sopenharmony_ci * 34262306a36Sopenharmony_ci * If the operation returns an error other than 0 or ``-ENOIOCTLCMD`` 34362306a36Sopenharmony_ci * for any subdevice, then abort and return with that error code, zero 34462306a36Sopenharmony_ci * otherwise. 34562306a36Sopenharmony_ci * 34662306a36Sopenharmony_ci * Note: subdevs cannot be added or deleted while walking 34762306a36Sopenharmony_ci * the subdevs list. 34862306a36Sopenharmony_ci */ 34962306a36Sopenharmony_ci#define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \ 35062306a36Sopenharmony_ci({ \ 35162306a36Sopenharmony_ci long __err = 0; \ 35262306a36Sopenharmony_ci \ 35362306a36Sopenharmony_ci list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) { \ 35462306a36Sopenharmony_ci if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ 35562306a36Sopenharmony_ci __err = (sd)->ops->o->f((sd) , ##args); \ 35662306a36Sopenharmony_ci if (__err && __err != -ENOIOCTLCMD) \ 35762306a36Sopenharmony_ci break; \ 35862306a36Sopenharmony_ci } \ 35962306a36Sopenharmony_ci (__err == -ENOIOCTLCMD) ? 0 : __err; \ 36062306a36Sopenharmony_ci}) 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci/** 36362306a36Sopenharmony_ci * __v4l2_device_call_subdevs_until_err - Calls the specified operation for 36462306a36Sopenharmony_ci * all subdevs matching the condition. 36562306a36Sopenharmony_ci * 36662306a36Sopenharmony_ci * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over. 36762306a36Sopenharmony_ci * @cond: condition to be match 36862306a36Sopenharmony_ci * @o: name of the element at &struct v4l2_subdev_ops that contains @f. 36962306a36Sopenharmony_ci * Each element there groups a set of operations functions. 37062306a36Sopenharmony_ci * @f: operation function that will be called if @cond matches. 37162306a36Sopenharmony_ci * The operation functions are defined in groups, according to 37262306a36Sopenharmony_ci * each element at &struct v4l2_subdev_ops. 37362306a36Sopenharmony_ci * @args: arguments for @f. 37462306a36Sopenharmony_ci * 37562306a36Sopenharmony_ci * Return: 37662306a36Sopenharmony_ci * 37762306a36Sopenharmony_ci * If the operation returns an error other than 0 or ``-ENOIOCTLCMD`` 37862306a36Sopenharmony_ci * for any subdevice, then abort and return with that error code, 37962306a36Sopenharmony_ci * zero otherwise. 38062306a36Sopenharmony_ci * 38162306a36Sopenharmony_ci * Note: subdevs cannot be added or deleted while walking 38262306a36Sopenharmony_ci * the subdevs list. 38362306a36Sopenharmony_ci */ 38462306a36Sopenharmony_ci#define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \ 38562306a36Sopenharmony_ci({ \ 38662306a36Sopenharmony_ci struct v4l2_subdev *__sd; \ 38762306a36Sopenharmony_ci __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, cond, o, \ 38862306a36Sopenharmony_ci f , ##args); \ 38962306a36Sopenharmony_ci}) 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci/** 39262306a36Sopenharmony_ci * v4l2_device_call_all - Calls the specified operation for 39362306a36Sopenharmony_ci * all subdevs matching the &v4l2_subdev.grp_id, as assigned 39462306a36Sopenharmony_ci * by the bridge driver. 39562306a36Sopenharmony_ci * 39662306a36Sopenharmony_ci * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over. 39762306a36Sopenharmony_ci * @grpid: &struct v4l2_subdev->grp_id group ID to match. 39862306a36Sopenharmony_ci * Use 0 to match them all. 39962306a36Sopenharmony_ci * @o: name of the element at &struct v4l2_subdev_ops that contains @f. 40062306a36Sopenharmony_ci * Each element there groups a set of operations functions. 40162306a36Sopenharmony_ci * @f: operation function that will be called if @cond matches. 40262306a36Sopenharmony_ci * The operation functions are defined in groups, according to 40362306a36Sopenharmony_ci * each element at &struct v4l2_subdev_ops. 40462306a36Sopenharmony_ci * @args: arguments for @f. 40562306a36Sopenharmony_ci * 40662306a36Sopenharmony_ci * Ignore any errors. 40762306a36Sopenharmony_ci * 40862306a36Sopenharmony_ci * Note: subdevs cannot be added or deleted while walking 40962306a36Sopenharmony_ci * the subdevs list. 41062306a36Sopenharmony_ci */ 41162306a36Sopenharmony_ci#define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...) \ 41262306a36Sopenharmony_ci do { \ 41362306a36Sopenharmony_ci struct v4l2_subdev *__sd; \ 41462306a36Sopenharmony_ci \ 41562306a36Sopenharmony_ci __v4l2_device_call_subdevs_p(v4l2_dev, __sd, \ 41662306a36Sopenharmony_ci (grpid) == 0 || __sd->grp_id == (grpid), o, f , \ 41762306a36Sopenharmony_ci ##args); \ 41862306a36Sopenharmony_ci } while (0) 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci/** 42162306a36Sopenharmony_ci * v4l2_device_call_until_err - Calls the specified operation for 42262306a36Sopenharmony_ci * all subdevs matching the &v4l2_subdev.grp_id, as assigned 42362306a36Sopenharmony_ci * by the bridge driver, until an error occurs. 42462306a36Sopenharmony_ci * 42562306a36Sopenharmony_ci * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over. 42662306a36Sopenharmony_ci * @grpid: &struct v4l2_subdev->grp_id group ID to match. 42762306a36Sopenharmony_ci * Use 0 to match them all. 42862306a36Sopenharmony_ci * @o: name of the element at &struct v4l2_subdev_ops that contains @f. 42962306a36Sopenharmony_ci * Each element there groups a set of operations functions. 43062306a36Sopenharmony_ci * @f: operation function that will be called if @cond matches. 43162306a36Sopenharmony_ci * The operation functions are defined in groups, according to 43262306a36Sopenharmony_ci * each element at &struct v4l2_subdev_ops. 43362306a36Sopenharmony_ci * @args: arguments for @f. 43462306a36Sopenharmony_ci * 43562306a36Sopenharmony_ci * Return: 43662306a36Sopenharmony_ci * 43762306a36Sopenharmony_ci * If the operation returns an error other than 0 or ``-ENOIOCTLCMD`` 43862306a36Sopenharmony_ci * for any subdevice, then abort and return with that error code, 43962306a36Sopenharmony_ci * zero otherwise. 44062306a36Sopenharmony_ci * 44162306a36Sopenharmony_ci * Note: subdevs cannot be added or deleted while walking 44262306a36Sopenharmony_ci * the subdevs list. 44362306a36Sopenharmony_ci */ 44462306a36Sopenharmony_ci#define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ 44562306a36Sopenharmony_ci({ \ 44662306a36Sopenharmony_ci struct v4l2_subdev *__sd; \ 44762306a36Sopenharmony_ci __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, \ 44862306a36Sopenharmony_ci (grpid) == 0 || __sd->grp_id == (grpid), o, f , \ 44962306a36Sopenharmony_ci ##args); \ 45062306a36Sopenharmony_ci}) 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci/** 45362306a36Sopenharmony_ci * v4l2_device_mask_call_all - Calls the specified operation for 45462306a36Sopenharmony_ci * all subdevices where a group ID matches a specified bitmask. 45562306a36Sopenharmony_ci * 45662306a36Sopenharmony_ci * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over. 45762306a36Sopenharmony_ci * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id 45862306a36Sopenharmony_ci * group ID to be matched. Use 0 to match them all. 45962306a36Sopenharmony_ci * @o: name of the element at &struct v4l2_subdev_ops that contains @f. 46062306a36Sopenharmony_ci * Each element there groups a set of operations functions. 46162306a36Sopenharmony_ci * @f: operation function that will be called if @cond matches. 46262306a36Sopenharmony_ci * The operation functions are defined in groups, according to 46362306a36Sopenharmony_ci * each element at &struct v4l2_subdev_ops. 46462306a36Sopenharmony_ci * @args: arguments for @f. 46562306a36Sopenharmony_ci * 46662306a36Sopenharmony_ci * Ignore any errors. 46762306a36Sopenharmony_ci * 46862306a36Sopenharmony_ci * Note: subdevs cannot be added or deleted while walking 46962306a36Sopenharmony_ci * the subdevs list. 47062306a36Sopenharmony_ci */ 47162306a36Sopenharmony_ci#define v4l2_device_mask_call_all(v4l2_dev, grpmsk, o, f, args...) \ 47262306a36Sopenharmony_ci do { \ 47362306a36Sopenharmony_ci struct v4l2_subdev *__sd; \ 47462306a36Sopenharmony_ci \ 47562306a36Sopenharmony_ci __v4l2_device_call_subdevs_p(v4l2_dev, __sd, \ 47662306a36Sopenharmony_ci (grpmsk) == 0 || (__sd->grp_id & (grpmsk)), o, \ 47762306a36Sopenharmony_ci f , ##args); \ 47862306a36Sopenharmony_ci } while (0) 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci/** 48162306a36Sopenharmony_ci * v4l2_device_mask_call_until_err - Calls the specified operation for 48262306a36Sopenharmony_ci * all subdevices where a group ID matches a specified bitmask. 48362306a36Sopenharmony_ci * 48462306a36Sopenharmony_ci * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over. 48562306a36Sopenharmony_ci * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id 48662306a36Sopenharmony_ci * group ID to be matched. Use 0 to match them all. 48762306a36Sopenharmony_ci * @o: name of the element at &struct v4l2_subdev_ops that contains @f. 48862306a36Sopenharmony_ci * Each element there groups a set of operations functions. 48962306a36Sopenharmony_ci * @f: operation function that will be called if @cond matches. 49062306a36Sopenharmony_ci * The operation functions are defined in groups, according to 49162306a36Sopenharmony_ci * each element at &struct v4l2_subdev_ops. 49262306a36Sopenharmony_ci * @args: arguments for @f. 49362306a36Sopenharmony_ci * 49462306a36Sopenharmony_ci * Return: 49562306a36Sopenharmony_ci * 49662306a36Sopenharmony_ci * If the operation returns an error other than 0 or ``-ENOIOCTLCMD`` 49762306a36Sopenharmony_ci * for any subdevice, then abort and return with that error code, 49862306a36Sopenharmony_ci * zero otherwise. 49962306a36Sopenharmony_ci * 50062306a36Sopenharmony_ci * Note: subdevs cannot be added or deleted while walking 50162306a36Sopenharmony_ci * the subdevs list. 50262306a36Sopenharmony_ci */ 50362306a36Sopenharmony_ci#define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \ 50462306a36Sopenharmony_ci({ \ 50562306a36Sopenharmony_ci struct v4l2_subdev *__sd; \ 50662306a36Sopenharmony_ci __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, \ 50762306a36Sopenharmony_ci (grpmsk) == 0 || (__sd->grp_id & (grpmsk)), o, \ 50862306a36Sopenharmony_ci f , ##args); \ 50962306a36Sopenharmony_ci}) 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci/** 51362306a36Sopenharmony_ci * v4l2_device_has_op - checks if any subdev with matching grpid has a 51462306a36Sopenharmony_ci * given ops. 51562306a36Sopenharmony_ci * 51662306a36Sopenharmony_ci * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over. 51762306a36Sopenharmony_ci * @grpid: &struct v4l2_subdev->grp_id group ID to match. 51862306a36Sopenharmony_ci * Use 0 to match them all. 51962306a36Sopenharmony_ci * @o: name of the element at &struct v4l2_subdev_ops that contains @f. 52062306a36Sopenharmony_ci * Each element there groups a set of operations functions. 52162306a36Sopenharmony_ci * @f: operation function that will be called if @cond matches. 52262306a36Sopenharmony_ci * The operation functions are defined in groups, according to 52362306a36Sopenharmony_ci * each element at &struct v4l2_subdev_ops. 52462306a36Sopenharmony_ci */ 52562306a36Sopenharmony_ci#define v4l2_device_has_op(v4l2_dev, grpid, o, f) \ 52662306a36Sopenharmony_ci({ \ 52762306a36Sopenharmony_ci struct v4l2_subdev *__sd; \ 52862306a36Sopenharmony_ci bool __result = false; \ 52962306a36Sopenharmony_ci list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list) { \ 53062306a36Sopenharmony_ci if ((grpid) && __sd->grp_id != (grpid)) \ 53162306a36Sopenharmony_ci continue; \ 53262306a36Sopenharmony_ci if (v4l2_subdev_has_op(__sd, o, f)) { \ 53362306a36Sopenharmony_ci __result = true; \ 53462306a36Sopenharmony_ci break; \ 53562306a36Sopenharmony_ci } \ 53662306a36Sopenharmony_ci } \ 53762306a36Sopenharmony_ci __result; \ 53862306a36Sopenharmony_ci}) 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci/** 54162306a36Sopenharmony_ci * v4l2_device_mask_has_op - checks if any subdev with matching group 54262306a36Sopenharmony_ci * mask has a given ops. 54362306a36Sopenharmony_ci * 54462306a36Sopenharmony_ci * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over. 54562306a36Sopenharmony_ci * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id 54662306a36Sopenharmony_ci * group ID to be matched. Use 0 to match them all. 54762306a36Sopenharmony_ci * @o: name of the element at &struct v4l2_subdev_ops that contains @f. 54862306a36Sopenharmony_ci * Each element there groups a set of operations functions. 54962306a36Sopenharmony_ci * @f: operation function that will be called if @cond matches. 55062306a36Sopenharmony_ci * The operation functions are defined in groups, according to 55162306a36Sopenharmony_ci * each element at &struct v4l2_subdev_ops. 55262306a36Sopenharmony_ci */ 55362306a36Sopenharmony_ci#define v4l2_device_mask_has_op(v4l2_dev, grpmsk, o, f) \ 55462306a36Sopenharmony_ci({ \ 55562306a36Sopenharmony_ci struct v4l2_subdev *__sd; \ 55662306a36Sopenharmony_ci bool __result = false; \ 55762306a36Sopenharmony_ci list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list) { \ 55862306a36Sopenharmony_ci if ((grpmsk) && !(__sd->grp_id & (grpmsk))) \ 55962306a36Sopenharmony_ci continue; \ 56062306a36Sopenharmony_ci if (v4l2_subdev_has_op(__sd, o, f)) { \ 56162306a36Sopenharmony_ci __result = true; \ 56262306a36Sopenharmony_ci break; \ 56362306a36Sopenharmony_ci } \ 56462306a36Sopenharmony_ci } \ 56562306a36Sopenharmony_ci __result; \ 56662306a36Sopenharmony_ci}) 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci#endif 569