12a1fcdf0SHans Verkuil /* 22a1fcdf0SHans Verkuil V4L2 device support header. 32a1fcdf0SHans Verkuil 42a1fcdf0SHans Verkuil Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl> 52a1fcdf0SHans Verkuil 62a1fcdf0SHans Verkuil This program is free software; you can redistribute it and/or modify 72a1fcdf0SHans Verkuil it under the terms of the GNU General Public License as published by 82a1fcdf0SHans Verkuil the Free Software Foundation; either version 2 of the License, or 92a1fcdf0SHans Verkuil (at your option) any later version. 102a1fcdf0SHans Verkuil 112a1fcdf0SHans Verkuil This program is distributed in the hope that it will be useful, 122a1fcdf0SHans Verkuil but WITHOUT ANY WARRANTY; without even the implied warranty of 132a1fcdf0SHans Verkuil MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 142a1fcdf0SHans Verkuil GNU General Public License for more details. 152a1fcdf0SHans Verkuil 162a1fcdf0SHans Verkuil You should have received a copy of the GNU General Public License 172a1fcdf0SHans Verkuil along with this program; if not, write to the Free Software 182a1fcdf0SHans Verkuil Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 192a1fcdf0SHans Verkuil */ 202a1fcdf0SHans Verkuil 212a1fcdf0SHans Verkuil #ifndef _V4L2_DEVICE_H 222a1fcdf0SHans Verkuil #define _V4L2_DEVICE_H 232a1fcdf0SHans Verkuil 242a1fcdf0SHans Verkuil #include <media/v4l2-subdev.h> 252a1fcdf0SHans Verkuil 262a1fcdf0SHans Verkuil /* Each instance of a V4L2 device should create the v4l2_device struct, 272a1fcdf0SHans Verkuil either stand-alone or embedded in a larger struct. 282a1fcdf0SHans Verkuil 292a1fcdf0SHans Verkuil It allows easy access to sub-devices (see v4l2-subdev.h) and provides 302a1fcdf0SHans Verkuil basic V4L2 device-level support. 312a1fcdf0SHans Verkuil */ 322a1fcdf0SHans Verkuil 33*1351a58cSKay Sievers #define V4L2_DEVICE_NAME_SIZE (20 + 16) 342a1fcdf0SHans Verkuil 352a1fcdf0SHans Verkuil struct v4l2_device { 363a63e449SHans Verkuil /* dev->driver_data points to this struct. 373a63e449SHans Verkuil Note: dev might be NULL if there is no parent device 383a63e449SHans Verkuil as is the case with e.g. ISA devices. */ 392a1fcdf0SHans Verkuil struct device *dev; 402a1fcdf0SHans Verkuil /* used to keep track of the registered subdevs */ 412a1fcdf0SHans Verkuil struct list_head subdevs; 422a1fcdf0SHans Verkuil /* lock this struct; can be used by the driver as well if this 432a1fcdf0SHans Verkuil struct is embedded into a larger struct. */ 442a1fcdf0SHans Verkuil spinlock_t lock; 452a1fcdf0SHans Verkuil /* unique device name, by default the driver name + bus ID */ 462a1fcdf0SHans Verkuil char name[V4L2_DEVICE_NAME_SIZE]; 4798ec6339SHans Verkuil /* notify callback called by some sub-devices. */ 4898ec6339SHans Verkuil void (*notify)(struct v4l2_subdev *sd, 4998ec6339SHans Verkuil unsigned int notification, void *arg); 502a1fcdf0SHans Verkuil }; 512a1fcdf0SHans Verkuil 523a63e449SHans Verkuil /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. 533a63e449SHans Verkuil dev may be NULL in rare cases (ISA devices). In that case you 543a63e449SHans Verkuil must fill in the v4l2_dev->name field before calling this function. */ 552a1fcdf0SHans Verkuil int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); 56ae6cfaacSHans Verkuil /* Set v4l2_dev->dev to NULL. Call when the USB parent disconnects. 57ae6cfaacSHans Verkuil Since the parent disappears this ensures that v4l2_dev doesn't have an 58ae6cfaacSHans Verkuil invalid parent pointer. */ 59ae6cfaacSHans Verkuil void v4l2_device_disconnect(struct v4l2_device *v4l2_dev); 60ae6cfaacSHans Verkuil /* Unregister all sub-devices and any other resources related to v4l2_dev. */ 612a1fcdf0SHans Verkuil void v4l2_device_unregister(struct v4l2_device *v4l2_dev); 622a1fcdf0SHans Verkuil 632a1fcdf0SHans Verkuil /* Register a subdev with a v4l2 device. While registered the subdev module 642a1fcdf0SHans Verkuil is marked as in-use. An error is returned if the module is no longer 652a1fcdf0SHans Verkuil loaded when you attempt to register it. */ 663a63e449SHans Verkuil int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, 673a63e449SHans Verkuil struct v4l2_subdev *sd); 682a1fcdf0SHans Verkuil /* Unregister a subdev with a v4l2 device. Can also be called if the subdev 692a1fcdf0SHans Verkuil wasn't registered. In that case it will do nothing. */ 702a1fcdf0SHans Verkuil void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); 712a1fcdf0SHans Verkuil 722a1fcdf0SHans Verkuil /* Iterate over all subdevs. */ 733a63e449SHans Verkuil #define v4l2_device_for_each_subdev(sd, v4l2_dev) \ 743a63e449SHans Verkuil list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) 752a1fcdf0SHans Verkuil 762a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching the condition. 772a1fcdf0SHans Verkuil Ignore any errors. Note that you cannot add or delete a subdev 782a1fcdf0SHans Verkuil while walking the subdevs list. */ 793a63e449SHans Verkuil #define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...) \ 802a1fcdf0SHans Verkuil do { \ 812a1fcdf0SHans Verkuil struct v4l2_subdev *sd; \ 822a1fcdf0SHans Verkuil \ 833a63e449SHans Verkuil list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) \ 842a1fcdf0SHans Verkuil if ((cond) && sd->ops->o && sd->ops->o->f) \ 852a1fcdf0SHans Verkuil sd->ops->o->f(sd , ##args); \ 862a1fcdf0SHans Verkuil } while (0) 872a1fcdf0SHans Verkuil 882a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching the condition. 892a1fcdf0SHans Verkuil If the callback returns an error other than 0 or -ENOIOCTLCMD, then 902a1fcdf0SHans Verkuil return with that error code. Note that you cannot add or delete a 912a1fcdf0SHans Verkuil subdev while walking the subdevs list. */ 923a63e449SHans Verkuil #define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \ 932a1fcdf0SHans Verkuil ({ \ 942a1fcdf0SHans Verkuil struct v4l2_subdev *sd; \ 95069b7479SHans Verkuil long err = 0; \ 962a1fcdf0SHans Verkuil \ 973a63e449SHans Verkuil list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) { \ 982a1fcdf0SHans Verkuil if ((cond) && sd->ops->o && sd->ops->o->f) \ 992a1fcdf0SHans Verkuil err = sd->ops->o->f(sd , ##args); \ 1002a1fcdf0SHans Verkuil if (err && err != -ENOIOCTLCMD) \ 1012a1fcdf0SHans Verkuil break; \ 1022a1fcdf0SHans Verkuil } \ 1032a1fcdf0SHans Verkuil (err == -ENOIOCTLCMD) ? 0 : err; \ 1042a1fcdf0SHans Verkuil }) 1052a1fcdf0SHans Verkuil 1062a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching grp_id (if 0, then 1072a1fcdf0SHans Verkuil match them all). Ignore any errors. Note that you cannot add or delete 1082a1fcdf0SHans Verkuil a subdev while walking the subdevs list. */ 1093a63e449SHans Verkuil #define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...) \ 1103a63e449SHans Verkuil __v4l2_device_call_subdevs(v4l2_dev, \ 111f9129a2eSHans Verkuil !(grpid) || sd->grp_id == (grpid), o, f , ##args) 1122a1fcdf0SHans Verkuil 1132a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching grp_id (if 0, then 1142a1fcdf0SHans Verkuil match them all). If the callback returns an error other than 0 or 1152a1fcdf0SHans Verkuil -ENOIOCTLCMD, then return with that error code. Note that you cannot 1162a1fcdf0SHans Verkuil add or delete a subdev while walking the subdevs list. */ 1173a63e449SHans Verkuil #define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ 1183a63e449SHans Verkuil __v4l2_device_call_subdevs_until_err(v4l2_dev, \ 119f9129a2eSHans Verkuil !(grpid) || sd->grp_id == (grpid), o, f , ##args) 1202a1fcdf0SHans Verkuil 1212a1fcdf0SHans Verkuil #endif 122