linux/include/media/v4l2-async.h
<<
>>
Prefs
   1/*
   2 * V4L2 asynchronous subdevice registration API
   3 *
   4 * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
   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 version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#ifndef V4L2_ASYNC_H
  12#define V4L2_ASYNC_H
  13
  14#include <linux/list.h>
  15#include <linux/mutex.h>
  16
  17struct device;
  18struct device_node;
  19struct v4l2_device;
  20struct v4l2_subdev;
  21struct v4l2_async_notifier;
  22
  23/* A random max subdevice number, used to allocate an array on stack */
  24#define V4L2_MAX_SUBDEVS 128U
  25
  26/**
  27 * enum v4l2_async_match_type - type of asynchronous subdevice logic to be used
  28 *      in order to identify a match
  29 *
  30 * @V4L2_ASYNC_MATCH_CUSTOM: Match will use the logic provided by &struct
  31 *      v4l2_async_subdev.match ops
  32 * @V4L2_ASYNC_MATCH_DEVNAME: Match will use the device name
  33 * @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address
  34 * @V4L2_ASYNC_MATCH_FWNODE: Match will use firmware node
  35 *
  36 * This enum is used by the asyncrhronous sub-device logic to define the
  37 * algorithm that will be used to match an asynchronous device.
  38 */
  39enum v4l2_async_match_type {
  40        V4L2_ASYNC_MATCH_CUSTOM,
  41        V4L2_ASYNC_MATCH_DEVNAME,
  42        V4L2_ASYNC_MATCH_I2C,
  43        V4L2_ASYNC_MATCH_FWNODE,
  44};
  45
  46/**
  47 * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge
  48 *
  49 * @match_type: type of match that will be used
  50 * @match:      union of per-bus type matching data sets
  51 * @match.fwnode:
  52 *              pointer to &struct fwnode_handle to be matched.
  53 *              Used if @match_type is %V4L2_ASYNC_MATCH_FWNODE.
  54 * @match.device_name:
  55 *              string containing the device name to be matched.
  56 *              Used if @match_type is %V4L2_ASYNC_MATCH_DEVNAME.
  57 * @match.i2c:  embedded struct with I2C parameters to be matched.
  58 *              Both @match.i2c.adapter_id and @match.i2c.address
  59 *              should be matched.
  60 *              Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
  61 * @match.i2c.adapter_id:
  62 *              I2C adapter ID to be matched.
  63 *              Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
  64 * @match.i2c.address:
  65 *              I2C address to be matched.
  66 *              Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
  67 * @match.custom:
  68 *              Driver-specific match criteria.
  69 *              Used if @match_type is %V4L2_ASYNC_MATCH_CUSTOM.
  70 * @match.custom.match:
  71 *              Driver-specific match function to be used if
  72 *              %V4L2_ASYNC_MATCH_CUSTOM.
  73 * @match.custom.priv:
  74 *              Driver-specific private struct with match parameters
  75 *              to be used if %V4L2_ASYNC_MATCH_CUSTOM.
  76 * @list:       used to link struct v4l2_async_subdev objects, waiting to be
  77 *              probed, to a notifier->waiting list
  78 *
  79 * When this struct is used as a member in a driver specific struct,
  80 * the driver specific struct shall contain the &struct
  81 * v4l2_async_subdev as its first member.
  82 */
  83struct v4l2_async_subdev {
  84        enum v4l2_async_match_type match_type;
  85        union {
  86                struct fwnode_handle *fwnode;
  87                const char *device_name;
  88                struct {
  89                        int adapter_id;
  90                        unsigned short address;
  91                } i2c;
  92                struct {
  93                        bool (*match)(struct device *,
  94                                      struct v4l2_async_subdev *);
  95                        void *priv;
  96                } custom;
  97        } match;
  98
  99        /* v4l2-async core private: not to be used by drivers */
 100        struct list_head list;
 101};
 102
 103/**
 104 * struct v4l2_async_notifier_operations - Asynchronous V4L2 notifier operations
 105 * @bound:      a subdevice driver has successfully probed one of the subdevices
 106 * @complete:   All subdevices have been probed successfully. The complete
 107 *              callback is only executed for the root notifier.
 108 * @unbind:     a subdevice is leaving
 109 */
 110struct v4l2_async_notifier_operations {
 111        int (*bound)(struct v4l2_async_notifier *notifier,
 112                     struct v4l2_subdev *subdev,
 113                     struct v4l2_async_subdev *asd);
 114        int (*complete)(struct v4l2_async_notifier *notifier);
 115        void (*unbind)(struct v4l2_async_notifier *notifier,
 116                       struct v4l2_subdev *subdev,
 117                       struct v4l2_async_subdev *asd);
 118};
 119
 120/**
 121 * struct v4l2_async_notifier - v4l2_device notifier data
 122 *
 123 * @ops:        notifier operations
 124 * @num_subdevs: number of subdevices used in the subdevs array
 125 * @max_subdevs: number of subdevices allocated in the subdevs array
 126 * @subdevs:    array of pointers to subdevice descriptors
 127 * @v4l2_dev:   v4l2_device of the root notifier, NULL otherwise
 128 * @sd:         sub-device that registered the notifier, NULL otherwise
 129 * @parent:     parent notifier
 130 * @waiting:    list of struct v4l2_async_subdev, waiting for their drivers
 131 * @done:       list of struct v4l2_subdev, already probed
 132 * @list:       member in a global list of notifiers
 133 */
 134struct v4l2_async_notifier {
 135        const struct v4l2_async_notifier_operations *ops;
 136        unsigned int num_subdevs;
 137        unsigned int max_subdevs;
 138        struct v4l2_async_subdev **subdevs;
 139        struct v4l2_device *v4l2_dev;
 140        struct v4l2_subdev *sd;
 141        struct v4l2_async_notifier *parent;
 142        struct list_head waiting;
 143        struct list_head done;
 144        struct list_head list;
 145};
 146
 147/**
 148 * v4l2_async_notifier_register - registers a subdevice asynchronous notifier
 149 *
 150 * @v4l2_dev: pointer to &struct v4l2_device
 151 * @notifier: pointer to &struct v4l2_async_notifier
 152 */
 153int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
 154                                 struct v4l2_async_notifier *notifier);
 155
 156/**
 157 * v4l2_async_subdev_notifier_register - registers a subdevice asynchronous
 158 *                                       notifier for a sub-device
 159 *
 160 * @sd: pointer to &struct v4l2_subdev
 161 * @notifier: pointer to &struct v4l2_async_notifier
 162 */
 163int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
 164                                        struct v4l2_async_notifier *notifier);
 165
 166/**
 167 * v4l2_async_notifier_unregister - unregisters a subdevice asynchronous notifier
 168 *
 169 * @notifier: pointer to &struct v4l2_async_notifier
 170 */
 171void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
 172
 173/**
 174 * v4l2_async_notifier_cleanup - clean up notifier resources
 175 * @notifier: the notifier the resources of which are to be cleaned up
 176 *
 177 * Release memory resources related to a notifier, including the async
 178 * sub-devices allocated for the purposes of the notifier but not the notifier
 179 * itself. The user is responsible for calling this function to clean up the
 180 * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints or
 181 * @v4l2_fwnode_reference_parse_sensor_common.
 182 *
 183 * There is no harm from calling v4l2_async_notifier_cleanup in other
 184 * cases as long as its memory has been zeroed after it has been
 185 * allocated.
 186 */
 187void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier);
 188
 189/**
 190 * v4l2_async_register_subdev - registers a sub-device to the asynchronous
 191 *      subdevice framework
 192 *
 193 * @sd: pointer to &struct v4l2_subdev
 194 */
 195int v4l2_async_register_subdev(struct v4l2_subdev *sd);
 196
 197/**
 198 * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device to
 199 *                                            the asynchronous sub-device
 200 *                                            framework and parse set up common
 201 *                                            sensor related devices
 202 *
 203 * @sd: pointer to struct &v4l2_subdev
 204 *
 205 * This function is just like v4l2_async_register_subdev() with the exception
 206 * that calling it will also parse firmware interfaces for remote references
 207 * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the
 208 * async sub-devices. The sub-device is similarly unregistered by calling
 209 * v4l2_async_unregister_subdev().
 210 *
 211 * While registered, the subdev module is marked as in-use.
 212 *
 213 * An error is returned if the module is no longer loaded on any attempts
 214 * to register it.
 215 */
 216int __must_check v4l2_async_register_subdev_sensor_common(
 217        struct v4l2_subdev *sd);
 218
 219/**
 220 * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous
 221 *      subdevice framework
 222 *
 223 * @sd: pointer to &struct v4l2_subdev
 224 */
 225void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
 226#endif
 227