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