| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 1 | /* | 
 | 2 |  * camera image capture (abstract) bus driver header | 
 | 3 |  * | 
 | 4 |  * Copyright (C) 2006, Sascha Hauer, Pengutronix | 
 | 5 |  * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | 
 | 6 |  * | 
 | 7 |  * This program is free software; you can redistribute it and/or modify | 
 | 8 |  * it under the terms of the GNU General Public License version 2 as | 
 | 9 |  * published by the Free Software Foundation. | 
 | 10 |  */ | 
 | 11 |  | 
 | 12 | #ifndef SOC_CAMERA_H | 
 | 13 | #define SOC_CAMERA_H | 
 | 14 |  | 
 | 15 | #include <linux/videodev2.h> | 
| Paulius Zaleckas | 092d392 | 2008-07-11 20:50:31 -0300 | [diff] [blame] | 16 | #include <media/videobuf-core.h> | 
| Robert Jarzmik | 2e52106 | 2008-08-01 20:14:50 -0300 | [diff] [blame] | 17 | #include <linux/pm.h> | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 18 |  | 
 | 19 | struct soc_camera_device { | 
 | 20 | 	struct list_head list; | 
 | 21 | 	struct device dev; | 
 | 22 | 	struct device *control; | 
 | 23 | 	unsigned short width;		/* Current window */ | 
 | 24 | 	unsigned short height;		/* sizes */ | 
 | 25 | 	unsigned short x_min;		/* Camera capabilities */ | 
 | 26 | 	unsigned short y_min; | 
 | 27 | 	unsigned short x_current;	/* Current window location */ | 
 | 28 | 	unsigned short y_current; | 
 | 29 | 	unsigned short width_min; | 
 | 30 | 	unsigned short width_max; | 
 | 31 | 	unsigned short height_min; | 
 | 32 | 	unsigned short height_max; | 
 | 33 | 	unsigned short y_skip_top;	/* Lines to skip at the top */ | 
 | 34 | 	unsigned short gain; | 
 | 35 | 	unsigned short exposure; | 
 | 36 | 	unsigned char iface;		/* Host number */ | 
 | 37 | 	unsigned char devnum;		/* Device number per host */ | 
| Guennadi Liakhovetski | ad5f2e8 | 2008-03-07 21:57:18 -0300 | [diff] [blame] | 38 | 	unsigned char buswidth;		/* See comment in .c */ | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 39 | 	struct soc_camera_ops *ops; | 
 | 40 | 	struct video_device *vdev; | 
 | 41 | 	const struct soc_camera_data_format *current_fmt; | 
| Guennadi Liakhovetski | 26f1b94 | 2008-03-24 12:18:36 -0300 | [diff] [blame] | 42 | 	const struct soc_camera_data_format *formats; | 
 | 43 | 	int num_formats; | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 44 | 	struct module *owner; | 
| Guennadi Liakhovetski | 9dc4e48 | 2008-04-22 14:45:32 -0300 | [diff] [blame] | 45 | 	/* soc_camera.c private count. Only accessed with video_lock held */ | 
 | 46 | 	int use_count; | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 47 | }; | 
 | 48 |  | 
 | 49 | struct soc_camera_file { | 
 | 50 | 	struct soc_camera_device *icd; | 
 | 51 | 	struct videobuf_queue vb_vidq; | 
 | 52 | }; | 
 | 53 |  | 
 | 54 | struct soc_camera_host { | 
 | 55 | 	struct list_head list; | 
 | 56 | 	struct device dev; | 
 | 57 | 	unsigned char nr;				/* Host number */ | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 58 | 	void *priv; | 
 | 59 | 	char *drv_name; | 
| Guennadi Liakhovetski | b8d9904 | 2008-04-04 13:41:25 -0300 | [diff] [blame] | 60 | 	struct soc_camera_host_ops *ops; | 
 | 61 | }; | 
 | 62 |  | 
 | 63 | struct soc_camera_host_ops { | 
 | 64 | 	struct module *owner; | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 65 | 	int (*add)(struct soc_camera_device *); | 
 | 66 | 	void (*remove)(struct soc_camera_device *); | 
| Robert Jarzmik | 2e52106 | 2008-08-01 20:14:50 -0300 | [diff] [blame] | 67 | 	int (*suspend)(struct soc_camera_device *, pm_message_t state); | 
 | 68 | 	int (*resume)(struct soc_camera_device *); | 
| Guennadi Liakhovetski | ad5f2e8 | 2008-03-07 21:57:18 -0300 | [diff] [blame] | 69 | 	int (*set_fmt_cap)(struct soc_camera_device *, __u32, | 
 | 70 | 			   struct v4l2_rect *); | 
 | 71 | 	int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *); | 
