linux/include/media/v4l2-device.h
<<
>>
Prefs
   1/*
   2    V4L2 device support header.
   3
   4    Copyright (C) 2008  Hans Verkuil <hverkuil@xs4all.nl>
   5
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 2 of the License, or
   9    (at your option) any later version.
  10
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15
  16    You should have received a copy of the GNU General Public License
  17    along with this program; if not, write to the Free Software
  18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 */
  20
  21#ifndef _V4L2_DEVICE_H
  22#define _V4L2_DEVICE_H
  23
  24#include <media/media-device.h>
  25#include <media/v4l2-subdev.h>
  26#include <media/v4l2-dev.h>
  27
  28#define V4L2_DEVICE_NAME_SIZE (20 + 16)
  29
  30struct v4l2_ctrl_handler;
  31
  32/**
  33 * struct v4l2_device - main struct to for V4L2 device drivers
  34 *
  35 * @dev: pointer to struct device.
  36 * @mdev: pointer to struct media_device
  37 * @subdevs: used to keep track of the registered subdevs
  38 * @lock: lock this struct; can be used by the driver as well
  39 *      if this struct is embedded into a larger struct.
  40 * @name: unique device name, by default the driver name + bus ID
  41 * @notify: notify callback called by some sub-devices.
  42 * @ctrl_handler: The control handler. May be %NULL.
  43 * @prio: Device's priority state
  44 * @ref: Keep track of the references to this struct.
  45 * @release: Release function that is called when the ref count
  46 *      goes to 0.
  47 *
  48 * Each instance of a V4L2 device should create the v4l2_device struct,
  49 * either stand-alone or embedded in a larger struct.
  50 *
  51 * It allows easy access to sub-devices (see v4l2-subdev.h) and provides
  52 * basic V4L2 device-level support.
  53 *
  54 * .. note::
  55 *
  56 *    #) @dev->driver_data points to this struct.
  57 *    #) @dev might be %NULL if there is no parent device
  58 */
  59
  60struct v4l2_device {
  61        struct device *dev;
  62#if defined(CONFIG_MEDIA_CONTROLLER)
  63        struct media_device *mdev;
  64#endif
  65        struct list_head subdevs;
  66        spinlock_t lock;
  67        char name[V4L2_DEVICE_NAME_SIZE];
  68        void (*notify)(struct v4l2_subdev *sd,
  69                        unsigned int notification, void *arg);
  70        struct v4l2_ctrl_handler *ctrl_handler;
  71        struct v4l2_prio_state prio;
  72        struct kref ref;
  73        void (*release)(struct v4l2_device *v4l2_dev);
  74};
  75
  76/**
  77 * v4l2_device_get - gets a V4L2 device reference
  78 *
  79 * @v4l2_dev: pointer to struct &v4l2_device
  80 *
  81 * This is an ancillary routine meant to increment the usage for the
  82 * struct &v4l2_device pointed by @v4l2_dev.
  83 */
  84static inline void v4l2_device_get(struct v4l2_device *v4l2_dev)
  85{
  86        kref_get(&v4l2_dev->ref);
  87}
  88
  89/**
  90 * v4l2_device_put - putss a V4L2 device reference
  91 *
  92 * @v4l2_dev: pointer to struct &v4l2_device
  93 *
  94 * This is an ancillary routine meant to decrement the usage for the
  95 * struct &v4l2_device pointed by @v4l2_dev.
  96 */
  97int v4l2_device_put(struct v4l2_device *v4l2_dev);
  98
  99/**
 100 * v4l2_device_register - Initialize v4l2_dev and make @dev->driver_data
 101 *      point to @v4l2_dev.
 102 *
 103 * @dev: pointer to struct &device
 104 * @v4l2_dev: pointer to struct &v4l2_device
 105 *
 106 * .. note::
 107 *      @dev may be %NULL in rare cases (ISA devices).
 108 *      In such case the caller must fill in the @v4l2_dev->name field
 109 *      before calling this function.
 110 */
 111int __must_check v4l2_device_register(struct device *dev,
 112                                      struct v4l2_device *v4l2_dev);
 113
 114/**
 115 * v4l2_device_set_name - Optional function to initialize the
 116 *      name field of struct &v4l2_device
 117 *
 118 * @v4l2_dev: pointer to struct &v4l2_device
 119 * @basename: base name for the device name
 120 * @instance: pointer to a static atomic_t var with the instance usage for
 121 *      the device driver.
 122 *
 123 * v4l2_device_set_name() initializes the name field of struct &v4l2_device
 124 * using the driver name and a driver-global atomic_t instance.
 125 *
 126 * This function will increment the instance counter and returns the
 127 * instance value used in the name.
 128 *
 129 * Example:
 130 *
 131 *   static atomic_t drv_instance = ATOMIC_INIT(0);
 132 *
 133 *   ...
 134 *
 135 *   instance = v4l2_device_set_name(&\ v4l2_dev, "foo", &\ drv_instance);
 136 *
 137 * The first time this is called the name field will be set to foo0 and
 138 * this function returns 0. If the name ends with a digit (e.g. cx18),
 139 * then the name will be set to cx18-0 since cx180 would look really odd.
 140 */
 141int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
 142                         atomic_t *instance);
 143
 144/**
 145 * v4l2_device_disconnect - Change V4L2 device state to disconnected.
 146 *
 147 * @v4l2_dev: pointer to struct v4l2_device
 148 *
 149 * Should be called when the USB parent disconnects.
 150 * Since the parent disappears, this ensures that @v4l2_dev doesn't have
 151 * an invalid parent pointer.
 152 *
 153 * .. note:: This function sets @v4l2_dev->dev to NULL.
 154 */
 155void v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
 156
 157/**
 158 *  v4l2_device_unregister - Unregister all sub-devices and any other
 159 *       resources related to @v4l2_dev.
 160 *
 161 * @v4l2_dev: pointer to struct v4l2_device
 162 */
 163void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
 164
 165/**
 166 * v4l2_device_register_subdev - Registers a subdev with a v4l2 device.
 167 *
 168 * @v4l2_dev: pointer to struct &v4l2_device
 169 * @sd: pointer to struct &v4l2_subdev
 170 *
 171 * While registered, the subdev module is marked as in-use.
 172 *
 173 * An error is returned if the module is no longer loaded on any attempts
 174 * to register it.
 175 */
 176int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
 177                                             struct v4l2_subdev *sd);
 178
 179/**
 180 * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device.
 181 *
 182 * @sd: pointer to struct &v4l2_subdev
 183 *
 184 * .. note ::
 185 *
 186 *      Can also be called if the subdev wasn't registered. In such
 187 *      case, it will do nothing.
 188 */
 189void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
 190
 191/**
 192 * v4l2_device_register_subdev_nodes - Registers device nodes for all subdevs
 193 *      of the v4l2 device that are marked with
 194 *      the %V4L2_SUBDEV_FL_HAS_DEVNODE flag.
 195 *
 196 * @v4l2_dev: pointer to struct v4l2_device
 197 */
 198int __must_check
 199v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
 200
 201/**
 202 * v4l2_subdev_notify - Sends a notification to v4l2_device.
 203 *
 204 * @sd: pointer to struct &v4l2_subdev
 205 * @notification: type of notification. Please notice that the notification
 206 *      type is driver-specific.
 207 * @arg: arguments for the notification. Those are specific to each
 208 *      notification type.
 209 */
 210static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 211                                      unsigned int notification, void *arg)
 212{
 213        if (sd && sd->v4l2_dev && sd->v4l2_dev->notify)
 214                sd->v4l2_dev->notify(sd, notification, arg);
 215}
 216
 217/* Iterate over all subdevs. */
 218#define v4l2_device_for_each_subdev(sd, v4l2_dev)                       \
 219        list_for_each_entry(sd, &(v4l2_dev)->subdevs, list)
 220
 221/* Call the specified callback for all subdevs matching the condition.
 222   Ignore any errors. Note that you cannot add or delete a subdev
 223   while walking the subdevs list. */
 224#define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...) \
 225        do {                                                            \
 226                list_for_each_entry((sd), &(v4l2_dev)->subdevs, list)   \
 227                        if ((cond) && (sd)->ops->o && (sd)->ops->o->f)  \
 228                                (sd)->ops->o->f((sd) , ##args);         \
 229        } while (0)
 230
 231#define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...)       \
 232        do {                                                            \
 233                struct v4l2_subdev *__sd;                               \
 234                                                                        \
 235                __v4l2_device_call_subdevs_p(v4l2_dev, __sd, cond, o,   \
 236                                                f , ##args);            \
 237        } while (0)
 238
 239/* Call the specified callback for all subdevs matching the condition.
 240   If the callback returns an error other than 0 or -ENOIOCTLCMD, then
 241   return with that error code. Note that you cannot add or delete a
 242   subdev while walking the subdevs list. */
 243#define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \
 244({                                                                      \
 245        long __err = 0;                                                 \
 246                                                                        \
 247        list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) {         \
 248                if ((cond) && (sd)->ops->o && (sd)->ops->o->f)          \
 249                        __err = (sd)->ops->o->f((sd) , ##args);         \
 250                if (__err && __err != -ENOIOCTLCMD)                     \
 251                        break;                                          \
 252        }                                                               \
 253        (__err == -ENOIOCTLCMD) ? 0 : __err;                            \
 254})
 255
 256#define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \
 257({                                                                      \
 258        struct v4l2_subdev *__sd;                                       \
 259        __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, cond, o, \
 260                                                f , ##args);            \
 261})
 262
 263/* Call the specified callback for all subdevs matching grp_id (if 0, then
 264   match them all). Ignore any errors. Note that you cannot add or delete
 265   a subdev while walking the subdevs list. */
 266#define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...)            \
 267        do {                                                            \
 268                struct v4l2_subdev *__sd;                               \
 269                                                                        \
 270                __v4l2_device_call_subdevs_p(v4l2_dev, __sd,            \
 271                        !(grpid) || __sd->grp_id == (grpid), o, f ,     \
 272                        ##args);                                        \
 273        } while (0)
 274
 275/* Call the specified callback for all subdevs matching grp_id (if 0, then
 276   match them all). If the callback returns an error other than 0 or
 277   -ENOIOCTLCMD, then return with that error code. Note that you cannot
 278   add or delete a subdev while walking the subdevs list. */
 279#define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...)      \
 280({                                                                      \
 281        struct v4l2_subdev *__sd;                                       \
 282        __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd,          \
 283                        !(grpid) || __sd->grp_id == (grpid), o, f ,     \
 284                        ##args);                                        \
 285})
 286
 287/*
 288 * Call the specified callback for all subdevs where grp_id & grpmsk != 0
 289 * (if grpmsk == `0, then match them all). Ignore any errors. Note that you
 290 * cannot add or delete a subdev while walking the subdevs list.
 291 */
 292#define v4l2_device_mask_call_all(v4l2_dev, grpmsk, o, f, args...)      \
 293        do {                                                            \
 294                struct v4l2_subdev *__sd;                               \
 295                                                                        \
 296                __v4l2_device_call_subdevs_p(v4l2_dev, __sd,            \
 297                        !(grpmsk) || (__sd->grp_id & (grpmsk)), o, f ,  \
 298                        ##args);                                        \
 299        } while (0)
 300
 301/*
 302 * Call the specified callback for all subdevs where grp_id & grpmsk != 0
 303 * (if grpmsk == 0, then match them all). If the callback returns an error
 304 * other than 0 or %-ENOIOCTLCMD, then return with that error code. Note that
 305 * you cannot add or delete a subdev while walking the subdevs list.
 306 */
 307#define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \
 308({                                                                      \
 309        struct v4l2_subdev *__sd;                                       \
 310        __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd,          \
 311                        !(grpmsk) || (__sd->grp_id & (grpmsk)), o, f ,  \
 312                        ##args);                                        \
 313})
 314
 315/*
 316 * Does any subdev with matching grpid (or all if grpid == 0) has the given
 317 * op?
 318 */
 319#define v4l2_device_has_op(v4l2_dev, grpid, o, f)                       \
 320({                                                                      \
 321        struct v4l2_subdev *__sd;                                       \
 322        bool __result = false;                                          \
 323        list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list) {         \
 324                if ((grpid) && __sd->grp_id != (grpid))                 \
 325                        continue;                                       \
 326                if (v4l2_subdev_has_op(__sd, o, f)) {                   \
 327                        __result = true;                                \
 328                        break;                                          \
 329                }                                                       \
 330        }                                                               \
 331        __result;                                                       \
 332})
 333
 334/*
 335 * Does any subdev with matching grpmsk (or all if grpmsk == 0) has the given
 336 * op?
 337 */
 338#define v4l2_device_mask_has_op(v4l2_dev, grpmsk, o, f)                 \
 339({                                                                      \
 340        struct v4l2_subdev *__sd;                                       \
 341        bool __result = false;                                          \
 342        list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list) {         \
 343                if ((grpmsk) && !(__sd->grp_id & (grpmsk)))             \
 344                        continue;                                       \
 345                if (v4l2_subdev_has_op(__sd, o, f)) {                   \
 346                        __result = true;                                \
 347                        break;                                          \
 348                }                                                       \
 349        }                                                               \
 350        __result;                                                       \
 351})
 352
 353#endif
 354