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 * @list:       used to link struct v4l2_async_subdev objects, waiting to be
  52 *              probed, to a notifier->waiting list
  53 *
  54 * When this struct is used as a member in a driver specific struct,
  55 * the driver specific struct shall contain the &struct
  56 * v4l2_async_subdev as its first member.
  57 */
  58struct v4l2_async_subdev {
  59        enum v4l2_async_match_type match_type;
  60        union {
  61                struct {
  62                        struct fwnode_handle *fwnode;
  63                } fwnode;
  64                struct {
  65                        const char *name;
  66                } device_name;
  67                struct {
  68                        int adapter_id;
  69                        unsigned short address;
  70                } i2c;
  71                struct {
  72                        bool (*match)(struct device *,
  73                                      struct v4l2_async_subdev *);
  74                        void *priv;
  75                } custom;
  76        } match;
  77
  78        /* v4l2-async core private: not to be used by drivers */
  79        struct list_head list;
  80};
  81
  82/**
  83 * struct v4l2_async_notifier_operations - Asynchronous V4L2 notifier operations
  84 * @bound:      a subdevice driver has successfully probed one of the subdevices
  85 * @complete:   All subdevices have been probed successfully. The complete
  86 *              callback is only executed for the root notifier.
  87 * @unbind:     a subdevice is leaving
  88 */
  89struct v4l2_async_notifier_operations {
  90        int (*bound)(struct v4l2_async_notifier *notifier,
  91                     struct v4l2_subdev *subdev,
  92                     struct v4l2_async_subdev *asd);
  93        int (*complete)(struct v4l2_async_notifier *notifier);
  94        void (*unbind)(struct v4l2_async_notifier *notifier,
  95                       struct v4l2_subdev *subdev,
  96                       struct v4l2_async_subdev *asd);
  97};
  98
  99/**
 100 * struct v4l2_async_notifier - v4l2_device notifier data
 101 *
 102 * @ops:        notifier operations
 103 * @num_subdevs: number of subdevices used in the subdevs array
 104 * @max_subdevs: number of subdevices allocated in the subdevs array
 105 * @subdevs:    array of pointers to subdevice descriptors
 106 * @v4l2_dev:   v4l2_device of the root notifier, NULL otherwise
 107 * @sd:         sub-device that registered the notifier, NULL otherwise
 108 * @parent:     parent notifier
 109 * @waiting:    list of struct v4l2_async_subdev, waiting for their drivers
 110 * @done:       list of struct v4l2_subdev, already probed
 111 * @list:       member in a global list of notifiers
 112 */
 113struct v4l2_async_notifier {
 114        const struct v4l2_async_notifier_operations *ops;
 115        unsigned int num_subdevs;
 116        unsigned int max_subdevs;
 117        struct v4l2_async_subdev **subdevs;
 118        struct v4l2_device *v4l2_dev;
 119        struct v4l2_subdev *sd;
 120        struct v4l2_async_notifier *parent;
 121        struct list_head waiting;
 122        struct list_head done;
 123        struct list_head list;
 124};
 125
 126/**
 127 * v4l2_async_notifier_register - registers a subdevice asynchronous notifier
 128 *
 129 * @v4l2_dev: pointer to &struct v4l2_device
 130 * @notifier: pointer to &struct v4l2_async_notifier
 131 */
 132int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
 133                                 struct v4l2_async_notifier *notifier);
 134
 135/**
 136 * v4l2_async_subdev_notifier_register - registers a subdevice asynchronous
 137 *                                       notifier for a sub-device
 138 *
 139 * @sd: pointer to &struct v4l2_subdev
 140 * @notifier: pointer to &struct v4l2_async_notifier
 141 */
 142int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
 143                                        struct v4l2_async_notifier *notifier);
 144
 145/**
 146 * v4l2_async_notifier_unregister - unregisters a subdevice asynchronous notifier
 147 *
 148 * @notifier: pointer to &struct v4l2_async_notifier
 149 */
 150void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
 151
 152/**
 153 * v4l2_async_notifier_cleanup - clean up notifier resources
 154 * @notifier: the notifier the resources of which are to be cleaned up
 155 *
 156 * Release memory resources related to a notifier, including the async
 157 * sub-devices allocated for the purposes of the notifier but not the notifier
 158 * itself. The user is responsible for calling this function to clean up the
 159 * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints or
 160 * @v4l2_fwnode_reference_parse_sensor_common.
 161 *
 162 * There is no harm from calling v4l2_async_notifier_cleanup in other
 163 * cases as long as its memory has been zeroed after it has been
 164 * allocated.
 165 */
 166void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier);
 167
 168/**
 169 * v4l2_async_register_subdev - registers a sub-device to the asynchronous
 170 *      subdevice framework
 171 *
 172 * @sd: pointer to &struct v4l2_subdev
 173 */
 174int v4l2_async_register_subdev(struct v4l2_subdev *sd);
 175
 176/**
 177 * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device to
 178 *                                            the asynchronous sub-device
 179 *                                            framework and parse set up common
 180 *                                            sensor related devices
 181 *
 182 * @sd: pointer to struct &v4l2_subdev
 183 *
 184 * This function is just like v4l2_async_register_subdev() with the exception
 185 * that calling it will also parse firmware interfaces for remote references
 186 * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the
 187 * async sub-devices. The sub-device is similarly unregistered by calling
 188 * v4l2_async_unregister_subdev().
 189 *
 190 * While registered, the subdev module is marked as in-use.
 191 *
 192 * An error is returned if the module is no longer loaded on any attempts
 193 * to register it.
 194 */
 195int __must_check v4l2_async_register_subdev_sensor_common(
 196        struct v4l2_subdev *sd);
 197
 198/**
 199 * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous
 200 *      subdevice framework
 201 *
 202 * @sd: pointer to &struct v4l2_subdev
 203 */
 204void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
 205#endif
 206