| Magnus Damm | a034d1b | 2008-07-11 20:59:34 -0300 | [diff] [blame] | 72 | 	void (*init_videobuf)(struct videobuf_queue *, | 
| Paulius Zaleckas | 092d392 | 2008-07-11 20:50:31 -0300 | [diff] [blame] | 73 | 			      struct soc_camera_device *); | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 74 | 	int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); | 
 | 75 | 	int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); | 
| Guennadi Liakhovetski | ad5f2e8 | 2008-03-07 21:57:18 -0300 | [diff] [blame] | 76 | 	int (*try_bus_param)(struct soc_camera_device *, __u32); | 
 | 77 | 	int (*set_bus_param)(struct soc_camera_device *, __u32); | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 78 | 	unsigned int (*poll)(struct file *, poll_table *); | 
 | 79 | }; | 
 | 80 |  | 
 | 81 | struct soc_camera_link { | 
 | 82 | 	/* Camera bus id, used to match a camera and a bus */ | 
 | 83 | 	int bus_id; | 
 | 84 | 	/* GPIO number to switch between 8 and 10 bit modes */ | 
 | 85 | 	unsigned int gpio; | 
| Stefan Herbrechtsmeier | 8103466 | 2008-08-14 12:04:11 -0300 | [diff] [blame] | 86 | 	/* Optional callbacks to power on or off and reset the sensor */ | 
 | 87 | 	int (*power)(struct device *, int); | 
 | 88 | 	int (*reset)(struct device *); | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 89 | }; | 
 | 90 |  | 
 | 91 | static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) | 
 | 92 | { | 
 | 93 | 	return container_of(dev, struct soc_camera_device, dev); | 
 | 94 | } | 
 | 95 |  | 
 | 96 | static inline struct soc_camera_host *to_soc_camera_host(struct device *dev) | 
 | 97 | { | 
 | 98 | 	return container_of(dev, struct soc_camera_host, dev); | 
 | 99 | } | 
 | 100 |  | 
| Guennadi Liakhovetski | b8d9904 | 2008-04-04 13:41:25 -0300 | [diff] [blame] | 101 | extern int soc_camera_host_register(struct soc_camera_host *ici); | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 102 | extern void soc_camera_host_unregister(struct soc_camera_host *ici); | 
 | 103 | extern int soc_camera_device_register(struct soc_camera_device *icd); | 
 | 104 | extern void soc_camera_device_unregister(struct soc_camera_device *icd); | 
 | 105 |  | 
 | 106 | extern int soc_camera_video_start(struct soc_camera_device *icd); | 
 | 107 | extern void soc_camera_video_stop(struct soc_camera_device *icd); | 
 | 108 |  | 
 | 109 | struct soc_camera_data_format { | 
 | 110 | 	char *name; | 
 | 111 | 	unsigned int depth; | 
 | 112 | 	__u32 fourcc; | 
 | 113 | 	enum v4l2_colorspace colorspace; | 
 | 114 | }; | 
 | 115 |  | 
 | 116 | struct soc_camera_ops { | 
 | 117 | 	struct module *owner; | 
| Guennadi Liakhovetski | 26f1b94 | 2008-03-24 12:18:36 -0300 | [diff] [blame] | 118 | 	int (*probe)(struct soc_camera_device *); | 
 | 119 | 	void (*remove)(struct soc_camera_device *); | 
| Robert Jarzmik | 2e52106 | 2008-08-01 20:14:50 -0300 | [diff] [blame] | 120 | 	int (*suspend)(struct soc_camera_device *, pm_message_t state); | 
 | 121 | 	int (*resume)(struct soc_camera_device *); | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 122 | 	int (*init)(struct soc_camera_device *); | 
 | 123 | 	int (*release)(struct soc_camera_device *); | 
 | 124 | 	int (*start_capture)(struct soc_camera_device *); | 
 | 125 | 	int (*stop_capture)(struct soc_camera_device *); | 
| Guennadi Liakhovetski | ad5f2e8 | 2008-03-07 21:57:18 -0300 | [diff] [blame] | 126 | 	int (*set_fmt_cap)(struct soc_camera_device *, __u32, | 
 | 127 | 			   struct v4l2_rect *); | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 128 | 	int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *); | 
