Root/
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/mutex.h> |
16 | #include <linux/pm.h> |
17 | #include <linux/videodev2.h> |
18 | #include <media/videobuf-core.h> |
19 | #include <media/v4l2-device.h> |
20 | |
21 | struct soc_camera_device { |
22 | struct list_head list; |
23 | struct device dev; |
24 | struct device *pdev; /* Platform device */ |
25 | s32 user_width; |
26 | s32 user_height; |
27 | enum v4l2_colorspace colorspace; |
28 | unsigned char iface; /* Host number */ |
29 | unsigned char devnum; /* Device number per host */ |
30 | struct soc_camera_sense *sense; /* See comment in struct definition */ |
31 | struct soc_camera_ops *ops; |
32 | struct video_device *vdev; |
33 | const struct soc_camera_format_xlate *current_fmt; |
34 | struct soc_camera_format_xlate *user_formats; |
35 | int num_user_formats; |
36 | enum v4l2_field field; /* Preserve field over close() */ |
37 | void *host_priv; /* Per-device host private data */ |
38 | /* soc_camera.c private count. Only accessed with .video_lock held */ |
39 | int use_count; |
40 | struct mutex video_lock; /* Protects device data */ |
41 | }; |
42 | |
43 | struct soc_camera_file { |
44 | struct soc_camera_device *icd; |
45 | struct videobuf_queue vb_vidq; |
46 | }; |
47 | |
48 | struct soc_camera_host { |
49 | struct v4l2_device v4l2_dev; |
50 | struct list_head list; |
51 | unsigned char nr; /* Host number */ |
52 | void *priv; |
53 | const char *drv_name; |
54 | struct soc_camera_host_ops *ops; |
55 | }; |
56 | |
57 | struct soc_camera_host_ops { |
58 | struct module *owner; |
59 | int (*add)(struct soc_camera_device *); |
60 | void (*remove)(struct soc_camera_device *); |
61 | int (*suspend)(struct soc_camera_device *, pm_message_t); |
62 | int (*resume)(struct soc_camera_device *); |
63 | /* |
64 | * .get_formats() is called for each client device format, but |
65 | * .put_formats() is only called once. Further, if any of the calls to |
66 | * .get_formats() fail, .put_formats() will not be called at all, the |
67 | * failing .get_formats() must then clean up internally. |
68 | */ |
69 | int (*get_formats)(struct soc_camera_device *, int, |
70 | struct soc_camera_format_xlate *); |
71 | void (*put_formats)(struct soc_camera_device *); |
72 | int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *); |
73 | int (*get_crop)(struct soc_camera_device *, struct v4l2_crop *); |
74 | int (*set_crop)(struct soc_camera_device *, struct v4l2_crop *); |
75 | int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *); |
76 | int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); |
77 | void (*init_videobuf)(struct videobuf_queue *, |
78 | struct soc_camera_device *); |
79 | int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); |
80 | int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); |
81 | int (*set_bus_param)(struct soc_camera_device *, __u32); |
82 | int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *); |
83 | int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *); |
84 | int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *); |
85 | int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *); |
86 | unsigned int (*poll)(struct file *, poll_table *); |
87 | const struct v4l2_queryctrl *controls; |
88 | int num_controls; |
89 | }; |
90 | |
91 | #define SOCAM_SENSOR_INVERT_PCLK (1 << 0) |
92 | #define SOCAM_SENSOR_INVERT_MCLK (1 << 1) |
93 | #define SOCAM_SENSOR_INVERT_HSYNC (1 << 2) |
94 | #define SOCAM_SENSOR_INVERT_VSYNC (1 << 3) |
95 | #define SOCAM_SENSOR_INVERT_DATA (1 << 4) |
96 | |
97 | struct i2c_board_info; |
98 | |
99 | struct soc_camera_link { |
100 | /* Camera bus id, used to match a camera and a bus */ |
101 | int bus_id; |
102 | /* Per camera SOCAM_SENSOR_* bus flags */ |
103 | unsigned long flags; |
104 | int i2c_adapter_id; |
105 | struct i2c_board_info *board_info; |
106 | const char *module_name; |
107 | void *priv; |
108 | |
109 | /* |
110 | * For non-I2C devices platform platform has to provide methods to |
111 | * add a device to the system and to remove |
112 | */ |
113 | int (*add_device)(struct soc_camera_link *, struct device *); |
114 | void (*del_device)(struct soc_camera_link *); |
115 | /* Optional callbacks to power on or off and reset the sensor */ |
116 | int (*power)(struct device *, int); |
117 | int (*reset)(struct device *); |
118 | /* |
119 | * some platforms may support different data widths than the sensors |
120 | * native ones due to different data line routing. Let the board code |
121 | * overwrite the width flags. |
122 | */ |
123 | int (*set_bus_param)(struct soc_camera_link *, unsigned long flags); |
124 | unsigned long (*query_bus_param)(struct soc_camera_link *); |
125 | void (*free_bus)(struct soc_camera_link *); |
126 | }; |
127 | |
128 | static inline struct soc_camera_device *to_soc_camera_dev( |
129 | const struct device *dev) |
130 | { |
131 | return container_of(dev, struct soc_camera_device, dev); |
132 | } |
133 | |
134 | static inline struct soc_camera_host *to_soc_camera_host( |
135 | const struct device *dev) |
136 | { |
137 | struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); |
138 | |
139 | return container_of(v4l2_dev, struct soc_camera_host, v4l2_dev); |
140 | } |
141 | |
142 | static inline struct soc_camera_link *to_soc_camera_link( |
143 | const struct soc_camera_device *icd) |
144 | { |
145 | return icd->dev.platform_data; |
146 | } |
147 | |
148 | static inline struct device *to_soc_camera_control( |
149 | const struct soc_camera_device *icd) |
150 | { |
151 | return dev_get_drvdata(&icd->dev); |
152 | } |
153 | |
154 | static inline struct v4l2_subdev *soc_camera_to_subdev( |
155 | const struct soc_camera_device *icd) |
156 | { |
157 | struct device *control = to_soc_camera_control(icd); |
158 | return dev_get_drvdata(control); |
159 | } |
160 | |
161 | int soc_camera_host_register(struct soc_camera_host *ici); |
162 | void soc_camera_host_unregister(struct soc_camera_host *ici); |
163 | |
164 | const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( |
165 | struct soc_camera_device *icd, unsigned int fourcc); |
166 | |
167 | /** |
168 | * struct soc_camera_format_xlate - match between host and sensor formats |
169 | * @code: code of a sensor provided format |
170 | * @host_fmt: host format after host translation from code |
171 | * |
172 | * Host and sensor translation structure. Used in table of host and sensor |
173 | * formats matchings in soc_camera_device. A host can override the generic list |
174 | * generation by implementing get_formats(), and use it for format checks and |
175 | * format setup. |
176 | */ |
177 | struct soc_camera_format_xlate { |
178 | enum v4l2_mbus_pixelcode code; |
179 | const struct soc_mbus_pixelfmt *host_fmt; |
180 | }; |
181 | |
182 | struct soc_camera_ops { |
183 | int (*suspend)(struct soc_camera_device *, pm_message_t state); |
184 | int (*resume)(struct soc_camera_device *); |
185 | unsigned long (*query_bus_param)(struct soc_camera_device *); |
186 | int (*set_bus_param)(struct soc_camera_device *, unsigned long); |
187 | int (*enum_input)(struct soc_camera_device *, struct v4l2_input *); |
188 | const struct v4l2_queryctrl *controls; |
189 | int num_controls; |
190 | }; |
191 | |
192 | #define SOCAM_SENSE_PCLK_CHANGED (1 << 0) |
193 | |
194 | /** |
195 | * This struct can be attached to struct soc_camera_device by the host driver |
196 | * to request sense from the camera, for example, when calling .set_fmt(). The |
197 | * host then can check which flags are set and verify respective values if any. |
198 | * For example, if SOCAM_SENSE_PCLK_CHANGED is set, it means, pixclock has |
199 | * changed during this operation. After completion the host should detach sense. |
200 | * |
201 | * @flags ored SOCAM_SENSE_* flags |
202 | * @master_clock if the host wants to be informed about pixel-clock |
203 | * change, it better set master_clock. |
204 | * @pixel_clock_max maximum pixel clock frequency supported by the host, |
205 | * camera is not allowed to exceed this. |
206 | * @pixel_clock if the camera driver changed pixel clock during this |
207 | * operation, it sets SOCAM_SENSE_PCLK_CHANGED, uses |
208 | * master_clock to calculate the new pixel-clock and |
209 | * sets this field. |
210 | */ |
211 | struct soc_camera_sense { |
212 | unsigned long flags; |
213 | unsigned long master_clock; |
214 | unsigned long pixel_clock_max; |
215 | unsigned long pixel_clock; |
216 | }; |
217 | |
218 | static inline struct v4l2_queryctrl const *soc_camera_find_qctrl( |
219 | struct soc_camera_ops *ops, int id) |
220 | { |
221 | int i; |
222 | |
223 | for (i = 0; i < ops->num_controls; i++) |
224 | if (ops->controls[i].id == id) |
225 | return &ops->controls[i]; |
226 | |
227 | return NULL; |
228 | } |
229 | |
230 | #define SOCAM_MASTER (1 << 0) |
231 | #define SOCAM_SLAVE (1 << 1) |
232 | #define SOCAM_HSYNC_ACTIVE_HIGH (1 << 2) |
233 | #define SOCAM_HSYNC_ACTIVE_LOW (1 << 3) |
234 | #define SOCAM_VSYNC_ACTIVE_HIGH (1 << 4) |
235 | #define SOCAM_VSYNC_ACTIVE_LOW (1 << 5) |
236 | #define SOCAM_DATAWIDTH_4 (1 << 6) |
237 | #define SOCAM_DATAWIDTH_8 (1 << 7) |
238 | #define SOCAM_DATAWIDTH_9 (1 << 8) |
239 | #define SOCAM_DATAWIDTH_10 (1 << 9) |
240 | #define SOCAM_DATAWIDTH_15 (1 << 10) |
241 | #define SOCAM_DATAWIDTH_16 (1 << 11) |
242 | #define SOCAM_PCLK_SAMPLE_RISING (1 << 12) |
243 | #define SOCAM_PCLK_SAMPLE_FALLING (1 << 13) |
244 | #define SOCAM_DATA_ACTIVE_HIGH (1 << 14) |
245 | #define SOCAM_DATA_ACTIVE_LOW (1 << 15) |
246 | |
247 | #define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_4 | SOCAM_DATAWIDTH_8 | \ |
248 | SOCAM_DATAWIDTH_9 | SOCAM_DATAWIDTH_10 | \ |
249 | SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_16) |
250 | |
251 | static inline unsigned long soc_camera_bus_param_compatible( |
252 | unsigned long camera_flags, unsigned long bus_flags) |
253 | { |
254 | unsigned long common_flags, hsync, vsync, pclk, data, buswidth, mode; |
255 | |
256 | common_flags = camera_flags & bus_flags; |
257 | |
258 | hsync = common_flags & (SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW); |
259 | vsync = common_flags & (SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW); |
260 | pclk = common_flags & (SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING); |
261 | data = common_flags & (SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_LOW); |
262 | mode = common_flags & (SOCAM_MASTER | SOCAM_SLAVE); |
263 | buswidth = common_flags & SOCAM_DATAWIDTH_MASK; |
264 | |
265 | return (!hsync || !vsync || !pclk || !data || !mode || !buswidth) ? 0 : |
266 | common_flags; |
267 | } |
268 | |
269 | static inline void soc_camera_limit_side(unsigned int *start, |
270 | unsigned int *length, unsigned int start_min, |
271 | unsigned int length_min, unsigned int length_max) |
272 | { |
273 | if (*length < length_min) |
274 | *length = length_min; |
275 | else if (*length > length_max) |
276 | *length = length_max; |
277 | |
278 | if (*start < start_min) |
279 | *start = start_min; |
280 | else if (*start > start_min + length_max - *length) |
281 | *start = start_min + length_max - *length; |
282 | } |
283 | |
284 | extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, |
285 | unsigned long flags); |
286 | |
287 | #endif |
288 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9