Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.4 397 lines 13 kB view raw
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * camera image capture (abstract) bus driver header 4 * 5 * Copyright (C) 2006, Sascha Hauer, Pengutronix 6 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> 7 */ 8 9#ifndef SOC_CAMERA_H 10#define SOC_CAMERA_H 11 12#include <linux/bitops.h> 13#include <linux/device.h> 14#include <linux/mutex.h> 15#include <linux/pm.h> 16#include <linux/videodev2.h> 17#include <media/videobuf2-v4l2.h> 18#include <media/v4l2-async.h> 19#include <media/v4l2-ctrls.h> 20#include <media/v4l2-device.h> 21 22struct file; 23struct soc_camera_desc; 24struct soc_camera_async_client; 25 26struct soc_camera_device { 27 struct list_head list; /* list of all registered devices */ 28 struct soc_camera_desc *sdesc; 29 struct device *pdev; /* Platform device */ 30 struct device *parent; /* Camera host device */ 31 struct device *control; /* E.g., the i2c client */ 32 s32 user_width; 33 s32 user_height; 34 u32 bytesperline; /* for padding, zero if unused */ 35 u32 sizeimage; 36 enum v4l2_colorspace colorspace; 37 unsigned char iface; /* Host number */ 38 unsigned char devnum; /* Device number per host */ 39 struct soc_camera_sense *sense; /* See comment in struct definition */ 40 struct video_device *vdev; 41 struct v4l2_ctrl_handler ctrl_handler; 42 const struct soc_camera_format_xlate *current_fmt; 43 struct soc_camera_format_xlate *user_formats; 44 int num_user_formats; 45 enum v4l2_field field; /* Preserve field over close() */ 46 void *host_priv; /* Per-device host private data */ 47 /* soc_camera.c private count. Only accessed with .host_lock held */ 48 int use_count; 49 struct file *streamer; /* stream owner */ 50 struct v4l2_clk *clk; 51 /* Asynchronous subdevice management */ 52 struct soc_camera_async_client *sasc; 53 /* video buffer queue */ 54 struct vb2_queue vb2_vidq; 55}; 56 57/* Host supports programmable stride */ 58#define SOCAM_HOST_CAP_STRIDE (1 << 0) 59 60enum soc_camera_subdev_role { 61 SOCAM_SUBDEV_DATA_SOURCE = 1, 62 SOCAM_SUBDEV_DATA_SINK, 63 SOCAM_SUBDEV_DATA_PROCESSOR, 64}; 65 66struct soc_camera_async_subdev { 67 struct v4l2_async_subdev asd; 68 enum soc_camera_subdev_role role; 69}; 70 71struct soc_camera_host { 72 struct v4l2_device v4l2_dev; 73 struct list_head list; 74 struct mutex host_lock; /* Main synchronisation lock */ 75 struct mutex clk_lock; /* Protect pipeline modifications */ 76 unsigned char nr; /* Host number */ 77 u32 capabilities; 78 struct soc_camera_device *icd; /* Currently attached client */ 79 void *priv; 80 const char *drv_name; 81 struct soc_camera_host_ops *ops; 82 struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */ 83 unsigned int *asd_sizes; /* 0-terminated array of asd group sizes */ 84}; 85 86struct soc_camera_host_ops { 87 struct module *owner; 88 int (*add)(struct soc_camera_device *); 89 void (*remove)(struct soc_camera_device *); 90 int (*clock_start)(struct soc_camera_host *); 91 void (*clock_stop)(struct soc_camera_host *); 92 /* 93 * .get_formats() is called for each client device format, but 94 * .put_formats() is only called once. Further, if any of the calls to 95 * .get_formats() fail, .put_formats() will not be called at all, the 96 * failing .get_formats() must then clean up internally. 97 */ 98 int (*get_formats)(struct soc_camera_device *, unsigned int, 99 struct soc_camera_format_xlate *); 100 void (*put_formats)(struct soc_camera_device *); 101 int (*get_selection)(struct soc_camera_device *, struct v4l2_selection *); 102 int (*set_selection)(struct soc_camera_device *, struct v4l2_selection *); 103 /* 104 * The difference to .set_selection() is, that .set_liveselection is not allowed 105 * to change the output sizes 106 */ 107 int (*set_liveselection)(struct soc_camera_device *, struct v4l2_selection *); 108 int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *); 109 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); 110 int (*init_videobuf2)(struct vb2_queue *, 111 struct soc_camera_device *); 112 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); 113 int (*set_bus_param)(struct soc_camera_device *); 114 int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *); 115 int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *); 116 int (*enum_framesizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *); 117 __poll_t (*poll)(struct file *, poll_table *); 118}; 119 120#define SOCAM_SENSOR_INVERT_PCLK (1 << 0) 121#define SOCAM_SENSOR_INVERT_MCLK (1 << 1) 122#define SOCAM_SENSOR_INVERT_HSYNC (1 << 2) 123#define SOCAM_SENSOR_INVERT_VSYNC (1 << 3) 124#define SOCAM_SENSOR_INVERT_DATA (1 << 4) 125 126struct i2c_board_info; 127struct regulator_bulk_data; 128 129struct soc_camera_subdev_desc { 130 /* Per camera SOCAM_SENSOR_* bus flags */ 131 unsigned long flags; 132 133 /* sensor driver private platform data */ 134 void *drv_priv; 135 136 /* 137 * Set unbalanced_power to true to deal with legacy drivers, failing to 138 * balance their calls to subdevice's .s_power() method. clock_state is 139 * then used internally by helper functions, it shouldn't be touched by 140 * drivers or the platform code. 141 */ 142 bool unbalanced_power; 143 unsigned long clock_state; 144 145 /* Optional callbacks to power on or off and reset the sensor */ 146 int (*power)(struct device *, int); 147 int (*reset)(struct device *); 148 149 /* 150 * some platforms may support different data widths than the sensors 151 * native ones due to different data line routing. Let the board code 152 * overwrite the width flags. 153 */ 154 int (*set_bus_param)(struct soc_camera_subdev_desc *, unsigned long flags); 155 unsigned long (*query_bus_param)(struct soc_camera_subdev_desc *); 156 void (*free_bus)(struct soc_camera_subdev_desc *); 157 158 /* Optional regulators that have to be managed on power on/off events */ 159 struct v4l2_subdev_platform_data sd_pdata; 160}; 161 162struct soc_camera_host_desc { 163 /* Camera bus id, used to match a camera and a bus */ 164 int bus_id; 165 int i2c_adapter_id; 166 struct i2c_board_info *board_info; 167 const char *module_name; 168 169 /* 170 * For non-I2C devices platform has to provide methods to add a device 171 * to the system and to remove it 172 */ 173 int (*add_device)(struct soc_camera_device *); 174 void (*del_device)(struct soc_camera_device *); 175}; 176 177/* 178 * Platform data for "soc-camera-pdrv" 179 * This MUST be kept binary-identical to struct soc_camera_link below, until 180 * it is completely replaced by this one, after which we can split it into its 181 * two components. 182 */ 183struct soc_camera_desc { 184 struct soc_camera_subdev_desc subdev_desc; 185 struct soc_camera_host_desc host_desc; 186}; 187 188/* Prepare to replace this struct: don't change its layout any more! */ 189struct soc_camera_link { 190 /* 191 * Subdevice part - keep at top and compatible to 192 * struct soc_camera_subdev_desc 193 */ 194 195 /* Per camera SOCAM_SENSOR_* bus flags */ 196 unsigned long flags; 197 198 void *priv; 199 200 /* Set by platforms to handle misbehaving drivers */ 201 bool unbalanced_power; 202 /* Used by soc-camera helper functions */ 203 unsigned long clock_state; 204 205 /* Optional callbacks to power on or off and reset the sensor */ 206 int (*power)(struct device *, int); 207 int (*reset)(struct device *); 208 /* 209 * some platforms may support different data widths than the sensors 210 * native ones due to different data line routing. Let the board code 211 * overwrite the width flags. 212 */ 213 int (*set_bus_param)(struct soc_camera_link *, unsigned long flags); 214 unsigned long (*query_bus_param)(struct soc_camera_link *); 215 void (*free_bus)(struct soc_camera_link *); 216 217 /* Optional regulators that have to be managed on power on/off events */ 218 struct regulator_bulk_data *regulators; 219 int num_regulators; 220 221 void *host_priv; 222 223 /* 224 * Host part - keep at bottom and compatible to 225 * struct soc_camera_host_desc 226 */ 227 228 /* Camera bus id, used to match a camera and a bus */ 229 int bus_id; 230 int i2c_adapter_id; 231 struct i2c_board_info *board_info; 232 const char *module_name; 233 234 /* 235 * For non-I2C devices platform has to provide methods to add a device 236 * to the system and to remove it 237 */ 238 int (*add_device)(struct soc_camera_device *); 239 void (*del_device)(struct soc_camera_device *); 240}; 241 242static inline struct soc_camera_host *to_soc_camera_host( 243 const struct device *dev) 244{ 245 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); 246 247 return container_of(v4l2_dev, struct soc_camera_host, v4l2_dev); 248} 249 250static inline struct soc_camera_desc *to_soc_camera_desc( 251 const struct soc_camera_device *icd) 252{ 253 return icd->sdesc; 254} 255 256static inline struct device *to_soc_camera_control( 257 const struct soc_camera_device *icd) 258{ 259 return icd->control; 260} 261 262static inline struct v4l2_subdev *soc_camera_to_subdev( 263 const struct soc_camera_device *icd) 264{ 265 struct device *control = to_soc_camera_control(icd); 266 return dev_get_drvdata(control); 267} 268 269int soc_camera_host_register(struct soc_camera_host *ici); 270void soc_camera_host_unregister(struct soc_camera_host *ici); 271 272const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( 273 struct soc_camera_device *icd, unsigned int fourcc); 274 275/** 276 * struct soc_camera_format_xlate - match between host and sensor formats 277 * @code: code of a sensor provided format 278 * @host_fmt: host format after host translation from code 279 * 280 * Host and sensor translation structure. Used in table of host and sensor 281 * formats matchings in soc_camera_device. A host can override the generic list 282 * generation by implementing get_formats(), and use it for format checks and 283 * format setup. 284 */ 285struct soc_camera_format_xlate { 286 u32 code; 287 const struct soc_mbus_pixelfmt *host_fmt; 288}; 289 290#define SOCAM_SENSE_PCLK_CHANGED (1 << 0) 291 292/** 293 * This struct can be attached to struct soc_camera_device by the host driver 294 * to request sense from the camera, for example, when calling .set_fmt(). The 295 * host then can check which flags are set and verify respective values if any. 296 * For example, if SOCAM_SENSE_PCLK_CHANGED is set, it means, pixclock has 297 * changed during this operation. After completion the host should detach sense. 298 * 299 * @flags ored SOCAM_SENSE_* flags 300 * @master_clock if the host wants to be informed about pixel-clock 301 * change, it better set master_clock. 302 * @pixel_clock_max maximum pixel clock frequency supported by the host, 303 * camera is not allowed to exceed this. 304 * @pixel_clock if the camera driver changed pixel clock during this 305 * operation, it sets SOCAM_SENSE_PCLK_CHANGED, uses 306 * master_clock to calculate the new pixel-clock and 307 * sets this field. 308 */ 309struct soc_camera_sense { 310 unsigned long flags; 311 unsigned long master_clock; 312 unsigned long pixel_clock_max; 313 unsigned long pixel_clock; 314}; 315 316#define SOCAM_DATAWIDTH(x) BIT((x) - 1) 317#define SOCAM_DATAWIDTH_4 SOCAM_DATAWIDTH(4) 318#define SOCAM_DATAWIDTH_8 SOCAM_DATAWIDTH(8) 319#define SOCAM_DATAWIDTH_9 SOCAM_DATAWIDTH(9) 320#define SOCAM_DATAWIDTH_10 SOCAM_DATAWIDTH(10) 321#define SOCAM_DATAWIDTH_12 SOCAM_DATAWIDTH(12) 322#define SOCAM_DATAWIDTH_15 SOCAM_DATAWIDTH(15) 323#define SOCAM_DATAWIDTH_16 SOCAM_DATAWIDTH(16) 324#define SOCAM_DATAWIDTH_18 SOCAM_DATAWIDTH(18) 325#define SOCAM_DATAWIDTH_24 SOCAM_DATAWIDTH(24) 326 327#define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_4 | SOCAM_DATAWIDTH_8 | \ 328 SOCAM_DATAWIDTH_9 | SOCAM_DATAWIDTH_10 | \ 329 SOCAM_DATAWIDTH_12 | SOCAM_DATAWIDTH_15 | \ 330 SOCAM_DATAWIDTH_16 | SOCAM_DATAWIDTH_18 | \ 331 SOCAM_DATAWIDTH_24) 332 333static inline void soc_camera_limit_side(int *start, int *length, 334 unsigned int start_min, 335 unsigned int length_min, unsigned int length_max) 336{ 337 if (*length < length_min) 338 *length = length_min; 339 else if (*length > length_max) 340 *length = length_max; 341 342 if (*start < start_min) 343 *start = start_min; 344 else if (*start > start_min + length_max - *length) 345 *start = start_min + length_max - *length; 346} 347 348unsigned long soc_camera_apply_board_flags(struct soc_camera_subdev_desc *ssdd, 349 const struct v4l2_mbus_config *cfg); 350 351int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd); 352int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd, 353 struct v4l2_clk *clk); 354int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd, 355 struct v4l2_clk *clk); 356 357static inline int soc_camera_set_power(struct device *dev, 358 struct soc_camera_subdev_desc *ssdd, struct v4l2_clk *clk, bool on) 359{ 360 return on ? soc_camera_power_on(dev, ssdd, clk) 361 : soc_camera_power_off(dev, ssdd, clk); 362} 363 364/* This is only temporary here - until v4l2-subdev begins to link to video_device */ 365#include <linux/i2c.h> 366static inline struct video_device *soc_camera_i2c_to_vdev(const struct i2c_client *client) 367{ 368 struct v4l2_subdev *sd = i2c_get_clientdata(client); 369 struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); 370 return icd ? icd->vdev : NULL; 371} 372 373static inline struct soc_camera_subdev_desc *soc_camera_i2c_to_desc(const struct i2c_client *client) 374{ 375 return client->dev.platform_data; 376} 377 378static inline struct v4l2_subdev *soc_camera_vdev_to_subdev(struct video_device *vdev) 379{ 380 struct soc_camera_device *icd = video_get_drvdata(vdev); 381 return soc_camera_to_subdev(icd); 382} 383 384static inline struct soc_camera_device *soc_camera_from_vb2q(const struct vb2_queue *vq) 385{ 386 return container_of(vq, struct soc_camera_device, vb2_vidq); 387} 388 389static inline u32 soc_camera_grp_id(const struct soc_camera_device *icd) 390{ 391 return (icd->iface << 8) | (icd->devnum + 1); 392} 393 394void soc_camera_lock(struct vb2_queue *vq); 395void soc_camera_unlock(struct vb2_queue *vq); 396 397#endif