| Guennadi Liakhovetski | ad5f2e8 | 2008-03-07 21:57:18 -0300 | [diff] [blame] | 129 | 	unsigned long (*query_bus_param)(struct soc_camera_device *); | 
 | 130 | 	int (*set_bus_param)(struct soc_camera_device *, unsigned long); | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 131 | 	int (*get_chip_id)(struct soc_camera_device *, | 
 | 132 | 			   struct v4l2_chip_ident *); | 
 | 133 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 
 | 134 | 	int (*get_register)(struct soc_camera_device *, struct v4l2_register *); | 
 | 135 | 	int (*set_register)(struct soc_camera_device *, struct v4l2_register *); | 
 | 136 | #endif | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 137 | 	int (*get_control)(struct soc_camera_device *, struct v4l2_control *); | 
 | 138 | 	int (*set_control)(struct soc_camera_device *, struct v4l2_control *); | 
 | 139 | 	const struct v4l2_queryctrl *controls; | 
 | 140 | 	int num_controls; | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 141 | }; | 
 | 142 |  | 
 | 143 | static inline struct v4l2_queryctrl const *soc_camera_find_qctrl( | 
 | 144 | 	struct soc_camera_ops *ops, int id) | 
 | 145 | { | 
 | 146 | 	int i; | 
 | 147 |  | 
 | 148 | 	for (i = 0; i < ops->num_controls; i++) | 
 | 149 | 		if (ops->controls[i].id == id) | 
 | 150 | 			return &ops->controls[i]; | 
 | 151 |  | 
 | 152 | 	return NULL; | 
 | 153 | } | 
 | 154 |  | 
| Guennadi Liakhovetski | ad5f2e8 | 2008-03-07 21:57:18 -0300 | [diff] [blame] | 155 | #define SOCAM_MASTER			(1 << 0) | 
 | 156 | #define SOCAM_SLAVE			(1 << 1) | 
 | 157 | #define SOCAM_HSYNC_ACTIVE_HIGH		(1 << 2) | 
 | 158 | #define SOCAM_HSYNC_ACTIVE_LOW		(1 << 3) | 
 | 159 | #define SOCAM_VSYNC_ACTIVE_HIGH		(1 << 4) | 
 | 160 | #define SOCAM_VSYNC_ACTIVE_LOW		(1 << 5) | 
 | 161 | #define SOCAM_DATAWIDTH_8		(1 << 6) | 
 | 162 | #define SOCAM_DATAWIDTH_9		(1 << 7) | 
 | 163 | #define SOCAM_DATAWIDTH_10		(1 << 8) | 
| Magnus Damm | b15cf1f | 2008-07-11 21:03:25 -0300 | [diff] [blame] | 164 | #define SOCAM_DATAWIDTH_16		(1 << 9) | 
 | 165 | #define SOCAM_PCLK_SAMPLE_RISING	(1 << 10) | 
 | 166 | #define SOCAM_PCLK_SAMPLE_FALLING	(1 << 11) | 
| Guennadi Liakhovetski | ad5f2e8 | 2008-03-07 21:57:18 -0300 | [diff] [blame] | 167 |  | 
 | 168 | #define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_9 | \ | 
| Magnus Damm | b15cf1f | 2008-07-11 21:03:25 -0300 | [diff] [blame] | 169 | 			      SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_16) | 
| Guennadi Liakhovetski | ad5f2e8 | 2008-03-07 21:57:18 -0300 | [diff] [blame] | 170 |  | 
 | 171 | static inline unsigned long soc_camera_bus_param_compatible( | 
 | 172 | 			unsigned long camera_flags, unsigned long bus_flags) | 
 | 173 | { | 
 | 174 | 	unsigned long common_flags, hsync, vsync, pclk; | 
 | 175 |  | 
 | 176 | 	common_flags = camera_flags & bus_flags; | 
 | 177 |  | 
 | 178 | 	hsync = common_flags & (SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW); | 
 | 179 | 	vsync = common_flags & (SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW); | 
 | 180 | 	pclk = common_flags & (SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING); | 
 | 181 |  | 
 | 182 | 	return (!hsync || !vsync || !pclk) ? 0 : common_flags; | 
 | 183 | } | 
| Guennadi Liakhovetski | e55222e | 2008-04-22 14:42:03 -0300 | [diff] [blame] | 184 |  | 
 | 185 | #endif |