diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera')
9 files changed, 22210 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0001-omap3isp-Add-ISP-main-driver-and-register-definitio.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0001-omap3isp-Add-ISP-main-driver-and-register-definitio.patch new file mode 100644 index 0000000000..e6e07d8afc --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0001-omap3isp-Add-ISP-main-driver-and-register-definitio.patch | |||
@@ -0,0 +1,4625 @@ | |||
1 | From 77c99cd863b906c803c3dec08753c19bf9b67882 Mon Sep 17 00:00:00 2001 | ||
2 | From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
3 | Date: Tue, 10 Mar 2009 10:49:02 +0200 | ||
4 | Subject: [PATCH] omap3isp: Add ISP main driver and register definitions | ||
5 | |||
6 | TODO: | ||
7 | |||
8 | - Release resoures in isp_probe() if something fails. | ||
9 | |||
10 | - Implement a sensible generic interface so that the ISP can offer a | ||
11 | v4l2_subdev (like the v4l2-int-device slaves) interface towards the | ||
12 | camera driver. | ||
13 | |||
14 | - Handle CSI1 and CSI2 error cases (currently unhandled?). | ||
15 | |||
16 | - Fix H3A / HIST interrupt enabling / disabling. | ||
17 | |||
18 | - Clean up the private ioctls. | ||
19 | |||
20 | - Handle SBL overflows somehow. | ||
21 | |||
22 | Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
23 | --- | ||
24 | drivers/media/video/Makefile | 2 + | ||
25 | drivers/media/video/isp/Makefile | 12 + | ||
26 | drivers/media/video/isp/isp.c | 2547 ++++++++++++++++++++++++++++++++++++++ | ||
27 | drivers/media/video/isp/isp.h | 318 +++++ | ||
28 | drivers/media/video/isp/ispreg.h | 1674 +++++++++++++++++++++++++ | ||
29 | 5 files changed, 4553 insertions(+), 0 deletions(-) | ||
30 | create mode 100644 drivers/media/video/isp/Makefile | ||
31 | create mode 100644 drivers/media/video/isp/isp.c | ||
32 | create mode 100644 drivers/media/video/isp/isp.h | ||
33 | create mode 100644 drivers/media/video/isp/ispreg.h | ||
34 | |||
35 | diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile | ||
36 | index 72f6d03..e654270 100644 | ||
37 | --- a/drivers/media/video/Makefile | ||
38 | +++ b/drivers/media/video/Makefile | ||
39 | @@ -106,6 +106,8 @@ obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o | ||
40 | obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o | ||
41 | obj-$(CONFIG_VIDEO_OV7670) += ov7670.o | ||
42 | |||
43 | +obj-y += isp/ | ||
44 | + | ||
45 | obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o | ||
46 | |||
47 | obj-$(CONFIG_USB_DABUSB) += dabusb.o | ||
48 | diff --git a/drivers/media/video/isp/Makefile b/drivers/media/video/isp/Makefile | ||
49 | new file mode 100644 | ||
50 | index 0000000..f14d617 | ||
51 | --- /dev/null | ||
52 | +++ b/drivers/media/video/isp/Makefile | ||
53 | @@ -0,0 +1,12 @@ | ||
54 | +# Makefile for OMAP3 ISP driver | ||
55 | + | ||
56 | +ifdef CONFIG_ARCH_OMAP3410 | ||
57 | +isp-mod-objs += \ | ||
58 | + isp.o ispccdc.o | ||
59 | +else | ||
60 | +isp-mod-objs += \ | ||
61 | + isp.o ispccdc.o ispmmu.o \ | ||
62 | + isppreview.o ispresizer.o isph3a.o isphist.o isp_af.o ispcsi2.o | ||
63 | +endif | ||
64 | + | ||
65 | +obj-$(CONFIG_VIDEO_OMAP3) += isp-mod.o | ||
66 | diff --git a/drivers/media/video/isp/isp.c b/drivers/media/video/isp/isp.c | ||
67 | new file mode 100644 | ||
68 | index 0000000..54c839b | ||
69 | --- /dev/null | ||
70 | +++ b/drivers/media/video/isp/isp.c | ||
71 | @@ -0,0 +1,2547 @@ | ||
72 | +/* | ||
73 | + * isp.c | ||
74 | + * | ||
75 | + * Driver Library for ISP Control module in TI's OMAP3 Camera ISP | ||
76 | + * ISP interface and IRQ related APIs are defined here. | ||
77 | + * | ||
78 | + * Copyright (C) 2009 Texas Instruments. | ||
79 | + * Copyright (C) 2009 Nokia. | ||
80 | + * | ||
81 | + * Contributors: | ||
82 | + * Sameer Venkatraman <sameerv@ti.com> | ||
83 | + * Mohit Jalori <mjalori@ti.com> | ||
84 | + * Sergio Aguirre <saaguirre@ti.com> | ||
85 | + * Sakari Ailus <sakari.ailus@nokia.com> | ||
86 | + * Tuukka Toivonen <tuukka.o.toivonen@nokia.com> | ||
87 | + * Toni Leinonen <toni.leinonen@nokia.com> | ||
88 | + * | ||
89 | + * This package is free software; you can redistribute it and/or modify | ||
90 | + * it under the terms of the GNU General Public License version 2 as | ||
91 | + * published by the Free Software Foundation. | ||
92 | + * | ||
93 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
94 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
95 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
96 | + */ | ||
97 | + | ||
98 | +#include <asm/cacheflush.h> | ||
99 | + | ||
100 | +#include <linux/delay.h> | ||
101 | +#include <linux/interrupt.h> | ||
102 | +#include <linux/clk.h> | ||
103 | +#include <linux/dma-mapping.h> | ||
104 | +#include <linux/vmalloc.h> | ||
105 | +#include <linux/platform_device.h> | ||
106 | + | ||
107 | +#include "isp.h" | ||
108 | +#include "ispmmu.h" | ||
109 | +#include "ispreg.h" | ||
110 | +#include "ispccdc.h" | ||
111 | +#include "isph3a.h" | ||
112 | +#include "isphist.h" | ||
113 | +#include "isp_af.h" | ||
114 | +#include "isppreview.h" | ||
115 | +#include "ispresizer.h" | ||
116 | +#include "ispcsi2.h" | ||
117 | + | ||
118 | +static struct isp_device *omap3isp; | ||
119 | + | ||
120 | +static int isp_try_size(struct v4l2_pix_format *pix_input, | ||
121 | + struct v4l2_pix_format *pix_output); | ||
122 | + | ||
123 | +static void isp_save_ctx(void); | ||
124 | + | ||
125 | +static void isp_restore_ctx(void); | ||
126 | + | ||
127 | +static void isp_buf_init(void); | ||
128 | + | ||
129 | +/* List of image formats supported via OMAP ISP */ | ||
130 | +const static struct v4l2_fmtdesc isp_formats[] = { | ||
131 | + { | ||
132 | + .description = "UYVY, packed", | ||
133 | + .pixelformat = V4L2_PIX_FMT_UYVY, | ||
134 | + }, | ||
135 | + { | ||
136 | + .description = "YUYV (YUV 4:2:2), packed", | ||
137 | + .pixelformat = V4L2_PIX_FMT_YUYV, | ||
138 | + }, | ||
139 | + { | ||
140 | + .description = "Bayer10 (GrR/BGb)", | ||
141 | + .pixelformat = V4L2_PIX_FMT_SGRBG10, | ||
142 | + }, | ||
143 | +}; | ||
144 | + | ||
145 | +/* ISP Crop capabilities */ | ||
146 | +static struct v4l2_rect ispcroprect; | ||
147 | +static struct v4l2_rect cur_rect; | ||
148 | + | ||
149 | +/** | ||
150 | + * struct vcontrol - Video control structure. | ||
151 | + * @qc: V4L2 Query control structure. | ||
152 | + * @current_value: Current value of the control. | ||
153 | + */ | ||
154 | +static struct vcontrol { | ||
155 | + struct v4l2_queryctrl qc; | ||
156 | + int current_value; | ||
157 | +} video_control[] = { | ||
158 | + { | ||
159 | + { | ||
160 | + .id = V4L2_CID_BRIGHTNESS, | ||
161 | + .type = V4L2_CTRL_TYPE_INTEGER, | ||
162 | + .name = "Brightness", | ||
163 | + .minimum = ISPPRV_BRIGHT_LOW, | ||
164 | + .maximum = ISPPRV_BRIGHT_HIGH, | ||
165 | + .step = ISPPRV_BRIGHT_STEP, | ||
166 | + .default_value = ISPPRV_BRIGHT_DEF, | ||
167 | + }, | ||
168 | + .current_value = ISPPRV_BRIGHT_DEF, | ||
169 | + }, | ||
170 | + { | ||
171 | + { | ||
172 | + .id = V4L2_CID_CONTRAST, | ||
173 | + .type = V4L2_CTRL_TYPE_INTEGER, | ||
174 | + .name = "Contrast", | ||
175 | + .minimum = ISPPRV_CONTRAST_LOW, | ||
176 | + .maximum = ISPPRV_CONTRAST_HIGH, | ||
177 | + .step = ISPPRV_CONTRAST_STEP, | ||
178 | + .default_value = ISPPRV_CONTRAST_DEF, | ||
179 | + }, | ||
180 | + .current_value = ISPPRV_CONTRAST_DEF, | ||
181 | + }, | ||
182 | + { | ||
183 | + { | ||
184 | + .id = V4L2_CID_COLORFX, | ||
185 | + .type = V4L2_CTRL_TYPE_MENU, | ||
186 | + .name = "Color Effects", | ||
187 | + .minimum = V4L2_COLORFX_NONE, | ||
188 | + .maximum = V4L2_COLORFX_SEPIA, | ||
189 | + .step = 1, | ||
190 | + .default_value = V4L2_COLORFX_NONE, | ||
191 | + }, | ||
192 | + .current_value = V4L2_COLORFX_NONE, | ||
193 | + } | ||
194 | +}; | ||
195 | + | ||
196 | +static struct v4l2_querymenu video_menu[] = { | ||
197 | + { | ||
198 | + .id = V4L2_CID_COLORFX, | ||
199 | + .index = 0, | ||
200 | + .name = "None", | ||
201 | + }, | ||
202 | + { | ||
203 | + .id = V4L2_CID_COLORFX, | ||
204 | + .index = 1, | ||
205 | + .name = "B&W", | ||
206 | + }, | ||
207 | + { | ||
208 | + .id = V4L2_CID_COLORFX, | ||
209 | + .index = 2, | ||
210 | + .name = "Sepia", | ||
211 | + }, | ||
212 | +}; | ||
213 | + | ||
214 | +struct isp_buf { | ||
215 | + dma_addr_t isp_addr; | ||
216 | + void (*complete)(struct videobuf_buffer *vb, void *priv); | ||
217 | + struct videobuf_buffer *vb; | ||
218 | + void *priv; | ||
219 | + u32 vb_state; | ||
220 | +}; | ||
221 | + | ||
222 | +#define ISP_BUFS_IS_FULL(bufs) \ | ||
223 | + (((bufs)->queue + 1) % NUM_BUFS == (bufs)->done) | ||
224 | +#define ISP_BUFS_IS_EMPTY(bufs) ((bufs)->queue == (bufs)->done) | ||
225 | +#define ISP_BUFS_IS_LAST(bufs) \ | ||
226 | + ((bufs)->queue == ((bufs)->done + 1) % NUM_BUFS) | ||
227 | +#define ISP_BUFS_QUEUED(bufs) \ | ||
228 | + ((((bufs)->done - (bufs)->queue + NUM_BUFS)) % NUM_BUFS) | ||
229 | +#define ISP_BUF_DONE(bufs) ((bufs)->buf + (bufs)->done) | ||
230 | +#define ISP_BUF_NEXT_DONE(bufs) \ | ||
231 | + ((bufs)->buf + ((bufs)->done + 1) % NUM_BUFS) | ||
232 | +#define ISP_BUF_QUEUE(bufs) ((bufs)->buf + (bufs)->queue) | ||
233 | +#define ISP_BUF_MARK_DONE(bufs) \ | ||
234 | + (bufs)->done = ((bufs)->done + 1) % NUM_BUFS; | ||
235 | +#define ISP_BUF_MARK_QUEUED(bufs) \ | ||
236 | + (bufs)->queue = ((bufs)->queue + 1) % NUM_BUFS; | ||
237 | + | ||
238 | +struct isp_bufs { | ||
239 | + dma_addr_t isp_addr_capture[VIDEO_MAX_FRAME]; | ||
240 | + spinlock_t lock; /* For handling current buffer */ | ||
241 | + /* queue full: (ispsg.queue + 1) % NUM_BUFS == ispsg.done | ||
242 | + queue empty: ispsg.queue == ispsg.done */ | ||
243 | + struct isp_buf buf[NUM_BUFS]; | ||
244 | + /* Next slot to queue a buffer. */ | ||
245 | + int queue; | ||
246 | + /* Buffer that is being processed. */ | ||
247 | + int done; | ||
248 | + /* Wait for this many hs_vs before anything else. */ | ||
249 | + int wait_hs_vs; | ||
250 | +}; | ||
251 | + | ||
252 | +/** | ||
253 | + * struct ispirq - Structure for containing callbacks to be called in ISP ISR. | ||
254 | + * @isp_callbk: Array which stores callback functions, indexed by the type of | ||
255 | + * callback (8 possible types). | ||
256 | + * @isp_callbk_arg1: Pointer to array containing pointers to the first argument | ||
257 | + * to be passed to the requested callback function. | ||
258 | + * @isp_callbk_arg2: Pointer to array containing pointers to the second | ||
259 | + * argument to be passed to the requested callback function. | ||
260 | + * | ||
261 | + * This structure is used to contain all the callback functions related for | ||
262 | + * each callback type (CBK_CCDC_VD0, CBK_CCDC_VD1, CBK_PREV_DONE, | ||
263 | + * CBK_RESZ_DONE, CBK_MMU_ERR, CBK_H3A_AWB_DONE, CBK_HIST_DONE, CBK_HS_VS, | ||
264 | + * CBK_LSC_ISR). | ||
265 | + */ | ||
266 | +struct isp_irq { | ||
267 | + isp_callback_t isp_callbk[CBK_END]; | ||
268 | + isp_vbq_callback_ptr isp_callbk_arg1[CBK_END]; | ||
269 | + void *isp_callbk_arg2[CBK_END]; | ||
270 | +}; | ||
271 | + | ||
272 | +/** | ||
273 | + * struct ispmodule - Structure for storing ISP sub-module information. | ||
274 | + * @isp_pipeline: Bit mask for submodules enabled within the ISP. | ||
275 | + * @applyCrop: Flag to do a crop operation when video buffer queue ISR is done | ||
276 | + * @pix: Structure containing the format and layout of the output image. | ||
277 | + * @ccdc_input_width: ISP CCDC module input image width. | ||
278 | + * @ccdc_input_height: ISP CCDC module input image height. | ||
279 | + * @ccdc_output_width: ISP CCDC module output image width. | ||
280 | + * @ccdc_output_height: ISP CCDC module output image height. | ||
281 | + * @preview_input_width: ISP Preview module input image width. | ||
282 | + * @preview_input_height: ISP Preview module input image height. | ||
283 | + * @preview_output_width: ISP Preview module output image width. | ||
284 | + * @preview_output_height: ISP Preview module output image height. | ||
285 | + * @resizer_input_width: ISP Resizer module input image width. | ||
286 | + * @resizer_input_height: ISP Resizer module input image height. | ||
287 | + * @resizer_output_width: ISP Resizer module output image width. | ||
288 | + * @resizer_output_height: ISP Resizer module output image height. | ||
289 | + */ | ||
290 | +struct isp_module { | ||
291 | + unsigned int isp_pipeline; | ||
292 | + int applyCrop; | ||
293 | + struct v4l2_pix_format pix; | ||
294 | + unsigned int ccdc_input_width; | ||
295 | + unsigned int ccdc_input_height; | ||
296 | + unsigned int ccdc_output_width; | ||
297 | + unsigned int ccdc_output_height; | ||
298 | + unsigned int preview_input_width; | ||
299 | + unsigned int preview_input_height; | ||
300 | + unsigned int preview_output_width; | ||
301 | + unsigned int preview_output_height; | ||
302 | + unsigned int resizer_input_width; | ||
303 | + unsigned int resizer_input_height; | ||
304 | + unsigned int resizer_output_width; | ||
305 | + unsigned int resizer_output_height; | ||
306 | +}; | ||
307 | + | ||
308 | +#define RAW_CAPTURE(isp) \ | ||
309 | + (!((isp)->module.isp_pipeline & OMAP_ISP_PREVIEW)) | ||
310 | + | ||
311 | +/** | ||
312 | + * struct isp - Structure for storing ISP Control module information | ||
313 | + * @lock: Spinlock to sync between isr and processes. | ||
314 | + * @isp_mutex: Semaphore used to get access to the ISP. | ||
315 | + * @ref_count: Reference counter. | ||
316 | + * @cam_ick: Pointer to ISP Interface clock. | ||
317 | + * @cam_fck: Pointer to ISP Functional clock. | ||
318 | + * | ||
319 | + * This structure is used to store the OMAP ISP Control Information. | ||
320 | + */ | ||
321 | +static struct isp { | ||
322 | + spinlock_t lock; /* For handling registered ISP callbacks */ | ||
323 | + struct mutex isp_mutex; /* For handling ref_count field */ | ||
324 | + int ref_count; | ||
325 | + struct clk *cam_ick; | ||
326 | + struct clk *cam_mclk; | ||
327 | + struct clk *csi2_fck; | ||
328 | + struct isp_interface_config *config; | ||
329 | + dma_addr_t tmp_buf; | ||
330 | + size_t tmp_buf_size; | ||
331 | + unsigned long tmp_buf_offset; | ||
332 | + struct isp_bufs bufs; | ||
333 | + struct isp_irq irq; | ||
334 | + struct isp_module module; | ||
335 | +} isp_obj; | ||
336 | + | ||
337 | +/* Structure for saving/restoring ISP module registers */ | ||
338 | +static struct isp_reg isp_reg_list[] = { | ||
339 | + {OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG, 0}, | ||
340 | + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_GRESET_LENGTH, 0}, | ||
341 | + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_PSTRB_REPLAY, 0}, | ||
342 | + {OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, 0}, | ||
343 | + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, 0}, | ||
344 | + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_FRAME, 0}, | ||
345 | + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_PSTRB_DELAY, 0}, | ||
346 | + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_STRB_DELAY, 0}, | ||
347 | + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_SHUT_DELAY, 0}, | ||
348 | + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_PSTRB_LENGTH, 0}, | ||
349 | + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_STRB_LENGTH, 0}, | ||
350 | + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_SHUT_LENGTH, 0}, | ||
351 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF_SYSCONFIG, 0}, | ||
352 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF_IRQENABLE, 0}, | ||
353 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF0_CTRL, 0}, | ||
354 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF1_CTRL, 0}, | ||
355 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF0_START, 0}, | ||
356 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF1_START, 0}, | ||
357 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF0_END, 0}, | ||
358 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF1_END, 0}, | ||
359 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF0_WINDOWSIZE, 0}, | ||
360 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF1_WINDOWSIZE, 0}, | ||
361 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF0_THRESHOLD, 0}, | ||
362 | + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF1_THRESHOLD, 0}, | ||
363 | + {0, ISP_TOK_TERM, 0} | ||
364 | +}; | ||
365 | + | ||
366 | +u32 isp_reg_readl(enum isp_mem_resources isp_mmio_range, u32 reg_offset) | ||
367 | +{ | ||
368 | + return __raw_readl(omap3isp->mmio_base[isp_mmio_range] + reg_offset); | ||
369 | +} | ||
370 | +EXPORT_SYMBOL(isp_reg_readl); | ||
371 | + | ||
372 | +void isp_reg_writel(u32 reg_value, enum isp_mem_resources isp_mmio_range, | ||
373 | + u32 reg_offset) | ||
374 | +{ | ||
375 | + __raw_writel(reg_value, | ||
376 | + omap3isp->mmio_base[isp_mmio_range] + reg_offset); | ||
377 | +} | ||
378 | +EXPORT_SYMBOL(isp_reg_writel); | ||
379 | + | ||
380 | +/* | ||
381 | + * | ||
382 | + * V4L2 Handling | ||
383 | + * | ||
384 | + */ | ||
385 | + | ||
386 | +/** | ||
387 | + * find_vctrl - Returns the index of the ctrl array of the requested ctrl ID. | ||
388 | + * @id: Requested control ID. | ||
389 | + * | ||
390 | + * Returns 0 if successful, -EINVAL if not found, or -EDOM if its out of | ||
391 | + * domain. | ||
392 | + **/ | ||
393 | +static int find_vctrl(int id) | ||
394 | +{ | ||
395 | + int i; | ||
396 | + | ||
397 | + if (id < V4L2_CID_BASE) | ||
398 | + return -EDOM; | ||
399 | + | ||
400 | + for (i = (ARRAY_SIZE(video_control) - 1); i >= 0; i--) | ||
401 | + if (video_control[i].qc.id == id) | ||
402 | + break; | ||
403 | + | ||
404 | + if (i < 0) | ||
405 | + i = -EINVAL; | ||
406 | + | ||
407 | + return i; | ||
408 | +} | ||
409 | + | ||
410 | +static int find_next_vctrl(int id) | ||
411 | +{ | ||
412 | + int i; | ||
413 | + u32 best = (u32)-1; | ||
414 | + | ||
415 | + for (i = 0; i < ARRAY_SIZE(video_control); i++) { | ||
416 | + if (video_control[i].qc.id > id && | ||
417 | + (best == (u32)-1 || | ||
418 | + video_control[i].qc.id < | ||
419 | + video_control[best].qc.id)) { | ||
420 | + best = i; | ||
421 | + } | ||
422 | + } | ||
423 | + | ||
424 | + if (best == (u32)-1) | ||
425 | + return -EINVAL; | ||
426 | + | ||
427 | + return best; | ||
428 | +} | ||
429 | + | ||
430 | +/** | ||
431 | + * find_vmenu - Returns index of the menu array of the requested ctrl option. | ||
432 | + * @id: Requested control ID. | ||
433 | + * @index: Requested menu option index. | ||
434 | + * | ||
435 | + * Returns 0 if successful, -EINVAL if not found, or -EDOM if its out of | ||
436 | + * domain. | ||
437 | + **/ | ||
438 | +static int find_vmenu(int id, int index) | ||
439 | +{ | ||
440 | + int i; | ||
441 | + | ||
442 | + if (id < V4L2_CID_BASE) | ||
443 | + return -EDOM; | ||
444 | + | ||
445 | + for (i = (ARRAY_SIZE(video_menu) - 1); i >= 0; i--) { | ||
446 | + if (video_menu[i].id != id || video_menu[i].index != index) | ||
447 | + continue; | ||
448 | + return i; | ||
449 | + } | ||
450 | + | ||
451 | + return -EINVAL; | ||
452 | +} | ||
453 | + | ||
454 | +/** | ||
455 | + * isp_release_resources - Free ISP submodules | ||
456 | + **/ | ||
457 | +static void isp_release_resources(void) | ||
458 | +{ | ||
459 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_CCDC) | ||
460 | + ispccdc_free(); | ||
461 | + | ||
462 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_PREVIEW) | ||
463 | + isppreview_free(); | ||
464 | + | ||
465 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_RESIZER) | ||
466 | + ispresizer_free(); | ||
467 | + return; | ||
468 | +} | ||
469 | + | ||
470 | +static int isp_wait(int (*busy)(void), int wait_for_busy, int max_wait) | ||
471 | +{ | ||
472 | + int wait = 0; | ||
473 | + | ||
474 | + if (max_wait == 0) | ||
475 | + max_wait = 10000; /* 10 ms */ | ||
476 | + | ||
477 | + while ((wait_for_busy && !busy()) | ||
478 | + || (!wait_for_busy && busy())) { | ||
479 | + rmb(); | ||
480 | + udelay(1); | ||
481 | + wait++; | ||
482 | + if (wait > max_wait) { | ||
483 | + printk(KERN_ALERT "%s: wait is too much\n", __func__); | ||
484 | + return -EBUSY; | ||
485 | + } | ||
486 | + } | ||
487 | + DPRINTK_ISPCTRL(KERN_ALERT "%s: wait %d\n", __func__, wait); | ||
488 | + | ||
489 | + return 0; | ||
490 | +} | ||
491 | + | ||
492 | +static int ispccdc_sbl_wait_idle(int max_wait) | ||
493 | +{ | ||
494 | + return isp_wait(ispccdc_sbl_busy, 0, max_wait); | ||
495 | +} | ||
496 | + | ||
497 | +static void isp_enable_interrupts(int is_raw) | ||
498 | +{ | ||
499 | + isp_reg_writel(-1, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); | ||
500 | + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
501 | + IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ | | ||
502 | + IRQ0ENABLE_HS_VS_IRQ | | ||
503 | + IRQ0ENABLE_CCDC_VD0_IRQ | | ||
504 | + IRQ0ENABLE_CCDC_VD1_IRQ); | ||
505 | + | ||
506 | + if (is_raw) | ||
507 | + return; | ||
508 | + | ||
509 | + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
510 | + IRQ0ENABLE_PRV_DONE_IRQ | | ||
511 | + IRQ0ENABLE_RSZ_DONE_IRQ); | ||
512 | + | ||
513 | + return; | ||
514 | +} | ||
515 | + | ||
516 | +static void isp_disable_interrupts(void) | ||
517 | +{ | ||
518 | + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
519 | + ~(IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ | | ||
520 | + IRQ0ENABLE_HS_VS_IRQ | | ||
521 | + IRQ0ENABLE_CCDC_VD0_IRQ | | ||
522 | + IRQ0ENABLE_CCDC_VD1_IRQ | | ||
523 | + IRQ0ENABLE_PRV_DONE_IRQ | | ||
524 | + IRQ0ENABLE_RSZ_DONE_IRQ)); | ||
525 | +} | ||
526 | + | ||
527 | +/** | ||
528 | + * isp_set_callback - Sets the callback for the ISP module done events. | ||
529 | + * @type: Type of the event for which callback is requested. | ||
530 | + * @callback: Method to be called as callback in the ISR context. | ||
531 | + * @arg1: First argument to be passed when callback is called in ISR. | ||
532 | + * @arg2: Second argument to be passed when callback is called in ISR. | ||
533 | + * | ||
534 | + * This function sets a callback function for a done event in the ISP | ||
535 | + * module, and enables the corresponding interrupt. | ||
536 | + **/ | ||
537 | +int isp_set_callback(enum isp_callback_type type, isp_callback_t callback, | ||
538 | + isp_vbq_callback_ptr arg1, | ||
539 | + void *arg2) | ||
540 | +{ | ||
541 | + unsigned long irqflags = 0; | ||
542 | + | ||
543 | + if (callback == NULL) { | ||
544 | + DPRINTK_ISPCTRL("ISP_ERR : Null Callback\n"); | ||
545 | + return -EINVAL; | ||
546 | + } | ||
547 | + | ||
548 | + spin_lock_irqsave(&isp_obj.lock, irqflags); | ||
549 | + isp_obj.irq.isp_callbk[type] = callback; | ||
550 | + isp_obj.irq.isp_callbk_arg1[type] = arg1; | ||
551 | + isp_obj.irq.isp_callbk_arg2[type] = arg2; | ||
552 | + spin_unlock_irqrestore(&isp_obj.lock, irqflags); | ||
553 | + | ||
554 | + switch (type) { | ||
555 | + case CBK_H3A_AWB_DONE: | ||
556 | + isp_reg_writel(IRQ0ENABLE_H3A_AWB_DONE_IRQ, | ||
557 | + OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); | ||
558 | + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
559 | + IRQ0ENABLE_H3A_AWB_DONE_IRQ); | ||
560 | + break; | ||
561 | + case CBK_H3A_AF_DONE: | ||
562 | + isp_reg_writel(IRQ0ENABLE_H3A_AF_DONE_IRQ, | ||
563 | + OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); | ||
564 | + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
565 | + IRQ0ENABLE_H3A_AF_DONE_IRQ); | ||
566 | + break; | ||
567 | + case CBK_HIST_DONE: | ||
568 | + isp_reg_writel(IRQ0ENABLE_HIST_DONE_IRQ, | ||
569 | + OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); | ||
570 | + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
571 | + IRQ0ENABLE_HIST_DONE_IRQ); | ||
572 | + break; | ||
573 | + case CBK_PREV_DONE: | ||
574 | + isp_reg_writel(IRQ0ENABLE_PRV_DONE_IRQ, | ||
575 | + OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); | ||
576 | + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
577 | + IRQ0ENABLE_PRV_DONE_IRQ); | ||
578 | + break; | ||
579 | + default: | ||
580 | + break; | ||
581 | + } | ||
582 | + | ||
583 | + return 0; | ||
584 | +} | ||
585 | +EXPORT_SYMBOL(isp_set_callback); | ||
586 | + | ||
587 | +/** | ||
588 | + * isp_unset_callback - Clears the callback for the ISP module done events. | ||
589 | + * @type: Type of the event for which callback to be cleared. | ||
590 | + * | ||
591 | + * This function clears a callback function for a done event in the ISP | ||
592 | + * module, and disables the corresponding interrupt. | ||
593 | + **/ | ||
594 | +int isp_unset_callback(enum isp_callback_type type) | ||
595 | +{ | ||
596 | + unsigned long irqflags = 0; | ||
597 | + | ||
598 | + spin_lock_irqsave(&isp_obj.lock, irqflags); | ||
599 | + isp_obj.irq.isp_callbk[type] = NULL; | ||
600 | + isp_obj.irq.isp_callbk_arg1[type] = NULL; | ||
601 | + isp_obj.irq.isp_callbk_arg2[type] = NULL; | ||
602 | + spin_unlock_irqrestore(&isp_obj.lock, irqflags); | ||
603 | + | ||
604 | + switch (type) { | ||
605 | + case CBK_H3A_AWB_DONE: | ||
606 | + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
607 | + ~IRQ0ENABLE_H3A_AWB_DONE_IRQ); | ||
608 | + break; | ||
609 | + case CBK_H3A_AF_DONE: | ||
610 | + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
611 | + ~IRQ0ENABLE_H3A_AF_DONE_IRQ); | ||
612 | + break; | ||
613 | + case CBK_HIST_DONE: | ||
614 | + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
615 | + ~IRQ0ENABLE_HIST_DONE_IRQ); | ||
616 | + break; | ||
617 | + case CBK_CSIA: | ||
618 | + isp_csi2_irq_set(0); | ||
619 | + break; | ||
620 | + case CBK_CSIB: | ||
621 | + isp_reg_writel(IRQ0ENABLE_CSIB_IRQ, OMAP3_ISP_IOMEM_MAIN, | ||
622 | + ISP_IRQ0STATUS); | ||
623 | + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
624 | + IRQ0ENABLE_CSIB_IRQ); | ||
625 | + break; | ||
626 | + case CBK_PREV_DONE: | ||
627 | + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
628 | + ~IRQ0ENABLE_PRV_DONE_IRQ); | ||
629 | + break; | ||
630 | + default: | ||
631 | + break; | ||
632 | + } | ||
633 | + | ||
634 | + return 0; | ||
635 | +} | ||
636 | +EXPORT_SYMBOL(isp_unset_callback); | ||
637 | + | ||
638 | +/** | ||
639 | + * isp_set_xclk - Configures the specified cam_xclk to the desired frequency. | ||
640 | + * @xclk: Desired frequency of the clock in Hz. | ||
641 | + * @xclksel: XCLK to configure (0 = A, 1 = B). | ||
642 | + * | ||
643 | + * Configures the specified MCLK divisor in the ISP timing control register | ||
644 | + * (TCTRL_CTRL) to generate the desired xclk clock value. | ||
645 | + * | ||
646 | + * Divisor = CM_CAM_MCLK_HZ / xclk | ||
647 | + * | ||
648 | + * Returns the final frequency that is actually being generated | ||
649 | + **/ | ||
650 | +u32 isp_set_xclk(u32 xclk, u8 xclksel) | ||
651 | +{ | ||
652 | + u32 divisor; | ||
653 | + u32 currentxclk; | ||
654 | + | ||
655 | + if (xclk >= CM_CAM_MCLK_HZ) { | ||
656 | + divisor = ISPTCTRL_CTRL_DIV_BYPASS; | ||
657 | + currentxclk = CM_CAM_MCLK_HZ; | ||
658 | + } else if (xclk >= 2) { | ||
659 | + divisor = CM_CAM_MCLK_HZ / xclk; | ||
660 | + if (divisor >= ISPTCTRL_CTRL_DIV_BYPASS) | ||
661 | + divisor = ISPTCTRL_CTRL_DIV_BYPASS - 1; | ||
662 | + currentxclk = CM_CAM_MCLK_HZ / divisor; | ||
663 | + } else { | ||
664 | + divisor = xclk; | ||
665 | + currentxclk = 0; | ||
666 | + } | ||
667 | + | ||
668 | + switch (xclksel) { | ||
669 | + case 0: | ||
670 | + isp_reg_and_or(OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, | ||
671 | + ~ISPTCTRL_CTRL_DIVA_MASK, | ||
672 | + divisor << ISPTCTRL_CTRL_DIVA_SHIFT); | ||
673 | + DPRINTK_ISPCTRL("isp_set_xclk(): cam_xclka set to %d Hz\n", | ||
674 | + currentxclk); | ||
675 | + break; | ||
676 | + case 1: | ||
677 | + isp_reg_and_or(OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, | ||
678 | + ~ISPTCTRL_CTRL_DIVB_MASK, | ||
679 | + divisor << ISPTCTRL_CTRL_DIVB_SHIFT); | ||
680 | + DPRINTK_ISPCTRL("isp_set_xclk(): cam_xclkb set to %d Hz\n", | ||
681 | + currentxclk); | ||
682 | + break; | ||
683 | + default: | ||
684 | + DPRINTK_ISPCTRL("ISP_ERR: isp_set_xclk(): Invalid requested " | ||
685 | + "xclk. Must be 0 (A) or 1 (B)." | ||
686 | + "\n"); | ||
687 | + return -EINVAL; | ||
688 | + } | ||
689 | + | ||
690 | + return currentxclk; | ||
691 | +} | ||
692 | +EXPORT_SYMBOL(isp_set_xclk); | ||
693 | + | ||
694 | +/** | ||
695 | + * isp_power_settings - Sysconfig settings, for Power Management. | ||
696 | + * @isp_sysconfig: Structure containing the power settings for ISP to configure | ||
697 | + * | ||
698 | + * Sets the power settings for the ISP, and SBL bus. | ||
699 | + **/ | ||
700 | +static void isp_power_settings(int idle) | ||
701 | +{ | ||
702 | + if (idle) { | ||
703 | + isp_reg_writel(ISP_SYSCONFIG_AUTOIDLE | | ||
704 | + (ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY << | ||
705 | + ISP_SYSCONFIG_MIDLEMODE_SHIFT), | ||
706 | + OMAP3_ISP_IOMEM_MAIN, | ||
707 | + ISP_SYSCONFIG); | ||
708 | + if (omap_rev() == OMAP3430_REV_ES1_0) { | ||
709 | + isp_reg_writel(ISPCSI1_AUTOIDLE | | ||
710 | + (ISPCSI1_MIDLEMODE_SMARTSTANDBY << | ||
711 | + ISPCSI1_MIDLEMODE_SHIFT), | ||
712 | + OMAP3_ISP_IOMEM_CSI2A, | ||
713 | + ISP_CSIA_SYSCONFIG); | ||
714 | + isp_reg_writel(ISPCSI1_AUTOIDLE | | ||
715 | + (ISPCSI1_MIDLEMODE_SMARTSTANDBY << | ||
716 | + ISPCSI1_MIDLEMODE_SHIFT), | ||
717 | + OMAP3_ISP_IOMEM_CCP2, | ||
718 | + ISP_CSIB_SYSCONFIG); | ||
719 | + } | ||
720 | + isp_reg_writel(ISPCTRL_SBL_AUTOIDLE, OMAP3_ISP_IOMEM_MAIN, | ||
721 | + ISP_CTRL); | ||
722 | + | ||
723 | + } else { | ||
724 | + isp_reg_writel(ISP_SYSCONFIG_AUTOIDLE | | ||
725 | + (ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY << | ||
726 | + ISP_SYSCONFIG_MIDLEMODE_SHIFT), | ||
727 | + OMAP3_ISP_IOMEM_MAIN, | ||
728 | + ISP_SYSCONFIG); | ||
729 | + if (omap_rev() == OMAP3430_REV_ES1_0) { | ||
730 | + isp_reg_writel(ISPCSI1_AUTOIDLE | | ||
731 | + (ISPCSI1_MIDLEMODE_FORCESTANDBY << | ||
732 | + ISPCSI1_MIDLEMODE_SHIFT), | ||
733 | + OMAP3_ISP_IOMEM_CSI2A, | ||
734 | + ISP_CSIA_SYSCONFIG); | ||
735 | + | ||
736 | + isp_reg_writel(ISPCSI1_AUTOIDLE | | ||
737 | + (ISPCSI1_MIDLEMODE_FORCESTANDBY << | ||
738 | + ISPCSI1_MIDLEMODE_SHIFT), | ||
739 | + OMAP3_ISP_IOMEM_CCP2, | ||
740 | + ISP_CSIB_SYSCONFIG); | ||
741 | + } | ||
742 | + | ||
743 | + isp_reg_writel(ISPCTRL_SBL_AUTOIDLE, OMAP3_ISP_IOMEM_MAIN, | ||
744 | + ISP_CTRL); | ||
745 | + } | ||
746 | +} | ||
747 | + | ||
748 | +#define BIT_SET(var, shift, mask, val) \ | ||
749 | + do { \ | ||
750 | + var = (var & ~(mask << shift)) \ | ||
751 | + | (val << shift); \ | ||
752 | + } while (0) | ||
753 | + | ||
754 | +static int isp_init_csi(struct isp_interface_config *config) | ||
755 | +{ | ||
756 | + u32 i = 0, val, reg; | ||
757 | + int format; | ||
758 | + | ||
759 | + switch (config->u.csi.format) { | ||
760 | + case V4L2_PIX_FMT_SGRBG10: | ||
761 | + format = 0x16; /* RAW10+VP */ | ||
762 | + break; | ||
763 | + case V4L2_PIX_FMT_SGRBG10DPCM8: | ||
764 | + format = 0x12; /* RAW8+DPCM10+VP */ | ||
765 | + break; | ||
766 | + default: | ||
767 | + printk(KERN_ERR "isp_init_csi: bad csi format\n"); | ||
768 | + return -EINVAL; | ||
769 | + } | ||
770 | + | ||
771 | + /* Reset the CSI and wait for reset to complete */ | ||
772 | + isp_reg_writel(isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_SYSCONFIG) | | ||
773 | + BIT(1), | ||
774 | + OMAP3_ISP_IOMEM_CCP2, | ||
775 | + ISPCSI1_SYSCONFIG); | ||
776 | + while (!(isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_SYSSTATUS) & | ||
777 | + BIT(0))) { | ||
778 | + udelay(10); | ||
779 | + if (i++ > 10) | ||
780 | + break; | ||
781 | + } | ||
782 | + if (!(isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_SYSSTATUS) & | ||
783 | + BIT(0))) { | ||
784 | + printk(KERN_WARNING | ||
785 | + "omap3_isp: timeout waiting for csi reset\n"); | ||
786 | + } | ||
787 | + | ||
788 | + /* ISPCSI1_CTRL */ | ||
789 | + val = isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_CTRL); | ||
790 | + val &= ~BIT(11); /* Enable VP only off -> | ||
791 | + extract embedded data to interconnect */ | ||
792 | + BIT_SET(val, 8, 0x3, config->u.csi.vpclk); /* Video port clock */ | ||
793 | +/* val |= BIT(3); */ /* Wait for FEC before disabling interface */ | ||
794 | + val |= BIT(2); /* I/O cell output is parallel | ||
795 | + (no effect, but errata says should be enabled | ||
796 | + for class 1/2) */ | ||
797 | + val |= BIT(12); /* VP clock polarity to falling edge | ||
798 | + (needed or bad picture!) */ | ||
799 | + | ||
800 | + /* Data/strobe physical layer */ | ||
801 | + BIT_SET(val, 1, 1, config->u.csi.signalling); | ||
802 | + BIT_SET(val, 10, 1, config->u.csi.strobe_clock_inv); | ||
803 | + val |= BIT(4); /* Magic bit to enable CSI1 and strobe mode */ | ||
804 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_CCP2, ISPCSI1_CTRL); | ||
805 | + | ||
806 | + /* ISPCSI1_LCx_CTRL logical channel #0 */ | ||
807 | + reg = ISPCSI1_LCx_CTRL(0); /* reg = ISPCSI1_CTRL1; */ | ||
808 | + val = isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, reg); | ||
809 | + /* Format = RAW10+VP or RAW8+DPCM10+VP*/ | ||
810 | + BIT_SET(val, 3, 0x1f, format); | ||
811 | + /* Enable setting of frame regions of interest */ | ||
812 | + BIT_SET(val, 1, 1, 1); | ||
813 | + BIT_SET(val, 2, 1, config->u.csi.crc); | ||
814 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_CCP2, reg); | ||
815 | + | ||
816 | + /* ISPCSI1_DAT_START for logical channel #0 */ | ||
817 | + reg = ISPCSI1_LCx_DAT_START(0); /* reg = ISPCSI1_DAT_START; */ | ||
818 | + val = isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, reg); | ||
819 | + BIT_SET(val, 16, 0xfff, config->u.csi.data_start); | ||
820 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_CCP2, reg); | ||
821 | + | ||
822 | + /* ISPCSI1_DAT_SIZE for logical channel #0 */ | ||
823 | + reg = ISPCSI1_LCx_DAT_SIZE(0); /* reg = ISPCSI1_DAT_SIZE; */ | ||
824 | + val = isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, reg); | ||
825 | + BIT_SET(val, 16, 0xfff, config->u.csi.data_size); | ||
826 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_CCP2, reg); | ||
827 | + | ||
828 | + /* Clear status bits for logical channel #0 */ | ||
829 | + isp_reg_writel(0xFFF & ~BIT(6), OMAP3_ISP_IOMEM_CCP2, | ||
830 | + ISPCSI1_LC01_IRQSTATUS); | ||
831 | + | ||
832 | + /* Enable CSI1 */ | ||
833 | + val = isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_CTRL); | ||
834 | + val |= BIT(0) | BIT(4); | ||
835 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_CCP2, ISPCSI1_CTRL); | ||
836 | + | ||
837 | + if (!(isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_CTRL) & BIT(4))) { | ||
838 | + printk(KERN_WARNING "OMAP3 CSI1 bus not available\n"); | ||
839 | + if (config->u.csi.signalling) /* Strobe mode requires CSI1 */ | ||
840 | + return -EIO; | ||
841 | + } | ||
842 | + | ||
843 | + return 0; | ||
844 | +} | ||
845 | + | ||
846 | +/** | ||
847 | + * isp_configure_interface - Configures ISP Control I/F related parameters. | ||
848 | + * @config: Pointer to structure containing the desired configuration for the | ||
849 | + * ISP. | ||
850 | + * | ||
851 | + * Configures ISP control register (ISP_CTRL) with the values specified inside | ||
852 | + * the config structure. Controls: | ||
853 | + * - Selection of parallel or serial input to the preview hardware. | ||
854 | + * - Data lane shifter. | ||
855 | + * - Pixel clock polarity. | ||
856 | + * - 8 to 16-bit bridge at the input of CCDC module. | ||
857 | + * - HS or VS synchronization signal detection | ||
858 | + **/ | ||
859 | +int isp_configure_interface(struct isp_interface_config *config) | ||
860 | +{ | ||
861 | + u32 ispctrl_val = isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL); | ||
862 | + int r; | ||
863 | + | ||
864 | + isp_obj.config = config; | ||
865 | + | ||
866 | + ispctrl_val &= ISPCTRL_SHIFT_MASK; | ||
867 | + ispctrl_val |= config->dataline_shift << ISPCTRL_SHIFT_SHIFT; | ||
868 | + ispctrl_val &= ~ISPCTRL_PAR_CLK_POL_INV; | ||
869 | + | ||
870 | + ispctrl_val &= ISPCTRL_PAR_SER_CLK_SEL_MASK; | ||
871 | + | ||
872 | + isp_buf_init(); | ||
873 | + | ||
874 | + switch (config->ccdc_par_ser) { | ||
875 | + case ISP_PARLL: | ||
876 | + ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL; | ||
877 | + ispctrl_val |= config->u.par.par_clk_pol | ||
878 | + << ISPCTRL_PAR_CLK_POL_SHIFT; | ||
879 | + ispctrl_val &= ~ISPCTRL_PAR_BRIDGE_BENDIAN; | ||
880 | + ispctrl_val |= config->u.par.par_bridge | ||
881 | + << ISPCTRL_PAR_BRIDGE_SHIFT; | ||
882 | + break; | ||
883 | + case ISP_CSIA: | ||
884 | + ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIA; | ||
885 | + ispctrl_val &= ~ISPCTRL_PAR_BRIDGE_BENDIAN; | ||
886 | + | ||
887 | + isp_csi2_ctx_config_format(0, config->u.csi.format); | ||
888 | + isp_csi2_ctx_update(0, false); | ||
889 | + | ||
890 | + if (config->u.csi.crc) | ||
891 | + isp_csi2_ctrl_config_ecc_enable(true); | ||
892 | + | ||
893 | + isp_csi2_ctrl_config_vp_out_ctrl(config->u.csi.vpclk); | ||
894 | + isp_csi2_ctrl_config_vp_only_enable(true); | ||
895 | + isp_csi2_ctrl_config_vp_clk_enable(true); | ||
896 | + isp_csi2_ctrl_update(false); | ||
897 | + | ||
898 | + isp_csi2_irq_complexio1_set(1); | ||
899 | + isp_csi2_irq_status_set(1); | ||
900 | + isp_csi2_irq_set(1); | ||
901 | + | ||
902 | + isp_csi2_enable(1); | ||
903 | + mdelay(3); | ||
904 | + break; | ||
905 | + case ISP_CSIB: | ||
906 | + ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIB; | ||
907 | + r = isp_init_csi(config); | ||
908 | + if (r) | ||
909 | + return r; | ||
910 | + break; | ||
911 | + case ISP_NONE: | ||
912 | + return 0; | ||
913 | + default: | ||
914 | + return -EINVAL; | ||
915 | + } | ||
916 | + | ||
917 | + ispctrl_val &= ~ISPCTRL_SYNC_DETECT_VSRISE; | ||
918 | + ispctrl_val |= config->hsvs_syncdetect; | ||
919 | + | ||
920 | + isp_reg_writel(ispctrl_val, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL); | ||
921 | + | ||
922 | + /* Set sensor specific fields in CCDC and Previewer module.*/ | ||
923 | + isppreview_set_skip(config->prev_sph, config->prev_slv); | ||
924 | + ispccdc_set_wenlog(config->wenlog); | ||
925 | + | ||
926 | + return 0; | ||
927 | +} | ||
928 | +EXPORT_SYMBOL(isp_configure_interface); | ||
929 | + | ||
930 | +static int isp_buf_process(struct isp_bufs *bufs); | ||
931 | + | ||
932 | +/** | ||
933 | + * omap34xx_isp_isr - Interrupt Service Routine for Camera ISP module. | ||
934 | + * @irq: Not used currently. | ||
935 | + * @ispirq_disp: Pointer to the object that is passed while request_irq is | ||
936 | + * called. This is the isp_obj.irq object containing info on the | ||
937 | + * callback. | ||
938 | + * | ||
939 | + * Handles the corresponding callback if plugged in. | ||
940 | + * | ||
941 | + * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the | ||
942 | + * IRQ wasn't handled. | ||
943 | + **/ | ||
944 | +static irqreturn_t omap34xx_isp_isr(int irq, void *_isp) | ||
945 | +{ | ||
946 | + struct isp *isp = _isp; | ||
947 | + struct isp_irq *irqdis = &isp->irq; | ||
948 | + struct isp_bufs *bufs = &isp->bufs; | ||
949 | + unsigned long flags; | ||
950 | + u32 irqstatus = 0; | ||
951 | + unsigned long irqflags = 0; | ||
952 | + int wait_hs_vs = 0; | ||
953 | + | ||
954 | + irqstatus = isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); | ||
955 | + isp_reg_writel(irqstatus, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); | ||
956 | + | ||
957 | + spin_lock_irqsave(&bufs->lock, flags); | ||
958 | + wait_hs_vs = bufs->wait_hs_vs; | ||
959 | + if (irqstatus & HS_VS && bufs->wait_hs_vs) | ||
960 | + bufs->wait_hs_vs--; | ||
961 | + spin_unlock_irqrestore(&bufs->lock, flags); | ||
962 | + | ||
963 | + spin_lock_irqsave(&isp_obj.lock, irqflags); | ||
964 | + /* | ||
965 | + * We need to wait for the first HS_VS interrupt from CCDC. | ||
966 | + * Otherwise our frame (and everything else) might be bad. | ||
967 | + */ | ||
968 | + if (wait_hs_vs) | ||
969 | + goto out_ignore_buff; | ||
970 | + | ||
971 | + if (irqstatus & CCDC_VD0) { | ||
972 | + if (RAW_CAPTURE(&isp_obj)) | ||
973 | + isp_buf_process(bufs); | ||
974 | + if (!ispccdc_busy()) | ||
975 | + ispccdc_config_shadow_registers(); | ||
976 | + } | ||
977 | + | ||
978 | + if (irqstatus & PREV_DONE) { | ||
979 | + if (irqdis->isp_callbk[CBK_PREV_DONE]) | ||
980 | + irqdis->isp_callbk[CBK_PREV_DONE]( | ||
981 | + PREV_DONE, | ||
982 | + irqdis->isp_callbk_arg1[CBK_PREV_DONE], | ||
983 | + irqdis->isp_callbk_arg2[CBK_PREV_DONE]); | ||
984 | + else if (!RAW_CAPTURE(&isp_obj) && !ispresizer_busy()) { | ||
985 | + if (isp_obj.module.applyCrop) { | ||
986 | + ispresizer_applycrop(); | ||
987 | + if (!ispresizer_busy()) | ||
988 | + isp_obj.module.applyCrop = 0; | ||
989 | + } | ||
990 | + if (!isppreview_busy()) { | ||
991 | + ispresizer_enable(1); | ||
992 | + if (isppreview_busy()) { | ||
993 | + /* FIXME: locking! */ | ||
994 | + ISP_BUF_DONE(bufs)->vb_state = | ||
995 | + VIDEOBUF_ERROR; | ||
996 | + printk(KERN_ERR "%s: can't stop" | ||
997 | + " preview\n", __func__); | ||
998 | + } | ||
999 | + } | ||
1000 | + if (!isppreview_busy()) | ||
1001 | + isppreview_config_shadow_registers(); | ||
1002 | + if (!isppreview_busy()) | ||
1003 | + isph3a_update_wb(); | ||
1004 | + } | ||
1005 | + } | ||
1006 | + | ||
1007 | + if (irqstatus & RESZ_DONE) { | ||
1008 | + if (!RAW_CAPTURE(&isp_obj)) { | ||
1009 | + if (!ispresizer_busy()) | ||
1010 | + ispresizer_config_shadow_registers(); | ||
1011 | + isp_buf_process(bufs); | ||
1012 | + } | ||
1013 | + } | ||
1014 | + | ||
1015 | + if (irqstatus & H3A_AWB_DONE) { | ||
1016 | + if (irqdis->isp_callbk[CBK_H3A_AWB_DONE]) | ||
1017 | + irqdis->isp_callbk[CBK_H3A_AWB_DONE]( | ||
1018 | + H3A_AWB_DONE, | ||
1019 | + irqdis->isp_callbk_arg1[CBK_H3A_AWB_DONE], | ||
1020 | + irqdis->isp_callbk_arg2[CBK_H3A_AWB_DONE]); | ||
1021 | + } | ||
1022 | + | ||
1023 | + if (irqstatus & HIST_DONE) { | ||
1024 | + if (irqdis->isp_callbk[CBK_HIST_DONE]) | ||
1025 | + irqdis->isp_callbk[CBK_HIST_DONE]( | ||
1026 | + HIST_DONE, | ||
1027 | + irqdis->isp_callbk_arg1[CBK_HIST_DONE], | ||
1028 | + irqdis->isp_callbk_arg2[CBK_HIST_DONE]); | ||
1029 | + } | ||
1030 | + | ||
1031 | + if (irqstatus & H3A_AF_DONE) { | ||
1032 | + if (irqdis->isp_callbk[CBK_H3A_AF_DONE]) | ||
1033 | + irqdis->isp_callbk[CBK_H3A_AF_DONE]( | ||
1034 | + H3A_AF_DONE, | ||
1035 | + irqdis->isp_callbk_arg1[CBK_H3A_AF_DONE], | ||
1036 | + irqdis->isp_callbk_arg2[CBK_H3A_AF_DONE]); | ||
1037 | + } | ||
1038 | + | ||
1039 | + | ||
1040 | +out_ignore_buff: | ||
1041 | + if (irqstatus & LSC_PRE_ERR) { | ||
1042 | + struct isp_buf *buf = ISP_BUF_DONE(bufs); | ||
1043 | + /* Mark buffer faulty. */ | ||
1044 | + buf->vb_state = VIDEOBUF_ERROR; | ||
1045 | + ispccdc_lsc_error_handler(); | ||
1046 | + printk(KERN_ERR "%s: lsc prefetch error\n", __func__); | ||
1047 | + } | ||
1048 | + | ||
1049 | + if (irqstatus & CSIA) { | ||
1050 | + struct isp_buf *buf = ISP_BUF_DONE(bufs); | ||
1051 | + isp_csi2_isr(); | ||
1052 | + buf->vb_state = VIDEOBUF_ERROR; | ||
1053 | + } | ||
1054 | + | ||
1055 | + if (irqstatus & IRQ0STATUS_CSIB_IRQ) { | ||
1056 | + u32 ispcsi1_irqstatus; | ||
1057 | + | ||
1058 | + ispcsi1_irqstatus = isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, | ||
1059 | + ISPCSI1_LC01_IRQSTATUS); | ||
1060 | + DPRINTK_ISPCTRL("%x\n", ispcsi1_irqstatus); | ||
1061 | + } | ||
1062 | + | ||
1063 | + if (irqdis->isp_callbk[CBK_CATCHALL]) { | ||
1064 | + irqdis->isp_callbk[CBK_CATCHALL]( | ||
1065 | + irqstatus, | ||
1066 | + irqdis->isp_callbk_arg1[CBK_CATCHALL], | ||
1067 | + irqdis->isp_callbk_arg2[CBK_CATCHALL]); | ||
1068 | + } | ||
1069 | + | ||
1070 | + spin_unlock_irqrestore(&isp_obj.lock, irqflags); | ||
1071 | + | ||
1072 | +#if 1 | ||
1073 | + { | ||
1074 | + static const struct { | ||
1075 | + int num; | ||
1076 | + char *name; | ||
1077 | + } bits[] = { | ||
1078 | + { 31, "HS_VS_IRQ" }, | ||
1079 | + { 30, "SEC_ERR_IRQ" }, | ||
1080 | + { 29, "OCP_ERR_IRQ" }, | ||
1081 | + { 28, "MMU_ERR_IRQ" }, | ||
1082 | + { 27, "res27" }, | ||
1083 | + { 26, "res26" }, | ||
1084 | + { 25, "OVF_IRQ" }, | ||
1085 | + { 24, "RSZ_DONE_IRQ" }, | ||
1086 | + { 23, "res23" }, | ||
1087 | + { 22, "res22" }, | ||
1088 | + { 21, "CBUFF_IRQ" }, | ||
1089 | + { 20, "PRV_DONE_IRQ" }, | ||
1090 | + { 19, "CCDC_LSC_PREFETCH_ERROR" }, | ||
1091 | + { 18, "CCDC_LSC_PREFETCH_COMPLETED" }, | ||
1092 | + { 17, "CCDC_LSC_DONE" }, | ||
1093 | + { 16, "HIST_DONE_IRQ" }, | ||
1094 | + { 15, "res15" }, | ||
1095 | + { 14, "res14" }, | ||
1096 | + { 13, "H3A_AWB_DONE_IRQ" }, | ||
1097 | + { 12, "H3A_AF_DONE_IRQ" }, | ||
1098 | + { 11, "CCDC_ERR_IRQ" }, | ||
1099 | + { 10, "CCDC_VD2_IRQ" }, | ||
1100 | + { 9, "CCDC_VD1_IRQ" }, | ||
1101 | + { 8, "CCDC_VD0_IRQ" }, | ||
1102 | + { 7, "res7" }, | ||
1103 | + { 6, "res6" }, | ||
1104 | + { 5, "res5" }, | ||
1105 | + { 4, "CSIB_IRQ" }, | ||
1106 | + { 3, "CSIB_LCM_IRQ" }, | ||
1107 | + { 2, "res2" }, | ||
1108 | + { 1, "res1" }, | ||
1109 | + { 0, "CSIA_IRQ" }, | ||
1110 | + }; | ||
1111 | + int i; | ||
1112 | + for (i = 0; i < ARRAY_SIZE(bits); i++) { | ||
1113 | + if ((1 << bits[i].num) & irqstatus) | ||
1114 | + DPRINTK_ISPCTRL("%s ", bits[i].name); | ||
1115 | + } | ||
1116 | + DPRINTK_ISPCTRL("\n"); | ||
1117 | + } | ||
1118 | +#endif | ||
1119 | + | ||
1120 | + return IRQ_HANDLED; | ||
1121 | +} | ||
1122 | + | ||
1123 | +/* Device name, needed for resource tracking layer */ | ||
1124 | +struct device_driver camera_drv = { | ||
1125 | + .name = "camera" | ||
1126 | +}; | ||
1127 | + | ||
1128 | +struct device camera_dev = { | ||
1129 | + .driver = &camera_drv, | ||
1130 | +}; | ||
1131 | + | ||
1132 | +/** | ||
1133 | + * isp_tmp_buf_free - To free allocated 10MB memory | ||
1134 | + * | ||
1135 | + **/ | ||
1136 | +static void isp_tmp_buf_free(void) | ||
1137 | +{ | ||
1138 | + if (isp_obj.tmp_buf) { | ||
1139 | + ispmmu_vfree(isp_obj.tmp_buf); | ||
1140 | + isp_obj.tmp_buf = 0; | ||
1141 | + isp_obj.tmp_buf_size = 0; | ||
1142 | + } | ||
1143 | +} | ||
1144 | + | ||
1145 | +/** | ||
1146 | + * isp_tmp_buf_alloc - To allocate a 10MB memory | ||
1147 | + * | ||
1148 | + **/ | ||
1149 | +static u32 isp_tmp_buf_alloc(size_t size) | ||
1150 | +{ | ||
1151 | + isp_tmp_buf_free(); | ||
1152 | + | ||
1153 | + printk(KERN_INFO "%s: allocating %d bytes\n", __func__, size); | ||
1154 | + | ||
1155 | + isp_obj.tmp_buf = ispmmu_vmalloc(size); | ||
1156 | + if (IS_ERR((void *)isp_obj.tmp_buf)) { | ||
1157 | + printk(KERN_ERR "ispmmu_vmap mapping failed "); | ||
1158 | + return -ENOMEM; | ||
1159 | + } | ||
1160 | + isp_obj.tmp_buf_size = size; | ||
1161 | + | ||
1162 | + isppreview_set_outaddr(isp_obj.tmp_buf); | ||
1163 | + ispresizer_set_inaddr(isp_obj.tmp_buf); | ||
1164 | + | ||
1165 | + return 0; | ||
1166 | +} | ||
1167 | + | ||
1168 | +/** | ||
1169 | + * isp_start - Starts ISP submodule | ||
1170 | + * | ||
1171 | + * Start the needed isp components assuming these components | ||
1172 | + * are configured correctly. | ||
1173 | + **/ | ||
1174 | +void isp_start(void) | ||
1175 | +{ | ||
1176 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_PREVIEW | ||
1177 | + && is_isppreview_enabled()) | ||
1178 | + isppreview_enable(1); | ||
1179 | + | ||
1180 | + return; | ||
1181 | +} | ||
1182 | +EXPORT_SYMBOL(isp_start); | ||
1183 | + | ||
1184 | +#define ISP_STATISTICS_BUSY \ | ||
1185 | + () | ||
1186 | +#define ISP_STOP_TIMEOUT msecs_to_jiffies(1000) | ||
1187 | +static int __isp_disable_modules(int suspend) | ||
1188 | +{ | ||
1189 | + unsigned long timeout = jiffies + ISP_STOP_TIMEOUT; | ||
1190 | + int reset = 0; | ||
1191 | + | ||
1192 | + /* | ||
1193 | + * We need to stop all the modules after CCDC first or they'll | ||
1194 | + * never stop since they may not get a full frame from CCDC. | ||
1195 | + */ | ||
1196 | + if (suspend) { | ||
1197 | + isp_af_suspend(); | ||
1198 | + isph3a_aewb_suspend(); | ||
1199 | + isp_hist_suspend(); | ||
1200 | + isppreview_suspend(); | ||
1201 | + ispresizer_suspend(); | ||
1202 | + } else { | ||
1203 | + isp_af_enable(0); | ||
1204 | + isph3a_aewb_enable(0); | ||
1205 | + isp_hist_enable(0); | ||
1206 | + isppreview_enable(0); | ||
1207 | + ispresizer_enable(0); | ||
1208 | + } | ||
1209 | + | ||
1210 | + timeout = jiffies + ISP_STOP_TIMEOUT; | ||
1211 | + while (isp_af_busy() | ||
1212 | + || isph3a_aewb_busy() | ||
1213 | + || isp_hist_busy() | ||
1214 | + || isppreview_busy() | ||
1215 | + || ispresizer_busy()) { | ||
1216 | + if (time_after(jiffies, timeout)) { | ||
1217 | + printk(KERN_ERR "%s: can't stop non-ccdc modules\n", | ||
1218 | + __func__); | ||
1219 | + reset = 1; | ||
1220 | + break; | ||
1221 | + } | ||
1222 | + msleep(1); | ||
1223 | + } | ||
1224 | + | ||
1225 | + /* Let's stop CCDC now. */ | ||
1226 | + if (suspend) | ||
1227 | + /* This function supends lsc too */ | ||
1228 | + ispccdc_suspend(); | ||
1229 | + else { | ||
1230 | + ispccdc_enable_lsc(0); | ||
1231 | + ispccdc_enable(0); | ||
1232 | + } | ||
1233 | + | ||
1234 | + timeout = jiffies + ISP_STOP_TIMEOUT; | ||
1235 | + while (ispccdc_busy()) { | ||
1236 | + if (time_after(jiffies, timeout)) { | ||
1237 | + printk(KERN_ERR "%s: can't stop ccdc\n", __func__); | ||
1238 | + reset = 1; | ||
1239 | + break; | ||
1240 | + } | ||
1241 | + msleep(1); | ||
1242 | + } | ||
1243 | + | ||
1244 | + return reset; | ||
1245 | +} | ||
1246 | + | ||
1247 | +static int isp_stop_modules(void) | ||
1248 | +{ | ||
1249 | + return __isp_disable_modules(0); | ||
1250 | +} | ||
1251 | + | ||
1252 | +static int isp_suspend_modules(void) | ||
1253 | +{ | ||
1254 | + return __isp_disable_modules(1); | ||
1255 | +} | ||
1256 | + | ||
1257 | +static void isp_resume_modules(void) | ||
1258 | +{ | ||
1259 | + ispresizer_resume(); | ||
1260 | + isppreview_resume(); | ||
1261 | + isp_hist_resume(); | ||
1262 | + isph3a_aewb_resume(); | ||
1263 | + isp_af_resume(); | ||
1264 | + ispccdc_resume(); | ||
1265 | +} | ||
1266 | + | ||
1267 | +static void isp_reset(void) | ||
1268 | +{ | ||
1269 | + unsigned long timeout = 0; | ||
1270 | + | ||
1271 | + isp_reg_writel(isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG) | ||
1272 | + | ISP_SYSCONFIG_SOFTRESET, | ||
1273 | + OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG); | ||
1274 | + while (!(isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_SYSSTATUS) & 0x1)) { | ||
1275 | + if (timeout++ > 10000) { | ||
1276 | + printk(KERN_ALERT "%s: cannot reset ISP\n", __func__); | ||
1277 | + break; | ||
1278 | + } | ||
1279 | + udelay(1); | ||
1280 | + } | ||
1281 | +} | ||
1282 | + | ||
1283 | +/** | ||
1284 | + * isp_stop - Stops isp submodules | ||
1285 | + **/ | ||
1286 | +void isp_stop() | ||
1287 | +{ | ||
1288 | + int reset; | ||
1289 | + | ||
1290 | + isp_disable_interrupts(); | ||
1291 | + reset = isp_stop_modules(); | ||
1292 | + isp_buf_init(); | ||
1293 | + if (!reset) | ||
1294 | + return; | ||
1295 | + | ||
1296 | + isp_save_ctx(); | ||
1297 | + isp_reset(); | ||
1298 | + isp_restore_ctx(); | ||
1299 | +} | ||
1300 | +EXPORT_SYMBOL(isp_stop); | ||
1301 | + | ||
1302 | +static void isp_set_buf(struct isp_buf *buf) | ||
1303 | +{ | ||
1304 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_RESIZER | ||
1305 | + && is_ispresizer_enabled()) | ||
1306 | + ispresizer_set_outaddr(buf->isp_addr); | ||
1307 | + else if (isp_obj.module.isp_pipeline & OMAP_ISP_CCDC) | ||
1308 | + ispccdc_set_outaddr(buf->isp_addr); | ||
1309 | + | ||
1310 | +} | ||
1311 | + | ||
1312 | +/** | ||
1313 | + * isp_calc_pipeline - Sets pipeline depending of input and output pixel format | ||
1314 | + * @pix_input: Pointer to V4L2 pixel format structure for input image. | ||
1315 | + * @pix_output: Pointer to V4L2 pixel format structure for output image. | ||
1316 | + **/ | ||
1317 | +static u32 isp_calc_pipeline(struct v4l2_pix_format *pix_input, | ||
1318 | + struct v4l2_pix_format *pix_output) | ||
1319 | +{ | ||
1320 | + isp_release_resources(); | ||
1321 | + if ((pix_input->pixelformat == V4L2_PIX_FMT_SGRBG10 | ||
1322 | + || pix_input->pixelformat == V4L2_PIX_FMT_SGRBG10DPCM8) | ||
1323 | + && pix_output->pixelformat != V4L2_PIX_FMT_SGRBG10) { | ||
1324 | + isp_obj.module.isp_pipeline = | ||
1325 | + OMAP_ISP_CCDC | OMAP_ISP_PREVIEW | OMAP_ISP_RESIZER; | ||
1326 | + ispccdc_request(); | ||
1327 | + isppreview_request(); | ||
1328 | + ispresizer_request(); | ||
1329 | + ispccdc_config_datapath(CCDC_RAW, CCDC_OTHERS_VP); | ||
1330 | + isppreview_config_datapath(PRV_RAW_CCDC, PREVIEW_MEM); | ||
1331 | + ispresizer_config_datapath(RSZ_MEM_YUV); | ||
1332 | + } else { | ||
1333 | + isp_obj.module.isp_pipeline = OMAP_ISP_CCDC; | ||
1334 | + ispccdc_request(); | ||
1335 | + if (pix_input->pixelformat == V4L2_PIX_FMT_SGRBG10 | ||
1336 | + || pix_input->pixelformat == V4L2_PIX_FMT_SGRBG10DPCM8) | ||
1337 | + ispccdc_config_datapath(CCDC_RAW, CCDC_OTHERS_VP_MEM); | ||
1338 | + else | ||
1339 | + ispccdc_config_datapath(CCDC_YUV_SYNC, | ||
1340 | + CCDC_OTHERS_MEM); | ||
1341 | + } | ||
1342 | + return 0; | ||
1343 | +} | ||
1344 | + | ||
1345 | +/** | ||
1346 | + * isp_config_pipeline - Configures the image size and ycpos for ISP submodules | ||
1347 | + * @pix_input: Pointer to V4L2 pixel format structure for input image. | ||
1348 | + * @pix_output: Pointer to V4L2 pixel format structure for output image. | ||
1349 | + * | ||
1350 | + * The configuration of ycpos depends on the output pixel format for both the | ||
1351 | + * Preview and Resizer submodules. | ||
1352 | + **/ | ||
1353 | +static void isp_config_pipeline(struct v4l2_pix_format *pix_input, | ||
1354 | + struct v4l2_pix_format *pix_output) | ||
1355 | +{ | ||
1356 | + ispccdc_config_size(isp_obj.module.ccdc_input_width, | ||
1357 | + isp_obj.module.ccdc_input_height, | ||
1358 | + isp_obj.module.ccdc_output_width, | ||
1359 | + isp_obj.module.ccdc_output_height); | ||
1360 | + | ||
1361 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_PREVIEW) { | ||
1362 | + isppreview_config_size(isp_obj.module.preview_input_width, | ||
1363 | + isp_obj.module.preview_input_height, | ||
1364 | + isp_obj.module.preview_output_width, | ||
1365 | + isp_obj.module.preview_output_height); | ||
1366 | + } | ||
1367 | + | ||
1368 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_RESIZER) { | ||
1369 | + ispresizer_config_size(isp_obj.module.resizer_input_width, | ||
1370 | + isp_obj.module.resizer_input_height, | ||
1371 | + isp_obj.module.resizer_output_width, | ||
1372 | + isp_obj.module.resizer_output_height); | ||
1373 | + } | ||
1374 | + | ||
1375 | + if (pix_output->pixelformat == V4L2_PIX_FMT_UYVY) { | ||
1376 | + isppreview_config_ycpos(YCPOS_YCrYCb); | ||
1377 | + if (is_ispresizer_enabled()) | ||
1378 | + ispresizer_config_ycpos(0); | ||
1379 | + } else { | ||
1380 | + isppreview_config_ycpos(YCPOS_CrYCbY); | ||
1381 | + if (is_ispresizer_enabled()) | ||
1382 | + ispresizer_config_ycpos(1); | ||
1383 | + } | ||
1384 | + | ||
1385 | + return; | ||
1386 | +} | ||
1387 | + | ||
1388 | +static void isp_buf_init(void) | ||
1389 | +{ | ||
1390 | + struct isp_bufs *bufs = &isp_obj.bufs; | ||
1391 | + int sg; | ||
1392 | + | ||
1393 | + bufs->queue = 0; | ||
1394 | + bufs->done = 0; | ||
1395 | + bufs->wait_hs_vs = isp_obj.config->wait_hs_vs; | ||
1396 | + for (sg = 0; sg < NUM_BUFS; sg++) { | ||
1397 | + bufs->buf[sg].complete = NULL; | ||
1398 | + bufs->buf[sg].vb = NULL; | ||
1399 | + bufs->buf[sg].priv = NULL; | ||
1400 | + } | ||
1401 | +} | ||
1402 | + | ||
1403 | +/** | ||
1404 | + * isp_vbq_sync - Walks the pages table and flushes the cache for | ||
1405 | + * each page. | ||
1406 | + **/ | ||
1407 | +static int isp_vbq_sync(struct videobuf_buffer *vb, int when) | ||
1408 | +{ | ||
1409 | + flush_cache_all(); | ||
1410 | + | ||
1411 | + return 0; | ||
1412 | +} | ||
1413 | + | ||
1414 | +static int isp_buf_process(struct isp_bufs *bufs) | ||
1415 | +{ | ||
1416 | + struct isp_buf *buf = NULL; | ||
1417 | + unsigned long flags; | ||
1418 | + int last; | ||
1419 | + | ||
1420 | + spin_lock_irqsave(&bufs->lock, flags); | ||
1421 | + | ||
1422 | + if (ISP_BUFS_IS_EMPTY(bufs)) | ||
1423 | + goto out; | ||
1424 | + | ||
1425 | + if (RAW_CAPTURE(&isp_obj) && ispccdc_sbl_wait_idle(1000)) { | ||
1426 | + printk(KERN_ERR "ccdc %d won't become idle!\n", | ||
1427 | + RAW_CAPTURE(&isp_obj)); | ||
1428 | + goto out; | ||
1429 | + } | ||
1430 | + | ||
1431 | + /* We had at least one buffer in queue. */ | ||
1432 | + buf = ISP_BUF_DONE(bufs); | ||
1433 | + last = ISP_BUFS_IS_LAST(bufs); | ||
1434 | + | ||
1435 | + if (!last) { | ||
1436 | + /* Set new buffer address. */ | ||
1437 | + isp_set_buf(ISP_BUF_NEXT_DONE(bufs)); | ||
1438 | + } else { | ||
1439 | + /* Tell ISP not to write any of our buffers. */ | ||
1440 | + isp_disable_interrupts(); | ||
1441 | + if (RAW_CAPTURE(&isp_obj)) | ||
1442 | + ispccdc_enable(0); | ||
1443 | + else | ||
1444 | + ispresizer_enable(0); | ||
1445 | + /* | ||
1446 | + * We must wait for the HS_VS since before that the | ||
1447 | + * CCDC may trigger interrupts even if it's not | ||
1448 | + * receiving a frame. | ||
1449 | + */ | ||
1450 | + bufs->wait_hs_vs = isp_obj.config->wait_hs_vs; | ||
1451 | + } | ||
1452 | + if ((RAW_CAPTURE(&isp_obj) && ispccdc_busy()) | ||
1453 | + || (!RAW_CAPTURE(&isp_obj) && ispresizer_busy())) { | ||
1454 | + /* | ||
1455 | + * Next buffer available: for the transfer to succeed, the | ||
1456 | + * CCDC (RAW capture) or resizer (YUV capture) must be idle | ||
1457 | + * for the duration of transfer setup. Bad things happen | ||
1458 | + * otherwise! | ||
1459 | + * | ||
1460 | + * Next buffer not available: if we fail to stop the | ||
1461 | + * ISP the buffer is probably going to be bad. | ||
1462 | + */ | ||
1463 | + /* Mark this buffer faulty. */ | ||
1464 | + buf->vb_state = VIDEOBUF_ERROR; | ||
1465 | + /* Mark next faulty, too, in case we have one. */ | ||
1466 | + if (!last) { | ||
1467 | + ISP_BUF_NEXT_DONE(bufs)->vb_state = | ||
1468 | + VIDEOBUF_ERROR; | ||
1469 | + printk(KERN_ALERT "OUCH!!!\n"); | ||
1470 | + } else { | ||
1471 | + printk(KERN_ALERT "Ouch!\n"); | ||
1472 | + } | ||
1473 | + } | ||
1474 | + | ||
1475 | + /* Mark the current buffer as done. */ | ||
1476 | + ISP_BUF_MARK_DONE(bufs); | ||
1477 | + | ||
1478 | + DPRINTK_ISPCTRL(KERN_ALERT "%s: finish %d mmu %p\n", __func__, | ||
1479 | + (bufs->done - 1 + NUM_BUFS) % NUM_BUFS, | ||
1480 | + (bufs->buf+((bufs->done - 1 + NUM_BUFS) | ||
1481 | + % NUM_BUFS))->isp_addr); | ||
1482 | + | ||
1483 | +out: | ||
1484 | + spin_unlock_irqrestore(&bufs->lock, flags); | ||
1485 | + | ||
1486 | + if (buf != NULL) { | ||
1487 | + /* | ||
1488 | + * We want to dequeue a buffer from the video buffer | ||
1489 | + * queue. Let's do it! | ||
1490 | + */ | ||
1491 | + isp_vbq_sync(buf->vb, DMA_FROM_DEVICE); | ||
1492 | + buf->vb->state = buf->vb_state; | ||
1493 | + buf->complete(buf->vb, buf->priv); | ||
1494 | + } | ||
1495 | + | ||
1496 | + return 0; | ||
1497 | +} | ||
1498 | + | ||
1499 | +int isp_buf_queue(struct videobuf_buffer *vb, | ||
1500 | + void (*complete)(struct videobuf_buffer *vb, void *priv), | ||
1501 | + void *priv) | ||
1502 | +{ | ||
1503 | + unsigned long flags; | ||
1504 | + struct isp_buf *buf; | ||
1505 | + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); | ||
1506 | + const struct scatterlist *sglist = dma->sglist; | ||
1507 | + struct isp_bufs *bufs = &isp_obj.bufs; | ||
1508 | + int sglen = dma->sglen; | ||
1509 | + | ||
1510 | + BUG_ON(sglen < 0 || !sglist); | ||
1511 | + | ||
1512 | + isp_vbq_sync(vb, DMA_TO_DEVICE); | ||
1513 | + | ||
1514 | + spin_lock_irqsave(&bufs->lock, flags); | ||
1515 | + | ||
1516 | + BUG_ON(ISP_BUFS_IS_FULL(bufs)); | ||
1517 | + | ||
1518 | + buf = ISP_BUF_QUEUE(bufs); | ||
1519 | + | ||
1520 | + buf->isp_addr = bufs->isp_addr_capture[vb->i]; | ||
1521 | + buf->complete = complete; | ||
1522 | + buf->vb = vb; | ||
1523 | + buf->priv = priv; | ||
1524 | + buf->vb_state = VIDEOBUF_DONE; | ||
1525 | + | ||
1526 | + if (ISP_BUFS_IS_EMPTY(bufs)) { | ||
1527 | + isp_enable_interrupts(RAW_CAPTURE(&isp_obj)); | ||
1528 | + isp_set_buf(buf); | ||
1529 | + ispccdc_enable(1); | ||
1530 | + isp_start(); | ||
1531 | + } | ||
1532 | + | ||
1533 | + ISP_BUF_MARK_QUEUED(bufs); | ||
1534 | + | ||
1535 | + spin_unlock_irqrestore(&bufs->lock, flags); | ||
1536 | + | ||
1537 | + DPRINTK_ISPCTRL(KERN_ALERT "%s: queue %d vb %d, mmu %p\n", __func__, | ||
1538 | + (bufs->queue - 1 + NUM_BUFS) % NUM_BUFS, vb->i, | ||
1539 | + buf->isp_addr); | ||
1540 | + | ||
1541 | + return 0; | ||
1542 | +} | ||
1543 | +EXPORT_SYMBOL(isp_buf_queue); | ||
1544 | + | ||
1545 | +int isp_vbq_setup(struct videobuf_queue *vbq, unsigned int *cnt, | ||
1546 | + unsigned int *size) | ||
1547 | +{ | ||
1548 | + int rval = 0; | ||
1549 | + size_t tmp_size = PAGE_ALIGN(isp_obj.module.preview_output_width | ||
1550 | + * isp_obj.module.preview_output_height | ||
1551 | + * ISP_BYTES_PER_PIXEL); | ||
1552 | + | ||
1553 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_PREVIEW | ||
1554 | + && isp_obj.tmp_buf_size < tmp_size) | ||
1555 | + rval = isp_tmp_buf_alloc(tmp_size); | ||
1556 | + | ||
1557 | + return rval; | ||
1558 | +} | ||
1559 | +EXPORT_SYMBOL(isp_vbq_setup); | ||
1560 | + | ||
1561 | +/** | ||
1562 | + * isp_vbq_prepare - Videobuffer queue prepare. | ||
1563 | + * @vbq: Pointer to videobuf_queue structure. | ||
1564 | + * @vb: Pointer to videobuf_buffer structure. | ||
1565 | + * @field: Requested Field order for the videobuffer. | ||
1566 | + * | ||
1567 | + * Returns 0 if successful, or -EIO if the ispmmu was unable to map a | ||
1568 | + * scatter-gather linked list data space. | ||
1569 | + **/ | ||
1570 | +int isp_vbq_prepare(struct videobuf_queue *vbq, struct videobuf_buffer *vb, | ||
1571 | + enum v4l2_field field) | ||
1572 | +{ | ||
1573 | + unsigned int isp_addr; | ||
1574 | + struct videobuf_dmabuf *vdma; | ||
1575 | + struct isp_bufs *bufs = &isp_obj.bufs; | ||
1576 | + | ||
1577 | + int err = 0; | ||
1578 | + | ||
1579 | + vdma = videobuf_to_dma(vb); | ||
1580 | + | ||
1581 | + isp_addr = ispmmu_vmap(vdma->sglist, vdma->sglen); | ||
1582 | + | ||
1583 | + if (IS_ERR_VALUE(isp_addr)) | ||
1584 | + err = -EIO; | ||
1585 | + else | ||
1586 | + bufs->isp_addr_capture[vb->i] = isp_addr; | ||
1587 | + | ||
1588 | + return err; | ||
1589 | +} | ||
1590 | +EXPORT_SYMBOL(isp_vbq_prepare); | ||
1591 | + | ||
1592 | +/** | ||
1593 | + * isp_vbq_release - Videobuffer queue release. | ||
1594 | + * @vbq: Pointer to videobuf_queue structure. | ||
1595 | + * @vb: Pointer to videobuf_buffer structure. | ||
1596 | + **/ | ||
1597 | +void isp_vbq_release(struct videobuf_queue *vbq, struct videobuf_buffer *vb) | ||
1598 | +{ | ||
1599 | + struct isp_bufs *bufs = &isp_obj.bufs; | ||
1600 | + | ||
1601 | + ispmmu_vunmap(bufs->isp_addr_capture[vb->i]); | ||
1602 | + bufs->isp_addr_capture[vb->i] = (dma_addr_t)NULL; | ||
1603 | + return; | ||
1604 | +} | ||
1605 | +EXPORT_SYMBOL(isp_vbq_release); | ||
1606 | + | ||
1607 | +/** | ||
1608 | + * isp_queryctrl - Query V4L2 control from existing controls in ISP. | ||
1609 | + * @a: Pointer to v4l2_queryctrl structure. It only needs the id field filled. | ||
1610 | + * | ||
1611 | + * Returns 0 if successful, or -EINVAL if not found in ISP. | ||
1612 | + **/ | ||
1613 | +int isp_queryctrl(struct v4l2_queryctrl *a) | ||
1614 | +{ | ||
1615 | + int i; | ||
1616 | + | ||
1617 | + if (a->id & V4L2_CTRL_FLAG_NEXT_CTRL) { | ||
1618 | + a->id &= ~V4L2_CTRL_FLAG_NEXT_CTRL; | ||
1619 | + i = find_next_vctrl(a->id); | ||
1620 | + } else { | ||
1621 | + i = find_vctrl(a->id); | ||
1622 | + } | ||
1623 | + | ||
1624 | + if (i < 0) | ||
1625 | + return -EINVAL; | ||
1626 | + | ||
1627 | + *a = video_control[i].qc; | ||
1628 | + return 0; | ||
1629 | +} | ||
1630 | +EXPORT_SYMBOL(isp_queryctrl); | ||
1631 | + | ||
1632 | +/** | ||
1633 | + * isp_queryctrl - Query V4L2 control from existing controls in ISP. | ||
1634 | + * @a: Pointer to v4l2_queryctrl structure. It only needs the id field filled. | ||
1635 | + * | ||
1636 | + * Returns 0 if successful, or -EINVAL if not found in ISP. | ||
1637 | + **/ | ||
1638 | +int isp_querymenu(struct v4l2_querymenu *a) | ||
1639 | +{ | ||
1640 | + int i; | ||
1641 | + | ||
1642 | + i = find_vmenu(a->id, a->index); | ||
1643 | + | ||
1644 | + if (i < 0) | ||
1645 | + return -EINVAL; | ||
1646 | + | ||
1647 | + *a = video_menu[i]; | ||
1648 | + return 0; | ||
1649 | +} | ||
1650 | +EXPORT_SYMBOL(isp_querymenu); | ||
1651 | + | ||
1652 | +/** | ||
1653 | + * isp_g_ctrl - Gets value of the desired V4L2 control. | ||
1654 | + * @a: V4L2 control to read actual value from. | ||
1655 | + * | ||
1656 | + * Return 0 if successful, or -EINVAL if chosen control is not found. | ||
1657 | + **/ | ||
1658 | +int isp_g_ctrl(struct v4l2_control *a) | ||
1659 | +{ | ||
1660 | + u8 current_value; | ||
1661 | + int rval = 0; | ||
1662 | + | ||
1663 | + if (!isp_obj.ref_count) | ||
1664 | + return -EINVAL; | ||
1665 | + | ||
1666 | + switch (a->id) { | ||
1667 | + case V4L2_CID_BRIGHTNESS: | ||
1668 | + isppreview_query_brightness(¤t_value); | ||
1669 | + a->value = current_value / ISPPRV_BRIGHT_UNITS; | ||
1670 | + break; | ||
1671 | + case V4L2_CID_CONTRAST: | ||
1672 | + isppreview_query_contrast(¤t_value); | ||
1673 | + a->value = current_value / ISPPRV_CONTRAST_UNITS; | ||
1674 | + break; | ||
1675 | + case V4L2_CID_COLORFX: | ||
1676 | + isppreview_get_color(¤t_value); | ||
1677 | + a->value = current_value; | ||
1678 | + break; | ||
1679 | + default: | ||
1680 | + rval = -EINVAL; | ||
1681 | + break; | ||
1682 | + } | ||
1683 | + | ||
1684 | + return rval; | ||
1685 | +} | ||
1686 | +EXPORT_SYMBOL(isp_g_ctrl); | ||
1687 | + | ||
1688 | +/** | ||
1689 | + * isp_s_ctrl - Sets value of the desired V4L2 control. | ||
1690 | + * @a: V4L2 control to read actual value from. | ||
1691 | + * | ||
1692 | + * Return 0 if successful, -EINVAL if chosen control is not found or value | ||
1693 | + * is out of bounds, -EFAULT if copy_from_user or copy_to_user operation fails | ||
1694 | + * from camera abstraction layer related controls or the transfered user space | ||
1695 | + * pointer via the value field is not set properly. | ||
1696 | + **/ | ||
1697 | +int isp_s_ctrl(struct v4l2_control *a) | ||
1698 | +{ | ||
1699 | + int rval = 0; | ||
1700 | + u8 new_value = a->value; | ||
1701 | + | ||
1702 | + if (!isp_obj.ref_count) | ||
1703 | + return -EINVAL; | ||
1704 | + | ||
1705 | + switch (a->id) { | ||
1706 | + case V4L2_CID_BRIGHTNESS: | ||
1707 | + if (new_value > ISPPRV_BRIGHT_HIGH) | ||
1708 | + rval = -EINVAL; | ||
1709 | + else | ||
1710 | + isppreview_update_brightness(&new_value); | ||
1711 | + break; | ||
1712 | + case V4L2_CID_CONTRAST: | ||
1713 | + if (new_value > ISPPRV_CONTRAST_HIGH) | ||
1714 | + rval = -EINVAL; | ||
1715 | + else | ||
1716 | + isppreview_update_contrast(&new_value); | ||
1717 | + break; | ||
1718 | + case V4L2_CID_COLORFX: | ||
1719 | + if (new_value > V4L2_COLORFX_SEPIA) | ||
1720 | + rval = -EINVAL; | ||
1721 | + else | ||
1722 | + isppreview_set_color(&new_value); | ||
1723 | + break; | ||
1724 | + default: | ||
1725 | + rval = -EINVAL; | ||
1726 | + break; | ||
1727 | + } | ||
1728 | + | ||
1729 | + return rval; | ||
1730 | +} | ||
1731 | +EXPORT_SYMBOL(isp_s_ctrl); | ||
1732 | + | ||
1733 | +/** | ||
1734 | + * isp_handle_private - Handle all private ioctls for isp module. | ||
1735 | + * @cmd: ioctl cmd value | ||
1736 | + * @arg: ioctl arg value | ||
1737 | + * | ||
1738 | + * Return 0 if successful, -EINVAL if chosen cmd value is not handled or value | ||
1739 | + * is out of bounds, -EFAULT if ioctl arg value is not valid. | ||
1740 | + * Function simply routes the input ioctl cmd id to the appropriate handler in | ||
1741 | + * the isp module. | ||
1742 | + **/ | ||
1743 | +int isp_handle_private(int cmd, void *arg) | ||
1744 | +{ | ||
1745 | + int rval = 0; | ||
1746 | + | ||
1747 | + if (!isp_obj.ref_count) | ||
1748 | + return -EINVAL; | ||
1749 | + | ||
1750 | + switch (cmd) { | ||
1751 | + case VIDIOC_PRIVATE_ISP_CCDC_CFG: | ||
1752 | + rval = omap34xx_isp_ccdc_config(arg); | ||
1753 | + break; | ||
1754 | + case VIDIOC_PRIVATE_ISP_PRV_CFG: | ||
1755 | + rval = omap34xx_isp_preview_config(arg); | ||
1756 | + break; | ||
1757 | + case VIDIOC_PRIVATE_ISP_AEWB_CFG: { | ||
1758 | + struct isph3a_aewb_config *params; | ||
1759 | + params = (struct isph3a_aewb_config *)arg; | ||
1760 | + rval = isph3a_aewb_configure(params); | ||
1761 | + } | ||
1762 | + break; | ||
1763 | + case VIDIOC_PRIVATE_ISP_AEWB_REQ: { | ||
1764 | + struct isph3a_aewb_data *data; | ||
1765 | + data = (struct isph3a_aewb_data *)arg; | ||
1766 | + rval = isph3a_aewb_request_statistics(data); | ||
1767 | + } | ||
1768 | + break; | ||
1769 | + case VIDIOC_PRIVATE_ISP_HIST_CFG: { | ||
1770 | + struct isp_hist_config *params; | ||
1771 | + params = (struct isp_hist_config *)arg; | ||
1772 | + rval = isp_hist_configure(params); | ||
1773 | + } | ||
1774 | + break; | ||
1775 | + case VIDIOC_PRIVATE_ISP_HIST_REQ: { | ||
1776 | + struct isp_hist_data *data; | ||
1777 | + data = (struct isp_hist_data *)arg; | ||
1778 | + rval = isp_hist_request_statistics(data); | ||
1779 | + } | ||
1780 | + break; | ||
1781 | + case VIDIOC_PRIVATE_ISP_AF_CFG: { | ||
1782 | + struct af_configuration *params; | ||
1783 | + params = (struct af_configuration *)arg; | ||
1784 | + rval = isp_af_configure(params); | ||
1785 | + } | ||
1786 | + break; | ||
1787 | + case VIDIOC_PRIVATE_ISP_AF_REQ: { | ||
1788 | + struct isp_af_data *data; | ||
1789 | + data = (struct isp_af_data *)arg; | ||
1790 | + rval = isp_af_request_statistics(data); | ||
1791 | + } | ||
1792 | + break; | ||
1793 | + default: | ||
1794 | + rval = -EINVAL; | ||
1795 | + break; | ||
1796 | + } | ||
1797 | + return rval; | ||
1798 | +} | ||
1799 | +EXPORT_SYMBOL(isp_handle_private); | ||
1800 | + | ||
1801 | +/** | ||
1802 | + * isp_enum_fmt_cap - Gets more information of chosen format index and type | ||
1803 | + * @f: Pointer to structure containing index and type of format to read from. | ||
1804 | + * | ||
1805 | + * Returns 0 if successful, or -EINVAL if format index or format type is | ||
1806 | + * invalid. | ||
1807 | + **/ | ||
1808 | +int isp_enum_fmt_cap(struct v4l2_fmtdesc *f) | ||
1809 | +{ | ||
1810 | + int index = f->index; | ||
1811 | + enum v4l2_buf_type type = f->type; | ||
1812 | + int rval = -EINVAL; | ||
1813 | + | ||
1814 | + if (index >= NUM_ISP_CAPTURE_FORMATS) | ||
1815 | + goto err; | ||
1816 | + | ||
1817 | + memset(f, 0, sizeof(*f)); | ||
1818 | + f->index = index; | ||
1819 | + f->type = type; | ||
1820 | + | ||
1821 | + switch (f->type) { | ||
1822 | + case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
1823 | + rval = 0; | ||
1824 | + break; | ||
1825 | + default: | ||
1826 | + goto err; | ||
1827 | + } | ||
1828 | + | ||
1829 | + f->flags = isp_formats[index].flags; | ||
1830 | + strncpy(f->description, isp_formats[index].description, | ||
1831 | + sizeof(f->description)); | ||
1832 | + f->pixelformat = isp_formats[index].pixelformat; | ||
1833 | +err: | ||
1834 | + return rval; | ||
1835 | +} | ||
1836 | +EXPORT_SYMBOL(isp_enum_fmt_cap); | ||
1837 | + | ||
1838 | +/** | ||
1839 | + * isp_g_fmt_cap - Gets current output image format. | ||
1840 | + * @f: Pointer to V4L2 format structure to be filled with current output format | ||
1841 | + **/ | ||
1842 | +void isp_g_fmt_cap(struct v4l2_pix_format *pix) | ||
1843 | +{ | ||
1844 | + *pix = isp_obj.module.pix; | ||
1845 | + return; | ||
1846 | +} | ||
1847 | +EXPORT_SYMBOL(isp_g_fmt_cap); | ||
1848 | + | ||
1849 | +/** | ||
1850 | + * isp_s_fmt_cap - Sets I/O formats and crop and configures pipeline in ISP | ||
1851 | + * @f: Pointer to V4L2 format structure to be filled with current output format | ||
1852 | + * | ||
1853 | + * Returns 0 if successful, or return value of either isp_try_size or | ||
1854 | + * isp_try_fmt if there is an error. | ||
1855 | + **/ | ||
1856 | +int isp_s_fmt_cap(struct v4l2_pix_format *pix_input, | ||
1857 | + struct v4l2_pix_format *pix_output) | ||
1858 | +{ | ||
1859 | + int crop_scaling_w = 0, crop_scaling_h = 0; | ||
1860 | + int rval = 0; | ||
1861 | + | ||
1862 | + if (!isp_obj.ref_count) | ||
1863 | + return -EINVAL; | ||
1864 | + | ||
1865 | + rval = isp_calc_pipeline(pix_input, pix_output); | ||
1866 | + if (rval) | ||
1867 | + goto out; | ||
1868 | + | ||
1869 | + rval = isp_try_size(pix_input, pix_output); | ||
1870 | + if (rval) | ||
1871 | + goto out; | ||
1872 | + | ||
1873 | + rval = isp_try_fmt(pix_input, pix_output); | ||
1874 | + if (rval) | ||
1875 | + goto out; | ||
1876 | + | ||
1877 | + if (ispcroprect.width != pix_output->width) { | ||
1878 | + crop_scaling_w = 1; | ||
1879 | + ispcroprect.left = 0; | ||
1880 | + ispcroprect.width = pix_output->width; | ||
1881 | + } | ||
1882 | + | ||
1883 | + if (ispcroprect.height != pix_output->height) { | ||
1884 | + crop_scaling_h = 1; | ||
1885 | + ispcroprect.top = 0; | ||
1886 | + ispcroprect.height = pix_output->height; | ||
1887 | + } | ||
1888 | + | ||
1889 | + isp_config_pipeline(pix_input, pix_output); | ||
1890 | + | ||
1891 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_RESIZER | ||
1892 | + && (crop_scaling_h || crop_scaling_w)) | ||
1893 | + isp_config_crop(pix_output); | ||
1894 | + | ||
1895 | +out: | ||
1896 | + return rval; | ||
1897 | +} | ||
1898 | +EXPORT_SYMBOL(isp_s_fmt_cap); | ||
1899 | + | ||
1900 | +/** | ||
1901 | + * isp_config_crop - Configures crop parameters in isp resizer. | ||
1902 | + * @croppix: Pointer to V4L2 pixel format structure containing crop parameters | ||
1903 | + **/ | ||
1904 | +void isp_config_crop(struct v4l2_pix_format *croppix) | ||
1905 | +{ | ||
1906 | + u8 crop_scaling_w; | ||
1907 | + u8 crop_scaling_h; | ||
1908 | + unsigned long org_left, num_pix, new_top; | ||
1909 | + | ||
1910 | + struct v4l2_pix_format *pix = croppix; | ||
1911 | + | ||
1912 | + crop_scaling_w = (isp_obj.module.preview_output_width * 10) / | ||
1913 | + pix->width; | ||
1914 | + crop_scaling_h = (isp_obj.module.preview_output_height * 10) / | ||
1915 | + pix->height; | ||
1916 | + | ||
1917 | + cur_rect.left = (ispcroprect.left * crop_scaling_w) / 10; | ||
1918 | + cur_rect.top = (ispcroprect.top * crop_scaling_h) / 10; | ||
1919 | + cur_rect.width = (ispcroprect.width * crop_scaling_w) / 10; | ||
1920 | + cur_rect.height = (ispcroprect.height * crop_scaling_h) / 10; | ||
1921 | + | ||
1922 | + org_left = cur_rect.left; | ||
1923 | + while (((int)cur_rect.left & 0xFFFFFFF0) != (int)cur_rect.left) | ||
1924 | + (int)cur_rect.left--; | ||
1925 | + | ||
1926 | + num_pix = org_left - cur_rect.left; | ||
1927 | + new_top = (int)(num_pix * 3) / 4; | ||
1928 | + cur_rect.top = cur_rect.top - new_top; | ||
1929 | + cur_rect.height = (2 * new_top) + cur_rect.height; | ||
1930 | + | ||
1931 | + cur_rect.width = cur_rect.width + (2 * num_pix); | ||
1932 | + while (((int)cur_rect.width & 0xFFFFFFF0) != (int)cur_rect.width) | ||
1933 | + (int)cur_rect.width--; | ||
1934 | + | ||
1935 | + isp_obj.tmp_buf_offset = | ||
1936 | + cur_rect.left * 2 + | ||
1937 | + isp_obj.module.preview_output_width * 2 * cur_rect.top; | ||
1938 | + | ||
1939 | + ispresizer_trycrop(cur_rect.left, cur_rect.top, cur_rect.width, | ||
1940 | + cur_rect.height, | ||
1941 | + isp_obj.module.resizer_output_width, | ||
1942 | + isp_obj.module.resizer_output_height); | ||
1943 | + | ||
1944 | + return; | ||
1945 | +} | ||
1946 | +EXPORT_SYMBOL(isp_config_crop); | ||
1947 | + | ||
1948 | +/** | ||
1949 | + * isp_g_crop - Gets crop rectangle size and position. | ||
1950 | + * @a: Pointer to V4L2 crop structure to be filled. | ||
1951 | + * | ||
1952 | + * Always returns 0. | ||
1953 | + **/ | ||
1954 | +int isp_g_crop(struct v4l2_crop *a) | ||
1955 | +{ | ||
1956 | + struct v4l2_crop *crop = a; | ||
1957 | + | ||
1958 | + crop->c = ispcroprect; | ||
1959 | + | ||
1960 | + return 0; | ||
1961 | +} | ||
1962 | +EXPORT_SYMBOL(isp_g_crop); | ||
1963 | + | ||
1964 | +/** | ||
1965 | + * isp_s_crop - Sets crop rectangle size and position and queues crop operation | ||
1966 | + * @a: Pointer to V4L2 crop structure with desired parameters. | ||
1967 | + * @pix: Pointer to V4L2 pixel format structure with desired parameters. | ||
1968 | + * | ||
1969 | + * Returns 0 if successful, or -EINVAL if crop parameters are out of bounds. | ||
1970 | + **/ | ||
1971 | +int isp_s_crop(struct v4l2_crop *a, struct v4l2_pix_format *pix) | ||
1972 | +{ | ||
1973 | + struct v4l2_crop *crop = a; | ||
1974 | + int rval = 0; | ||
1975 | + | ||
1976 | + if (!isp_obj.ref_count) | ||
1977 | + return -EINVAL; | ||
1978 | + | ||
1979 | + if (crop->c.left < 0) | ||
1980 | + crop->c.left = 0; | ||
1981 | + if (crop->c.width < 0) | ||
1982 | + crop->c.width = 0; | ||
1983 | + if (crop->c.top < 0) | ||
1984 | + crop->c.top = 0; | ||
1985 | + if (crop->c.height < 0) | ||
1986 | + crop->c.height = 0; | ||
1987 | + | ||
1988 | + if (crop->c.left >= pix->width) | ||
1989 | + crop->c.left = pix->width - 1; | ||
1990 | + if (crop->c.top >= pix->height) | ||
1991 | + crop->c.top = pix->height - 1; | ||
1992 | + | ||
1993 | + if (crop->c.left + crop->c.width > pix->width) | ||
1994 | + crop->c.width = pix->width - crop->c.left; | ||
1995 | + if (crop->c.top + crop->c.height > pix->height) | ||
1996 | + crop->c.height = pix->height - crop->c.top; | ||
1997 | + | ||
1998 | + ispcroprect.left = crop->c.left; | ||
1999 | + ispcroprect.top = crop->c.top; | ||
2000 | + ispcroprect.width = crop->c.width; | ||
2001 | + ispcroprect.height = crop->c.height; | ||
2002 | + | ||
2003 | + isp_config_crop(pix); | ||
2004 | + | ||
2005 | + isp_obj.module.applyCrop = 1; | ||
2006 | + | ||
2007 | + return rval; | ||
2008 | +} | ||
2009 | +EXPORT_SYMBOL(isp_s_crop); | ||
2010 | + | ||
2011 | +/** | ||
2012 | + * isp_try_fmt_cap - Tries desired input/output image formats | ||
2013 | + * @pix_input: Pointer to V4L2 pixel format structure for input image. | ||
2014 | + * @pix_output: Pointer to V4L2 pixel format structure for output image. | ||
2015 | + * | ||
2016 | + * Returns 0 if successful, or return value of either isp_try_size or | ||
2017 | + * isp_try_fmt if there is an error. | ||
2018 | + **/ | ||
2019 | +int isp_try_fmt_cap(struct v4l2_pix_format *pix_input, | ||
2020 | + struct v4l2_pix_format *pix_output) | ||
2021 | +{ | ||
2022 | + int rval = 0; | ||
2023 | + | ||
2024 | + rval = isp_calc_pipeline(pix_input, pix_output); | ||
2025 | + if (rval) | ||
2026 | + goto out; | ||
2027 | + | ||
2028 | + rval = isp_try_size(pix_input, pix_output); | ||
2029 | + if (rval) | ||
2030 | + goto out; | ||
2031 | + | ||
2032 | + rval = isp_try_fmt(pix_input, pix_output); | ||
2033 | + if (rval) | ||
2034 | + goto out; | ||
2035 | + | ||
2036 | +out: | ||
2037 | + return rval; | ||
2038 | +} | ||
2039 | +EXPORT_SYMBOL(isp_try_fmt_cap); | ||
2040 | + | ||
2041 | +/** | ||
2042 | + * isp_try_size - Tries size configuration for I/O images of each ISP submodule | ||
2043 | + * @pix_input: Pointer to V4L2 pixel format structure for input image. | ||
2044 | + * @pix_output: Pointer to V4L2 pixel format structure for output image. | ||
2045 | + * | ||
2046 | + * Returns 0 if successful, or return value of ispccdc_try_size, | ||
2047 | + * isppreview_try_size, or ispresizer_try_size (depending on the pipeline | ||
2048 | + * configuration) if there is an error. | ||
2049 | + **/ | ||
2050 | +static int isp_try_size(struct v4l2_pix_format *pix_input, | ||
2051 | + struct v4l2_pix_format *pix_output) | ||
2052 | +{ | ||
2053 | + int rval = 0; | ||
2054 | + | ||
2055 | + if (pix_output->width <= ISPRSZ_MIN_OUTPUT | ||
2056 | + || pix_output->height <= ISPRSZ_MIN_OUTPUT) | ||
2057 | + return -EINVAL; | ||
2058 | + | ||
2059 | + if (pix_output->width >= ISPRSZ_MAX_OUTPUT | ||
2060 | + || pix_output->height > ISPRSZ_MAX_OUTPUT) | ||
2061 | + return -EINVAL; | ||
2062 | + | ||
2063 | + isp_obj.module.ccdc_input_width = pix_input->width; | ||
2064 | + isp_obj.module.ccdc_input_height = pix_input->height; | ||
2065 | + isp_obj.module.resizer_output_width = pix_output->width; | ||
2066 | + isp_obj.module.resizer_output_height = pix_output->height; | ||
2067 | + | ||
2068 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_CCDC) { | ||
2069 | + rval = ispccdc_try_size(isp_obj.module.ccdc_input_width, | ||
2070 | + isp_obj.module.ccdc_input_height, | ||
2071 | + &isp_obj.module.ccdc_output_width, | ||
2072 | + &isp_obj.module.ccdc_output_height); | ||
2073 | + if (rval) { | ||
2074 | + printk(KERN_ERR "ISP_ERR: The dimensions %dx%d are not" | ||
2075 | + " supported\n", pix_input->width, | ||
2076 | + pix_input->height); | ||
2077 | + return rval; | ||
2078 | + } | ||
2079 | + pix_output->width = isp_obj.module.ccdc_output_width; | ||
2080 | + pix_output->height = isp_obj.module.ccdc_output_height; | ||
2081 | + } | ||
2082 | + | ||
2083 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_PREVIEW) { | ||
2084 | + isp_obj.module.preview_input_width = | ||
2085 | + isp_obj.module.ccdc_output_width; | ||
2086 | + isp_obj.module.preview_input_height = | ||
2087 | + isp_obj.module.ccdc_output_height; | ||
2088 | + rval = isppreview_try_size( | ||
2089 | + isp_obj.module.preview_input_width, | ||
2090 | + isp_obj.module.preview_input_height, | ||
2091 | + &isp_obj.module.preview_output_width, | ||
2092 | + &isp_obj.module.preview_output_height); | ||
2093 | + if (rval) { | ||
2094 | + printk(KERN_ERR "ISP_ERR: The dimensions %dx%d are not" | ||
2095 | + " supported\n", pix_input->width, | ||
2096 | + pix_input->height); | ||
2097 | + return rval; | ||
2098 | + } | ||
2099 | + pix_output->width = isp_obj.module.preview_output_width; | ||
2100 | + pix_output->height = isp_obj.module.preview_output_height; | ||
2101 | + } | ||
2102 | + | ||
2103 | + if (isp_obj.module.isp_pipeline & OMAP_ISP_RESIZER) { | ||
2104 | + isp_obj.module.resizer_input_width = | ||
2105 | + isp_obj.module.preview_output_width; | ||
2106 | + isp_obj.module.resizer_input_height = | ||
2107 | + isp_obj.module.preview_output_height; | ||
2108 | + rval = ispresizer_try_size( | ||
2109 | + &isp_obj.module.resizer_input_width, | ||
2110 | + &isp_obj.module.resizer_input_height, | ||
2111 | + &isp_obj.module.resizer_output_width, | ||
2112 | + &isp_obj.module.resizer_output_height); | ||
2113 | + if (rval) { | ||
2114 | + printk(KERN_ERR "ISP_ERR: The dimensions %dx%d are not" | ||
2115 | + " supported\n", pix_input->width, | ||
2116 | + pix_input->height); | ||
2117 | + return rval; | ||
2118 | + } | ||
2119 | + pix_output->width = isp_obj.module.resizer_output_width; | ||
2120 | + pix_output->height = isp_obj.module.resizer_output_height; | ||
2121 | + } | ||
2122 | + | ||
2123 | + return rval; | ||
2124 | +} | ||
2125 | + | ||
2126 | +/** | ||
2127 | + * isp_try_fmt - Validates input/output format parameters. | ||
2128 | + * @pix_input: Pointer to V4L2 pixel format structure for input image. | ||
2129 | + * @pix_output: Pointer to V4L2 pixel format structure for output image. | ||
2130 | + * | ||
2131 | + * Always returns 0. | ||
2132 | + **/ | ||
2133 | +int isp_try_fmt(struct v4l2_pix_format *pix_input, | ||
2134 | + struct v4l2_pix_format *pix_output) | ||
2135 | +{ | ||
2136 | + int ifmt; | ||
2137 | + | ||
2138 | + for (ifmt = 0; ifmt < NUM_ISP_CAPTURE_FORMATS; ifmt++) { | ||
2139 | + if (pix_output->pixelformat == isp_formats[ifmt].pixelformat) | ||
2140 | + break; | ||
2141 | + } | ||
2142 | + if (ifmt == NUM_ISP_CAPTURE_FORMATS) | ||
2143 | + ifmt = 1; | ||
2144 | + pix_output->pixelformat = isp_formats[ifmt].pixelformat; | ||
2145 | + pix_output->field = V4L2_FIELD_NONE; | ||
2146 | + pix_output->bytesperline = pix_output->width * ISP_BYTES_PER_PIXEL; | ||
2147 | + pix_output->sizeimage = | ||
2148 | + PAGE_ALIGN(pix_output->bytesperline * pix_output->height); | ||
2149 | + pix_output->priv = 0; | ||
2150 | + switch (pix_output->pixelformat) { | ||
2151 | + case V4L2_PIX_FMT_YUYV: | ||
2152 | + case V4L2_PIX_FMT_UYVY: | ||
2153 | + pix_output->colorspace = V4L2_COLORSPACE_JPEG; | ||
2154 | + break; | ||
2155 | + default: | ||
2156 | + pix_output->colorspace = V4L2_COLORSPACE_SRGB; | ||
2157 | + } | ||
2158 | + | ||
2159 | + isp_obj.module.pix.pixelformat = pix_output->pixelformat; | ||
2160 | + isp_obj.module.pix.width = pix_output->width; | ||
2161 | + isp_obj.module.pix.height = pix_output->height; | ||
2162 | + isp_obj.module.pix.field = pix_output->field; | ||
2163 | + isp_obj.module.pix.bytesperline = pix_output->bytesperline; | ||
2164 | + isp_obj.module.pix.sizeimage = pix_output->sizeimage; | ||
2165 | + isp_obj.module.pix.priv = pix_output->priv; | ||
2166 | + isp_obj.module.pix.colorspace = pix_output->colorspace; | ||
2167 | + | ||
2168 | + return 0; | ||
2169 | +} | ||
2170 | +EXPORT_SYMBOL(isp_try_fmt); | ||
2171 | + | ||
2172 | +/** | ||
2173 | + * isp_save_ctx - Saves ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context. | ||
2174 | + * | ||
2175 | + * Routine for saving the context of each module in the ISP. | ||
2176 | + * CCDC, HIST, H3A, PREV, RESZ and MMU. | ||
2177 | + **/ | ||
2178 | +static void isp_save_ctx(void) | ||
2179 | +{ | ||
2180 | + isp_save_context(isp_reg_list); | ||
2181 | + ispccdc_save_context(); | ||
2182 | + ispmmu_save_context(); | ||
2183 | + isphist_save_context(); | ||
2184 | + isph3a_save_context(); | ||
2185 | + isppreview_save_context(); | ||
2186 | + ispresizer_save_context(); | ||
2187 | +} | ||
2188 | + | ||
2189 | +/** | ||
2190 | + * isp_restore_ctx - Restores ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context. | ||
2191 | + * | ||
2192 | + * Routine for restoring the context of each module in the ISP. | ||
2193 | + * CCDC, HIST, H3A, PREV, RESZ and MMU. | ||
2194 | + **/ | ||
2195 | +static void isp_restore_ctx(void) | ||
2196 | +{ | ||
2197 | + isp_restore_context(isp_reg_list); | ||
2198 | + ispccdc_restore_context(); | ||
2199 | + ispmmu_restore_context(); | ||
2200 | + isphist_restore_context(); | ||
2201 | + isph3a_restore_context(); | ||
2202 | + isppreview_restore_context(); | ||
2203 | + ispresizer_restore_context(); | ||
2204 | +} | ||
2205 | + | ||
2206 | +static int isp_enable_clocks(void) | ||
2207 | +{ | ||
2208 | + int r; | ||
2209 | + | ||
2210 | + r = clk_enable(isp_obj.cam_ick); | ||
2211 | + if (r) { | ||
2212 | + DPRINTK_ISPCTRL("ISP_ERR: clk_en for ick failed\n"); | ||
2213 | + goto out_clk_enable_ick; | ||
2214 | + } | ||
2215 | + r = clk_enable(isp_obj.cam_mclk); | ||
2216 | + if (r) { | ||
2217 | + DPRINTK_ISPCTRL("ISP_ERR: clk_en for mclk failed\n"); | ||
2218 | + goto out_clk_enable_mclk; | ||
2219 | + } | ||
2220 | + r = clk_enable(isp_obj.csi2_fck); | ||
2221 | + if (r) { | ||
2222 | + DPRINTK_ISPCTRL("ISP_ERR: clk_en for csi2_fclk" | ||
2223 | + " failed\n"); | ||
2224 | + goto out_clk_enable_csi2_fclk; | ||
2225 | + } | ||
2226 | + return 0; | ||
2227 | + | ||
2228 | +out_clk_enable_csi2_fclk: | ||
2229 | + clk_disable(isp_obj.cam_mclk); | ||
2230 | +out_clk_enable_mclk: | ||
2231 | + clk_disable(isp_obj.cam_ick); | ||
2232 | +out_clk_enable_ick: | ||
2233 | + return r; | ||
2234 | +} | ||
2235 | + | ||
2236 | +static void isp_disable_clocks(void) | ||
2237 | +{ | ||
2238 | + clk_disable(isp_obj.cam_ick); | ||
2239 | + clk_disable(isp_obj.cam_mclk); | ||
2240 | + clk_disable(isp_obj.csi2_fck); | ||
2241 | +} | ||
2242 | + | ||
2243 | +/** | ||
2244 | + * isp_get - Adquires the ISP resource. | ||
2245 | + * | ||
2246 | + * Initializes the clocks for the first acquire. | ||
2247 | + **/ | ||
2248 | +int isp_get(void) | ||
2249 | +{ | ||
2250 | + static int has_context; | ||
2251 | + int ret_err = 0; | ||
2252 | + | ||
2253 | + if (omap3isp == NULL) | ||
2254 | + return -EBUSY; | ||
2255 | + | ||
2256 | + DPRINTK_ISPCTRL("isp_get: old %d\n", isp_obj.ref_count); | ||
2257 | + mutex_lock(&(isp_obj.isp_mutex)); | ||
2258 | + if (isp_obj.ref_count == 0) { | ||
2259 | + ret_err = isp_enable_clocks(); | ||
2260 | + if (ret_err) | ||
2261 | + goto out_err; | ||
2262 | + /* We don't want to restore context before saving it! */ | ||
2263 | + if (has_context) | ||
2264 | + isp_restore_ctx(); | ||
2265 | + else | ||
2266 | + has_context = 1; | ||
2267 | + } else { | ||
2268 | + mutex_unlock(&isp_obj.isp_mutex); | ||
2269 | + return -EBUSY; | ||
2270 | + } | ||
2271 | + isp_obj.ref_count++; | ||
2272 | + mutex_unlock(&(isp_obj.isp_mutex)); | ||
2273 | + | ||
2274 | + DPRINTK_ISPCTRL("isp_get: new %d\n", isp_obj.ref_count); | ||
2275 | + return isp_obj.ref_count; | ||
2276 | + | ||
2277 | +out_err: | ||
2278 | + mutex_unlock(&(isp_obj.isp_mutex)); | ||
2279 | + return ret_err; | ||
2280 | +} | ||
2281 | +EXPORT_SYMBOL(isp_get); | ||
2282 | + | ||
2283 | +/** | ||
2284 | + * isp_put - Releases the ISP resource. | ||
2285 | + * | ||
2286 | + * Releases the clocks also for the last release. | ||
2287 | + **/ | ||
2288 | +int isp_put(void) | ||
2289 | +{ | ||
2290 | + if (omap3isp == NULL) | ||
2291 | + return -EBUSY; | ||
2292 | + | ||
2293 | + DPRINTK_ISPCTRL("isp_put: old %d\n", isp_obj.ref_count); | ||
2294 | + mutex_lock(&(isp_obj.isp_mutex)); | ||
2295 | + if (isp_obj.ref_count) { | ||
2296 | + if (--isp_obj.ref_count == 0) { | ||
2297 | + isp_save_ctx(); | ||
2298 | + isp_tmp_buf_free(); | ||
2299 | + isp_release_resources(); | ||
2300 | + isp_obj.module.isp_pipeline = 0; | ||
2301 | + isp_disable_clocks(); | ||
2302 | + memset(&ispcroprect, 0, sizeof(ispcroprect)); | ||
2303 | + memset(&cur_rect, 0, sizeof(cur_rect)); | ||
2304 | + } | ||
2305 | + } | ||
2306 | + mutex_unlock(&(isp_obj.isp_mutex)); | ||
2307 | + DPRINTK_ISPCTRL("isp_put: new %d\n", isp_obj.ref_count); | ||
2308 | + return isp_obj.ref_count; | ||
2309 | +} | ||
2310 | +EXPORT_SYMBOL(isp_put); | ||
2311 | + | ||
2312 | +/** | ||
2313 | + * isp_save_context - Saves the values of the ISP module registers. | ||
2314 | + * @reg_list: Structure containing pairs of register address and value to | ||
2315 | + * modify on OMAP. | ||
2316 | + **/ | ||
2317 | +void isp_save_context(struct isp_reg *reg_list) | ||
2318 | +{ | ||
2319 | + struct isp_reg *next = reg_list; | ||
2320 | + | ||
2321 | + for (; next->reg != ISP_TOK_TERM; next++) | ||
2322 | + next->val = isp_reg_readl(next->mmio_range, next->reg); | ||
2323 | +} | ||
2324 | +EXPORT_SYMBOL(isp_save_context); | ||
2325 | + | ||
2326 | +/** | ||
2327 | + * isp_restore_context - Restores the values of the ISP module registers. | ||
2328 | + * @reg_list: Structure containing pairs of register address and value to | ||
2329 | + * modify on OMAP. | ||
2330 | + **/ | ||
2331 | +void isp_restore_context(struct isp_reg *reg_list) | ||
2332 | +{ | ||
2333 | + struct isp_reg *next = reg_list; | ||
2334 | + | ||
2335 | + for (; next->reg != ISP_TOK_TERM; next++) | ||
2336 | + isp_reg_writel(next->val, next->mmio_range, next->reg); | ||
2337 | +} | ||
2338 | +EXPORT_SYMBOL(isp_restore_context); | ||
2339 | + | ||
2340 | +static int isp_remove(struct platform_device *pdev) | ||
2341 | +{ | ||
2342 | + struct isp_device *isp = platform_get_drvdata(pdev); | ||
2343 | + int i; | ||
2344 | + | ||
2345 | + isp_csi2_cleanup(); | ||
2346 | + isp_af_exit(); | ||
2347 | + isp_resizer_cleanup(); | ||
2348 | + isp_preview_cleanup(); | ||
2349 | + ispmmu_cleanup(); | ||
2350 | + isph3a_aewb_cleanup(); | ||
2351 | + isp_hist_cleanup(); | ||
2352 | + isp_ccdc_cleanup(); | ||
2353 | + | ||
2354 | + if (!isp) | ||
2355 | + return 0; | ||
2356 | + | ||
2357 | + clk_put(isp_obj.cam_ick); | ||
2358 | + clk_put(isp_obj.cam_mclk); | ||
2359 | + clk_put(isp_obj.csi2_fck); | ||
2360 | + | ||
2361 | + free_irq(isp->irq, &isp_obj); | ||
2362 | + | ||
2363 | + for (i = 0; i <= OMAP3_ISP_IOMEM_CSI2PHY; i++) { | ||
2364 | + if (isp->mmio_base[i]) { | ||
2365 | + iounmap((void *)isp->mmio_base[i]); | ||
2366 | + isp->mmio_base[i] = 0; | ||
2367 | + } | ||
2368 | + | ||
2369 | + if (isp->mmio_base_phys[i]) { | ||
2370 | + release_mem_region(isp->mmio_base_phys[i], | ||
2371 | + isp->mmio_size[i]); | ||
2372 | + isp->mmio_base_phys[i] = 0; | ||
2373 | + } | ||
2374 | + } | ||
2375 | + | ||
2376 | + omap3isp = NULL; | ||
2377 | + | ||
2378 | + kfree(isp); | ||
2379 | + | ||
2380 | + return 0; | ||
2381 | +} | ||
2382 | + | ||
2383 | +#ifdef CONFIG_PM | ||
2384 | + | ||
2385 | +static int isp_suspend(struct platform_device *pdev, pm_message_t state) | ||
2386 | +{ | ||
2387 | + int reset; | ||
2388 | + | ||
2389 | + mutex_lock(&(isp_obj.isp_mutex)); | ||
2390 | + DPRINTK_ISPCTRL("isp_suspend: starting\n"); | ||
2391 | + if (isp_obj.ref_count == 0) | ||
2392 | + goto out; | ||
2393 | + | ||
2394 | + isp_disable_interrupts(); | ||
2395 | + reset = isp_suspend_modules(); | ||
2396 | + isp_save_ctx(); | ||
2397 | + if (reset) | ||
2398 | + isp_reset(); | ||
2399 | + | ||
2400 | + isp_disable_clocks(); | ||
2401 | + | ||
2402 | +out: | ||
2403 | + DPRINTK_ISPCTRL("isp_suspend: done\n"); | ||
2404 | + mutex_unlock(&(isp_obj.isp_mutex)); | ||
2405 | + return 0; | ||
2406 | +} | ||
2407 | + | ||
2408 | +static int isp_resume(struct platform_device *pdev) | ||
2409 | +{ | ||
2410 | + int ret_err = 0; | ||
2411 | + | ||
2412 | + DPRINTK_ISPCTRL("isp_resume: starting\n"); | ||
2413 | + | ||
2414 | + if (omap3isp == NULL) | ||
2415 | + goto out; | ||
2416 | + | ||
2417 | + if (isp_obj.ref_count >= 0) { | ||
2418 | + ret_err = isp_enable_clocks(); | ||
2419 | + if (ret_err) | ||
2420 | + goto out; | ||
2421 | + isp_restore_ctx(); | ||
2422 | + isp_resume_modules(); | ||
2423 | + isp_enable_interrupts(RAW_CAPTURE(&isp_obj)); | ||
2424 | + isp_start(); | ||
2425 | + } | ||
2426 | + | ||
2427 | +out: | ||
2428 | + DPRINTK_ISPCTRL("isp_resume: done \n"); | ||
2429 | + return ret_err; | ||
2430 | +} | ||
2431 | + | ||
2432 | +#else | ||
2433 | + | ||
2434 | +#define isp_suspend NULL | ||
2435 | +#define isp_resume NULL | ||
2436 | + | ||
2437 | +#endif /* CONFIG_PM */ | ||
2438 | + | ||
2439 | + | ||
2440 | +static int isp_probe(struct platform_device *pdev) | ||
2441 | +{ | ||
2442 | + struct isp_device *isp; | ||
2443 | + int ret_err = 0; | ||
2444 | + int i; | ||
2445 | + | ||
2446 | + isp = kzalloc(sizeof(*isp), GFP_KERNEL); | ||
2447 | + if (!isp) { | ||
2448 | + dev_err(&pdev->dev, "could not allocate memory\n"); | ||
2449 | + return -ENOMEM; | ||
2450 | + } | ||
2451 | + | ||
2452 | + platform_set_drvdata(pdev, isp); | ||
2453 | + | ||
2454 | + isp->dev = &pdev->dev; | ||
2455 | + | ||
2456 | + for (i = 0; i <= OMAP3_ISP_IOMEM_CSI2PHY; i++) { | ||
2457 | + struct resource *mem; | ||
2458 | + /* request the mem region for the camera registers */ | ||
2459 | + mem = platform_get_resource(pdev, IORESOURCE_MEM, i); | ||
2460 | + if (!mem) { | ||
2461 | + dev_err(isp->dev, "no mem resource?\n"); | ||
2462 | + return -ENODEV; | ||
2463 | + } | ||
2464 | + | ||
2465 | + if (!request_mem_region(mem->start, mem->end - mem->start + 1, | ||
2466 | + pdev->name)) { | ||
2467 | + dev_err(isp->dev, | ||
2468 | + "cannot reserve camera register I/O region\n"); | ||
2469 | + return -ENODEV; | ||
2470 | + | ||
2471 | + } | ||
2472 | + isp->mmio_base_phys[i] = mem->start; | ||
2473 | + isp->mmio_size[i] = mem->end - mem->start + 1; | ||
2474 | + | ||
2475 | + /* map the region */ | ||
2476 | + isp->mmio_base[i] = (unsigned long) | ||
2477 | + ioremap_nocache(isp->mmio_base_phys[i], | ||
2478 | + isp->mmio_size[i]); | ||
2479 | + if (!isp->mmio_base[i]) { | ||
2480 | + dev_err(isp->dev, | ||
2481 | + "cannot map camera register I/O region\n"); | ||
2482 | + return -ENODEV; | ||
2483 | + } | ||
2484 | + } | ||
2485 | + | ||
2486 | + isp->irq = platform_get_irq(pdev, 0); | ||
2487 | + if (isp->irq <= 0) { | ||
2488 | + dev_err(isp->dev, "no irq for camera?\n"); | ||
2489 | + return -ENODEV; | ||
2490 | + } | ||
2491 | + | ||
2492 | + isp_obj.cam_ick = clk_get(&camera_dev, "cam_ick"); | ||
2493 | + if (IS_ERR(isp_obj.cam_ick)) { | ||
2494 | + DPRINTK_ISPCTRL("ISP_ERR: clk_get for " | ||
2495 | + "cam_ick failed\n"); | ||
2496 | + return PTR_ERR(isp_obj.cam_ick); | ||
2497 | + } | ||
2498 | + isp_obj.cam_mclk = clk_get(&camera_dev, "cam_mclk"); | ||
2499 | + if (IS_ERR(isp_obj.cam_mclk)) { | ||
2500 | + DPRINTK_ISPCTRL("ISP_ERR: clk_get for " | ||
2501 | + "cam_mclk failed\n"); | ||
2502 | + ret_err = PTR_ERR(isp_obj.cam_mclk); | ||
2503 | + goto out_clk_get_mclk; | ||
2504 | + } | ||
2505 | + isp_obj.csi2_fck = clk_get(&camera_dev, "csi2_96m_fck"); | ||
2506 | + if (IS_ERR(isp_obj.csi2_fck)) { | ||
2507 | + DPRINTK_ISPCTRL("ISP_ERR: clk_get for csi2_fclk" | ||
2508 | + " failed\n"); | ||
2509 | + ret_err = PTR_ERR(isp_obj.csi2_fck); | ||
2510 | + goto out_clk_get_csi2_fclk; | ||
2511 | + } | ||
2512 | + | ||
2513 | + if (request_irq(isp->irq, omap34xx_isp_isr, IRQF_SHARED, | ||
2514 | + "Omap 3 Camera ISP", &isp_obj)) { | ||
2515 | + DPRINTK_ISPCTRL("Could not install ISR\n"); | ||
2516 | + ret_err = -EINVAL; | ||
2517 | + goto out_request_irq; | ||
2518 | + } | ||
2519 | + | ||
2520 | + isp_obj.ref_count = 0; | ||
2521 | + | ||
2522 | + mutex_init(&(isp_obj.isp_mutex)); | ||
2523 | + spin_lock_init(&isp_obj.lock); | ||
2524 | + spin_lock_init(&isp_obj.bufs.lock); | ||
2525 | + | ||
2526 | + omap3isp = isp; | ||
2527 | + | ||
2528 | + ret_err = ispmmu_init(); | ||
2529 | + if (ret_err) | ||
2530 | + goto out_ispmmu_init; | ||
2531 | + | ||
2532 | + isp_ccdc_init(); | ||
2533 | + isp_hist_init(); | ||
2534 | + isph3a_aewb_init(); | ||
2535 | + isp_preview_init(); | ||
2536 | + isp_resizer_init(); | ||
2537 | + isp_af_init(); | ||
2538 | + isp_csi2_init(); | ||
2539 | + | ||
2540 | + isp_get(); | ||
2541 | + isp_power_settings(1); | ||
2542 | + isp_put(); | ||
2543 | + | ||
2544 | + isph3a_notify(1); | ||
2545 | + isp_af_notify(1); | ||
2546 | + | ||
2547 | + return 0; | ||
2548 | + | ||
2549 | +out_ispmmu_init: | ||
2550 | + omap3isp = NULL; | ||
2551 | + free_irq(isp->irq, &isp_obj); | ||
2552 | +out_request_irq: | ||
2553 | + clk_put(isp_obj.csi2_fck); | ||
2554 | +out_clk_get_csi2_fclk: | ||
2555 | + clk_put(isp_obj.cam_mclk); | ||
2556 | +out_clk_get_mclk: | ||
2557 | + clk_put(isp_obj.cam_ick); | ||
2558 | + | ||
2559 | + return ret_err; | ||
2560 | +} | ||
2561 | + | ||
2562 | +static struct platform_driver omap3isp_driver = { | ||
2563 | + .probe = isp_probe, | ||
2564 | + .remove = isp_remove, | ||
2565 | + .suspend = isp_suspend, | ||
2566 | + .resume = isp_resume, | ||
2567 | + .driver = { | ||
2568 | + .name = "omap3isp", | ||
2569 | + }, | ||
2570 | +}; | ||
2571 | + | ||
2572 | +/** | ||
2573 | + * isp_init - ISP module initialization. | ||
2574 | + **/ | ||
2575 | +static int __init isp_init(void) | ||
2576 | +{ | ||
2577 | + return platform_driver_register(&omap3isp_driver); | ||
2578 | +} | ||
2579 | + | ||
2580 | +/** | ||
2581 | + * isp_cleanup - ISP module cleanup. | ||
2582 | + **/ | ||
2583 | +static void __exit isp_cleanup(void) | ||
2584 | +{ | ||
2585 | + platform_driver_unregister(&omap3isp_driver); | ||
2586 | +} | ||
2587 | + | ||
2588 | +/** | ||
2589 | + * isp_print_status - Prints the values of the ISP Control Module registers | ||
2590 | + * | ||
2591 | + * Also prints other debug information stored in the ISP module structure. | ||
2592 | + **/ | ||
2593 | +void isp_print_status(void) | ||
2594 | +{ | ||
2595 | + if (!is_ispctrl_debug_enabled()) | ||
2596 | + return; | ||
2597 | + | ||
2598 | + DPRINTK_ISPCTRL("###ISP_CTRL=0x%x\n", | ||
2599 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL)); | ||
2600 | + DPRINTK_ISPCTRL("###ISP_TCTRL_CTRL=0x%x\n", | ||
2601 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL)); | ||
2602 | + DPRINTK_ISPCTRL("###ISP_SYSCONFIG=0x%x\n", | ||
2603 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG)); | ||
2604 | + DPRINTK_ISPCTRL("###ISP_SYSSTATUS=0x%x\n", | ||
2605 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_SYSSTATUS)); | ||
2606 | + DPRINTK_ISPCTRL("###ISP_IRQ0ENABLE=0x%x\n", | ||
2607 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE)); | ||
2608 | + DPRINTK_ISPCTRL("###ISP_IRQ0STATUS=0x%x\n", | ||
2609 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS)); | ||
2610 | +} | ||
2611 | +EXPORT_SYMBOL(isp_print_status); | ||
2612 | + | ||
2613 | +module_init(isp_init); | ||
2614 | +module_exit(isp_cleanup); | ||
2615 | + | ||
2616 | +MODULE_AUTHOR("Texas Instruments"); | ||
2617 | +MODULE_DESCRIPTION("ISP Control Module Library"); | ||
2618 | +MODULE_LICENSE("GPL"); | ||
2619 | diff --git a/drivers/media/video/isp/isp.h b/drivers/media/video/isp/isp.h | ||
2620 | new file mode 100644 | ||
2621 | index 0000000..55c98a9 | ||
2622 | --- /dev/null | ||
2623 | +++ b/drivers/media/video/isp/isp.h | ||
2624 | @@ -0,0 +1,318 @@ | ||
2625 | +/* | ||
2626 | + * isp.h | ||
2627 | + * | ||
2628 | + * Top level public header file for ISP Control module in | ||
2629 | + * TI's OMAP3 Camera ISP | ||
2630 | + * | ||
2631 | + * Copyright (C) 2009 Texas Instruments. | ||
2632 | + * Copyright (C) 2009 Nokia. | ||
2633 | + * | ||
2634 | + * Contributors: | ||
2635 | + * Sameer Venkatraman <sameerv@ti.com> | ||
2636 | + * Mohit Jalori <mjalori@ti.com> | ||
2637 | + * Sergio Aguirre <saaguirre@ti.com> | ||
2638 | + * Sakari Ailus <sakari.ailus@nokia.com> | ||
2639 | + * Tuukka Toivonen <tuukka.o.toivonen@nokia.com> | ||
2640 | + * | ||
2641 | + * This package is free software; you can redistribute it and/or modify | ||
2642 | + * it under the terms of the GNU General Public License version 2 as | ||
2643 | + * published by the Free Software Foundation. | ||
2644 | + * | ||
2645 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
2646 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
2647 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
2648 | + */ | ||
2649 | + | ||
2650 | +#ifndef OMAP_ISP_TOP_H | ||
2651 | +#define OMAP_ISP_TOP_H | ||
2652 | +#include <mach/cpu.h> | ||
2653 | +#include <media/videobuf-dma-sg.h> | ||
2654 | +#include <linux/videodev2.h> | ||
2655 | +#define OMAP_ISP_CCDC (1 << 0) | ||
2656 | +#define OMAP_ISP_PREVIEW (1 << 1) | ||
2657 | +#define OMAP_ISP_RESIZER (1 << 2) | ||
2658 | +#define OMAP_ISP_AEWB (1 << 3) | ||
2659 | +#define OMAP_ISP_AF (1 << 4) | ||
2660 | +#define OMAP_ISP_HIST (1 << 5) | ||
2661 | + | ||
2662 | +#define ISP_TOK_TERM 0xFFFFFFFF /* | ||
2663 | + * terminating token for ISP | ||
2664 | + * modules reg list | ||
2665 | + */ | ||
2666 | +#define NUM_BUFS VIDEO_MAX_FRAME | ||
2667 | + | ||
2668 | +#ifndef CONFIG_ARCH_OMAP3410 | ||
2669 | +#define USE_ISP_PREVIEW | ||
2670 | +#define USE_ISP_RESZ | ||
2671 | +#define is_isppreview_enabled() 1 | ||
2672 | +#define is_ispresizer_enabled() 1 | ||
2673 | +#else | ||
2674 | +#define is_isppreview_enabled() 0 | ||
2675 | +#define is_ispresizer_enabled() 0 | ||
2676 | +#endif | ||
2677 | + | ||
2678 | +#define ISP_BYTES_PER_PIXEL 2 | ||
2679 | +#define NUM_ISP_CAPTURE_FORMATS (sizeof(isp_formats) / \ | ||
2680 | + sizeof(isp_formats[0])) | ||
2681 | +typedef int (*isp_vbq_callback_ptr) (struct videobuf_buffer *vb); | ||
2682 | +typedef void (*isp_callback_t) (unsigned long status, | ||
2683 | + isp_vbq_callback_ptr arg1, void *arg2); | ||
2684 | + | ||
2685 | +enum isp_mem_resources { | ||
2686 | + OMAP3_ISP_IOMEM_MAIN, | ||
2687 | + OMAP3_ISP_IOMEM_CBUFF, | ||
2688 | + OMAP3_ISP_IOMEM_CCP2, | ||
2689 | + OMAP3_ISP_IOMEM_CCDC, | ||
2690 | + OMAP3_ISP_IOMEM_HIST, | ||
2691 | + OMAP3_ISP_IOMEM_H3A, | ||
2692 | + OMAP3_ISP_IOMEM_PREV, | ||
2693 | + OMAP3_ISP_IOMEM_RESZ, | ||
2694 | + OMAP3_ISP_IOMEM_SBL, | ||
2695 | + OMAP3_ISP_IOMEM_CSI2A, | ||
2696 | + OMAP3_ISP_IOMEM_CSI2PHY | ||
2697 | +}; | ||
2698 | + | ||
2699 | +struct isp_device { | ||
2700 | + struct device *dev; | ||
2701 | + | ||
2702 | + /*** platform HW resources ***/ | ||
2703 | + unsigned int irq; | ||
2704 | + | ||
2705 | +#define mmio_base_main mmio_base[OMAP3_ISP_IOMEM_MAIN] | ||
2706 | +#define mmio_cbuff_main mmio_base[OMAP3_ISP_IOMEM_CBUFF] | ||
2707 | +#define mmio_ccp2_main mmio_base[OMAP3_ISP_IOMEM_CCP2] | ||
2708 | +#define mmio_ccdc_main mmio_base[OMAP3_ISP_IOMEM_CCDC] | ||
2709 | +#define mmio_hist_main mmio_base[OMAP3_ISP_IOMEM_HIST] | ||
2710 | +#define mmio_h3a_main mmio_base[OMAP3_ISP_IOMEM_H3A] | ||
2711 | +#define mmio_prev_main mmio_base[OMAP3_ISP_IOMEM_PREV] | ||
2712 | +#define mmio_resz_main mmio_base[OMAP3_ISP_IOMEM_RESZ] | ||
2713 | +#define mmio_sbl_main mmio_base[OMAP3_ISP_IOMEM_SBL] | ||
2714 | +#define mmio_csi2_main mmio_base[OMAP3_ISP_IOMEM_CSI2A] | ||
2715 | +#define mmio_csi2phy_main mmio_base[OMAP3_ISP_IOMEM_CSI2PHY] | ||
2716 | + unsigned long mmio_base[OMAP3_ISP_IOMEM_CSI2PHY + 1]; | ||
2717 | + unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_CSI2PHY + 1]; | ||
2718 | + unsigned long mmio_size[OMAP3_ISP_IOMEM_CSI2PHY + 1]; | ||
2719 | +}; | ||
2720 | + | ||
2721 | +enum isp_interface_type { | ||
2722 | + ISP_PARLL = 1, | ||
2723 | + ISP_CSIA = 2, | ||
2724 | + ISP_CSIB = 4, | ||
2725 | + ISP_NONE = 8 /* memory input to preview / resizer */ | ||
2726 | +}; | ||
2727 | + | ||
2728 | +enum isp_irqevents { | ||
2729 | + CSIA = 0x01, | ||
2730 | + CSIB = 0x10, | ||
2731 | + CCDC_VD0 = 0x100, | ||
2732 | + CCDC_VD1 = 0x200, | ||
2733 | + CCDC_VD2 = 0x400, | ||
2734 | + CCDC_ERR = 0x800, | ||
2735 | + H3A_AWB_DONE = 0x2000, | ||
2736 | + H3A_AF_DONE = 0x1000, | ||
2737 | + HIST_DONE = 0x10000, | ||
2738 | + PREV_DONE = 0x100000, | ||
2739 | + LSC_DONE = 0x20000, | ||
2740 | + LSC_PRE_COMP = 0x40000, | ||
2741 | + LSC_PRE_ERR = 0x80000, | ||
2742 | + RESZ_DONE = 0x1000000, | ||
2743 | + SBL_OVF = 0x2000000, | ||
2744 | + MMU_ERR = 0x10000000, | ||
2745 | + OCP_ERR = 0x20000000, | ||
2746 | + HS_VS = 0x80000000 | ||
2747 | +}; | ||
2748 | + | ||
2749 | +enum isp_callback_type { | ||
2750 | + CBK_CCDC_VD0, | ||
2751 | + CBK_CCDC_VD1, | ||
2752 | + CBK_PREV_DONE, | ||
2753 | + CBK_RESZ_DONE, | ||
2754 | + CBK_MMU_ERR, | ||
2755 | + CBK_H3A_AWB_DONE, | ||
2756 | + CBK_HIST_DONE, | ||
2757 | + CBK_HS_VS, | ||
2758 | + CBK_LSC_ISR, | ||
2759 | + CBK_H3A_AF_DONE, | ||
2760 | + CBK_CATCHALL, | ||
2761 | + CBK_CSIA, | ||
2762 | + CBK_CSIB, | ||
2763 | + CBK_END, | ||
2764 | +}; | ||
2765 | + | ||
2766 | +/** | ||
2767 | + * struct isp_reg - Structure for ISP register values. | ||
2768 | + * @reg: 32-bit Register address. | ||
2769 | + * @val: 32-bit Register value. | ||
2770 | + */ | ||
2771 | +struct isp_reg { | ||
2772 | + enum isp_mem_resources mmio_range; | ||
2773 | + u32 reg; | ||
2774 | + u32 val; | ||
2775 | +}; | ||
2776 | + | ||
2777 | +/** | ||
2778 | + * struct isp_interface_config - ISP interface configuration. | ||
2779 | + * @ccdc_par_ser: ISP interface type. 0 - Parallel, 1 - CSIA, 2 - CSIB to CCDC. | ||
2780 | + * @par_bridge: CCDC Bridge input control. Parallel interface. | ||
2781 | + * 0 - Disable, 1 - Enable, first byte->cam_d(bits 7 to 0) | ||
2782 | + * 2 - Enable, first byte -> cam_d(bits 15 to 8) | ||
2783 | + * @par_clk_pol: Pixel clock polarity on the parallel interface. | ||
2784 | + * 0 - Non Inverted, 1 - Inverted | ||
2785 | + * @dataline_shift: Data lane shifter. | ||
2786 | + * 0 - No Shift, 1 - CAMEXT[13 to 2]->CAM[11 to 0] | ||
2787 | + * 2 - CAMEXT[13 to 4]->CAM[9 to 0] | ||
2788 | + * 3 - CAMEXT[13 to 6]->CAM[7 to 0] | ||
2789 | + * @hsvs_syncdetect: HS or VS synchronization signal detection. | ||
2790 | + * 0 - HS Falling, 1 - HS rising | ||
2791 | + * 2 - VS falling, 3 - VS rising | ||
2792 | + * @strobe: Strobe related parameter. | ||
2793 | + * @prestrobe: PreStrobe related parameter. | ||
2794 | + * @shutter: Shutter related parameter. | ||
2795 | + * @hskip: Horizontal Start Pixel performed in Preview module. | ||
2796 | + * @vskip: Vertical Start Line performed in Preview module. | ||
2797 | + * @wenlog: Store the value for the sensor specific wenlog field. | ||
2798 | + * @wait_hs_vs: Wait for this many hs_vs before anything else in the beginning. | ||
2799 | + */ | ||
2800 | +struct isp_interface_config { | ||
2801 | + enum isp_interface_type ccdc_par_ser; | ||
2802 | + u8 dataline_shift; | ||
2803 | + u32 hsvs_syncdetect; | ||
2804 | + int strobe; | ||
2805 | + int prestrobe; | ||
2806 | + int shutter; | ||
2807 | + u32 prev_sph; | ||
2808 | + u32 prev_slv; | ||
2809 | + u32 wenlog; | ||
2810 | + int wait_hs_vs; | ||
2811 | + union { | ||
2812 | + struct par { | ||
2813 | + unsigned par_bridge:2; | ||
2814 | + unsigned par_clk_pol:1; | ||
2815 | + } par; | ||
2816 | + struct csi { | ||
2817 | + unsigned crc:1; | ||
2818 | + unsigned mode:1; | ||
2819 | + unsigned edge:1; | ||
2820 | + unsigned signalling:1; | ||
2821 | + unsigned strobe_clock_inv:1; | ||
2822 | + unsigned vs_edge:1; | ||
2823 | + unsigned channel:3; | ||
2824 | + unsigned vpclk:2; /* Video port output clock */ | ||
2825 | + unsigned int data_start; | ||
2826 | + unsigned int data_size; | ||
2827 | + u32 format; /* V4L2_PIX_FMT_* */ | ||
2828 | + } csi; | ||
2829 | + } u; | ||
2830 | +}; | ||
2831 | + | ||
2832 | +u32 isp_reg_readl(enum isp_mem_resources isp_mmio_range, u32 reg_offset); | ||
2833 | + | ||
2834 | +void isp_reg_writel(u32 reg_value, enum isp_mem_resources isp_mmio_range, | ||
2835 | + u32 reg_offset); | ||
2836 | + | ||
2837 | +static inline void isp_reg_and(enum isp_mem_resources mmio_range, u32 reg, | ||
2838 | + u32 and_bits) | ||
2839 | +{ | ||
2840 | + u32 v = isp_reg_readl(mmio_range, reg); | ||
2841 | + | ||
2842 | + isp_reg_writel(v & and_bits, mmio_range, reg); | ||
2843 | +} | ||
2844 | + | ||
2845 | +static inline void isp_reg_or(enum isp_mem_resources mmio_range, u32 reg, | ||
2846 | + u32 or_bits) | ||
2847 | +{ | ||
2848 | + u32 v = isp_reg_readl(mmio_range, reg); | ||
2849 | + | ||
2850 | + isp_reg_writel(v | or_bits, mmio_range, reg); | ||
2851 | +} | ||
2852 | + | ||
2853 | +static inline void isp_reg_and_or(enum isp_mem_resources mmio_range, u32 reg, | ||
2854 | + u32 and_bits, u32 or_bits) | ||
2855 | +{ | ||
2856 | + u32 v = isp_reg_readl(mmio_range, reg); | ||
2857 | + | ||
2858 | + isp_reg_writel((v & and_bits) | or_bits, mmio_range, reg); | ||
2859 | +} | ||
2860 | + | ||
2861 | +void isp_start(void); | ||
2862 | + | ||
2863 | +void isp_stop(void); | ||
2864 | + | ||
2865 | +int isp_buf_queue(struct videobuf_buffer *vb, | ||
2866 | + void (*complete)(struct videobuf_buffer *vb, void *priv), | ||
2867 | + void *priv); | ||
2868 | + | ||
2869 | +int isp_vbq_setup(struct videobuf_queue *vbq, unsigned int *cnt, | ||
2870 | + unsigned int *size); | ||
2871 | + | ||
2872 | +int isp_vbq_prepare(struct videobuf_queue *vbq, struct videobuf_buffer *vb, | ||
2873 | + enum v4l2_field field); | ||
2874 | + | ||
2875 | +void isp_vbq_release(struct videobuf_queue *vbq, struct videobuf_buffer *vb); | ||
2876 | + | ||
2877 | +int isp_set_callback(enum isp_callback_type type, isp_callback_t callback, | ||
2878 | + isp_vbq_callback_ptr arg1, void *arg2); | ||
2879 | + | ||
2880 | +int isp_unset_callback(enum isp_callback_type type); | ||
2881 | + | ||
2882 | +u32 isp_set_xclk(u32 xclk, u8 xclksel); | ||
2883 | + | ||
2884 | +int isp_configure_interface(struct isp_interface_config *config); | ||
2885 | + | ||
2886 | +int isp_get(void); | ||
2887 | + | ||
2888 | +int isp_put(void); | ||
2889 | + | ||
2890 | +int isp_queryctrl(struct v4l2_queryctrl *a); | ||
2891 | + | ||
2892 | +int isp_querymenu(struct v4l2_querymenu *a); | ||
2893 | + | ||
2894 | +int isp_g_ctrl(struct v4l2_control *a); | ||
2895 | + | ||
2896 | +int isp_s_ctrl(struct v4l2_control *a); | ||
2897 | + | ||
2898 | +int isp_enum_fmt_cap(struct v4l2_fmtdesc *f); | ||
2899 | + | ||
2900 | +int isp_try_fmt_cap(struct v4l2_pix_format *pix_input, | ||
2901 | + struct v4l2_pix_format *pix_output); | ||
2902 | + | ||
2903 | +void isp_g_fmt_cap(struct v4l2_pix_format *pix); | ||
2904 | + | ||
2905 | +int isp_s_fmt_cap(struct v4l2_pix_format *pix_input, | ||
2906 | + struct v4l2_pix_format *pix_output); | ||
2907 | + | ||
2908 | +int isp_g_crop(struct v4l2_crop *a); | ||
2909 | + | ||
2910 | +int isp_s_crop(struct v4l2_crop *a, struct v4l2_pix_format *pix); | ||
2911 | + | ||
2912 | +void isp_config_crop(struct v4l2_pix_format *pix); | ||
2913 | + | ||
2914 | +int isp_try_fmt(struct v4l2_pix_format *pix_input, | ||
2915 | + struct v4l2_pix_format *pix_output); | ||
2916 | + | ||
2917 | +int isp_handle_private(int cmd, void *arg); | ||
2918 | + | ||
2919 | +void isp_save_context(struct isp_reg *); | ||
2920 | + | ||
2921 | +void isp_restore_context(struct isp_reg *); | ||
2922 | + | ||
2923 | +void isp_print_status(void); | ||
2924 | + | ||
2925 | +int __init isp_ccdc_init(void); | ||
2926 | +int __init isp_hist_init(void); | ||
2927 | +int __init isph3a_aewb_init(void); | ||
2928 | +int __init isp_preview_init(void); | ||
2929 | +int __init isp_resizer_init(void); | ||
2930 | +int __init isp_af_init(void); | ||
2931 | +int __init isp_csi2_init(void); | ||
2932 | + | ||
2933 | +void isp_ccdc_cleanup(void); | ||
2934 | +void isp_hist_cleanup(void); | ||
2935 | +void isph3a_aewb_cleanup(void); | ||
2936 | +void isp_preview_cleanup(void); | ||
2937 | +void isp_hist_cleanup(void); | ||
2938 | +void isp_resizer_cleanup(void); | ||
2939 | +void isp_af_exit(void); | ||
2940 | +void isp_csi2_cleanup(void); | ||
2941 | + | ||
2942 | +#endif /* OMAP_ISP_TOP_H */ | ||
2943 | diff --git a/drivers/media/video/isp/ispreg.h b/drivers/media/video/isp/ispreg.h | ||
2944 | new file mode 100644 | ||
2945 | index 0000000..4f8e1ef | ||
2946 | --- /dev/null | ||
2947 | +++ b/drivers/media/video/isp/ispreg.h | ||
2948 | @@ -0,0 +1,1674 @@ | ||
2949 | +/* | ||
2950 | + * ispreg.h | ||
2951 | + * | ||
2952 | + * Header file for all the ISP module in TI's OMAP3 Camera ISP. | ||
2953 | + * It has the OMAP HW register definitions. | ||
2954 | + * | ||
2955 | + * Copyright (C) 2009 Texas Instruments. | ||
2956 | + * Copyright (C) 2009 Nokia. | ||
2957 | + * | ||
2958 | + * Contributors: | ||
2959 | + * Tuukka Toivonen <tuukka.o.toivonen@nokia.com> | ||
2960 | + * Thara Gopinath <thara@ti.com> | ||
2961 | + * Sergio Aguirre <saaguirre@ti.com> | ||
2962 | + * | ||
2963 | + * This package is free software; you can redistribute it and/or modify | ||
2964 | + * it under the terms of the GNU General Public License version 2 as | ||
2965 | + * published by the Free Software Foundation. | ||
2966 | + * | ||
2967 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
2968 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
2969 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
2970 | + */ | ||
2971 | + | ||
2972 | +#ifndef __ISPREG_H__ | ||
2973 | +#define __ISPREG_H__ | ||
2974 | + | ||
2975 | +#include <mach/omap34xx.h> | ||
2976 | + | ||
2977 | +/* Note: Uncomment below defines as needed for enabling module specific debug | ||
2978 | + * messages | ||
2979 | + */ | ||
2980 | + | ||
2981 | +/* | ||
2982 | + #define OMAP_ISPCTRL_DEBUG | ||
2983 | + #define OMAP_ISPCCDC_DEBUG | ||
2984 | + #define OMAP_ISPPREV_DEBUG | ||
2985 | + #define OMAP_ISPRESZ_DEBUG | ||
2986 | + #define OMAP_ISPMMU_DEBUG | ||
2987 | + #define OMAP_ISPH3A_DEBUG | ||
2988 | + #define OMAP_ISP_AF_DEBUG | ||
2989 | + #define OMAP_ISPHIST_DEBUG | ||
2990 | +*/ | ||
2991 | + | ||
2992 | +#ifdef OMAP_ISPCTRL_DEBUG | ||
2993 | +#define DPRINTK_ISPCTRL(format, ...) \ | ||
2994 | + printk(KERN_INFO "ISPCTRL: " format, ## __VA_ARGS__) | ||
2995 | +#define is_ispctrl_debug_enabled() 1 | ||
2996 | +#else | ||
2997 | +#define DPRINTK_ISPCTRL(format, ...) | ||
2998 | +#define is_ispctrl_debug_enabled() 0 | ||
2999 | +#endif | ||
3000 | + | ||
3001 | +#ifdef OMAP_ISPCCDC_DEBUG | ||
3002 | +#define DPRINTK_ISPCCDC(format, ...) \ | ||
3003 | + printk(KERN_INFO "ISPCCDC: " format, ## __VA_ARGS__) | ||
3004 | +#define is_ispccdc_debug_enabled() 1 | ||
3005 | +#else | ||
3006 | +#define DPRINTK_ISPCCDC(format, ...) | ||
3007 | +#define is_ispccdc_debug_enabled() 0 | ||
3008 | +#endif | ||
3009 | + | ||
3010 | +#ifdef OMAP_ISPPREV_DEBUG | ||
3011 | +#define DPRINTK_ISPPREV(format, ...) \ | ||
3012 | + printk(KERN_INFO "ISPPREV: " format, ## __VA_ARGS__) | ||
3013 | +#define is_ispprev_debug_enabled() 1 | ||
3014 | +#else | ||
3015 | +#define DPRINTK_ISPPREV(format, ...) | ||
3016 | +#define is_ispprev_debug_enabled() 0 | ||
3017 | +#endif | ||
3018 | + | ||
3019 | +#ifdef OMAP_ISPRESZ_DEBUG | ||
3020 | +#define DPRINTK_ISPRESZ(format, ...) \ | ||
3021 | + printk(KERN_INFO "ISPRESZ: " format, ## __VA_ARGS__) | ||
3022 | +#define is_ispresz_debug_enabled() 1 | ||
3023 | +#else | ||
3024 | +#define DPRINTK_ISPRESZ(format, ...) | ||
3025 | +#define is_ispresz_debug_enabled() 0 | ||
3026 | +#endif | ||
3027 | + | ||
3028 | +#ifdef OMAP_ISPMMU_DEBUG | ||
3029 | +#define DPRINTK_ISPMMU(format, ...) \ | ||
3030 | + printk(KERN_INFO "ISPMMU: " format, ## __VA_ARGS__) | ||
3031 | +#define is_ispmmu_debug_enabled() 1 | ||
3032 | +#else | ||
3033 | +#define DPRINTK_ISPMMU(format, ...) | ||
3034 | +#define is_ispmmu_debug_enabled() 0 | ||
3035 | +#endif | ||
3036 | + | ||
3037 | +#ifdef OMAP_ISPH3A_DEBUG | ||
3038 | +#define DPRINTK_ISPH3A(format, ...) \ | ||
3039 | + printk(KERN_INFO "ISPH3A: " format, ## __VA_ARGS__) | ||
3040 | +#define is_isph3a_debug_enabled() 1 | ||
3041 | +#else | ||
3042 | +#define DPRINTK_ISPH3A(format, ...) | ||
3043 | +#define is_isph3a_debug_enabled() 0 | ||
3044 | +#endif | ||
3045 | + | ||
3046 | +#ifdef OMAP_ISP_AF_DEBUG | ||
3047 | +#define DPRINTK_ISP_AF(format, ...) \ | ||
3048 | + printk(KERN_INFO "ISP_AF: " format, ## __VA_ARGS__) | ||
3049 | +#define is_isp_af_debug_enabled() 1 | ||
3050 | +#else | ||
3051 | +#define DPRINTK_ISP_AF(format, ...) | ||
3052 | +#define is_isp_af_debug_enabled() 0 | ||
3053 | +#endif | ||
3054 | + | ||
3055 | +#ifdef OMAP_ISPHIST_DEBUG | ||
3056 | +#define DPRINTK_ISPHIST(format, ...) \ | ||
3057 | + printk(KERN_INFO "ISPHIST: " format, ## __VA_ARGS__) | ||
3058 | +#define is_isphist_debug_enabled() 1 | ||
3059 | +#else | ||
3060 | +#define DPRINTK_ISPHIST(format, ...) | ||
3061 | +#define is_isphist_debug_enabled() 0 | ||
3062 | +#endif | ||
3063 | + | ||
3064 | +#define ISP_32B_BOUNDARY_BUF 0xFFFFFFE0 | ||
3065 | +#define ISP_32B_BOUNDARY_OFFSET 0x0000FFE0 | ||
3066 | + | ||
3067 | +#define CM_CAM_MCLK_HZ 216000000 | ||
3068 | + | ||
3069 | +/* ISP Submodules offset */ | ||
3070 | + | ||
3071 | +#define OMAP3ISP_REG_BASE OMAP3430_ISP_BASE | ||
3072 | +#define OMAP3ISP_REG(offset) (OMAP3ISP_REG_BASE + (offset)) | ||
3073 | + | ||
3074 | +#define OMAP3ISP_CBUFF_REG_OFFSET 0x0100 | ||
3075 | +#define OMAP3ISP_CBUFF_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
3076 | + OMAP3ISP_CBUFF_REG_OFFSET) | ||
3077 | +#define OMAP3ISP_CBUFF_REG(offset) (OMAP3ISP_CBUFF_REG_BASE + (offset)) | ||
3078 | + | ||
3079 | +#define OMAP3ISP_CCP2_REG_OFFSET 0x0400 | ||
3080 | +#define OMAP3ISP_CCP2_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
3081 | + OMAP3ISP_CCP2_REG_OFFSET) | ||
3082 | +#define OMAP3ISP_CCP2_REG(offset) (OMAP3ISP_CCP2_REG_BASE + (offset)) | ||
3083 | + | ||
3084 | +#define OMAP3ISP_CCDC_REG_OFFSET 0x0600 | ||
3085 | +#define OMAP3ISP_CCDC_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
3086 | + OMAP3ISP_CCDC_REG_OFFSET) | ||
3087 | +#define OMAP3ISP_CCDC_REG(offset) (OMAP3ISP_CCDC_REG_BASE + (offset)) | ||
3088 | + | ||
3089 | +#define OMAP3ISP_HIST_REG_OFFSET 0x0A00 | ||
3090 | +#define OMAP3ISP_HIST_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
3091 | + OMAP3ISP_HIST_REG_OFFSET) | ||
3092 | +#define OMAP3ISP_HIST_REG(offset) (OMAP3ISP_HIST_REG_BASE + (offset)) | ||
3093 | + | ||
3094 | +#define OMAP3ISP_H3A_REG_OFFSET 0x0C00 | ||
3095 | +#define OMAP3ISP_H3A_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
3096 | + OMAP3ISP_H3A_REG_OFFSET) | ||
3097 | +#define OMAP3ISP_H3A_REG(offset) (OMAP3ISP_H3A_REG_BASE + (offset)) | ||
3098 | + | ||
3099 | +#define OMAP3ISP_PREV_REG_OFFSET 0x0E00 | ||
3100 | +#define OMAP3ISP_PREV_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
3101 | + OMAP3ISP_PREV_REG_OFFSET) | ||
3102 | +#define OMAP3ISP_PREV_REG(offset) (OMAP3ISP_PREV_REG_BASE + (offset)) | ||
3103 | + | ||
3104 | +#define OMAP3ISP_RESZ_REG_OFFSET 0x1000 | ||
3105 | +#define OMAP3ISP_RESZ_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
3106 | + OMAP3ISP_RESZ_REG_OFFSET) | ||
3107 | +#define OMAP3ISP_RESZ_REG(offset) (OMAP3ISP_RESZ_REG_BASE + (offset)) | ||
3108 | + | ||
3109 | +#define OMAP3ISP_SBL_REG_OFFSET 0x1200 | ||
3110 | +#define OMAP3ISP_SBL_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
3111 | + OMAP3ISP_SBL_REG_OFFSET) | ||
3112 | +#define OMAP3ISP_SBL_REG(offset) (OMAP3ISP_SBL_REG_BASE + (offset)) | ||
3113 | + | ||
3114 | +#define OMAP3ISP_MMU_REG_OFFSET 0x1400 | ||
3115 | +#define OMAP3ISP_MMU_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
3116 | + OMAP3ISP_MMU_REG_OFFSET) | ||
3117 | +#define OMAP3ISP_MMU_REG(offset) (OMAP3ISP_MMU_REG_BASE + (offset)) | ||
3118 | + | ||
3119 | +#define OMAP3ISP_CSI2A_REG_OFFSET 0x1800 | ||
3120 | +#define OMAP3ISP_CSI2A_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
3121 | + OMAP3ISP_CSI2A_REG_OFFSET) | ||
3122 | +#define OMAP3ISP_CSI2A_REG(offset) (OMAP3ISP_CSI2A_REG_BASE + (offset)) | ||
3123 | + | ||
3124 | +#define OMAP3ISP_CSI2PHY_REG_OFFSET 0x1970 | ||
3125 | +#define OMAP3ISP_CSI2PHY_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
3126 | + OMAP3ISP_CSI2PHY_REG_OFFSET) | ||
3127 | +#define OMAP3ISP_CSI2PHY_REG(offset) (OMAP3ISP_CSI2PHY_REG_BASE + (offset)) | ||
3128 | + | ||
3129 | +/* ISP module register offset */ | ||
3130 | + | ||
3131 | +#define ISP_REVISION (0x000) | ||
3132 | +#define ISP_SYSCONFIG (0x004) | ||
3133 | +#define ISP_SYSSTATUS (0x008) | ||
3134 | +#define ISP_IRQ0ENABLE (0x00C) | ||
3135 | +#define ISP_IRQ0STATUS (0x010) | ||
3136 | +#define ISP_IRQ1ENABLE (0x014) | ||
3137 | +#define ISP_IRQ1STATUS (0x018) | ||
3138 | +#define ISP_TCTRL_GRESET_LENGTH (0x030) | ||
3139 | +#define ISP_TCTRL_PSTRB_REPLAY (0x034) | ||
3140 | +#define ISP_CTRL (0x040) | ||
3141 | +#define ISP_SECURE (0x044) | ||
3142 | +#define ISP_TCTRL_CTRL (0x050) | ||
3143 | +#define ISP_TCTRL_FRAME (0x054) | ||
3144 | +#define ISP_TCTRL_PSTRB_DELAY (0x058) | ||
3145 | +#define ISP_TCTRL_STRB_DELAY (0x05C) | ||
3146 | +#define ISP_TCTRL_SHUT_DELAY (0x060) | ||
3147 | +#define ISP_TCTRL_PSTRB_LENGTH (0x064) | ||
3148 | +#define ISP_TCTRL_STRB_LENGTH (0x068) | ||
3149 | +#define ISP_TCTRL_SHUT_LENGTH (0x06C) | ||
3150 | +#define ISP_PING_PONG_ADDR (0x070) | ||
3151 | +#define ISP_PING_PONG_MEM_RANGE (0x074) | ||
3152 | +#define ISP_PING_PONG_BUF_SIZE (0x078) | ||
3153 | + | ||
3154 | +/* CSI1 receiver registers (ES2.0) */ | ||
3155 | +#define ISPCSI1_REVISION (0x000) | ||
3156 | +#define ISPCSI1_SYSCONFIG (0x004) | ||
3157 | +#define ISPCSI1_SYSSTATUS (0x008) | ||
3158 | +#define ISPCSI1_LC01_IRQENABLE (0x00C) | ||
3159 | +#define ISPCSI1_LC01_IRQSTATUS (0x010) | ||
3160 | +#define ISPCSI1_LC23_IRQENABLE (0x014) | ||
3161 | +#define ISPCSI1_LC23_IRQSTATUS (0x018) | ||
3162 | +#define ISPCSI1_LCM_IRQENABLE (0x02C) | ||
3163 | +#define ISPCSI1_LCM_IRQSTATUS (0x030) | ||
3164 | +#define ISPCSI1_CTRL (0x040) | ||
3165 | +#define ISPCSI1_DBG (0x044) | ||
3166 | +#define ISPCSI1_GNQ (0x048) | ||
3167 | +#define ISPCSI1_LCx_CTRL(x) ((0x050)+0x30*(x)) | ||
3168 | +#define ISPCSI1_LCx_CODE(x) ((0x054)+0x30*(x)) | ||
3169 | +#define ISPCSI1_LCx_STAT_START(x) ((0x058)+0x30*(x)) | ||
3170 | +#define ISPCSI1_LCx_STAT_SIZE(x) ((0x05C)+0x30*(x)) | ||
3171 | +#define ISPCSI1_LCx_SOF_ADDR(x) ((0x060)+0x30*(x)) | ||
3172 | +#define ISPCSI1_LCx_EOF_ADDR(x) ((0x064)+0x30*(x)) | ||
3173 | +#define ISPCSI1_LCx_DAT_START(x) ((0x068)+0x30*(x)) | ||
3174 | +#define ISPCSI1_LCx_DAT_SIZE(x) ((0x06C)+0x30*(x)) | ||
3175 | +#define ISPCSI1_LCx_DAT_PING_ADDR(x) ((0x070)+0x30*(x)) | ||
3176 | +#define ISPCSI1_LCx_DAT_PONG_ADDR(x) ((0x074)+0x30*(x)) | ||
3177 | +#define ISPCSI1_LCx_DAT_OFST(x) ((0x078)+0x30*(x)) | ||
3178 | +#define ISPCSI1_LCM_CTRL (0x1D0) | ||
3179 | +#define ISPCSI1_LCM_VSIZE (0x1D4) | ||
3180 | +#define ISPCSI1_LCM_HSIZE (0x1D8) | ||
3181 | +#define ISPCSI1_LCM_PREFETCH (0x1DC) | ||
3182 | +#define ISPCSI1_LCM_SRC_ADDR (0x1E0) | ||
3183 | +#define ISPCSI1_LCM_SRC_OFST (0x1E4) | ||
3184 | +#define ISPCSI1_LCM_DST_ADDR (0x1E8) | ||
3185 | +#define ISPCSI1_LCM_DST_OFST (0x1EC) | ||
3186 | +#define ISP_CSIB_SYSCONFIG ISPCSI1_SYSCONFIG | ||
3187 | +#define ISP_CSIA_SYSCONFIG ISPCSI2_SYSCONFIG | ||
3188 | + | ||
3189 | +/* ISP_CBUFF Registers */ | ||
3190 | + | ||
3191 | +#define ISP_CBUFF_SYSCONFIG (0x010) | ||
3192 | +#define ISP_CBUFF_IRQENABLE (0x01C) | ||
3193 | + | ||
3194 | +#define ISP_CBUFF0_CTRL (0x020) | ||
3195 | +#define ISP_CBUFF1_CTRL (0x024) | ||
3196 | + | ||
3197 | +#define ISP_CBUFF0_START (0x040) | ||
3198 | +#define ISP_CBUFF1_START (0x044) | ||
3199 | + | ||
3200 | +#define ISP_CBUFF0_END (0x050) | ||
3201 | +#define ISP_CBUFF1_END (0x054) | ||
3202 | + | ||
3203 | +#define ISP_CBUFF0_WINDOWSIZE (0x060) | ||
3204 | +#define ISP_CBUFF1_WINDOWSIZE (0x064) | ||
3205 | + | ||
3206 | +#define ISP_CBUFF0_THRESHOLD (0x070) | ||
3207 | +#define ISP_CBUFF1_THRESHOLD (0x074) | ||
3208 | + | ||
3209 | +/* CCDC module register offset */ | ||
3210 | + | ||
3211 | +#define ISPCCDC_PID (0x000) | ||
3212 | +#define ISPCCDC_PCR (0x004) | ||
3213 | +#define ISPCCDC_SYN_MODE (0x008) | ||
3214 | +#define ISPCCDC_HD_VD_WID (0x00C) | ||
3215 | +#define ISPCCDC_PIX_LINES (0x010) | ||
3216 | +#define ISPCCDC_HORZ_INFO (0x014) | ||
3217 | +#define ISPCCDC_VERT_START (0x018) | ||
3218 | +#define ISPCCDC_VERT_LINES (0x01C) | ||
3219 | +#define ISPCCDC_CULLING (0x020) | ||
3220 | +#define ISPCCDC_HSIZE_OFF (0x024) | ||
3221 | +#define ISPCCDC_SDOFST (0x028) | ||
3222 | +#define ISPCCDC_SDR_ADDR (0x02C) | ||
3223 | +#define ISPCCDC_CLAMP (0x030) | ||
3224 | +#define ISPCCDC_DCSUB (0x034) | ||
3225 | +#define ISPCCDC_COLPTN (0x038) | ||
3226 | +#define ISPCCDC_BLKCMP (0x03C) | ||
3227 | +#define ISPCCDC_FPC (0x040) | ||
3228 | +#define ISPCCDC_FPC_ADDR (0x044) | ||
3229 | +#define ISPCCDC_VDINT (0x048) | ||
3230 | +#define ISPCCDC_ALAW (0x04C) | ||
3231 | +#define ISPCCDC_REC656IF (0x050) | ||
3232 | +#define ISPCCDC_CFG (0x054) | ||
3233 | +#define ISPCCDC_FMTCFG (0x058) | ||
3234 | +#define ISPCCDC_FMT_HORZ (0x05C) | ||
3235 | +#define ISPCCDC_FMT_VERT (0x060) | ||
3236 | +#define ISPCCDC_FMT_ADDR0 (0x064) | ||
3237 | +#define ISPCCDC_FMT_ADDR1 (0x068) | ||
3238 | +#define ISPCCDC_FMT_ADDR2 (0x06C) | ||
3239 | +#define ISPCCDC_FMT_ADDR3 (0x070) | ||
3240 | +#define ISPCCDC_FMT_ADDR4 (0x074) | ||
3241 | +#define ISPCCDC_FMT_ADDR5 (0x078) | ||
3242 | +#define ISPCCDC_FMT_ADDR6 (0x07C) | ||
3243 | +#define ISPCCDC_FMT_ADDR7 (0x080) | ||
3244 | +#define ISPCCDC_PRGEVEN0 (0x084) | ||
3245 | +#define ISPCCDC_PRGEVEN1 (0x088) | ||
3246 | +#define ISPCCDC_PRGODD0 (0x08C) | ||
3247 | +#define ISPCCDC_PRGODD1 (0x090) | ||
3248 | +#define ISPCCDC_VP_OUT (0x094) | ||
3249 | + | ||
3250 | +#define ISPCCDC_LSC_CONFIG (0x098) | ||
3251 | +#define ISPCCDC_LSC_INITIAL (0x09C) | ||
3252 | +#define ISPCCDC_LSC_TABLE_BASE (0x0A0) | ||
3253 | +#define ISPCCDC_LSC_TABLE_OFFSET (0x0A4) | ||
3254 | + | ||
3255 | +/* SBL */ | ||
3256 | +#define ISPSBL_CCDC_WR_0 (0x028) | ||
3257 | +#define ISPSBL_CCDC_WR_0_DATA_READY (1 << 21) | ||
3258 | +#define ISPSBL_CCDC_WR_1 (0x02C) | ||
3259 | +#define ISPSBL_CCDC_WR_2 (0x030) | ||
3260 | +#define ISPSBL_CCDC_WR_3 (0x034) | ||
3261 | + | ||
3262 | +/* Histogram registers */ | ||
3263 | +#define ISPHIST_PID (0x000) | ||
3264 | +#define ISPHIST_PCR (0x004) | ||
3265 | +#define ISPHIST_CNT (0x008) | ||
3266 | +#define ISPHIST_WB_GAIN (0x00C) | ||
3267 | +#define ISPHIST_R0_HORZ (0x010) | ||
3268 | +#define ISPHIST_R0_VERT (0x014) | ||
3269 | +#define ISPHIST_R1_HORZ (0x018) | ||
3270 | +#define ISPHIST_R1_VERT (0x01C) | ||
3271 | +#define ISPHIST_R2_HORZ (0x020) | ||
3272 | +#define ISPHIST_R2_VERT (0x024) | ||
3273 | +#define ISPHIST_R3_HORZ (0x028) | ||
3274 | +#define ISPHIST_R3_VERT (0x02C) | ||
3275 | +#define ISPHIST_ADDR (0x030) | ||
3276 | +#define ISPHIST_DATA (0x034) | ||
3277 | +#define ISPHIST_RADD (0x038) | ||
3278 | +#define ISPHIST_RADD_OFF (0x03C) | ||
3279 | +#define ISPHIST_H_V_INFO (0x040) | ||
3280 | + | ||
3281 | +/* H3A module registers */ | ||
3282 | +#define ISPH3A_PID (0x000) | ||
3283 | +#define ISPH3A_PCR (0x004) | ||
3284 | +#define ISPH3A_AEWWIN1 (0x04C) | ||
3285 | +#define ISPH3A_AEWINSTART (0x050) | ||
3286 | +#define ISPH3A_AEWINBLK (0x054) | ||
3287 | +#define ISPH3A_AEWSUBWIN (0x058) | ||
3288 | +#define ISPH3A_AEWBUFST (0x05C) | ||
3289 | +#define ISPH3A_AFPAX1 (0x008) | ||
3290 | +#define ISPH3A_AFPAX2 (0x00C) | ||
3291 | +#define ISPH3A_AFPAXSTART (0x010) | ||
3292 | +#define ISPH3A_AFIIRSH (0x014) | ||
3293 | +#define ISPH3A_AFBUFST (0x018) | ||
3294 | +#define ISPH3A_AFCOEF010 (0x01C) | ||
3295 | +#define ISPH3A_AFCOEF032 (0x020) | ||
3296 | +#define ISPH3A_AFCOEF054 (0x024) | ||
3297 | +#define ISPH3A_AFCOEF076 (0x028) | ||
3298 | +#define ISPH3A_AFCOEF098 (0x02C) | ||
3299 | +#define ISPH3A_AFCOEF0010 (0x030) | ||
3300 | +#define ISPH3A_AFCOEF110 (0x034) | ||
3301 | +#define ISPH3A_AFCOEF132 (0x038) | ||
3302 | +#define ISPH3A_AFCOEF154 (0x03C) | ||
3303 | +#define ISPH3A_AFCOEF176 (0x040) | ||
3304 | +#define ISPH3A_AFCOEF198 (0x044) | ||
3305 | +#define ISPH3A_AFCOEF1010 (0x048) | ||
3306 | + | ||
3307 | +#define ISPPRV_PCR (0x004) | ||
3308 | +#define ISPPRV_HORZ_INFO (0x008) | ||
3309 | +#define ISPPRV_VERT_INFO (0x00C) | ||
3310 | +#define ISPPRV_RSDR_ADDR (0x010) | ||
3311 | +#define ISPPRV_RADR_OFFSET (0x014) | ||
3312 | +#define ISPPRV_DSDR_ADDR (0x018) | ||
3313 | +#define ISPPRV_DRKF_OFFSET (0x01C) | ||
3314 | +#define ISPPRV_WSDR_ADDR (0x020) | ||
3315 | +#define ISPPRV_WADD_OFFSET (0x024) | ||
3316 | +#define ISPPRV_AVE (0x028) | ||
3317 | +#define ISPPRV_HMED (0x02C) | ||
3318 | +#define ISPPRV_NF (0x030) | ||
3319 | +#define ISPPRV_WB_DGAIN (0x034) | ||
3320 | +#define ISPPRV_WBGAIN (0x038) | ||
3321 | +#define ISPPRV_WBSEL (0x03C) | ||
3322 | +#define ISPPRV_CFA (0x040) | ||
3323 | +#define ISPPRV_BLKADJOFF (0x044) | ||
3324 | +#define ISPPRV_RGB_MAT1 (0x048) | ||
3325 | +#define ISPPRV_RGB_MAT2 (0x04C) | ||
3326 | +#define ISPPRV_RGB_MAT3 (0x050) | ||
3327 | +#define ISPPRV_RGB_MAT4 (0x054) | ||
3328 | +#define ISPPRV_RGB_MAT5 (0x058) | ||
3329 | +#define ISPPRV_RGB_OFF1 (0x05C) | ||
3330 | +#define ISPPRV_RGB_OFF2 (0x060) | ||
3331 | +#define ISPPRV_CSC0 (0x064) | ||
3332 | +#define ISPPRV_CSC1 (0x068) | ||
3333 | +#define ISPPRV_CSC2 (0x06C) | ||
3334 | +#define ISPPRV_CSC_OFFSET (0x070) | ||
3335 | +#define ISPPRV_CNT_BRT (0x074) | ||
3336 | +#define ISPPRV_CSUP (0x078) | ||
3337 | +#define ISPPRV_SETUP_YC (0x07C) | ||
3338 | +#define ISPPRV_SET_TBL_ADDR (0x080) | ||
3339 | +#define ISPPRV_SET_TBL_DATA (0x084) | ||
3340 | +#define ISPPRV_CDC_THR0 (0x090) | ||
3341 | +#define ISPPRV_CDC_THR1 (ISPPRV_CDC_THR0 + (0x4)) | ||
3342 | +#define ISPPRV_CDC_THR2 (ISPPRV_CDC_THR0 + (0x4) * 2) | ||
3343 | +#define ISPPRV_CDC_THR3 (ISPPRV_CDC_THR0 + (0x4) * 3) | ||
3344 | + | ||
3345 | +#define ISPPRV_REDGAMMA_TABLE_ADDR 0x0000 | ||
3346 | +#define ISPPRV_GREENGAMMA_TABLE_ADDR 0x0400 | ||
3347 | +#define ISPPRV_BLUEGAMMA_TABLE_ADDR 0x0800 | ||
3348 | +#define ISPPRV_NF_TABLE_ADDR 0x0C00 | ||
3349 | +#define ISPPRV_YENH_TABLE_ADDR 0x1000 | ||
3350 | +#define ISPPRV_CFA_TABLE_ADDR 0x1400 | ||
3351 | + | ||
3352 | +#define ISPPRV_MAXOUTPUT_WIDTH 1280 | ||
3353 | +#define ISPPRV_MAXOUTPUT_WIDTH_ES2 3300 | ||
3354 | +#define ISPRSZ_MIN_OUTPUT 64 | ||
3355 | +#define ISPRSZ_MAX_OUTPUT 3312 | ||
3356 | + | ||
3357 | +/* Resizer module register offset */ | ||
3358 | +#define ISPRSZ_PID (0x000) | ||
3359 | +#define ISPRSZ_PCR (0x004) | ||
3360 | +#define ISPRSZ_CNT (0x008) | ||
3361 | +#define ISPRSZ_OUT_SIZE (0x00C) | ||
3362 | +#define ISPRSZ_IN_START (0x010) | ||
3363 | +#define ISPRSZ_IN_SIZE (0x014) | ||
3364 | +#define ISPRSZ_SDR_INADD (0x018) | ||
3365 | +#define ISPRSZ_SDR_INOFF (0x01C) | ||
3366 | +#define ISPRSZ_SDR_OUTADD (0x020) | ||
3367 | +#define ISPRSZ_SDR_OUTOFF (0x024) | ||
3368 | +#define ISPRSZ_HFILT10 (0x028) | ||
3369 | +#define ISPRSZ_HFILT32 (0x02C) | ||
3370 | +#define ISPRSZ_HFILT54 (0x030) | ||
3371 | +#define ISPRSZ_HFILT76 (0x034) | ||
3372 | +#define ISPRSZ_HFILT98 (0x038) | ||
3373 | +#define ISPRSZ_HFILT1110 (0x03C) | ||
3374 | +#define ISPRSZ_HFILT1312 (0x040) | ||
3375 | +#define ISPRSZ_HFILT1514 (0x044) | ||
3376 | +#define ISPRSZ_HFILT1716 (0x048) | ||
3377 | +#define ISPRSZ_HFILT1918 (0x04C) | ||
3378 | +#define ISPRSZ_HFILT2120 (0x050) | ||
3379 | +#define ISPRSZ_HFILT2322 (0x054) | ||
3380 | +#define ISPRSZ_HFILT2524 (0x058) | ||
3381 | +#define ISPRSZ_HFILT2726 (0x05C) | ||
3382 | +#define ISPRSZ_HFILT2928 (0x060) | ||
3383 | +#define ISPRSZ_HFILT3130 (0x064) | ||
3384 | +#define ISPRSZ_VFILT10 (0x068) | ||
3385 | +#define ISPRSZ_VFILT32 (0x06C) | ||
3386 | +#define ISPRSZ_VFILT54 (0x070) | ||
3387 | +#define ISPRSZ_VFILT76 (0x074) | ||
3388 | +#define ISPRSZ_VFILT98 (0x078) | ||
3389 | +#define ISPRSZ_VFILT1110 (0x07C) | ||
3390 | +#define ISPRSZ_VFILT1312 (0x080) | ||
3391 | +#define ISPRSZ_VFILT1514 (0x084) | ||
3392 | +#define ISPRSZ_VFILT1716 (0x088) | ||
3393 | +#define ISPRSZ_VFILT1918 (0x08C) | ||
3394 | +#define ISPRSZ_VFILT2120 (0x090) | ||
3395 | +#define ISPRSZ_VFILT2322 (0x094) | ||
3396 | +#define ISPRSZ_VFILT2524 (0x098) | ||
3397 | +#define ISPRSZ_VFILT2726 (0x09C) | ||
3398 | +#define ISPRSZ_VFILT2928 (0x0A0) | ||
3399 | +#define ISPRSZ_VFILT3130 (0x0A4) | ||
3400 | +#define ISPRSZ_YENH (0x0A8) | ||
3401 | + | ||
3402 | +/* MMU module registers */ | ||
3403 | +#define ISPMMU_REVISION (0x000) | ||
3404 | +#define ISPMMU_SYSCONFIG (0x010) | ||
3405 | +#define ISPMMU_SYSSTATUS (0x014) | ||
3406 | +#define ISPMMU_IRQSTATUS (0x018) | ||
3407 | +#define ISPMMU_IRQENABLE (0x01C) | ||
3408 | +#define ISPMMU_WALKING_ST (0x040) | ||
3409 | +#define ISPMMU_CNTL (0x044) | ||
3410 | +#define ISPMMU_FAULT_AD (0x048) | ||
3411 | +#define ISPMMU_TTB (0x04C) | ||
3412 | +#define ISPMMU_LOCK (0x050) | ||
3413 | +#define ISPMMU_LD_TLB (0x054) | ||
3414 | +#define ISPMMU_CAM (0x058) | ||
3415 | +#define ISPMMU_RAM (0x05C) | ||
3416 | +#define ISPMMU_GFLUSH (0x060) | ||
3417 | +#define ISPMMU_FLUSH_ENTRY (0x064) | ||
3418 | +#define ISPMMU_READ_CAM (0x068) | ||
3419 | +#define ISPMMU_READ_RAM (0x06c) | ||
3420 | +#define ISPMMU_EMU_FAULT_AD (0x070) | ||
3421 | + | ||
3422 | +#define ISP_INT_CLR 0xFF113F11 | ||
3423 | +#define ISPPRV_PCR_EN 1 | ||
3424 | +#define ISPPRV_PCR_BUSY (1 << 1) | ||
3425 | +#define ISPPRV_PCR_SOURCE (1 << 2) | ||
3426 | +#define ISPPRV_PCR_ONESHOT (1 << 3) | ||
3427 | +#define ISPPRV_PCR_WIDTH (1 << 4) | ||
3428 | +#define ISPPRV_PCR_INVALAW (1 << 5) | ||
3429 | +#define ISPPRV_PCR_DRKFEN (1 << 6) | ||
3430 | +#define ISPPRV_PCR_DRKFCAP (1 << 7) | ||
3431 | +#define ISPPRV_PCR_HMEDEN (1 << 8) | ||
3432 | +#define ISPPRV_PCR_NFEN (1 << 9) | ||
3433 | +#define ISPPRV_PCR_CFAEN (1 << 10) | ||
3434 | +#define ISPPRV_PCR_CFAFMT_SHIFT 11 | ||
3435 | +#define ISPPRV_PCR_CFAFMT_MASK 0x7800 | ||
3436 | +#define ISPPRV_PCR_CFAFMT_BAYER (0 << 11) | ||
3437 | +#define ISPPRV_PCR_CFAFMT_SONYVGA (1 << 11) | ||
3438 | +#define ISPPRV_PCR_CFAFMT_RGBFOVEON (2 << 11) | ||
3439 | +#define ISPPRV_PCR_CFAFMT_DNSPL (3 << 11) | ||
3440 | +#define ISPPRV_PCR_CFAFMT_HONEYCOMB (4 << 11) | ||
3441 | +#define ISPPRV_PCR_CFAFMT_RRGGBBFOVEON (5 << 11) | ||
3442 | +#define ISPPRV_PCR_YNENHEN (1 << 15) | ||
3443 | +#define ISPPRV_PCR_SUPEN (1 << 16) | ||
3444 | +#define ISPPRV_PCR_YCPOS_SHIFT 17 | ||
3445 | +#define ISPPRV_PCR_YCPOS_YCrYCb (0 << 17) | ||
3446 | +#define ISPPRV_PCR_YCPOS_YCbYCr (1 << 17) | ||
3447 | +#define ISPPRV_PCR_YCPOS_CbYCrY (2 << 17) | ||
3448 | +#define ISPPRV_PCR_YCPOS_CrYCbY (3 << 17) | ||
3449 | +#define ISPPRV_PCR_RSZPORT (1 << 19) | ||
3450 | +#define ISPPRV_PCR_SDRPORT (1 << 20) | ||
3451 | +#define ISPPRV_PCR_SCOMP_EN (1 << 21) | ||
3452 | +#define ISPPRV_PCR_SCOMP_SFT_SHIFT (22) | ||
3453 | +#define ISPPRV_PCR_SCOMP_SFT_MASK (~(7 << 22)) | ||
3454 | +#define ISPPRV_PCR_GAMMA_BYPASS (1 << 26) | ||
3455 | +#define ISPPRV_PCR_DCOREN (1 << 27) | ||
3456 | +#define ISPPRV_PCR_DCCOUP (1 << 28) | ||
3457 | +#define ISPPRV_PCR_DRK_FAIL (1 << 31) | ||
3458 | + | ||
3459 | +#define ISPPRV_HORZ_INFO_EPH_SHIFT 0 | ||
3460 | +#define ISPPRV_HORZ_INFO_EPH_MASK 0x3fff | ||
3461 | +#define ISPPRV_HORZ_INFO_SPH_SHIFT 16 | ||
3462 | +#define ISPPRV_HORZ_INFO_SPH_MASK 0x3fff0 | ||
3463 | + | ||
3464 | +#define ISPPRV_VERT_INFO_ELV_SHIFT 0 | ||
3465 | +#define ISPPRV_VERT_INFO_ELV_MASK 0x3fff | ||
3466 | +#define ISPPRV_VERT_INFO_SLV_SHIFT 16 | ||
3467 | +#define ISPPRV_VERT_INFO_SLV_MASK 0x3fff0 | ||
3468 | + | ||
3469 | +#define ISPPRV_AVE_EVENDIST_SHIFT 2 | ||
3470 | +#define ISPPRV_AVE_EVENDIST_1 0x0 | ||
3471 | +#define ISPPRV_AVE_EVENDIST_2 0x1 | ||
3472 | +#define ISPPRV_AVE_EVENDIST_3 0x2 | ||
3473 | +#define ISPPRV_AVE_EVENDIST_4 0x3 | ||
3474 | +#define ISPPRV_AVE_ODDDIST_SHIFT 4 | ||
3475 | +#define ISPPRV_AVE_ODDDIST_1 0x0 | ||
3476 | +#define ISPPRV_AVE_ODDDIST_2 0x1 | ||
3477 | +#define ISPPRV_AVE_ODDDIST_3 0x2 | ||
3478 | +#define ISPPRV_AVE_ODDDIST_4 0x3 | ||
3479 | + | ||
3480 | +#define ISPPRV_HMED_THRESHOLD_SHIFT 0 | ||
3481 | +#define ISPPRV_HMED_EVENDIST (1 << 8) | ||
3482 | +#define ISPPRV_HMED_ODDDIST (1 << 9) | ||
3483 | + | ||
3484 | +#define ISPPRV_WBGAIN_COEF0_SHIFT 0 | ||
3485 | +#define ISPPRV_WBGAIN_COEF1_SHIFT 8 | ||
3486 | +#define ISPPRV_WBGAIN_COEF2_SHIFT 16 | ||
3487 | +#define ISPPRV_WBGAIN_COEF3_SHIFT 24 | ||
3488 | + | ||
3489 | +#define ISPPRV_WBSEL_COEF0 0x0 | ||
3490 | +#define ISPPRV_WBSEL_COEF1 0x1 | ||
3491 | +#define ISPPRV_WBSEL_COEF2 0x2 | ||
3492 | +#define ISPPRV_WBSEL_COEF3 0x3 | ||
3493 | + | ||
3494 | +#define ISPPRV_WBSEL_N0_0_SHIFT 0 | ||
3495 | +#define ISPPRV_WBSEL_N0_1_SHIFT 2 | ||
3496 | +#define ISPPRV_WBSEL_N0_2_SHIFT 4 | ||
3497 | +#define ISPPRV_WBSEL_N0_3_SHIFT 6 | ||
3498 | +#define ISPPRV_WBSEL_N1_0_SHIFT 8 | ||
3499 | +#define ISPPRV_WBSEL_N1_1_SHIFT 10 | ||
3500 | +#define ISPPRV_WBSEL_N1_2_SHIFT 12 | ||
3501 | +#define ISPPRV_WBSEL_N1_3_SHIFT 14 | ||
3502 | +#define ISPPRV_WBSEL_N2_0_SHIFT 16 | ||
3503 | +#define ISPPRV_WBSEL_N2_1_SHIFT 18 | ||
3504 | +#define ISPPRV_WBSEL_N2_2_SHIFT 20 | ||
3505 | +#define ISPPRV_WBSEL_N2_3_SHIFT 22 | ||
3506 | +#define ISPPRV_WBSEL_N3_0_SHIFT 24 | ||
3507 | +#define ISPPRV_WBSEL_N3_1_SHIFT 26 | ||
3508 | +#define ISPPRV_WBSEL_N3_2_SHIFT 28 | ||
3509 | +#define ISPPRV_WBSEL_N3_3_SHIFT 30 | ||
3510 | + | ||
3511 | +#define ISPPRV_CFA_GRADTH_HOR_SHIFT 0 | ||
3512 | +#define ISPPRV_CFA_GRADTH_VER_SHIFT 8 | ||
3513 | + | ||
3514 | +#define ISPPRV_BLKADJOFF_B_SHIFT 0 | ||
3515 | +#define ISPPRV_BLKADJOFF_G_SHIFT 8 | ||
3516 | +#define ISPPRV_BLKADJOFF_R_SHIFT 16 | ||
3517 | + | ||
3518 | +#define ISPPRV_RGB_MAT1_MTX_RR_SHIFT 0 | ||
3519 | +#define ISPPRV_RGB_MAT1_MTX_GR_SHIFT 16 | ||
3520 | + | ||
3521 | +#define ISPPRV_RGB_MAT2_MTX_BR_SHIFT 0 | ||
3522 | +#define ISPPRV_RGB_MAT2_MTX_RG_SHIFT 16 | ||
3523 | + | ||
3524 | +#define ISPPRV_RGB_MAT3_MTX_GG_SHIFT 0 | ||
3525 | +#define ISPPRV_RGB_MAT3_MTX_BG_SHIFT 16 | ||
3526 | + | ||
3527 | +#define ISPPRV_RGB_MAT4_MTX_RB_SHIFT 0 | ||
3528 | +#define ISPPRV_RGB_MAT4_MTX_GB_SHIFT 16 | ||
3529 | + | ||
3530 | +#define ISPPRV_RGB_MAT5_MTX_BB_SHIFT 0 | ||
3531 | + | ||
3532 | +#define ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT 0 | ||
3533 | +#define ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT 16 | ||
3534 | + | ||
3535 | +#define ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT 0 | ||
3536 | + | ||
3537 | +#define ISPPRV_CSC0_RY_SHIFT 0 | ||
3538 | +#define ISPPRV_CSC0_GY_SHIFT 10 | ||
3539 | +#define ISPPRV_CSC0_BY_SHIFT 20 | ||
3540 | + | ||
3541 | +#define ISPPRV_CSC1_RCB_SHIFT 0 | ||
3542 | +#define ISPPRV_CSC1_GCB_SHIFT 10 | ||
3543 | +#define ISPPRV_CSC1_BCB_SHIFT 20 | ||
3544 | + | ||
3545 | +#define ISPPRV_CSC2_RCR_SHIFT 0 | ||
3546 | +#define ISPPRV_CSC2_GCR_SHIFT 10 | ||
3547 | +#define ISPPRV_CSC2_BCR_SHIFT 20 | ||
3548 | + | ||
3549 | +#define ISPPRV_CSC_OFFSET_CR_SHIFT 0 | ||
3550 | +#define ISPPRV_CSC_OFFSET_CB_SHIFT 8 | ||
3551 | +#define ISPPRV_CSC_OFFSET_Y_SHIFT 16 | ||
3552 | + | ||
3553 | +#define ISPPRV_CNT_BRT_BRT_SHIFT 0 | ||
3554 | +#define ISPPRV_CNT_BRT_CNT_SHIFT 8 | ||
3555 | + | ||
3556 | +#define ISPPRV_CONTRAST_MAX 0x10 | ||
3557 | +#define ISPPRV_CONTRAST_MIN 0xFF | ||
3558 | +#define ISPPRV_BRIGHT_MIN 0x00 | ||
3559 | +#define ISPPRV_BRIGHT_MAX 0xFF | ||
3560 | + | ||
3561 | +#define ISPPRV_CSUP_CSUPG_SHIFT 0 | ||
3562 | +#define ISPPRV_CSUP_THRES_SHIFT 8 | ||
3563 | +#define ISPPRV_CSUP_HPYF_SHIFT 16 | ||
3564 | + | ||
3565 | +#define ISPPRV_SETUP_YC_MINC_SHIFT 0 | ||
3566 | +#define ISPPRV_SETUP_YC_MAXC_SHIFT 8 | ||
3567 | +#define ISPPRV_SETUP_YC_MINY_SHIFT 16 | ||
3568 | +#define ISPPRV_SETUP_YC_MAXY_SHIFT 24 | ||
3569 | +#define ISPPRV_YC_MAX 0xFF | ||
3570 | +#define ISPPRV_YC_MIN 0x0 | ||
3571 | + | ||
3572 | +/* Define bit fields within selected registers */ | ||
3573 | +#define ISP_REVISION_SHIFT 0 | ||
3574 | + | ||
3575 | +#define ISP_SYSCONFIG_AUTOIDLE 0 | ||
3576 | +#define ISP_SYSCONFIG_SOFTRESET (1 << 1) | ||
3577 | +#define ISP_SYSCONFIG_MIDLEMODE_SHIFT 12 | ||
3578 | +#define ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY 0x0 | ||
3579 | +#define ISP_SYSCONFIG_MIDLEMODE_NOSTANBY 0x1 | ||
3580 | +#define ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY 0x2 | ||
3581 | + | ||
3582 | +#define ISP_SYSSTATUS_RESETDONE 0 | ||
3583 | + | ||
3584 | +#define IRQ0ENABLE_CSIA_IRQ 1 | ||
3585 | +#define IRQ0ENABLE_CSIA_LC1_IRQ (1 << 1) | ||
3586 | +#define IRQ0ENABLE_CSIA_LC2_IRQ (1 << 2) | ||
3587 | +#define IRQ0ENABLE_CSIA_LC3_IRQ (1 << 3) | ||
3588 | +#define IRQ0ENABLE_CSIB_IRQ (1 << 4) | ||
3589 | +#define IRQ0ENABLE_CSIB_LC1_IRQ (1 << 5) | ||
3590 | +#define IRQ0ENABLE_CSIB_LC2_IRQ (1 << 6) | ||
3591 | +#define IRQ0ENABLE_CSIB_LC3_IRQ (1 << 7) | ||
3592 | +#define IRQ0ENABLE_CCDC_VD0_IRQ (1 << 8) | ||
3593 | +#define IRQ0ENABLE_CCDC_VD1_IRQ (1 << 9) | ||
3594 | +#define IRQ0ENABLE_CCDC_VD2_IRQ (1 << 10) | ||
3595 | +#define IRQ0ENABLE_CCDC_ERR_IRQ (1 << 11) | ||
3596 | +#define IRQ0ENABLE_H3A_AF_DONE_IRQ (1 << 12) | ||
3597 | +#define IRQ0ENABLE_H3A_AWB_DONE_IRQ (1 << 13) | ||
3598 | +#define IRQ0ENABLE_HIST_DONE_IRQ (1 << 16) | ||
3599 | +#define IRQ0ENABLE_CCDC_LSC_DONE_IRQ (1 << 17) | ||
3600 | +#define IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ (1 << 18) | ||
3601 | +#define IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ (1 << 19) | ||
3602 | +#define IRQ0ENABLE_PRV_DONE_IRQ (1 << 20) | ||
3603 | +#define IRQ0ENABLE_RSZ_DONE_IRQ (1 << 24) | ||
3604 | +#define IRQ0ENABLE_OVF_IRQ (1 << 25) | ||
3605 | +#define IRQ0ENABLE_PING_IRQ (1 << 26) | ||
3606 | +#define IRQ0ENABLE_PONG_IRQ (1 << 27) | ||
3607 | +#define IRQ0ENABLE_MMU_ERR_IRQ (1 << 28) | ||
3608 | +#define IRQ0ENABLE_OCP_ERR_IRQ (1 << 29) | ||
3609 | +#define IRQ0ENABLE_SEC_ERR_IRQ (1 << 30) | ||
3610 | +#define IRQ0ENABLE_HS_VS_IRQ (1 << 31) | ||
3611 | + | ||
3612 | +#define IRQ0STATUS_CSIA_IRQ 1 | ||
3613 | +#define IRQ0STATUS_CSIA_LC1_IRQ (1 << 1) | ||
3614 | +#define IRQ0STATUS_CSIA_LC2_IRQ (1 << 2) | ||
3615 | +#define IRQ0STATUS_CSIA_LC3_IRQ (1 << 3) | ||
3616 | +#define IRQ0STATUS_CSIB_IRQ (1 << 4) | ||
3617 | +#define IRQ0STATUS_CSIB_LC1_IRQ (1 << 5) | ||
3618 | +#define IRQ0STATUS_CSIB_LC2_IRQ (1 << 6) | ||
3619 | +#define IRQ0STATUS_CSIB_LC3_IRQ (1 << 7) | ||
3620 | +#define IRQ0STATUS_CCDC_VD0_IRQ (1 << 8) | ||
3621 | +#define IRQ0STATUS_CCDC_VD1_IRQ (1 << 9) | ||
3622 | +#define IRQ0STATUS_CCDC_VD2_IRQ (1 << 10) | ||
3623 | +#define IRQ0STATUS_CCDC_ERR_IRQ (1 << 11) | ||
3624 | +#define IRQ0STATUS_H3A_AF_DONE_IRQ (1 << 12) | ||
3625 | +#define IRQ0STATUS_H3A_AWB_DONE_IRQ (1 << 13) | ||
3626 | +#define IRQ0STATUS_HIST_DONE_IRQ (1 << 16) | ||
3627 | +#define IRQ0STATUS_PRV_DONE_IRQ (1 << 20) | ||
3628 | +#define IRQ0STATUS_RSZ_DONE_IRQ (1 << 24) | ||
3629 | +#define IRQ0STATUS_OVF_IRQ (1 << 25) | ||
3630 | +#define IRQ0STATUS_PING_IRQ (1 << 26) | ||
3631 | +#define IRQ0STATUS_PONG_IRQ (1 << 27) | ||
3632 | +#define IRQ0STATUS_MMU_ERR_IRQ (1 << 28) | ||
3633 | +#define IRQ0STATUS_OCP_ERR_IRQ (1 << 29) | ||
3634 | +#define IRQ0STATUS_SEC_ERR_IRQ (1 << 30) | ||
3635 | +#define IRQ0STATUS_HS_VS_IRQ (1 << 31) | ||
3636 | + | ||
3637 | +#define TCTRL_GRESET_LEN 0 | ||
3638 | + | ||
3639 | +#define TCTRL_PSTRB_REPLAY_DELAY 0 | ||
3640 | +#define TCTRL_PSTRB_REPLAY_COUNTER_SHIFT 25 | ||
3641 | + | ||
3642 | +#define ISPCTRL_PAR_SER_CLK_SEL_PARALLEL 0x0 | ||
3643 | +#define ISPCTRL_PAR_SER_CLK_SEL_CSIA 0x1 | ||
3644 | +#define ISPCTRL_PAR_SER_CLK_SEL_CSIB 0x2 | ||
3645 | +#define ISPCTRL_PAR_SER_CLK_SEL_MASK 0xFFFFFFFC | ||
3646 | + | ||
3647 | +#define ISPCTRL_PAR_BRIDGE_SHIFT 2 | ||
3648 | +#define ISPCTRL_PAR_BRIDGE_DISABLE (0x0 << 2) | ||
3649 | +#define ISPCTRL_PAR_BRIDGE_LENDIAN (0x2 << 2) | ||
3650 | +#define ISPCTRL_PAR_BRIDGE_BENDIAN (0x3 << 2) | ||
3651 | + | ||
3652 | +#define ISPCTRL_PAR_CLK_POL_SHIFT 4 | ||
3653 | +#define ISPCTRL_PAR_CLK_POL_INV (1 << 4) | ||
3654 | +#define ISPCTRL_PING_PONG_EN (1 << 5) | ||
3655 | +#define ISPCTRL_SHIFT_SHIFT 6 | ||
3656 | +#define ISPCTRL_SHIFT_0 (0x0 << 6) | ||
3657 | +#define ISPCTRL_SHIFT_2 (0x1 << 6) | ||
3658 | +#define ISPCTRL_SHIFT_4 (0x2 << 6) | ||
3659 | +#define ISPCTRL_SHIFT_MASK (~(0x3 << 6)) | ||
3660 | + | ||
3661 | +#define ISPCTRL_CCDC_CLK_EN (1 << 8) | ||
3662 | +#define ISPCTRL_SCMP_CLK_EN (1 << 9) | ||
3663 | +#define ISPCTRL_H3A_CLK_EN (1 << 10) | ||
3664 | +#define ISPCTRL_HIST_CLK_EN (1 << 11) | ||
3665 | +#define ISPCTRL_PREV_CLK_EN (1 << 12) | ||
3666 | +#define ISPCTRL_RSZ_CLK_EN (1 << 13) | ||
3667 | +#define ISPCTRL_SYNC_DETECT_SHIFT 14 | ||
3668 | +#define ISPCTRL_SYNC_DETECT_HSFALL (0x0 << ISPCTRL_SYNC_DETECT_SHIFT) | ||
3669 | +#define ISPCTRL_SYNC_DETECT_HSRISE (0x1 << ISPCTRL_SYNC_DETECT_SHIFT) | ||
3670 | +#define ISPCTRL_SYNC_DETECT_VSFALL (0x2 << ISPCTRL_SYNC_DETECT_SHIFT) | ||
3671 | +#define ISPCTRL_SYNC_DETECT_VSRISE (0x3 << ISPCTRL_SYNC_DETECT_SHIFT) | ||
3672 | +#define ISPCTRL_SYNC_DETECT_MASK (0x3 << ISPCTRL_SYNC_DETECT_SHIFT) | ||
3673 | + | ||
3674 | +#define ISPCTRL_CCDC_RAM_EN (1 << 16) | ||
3675 | +#define ISPCTRL_PREV_RAM_EN (1 << 17) | ||
3676 | +#define ISPCTRL_SBL_RD_RAM_EN (1 << 18) | ||
3677 | +#define ISPCTRL_SBL_WR1_RAM_EN (1 << 19) | ||
3678 | +#define ISPCTRL_SBL_WR0_RAM_EN (1 << 20) | ||
3679 | +#define ISPCTRL_SBL_AUTOIDLE (1 << 21) | ||
3680 | +#define ISPCTRL_SBL_SHARED_RPORTB (1 << 28) | ||
3681 | +#define ISPCTRL_JPEG_FLUSH (1 << 30) | ||
3682 | +#define ISPCTRL_CCDC_FLUSH (1 << 31) | ||
3683 | + | ||
3684 | +#define ISPSECURE_SECUREMODE 0 | ||
3685 | + | ||
3686 | +#define ISPTCTRL_CTRL_DIV_LOW 0x0 | ||
3687 | +#define ISPTCTRL_CTRL_DIV_HIGH 0x1 | ||
3688 | +#define ISPTCTRL_CTRL_DIV_BYPASS 0x1F | ||
3689 | + | ||
3690 | +#define ISPTCTRL_CTRL_DIVA_SHIFT 0 | ||
3691 | +#define ISPTCTRL_CTRL_DIVA_MASK (0x1F << ISPTCTRL_CTRL_DIVA_SHIFT) | ||
3692 | + | ||
3693 | +#define ISPTCTRL_CTRL_DIVB_SHIFT 5 | ||
3694 | +#define ISPTCTRL_CTRL_DIVB_MASK (0x1F << ISPTCTRL_CTRL_DIVB_SHIFT) | ||
3695 | + | ||
3696 | +#define ISPTCTRL_CTRL_DIVC_SHIFT 10 | ||
3697 | +#define ISPTCTRL_CTRL_DIVC_NOCLOCK (0x0 << 10) | ||
3698 | + | ||
3699 | +#define ISPTCTRL_CTRL_SHUTEN (1 << 21) | ||
3700 | +#define ISPTCTRL_CTRL_PSTRBEN (1 << 22) | ||
3701 | +#define ISPTCTRL_CTRL_STRBEN (1 << 23) | ||
3702 | +#define ISPTCTRL_CTRL_SHUTPOL (1 << 24) | ||
3703 | +#define ISPTCTRL_CTRL_STRBPSTRBPOL (1 << 26) | ||
3704 | + | ||
3705 | +#define ISPTCTRL_CTRL_INSEL_SHIFT 27 | ||
3706 | +#define ISPTCTRL_CTRL_INSEL_PARALLEL (0x0 << 27) | ||
3707 | +#define ISPTCTRL_CTRL_INSEL_CSIA (0x1 << 27) | ||
3708 | +#define ISPTCTRL_CTRL_INSEL_CSIB (0x2 << 27) | ||
3709 | + | ||
3710 | +#define ISPTCTRL_CTRL_GRESETEn (1 << 29) | ||
3711 | +#define ISPTCTRL_CTRL_GRESETPOL (1 << 30) | ||
3712 | +#define ISPTCTRL_CTRL_GRESETDIR (1 << 31) | ||
3713 | + | ||
3714 | +#define ISPTCTRL_FRAME_SHUT_SHIFT 0 | ||
3715 | +#define ISPTCTRL_FRAME_PSTRB_SHIFT 6 | ||
3716 | +#define ISPTCTRL_FRAME_STRB_SHIFT 12 | ||
3717 | + | ||
3718 | +#define ISPCCDC_PID_PREV_SHIFT 0 | ||
3719 | +#define ISPCCDC_PID_CID_SHIFT 8 | ||
3720 | +#define ISPCCDC_PID_TID_SHIFT 16 | ||
3721 | + | ||
3722 | +#define ISPCCDC_PCR_EN 1 | ||
3723 | +#define ISPCCDC_PCR_BUSY (1 << 1) | ||
3724 | + | ||
3725 | +#define ISPCCDC_SYN_MODE_VDHDOUT 0x1 | ||
3726 | +#define ISPCCDC_SYN_MODE_FLDOUT (1 << 1) | ||
3727 | +#define ISPCCDC_SYN_MODE_VDPOL (1 << 2) | ||
3728 | +#define ISPCCDC_SYN_MODE_HDPOL (1 << 3) | ||
3729 | +#define ISPCCDC_SYN_MODE_FLDPOL (1 << 4) | ||
3730 | +#define ISPCCDC_SYN_MODE_EXWEN (1 << 5) | ||
3731 | +#define ISPCCDC_SYN_MODE_DATAPOL (1 << 6) | ||
3732 | +#define ISPCCDC_SYN_MODE_FLDMODE (1 << 7) | ||
3733 | +#define ISPCCDC_SYN_MODE_DATSIZ_MASK 0xFFFFF8FF | ||
3734 | +#define ISPCCDC_SYN_MODE_DATSIZ_8_16 (0x0 << 8) | ||
3735 | +#define ISPCCDC_SYN_MODE_DATSIZ_12 (0x4 << 8) | ||
3736 | +#define ISPCCDC_SYN_MODE_DATSIZ_11 (0x5 << 8) | ||
3737 | +#define ISPCCDC_SYN_MODE_DATSIZ_10 (0x6 << 8) | ||
3738 | +#define ISPCCDC_SYN_MODE_DATSIZ_8 (0x7 << 8) | ||
3739 | +#define ISPCCDC_SYN_MODE_PACK8 (1 << 11) | ||
3740 | +#define ISPCCDC_SYN_MODE_INPMOD_MASK 0xFFFFCFFF | ||
3741 | +#define ISPCCDC_SYN_MODE_INPMOD_RAW (0 << 12) | ||
3742 | +#define ISPCCDC_SYN_MODE_INPMOD_YCBCR16 (1 << 12) | ||
3743 | +#define ISPCCDC_SYN_MODE_INPMOD_YCBCR8 (2 << 12) | ||
3744 | +#define ISPCCDC_SYN_MODE_LPF (1 << 14) | ||
3745 | +#define ISPCCDC_SYN_MODE_FLDSTAT (1 << 15) | ||
3746 | +#define ISPCCDC_SYN_MODE_VDHDEN (1 << 16) | ||
3747 | +#define ISPCCDC_SYN_MODE_WEN (1 << 17) | ||
3748 | +#define ISPCCDC_SYN_MODE_VP2SDR (1 << 18) | ||
3749 | +#define ISPCCDC_SYN_MODE_SDR2RSZ (1 << 19) | ||
3750 | + | ||
3751 | +#define ISPCCDC_HD_VD_WID_VDW_SHIFT 0 | ||
3752 | +#define ISPCCDC_HD_VD_WID_HDW_SHIFT 16 | ||
3753 | + | ||
3754 | +#define ISPCCDC_PIX_LINES_HLPRF_SHIFT 0 | ||
3755 | +#define ISPCCDC_PIX_LINES_PPLN_SHIFT 16 | ||
3756 | + | ||
3757 | +#define ISPCCDC_HORZ_INFO_NPH_SHIFT 0 | ||
3758 | +#define ISPCCDC_HORZ_INFO_NPH_MASK 0xFFFF8000 | ||
3759 | +#define ISPCCDC_HORZ_INFO_SPH_MASK 0x1000FFFF | ||
3760 | +#define ISPCCDC_HORZ_INFO_SPH_SHIFT 16 | ||
3761 | + | ||
3762 | +#define ISPCCDC_VERT_START_SLV0_SHIFT 16 | ||
3763 | +#define ISPCCDC_VERT_START_SLV0_MASK 0x1000FFFF | ||
3764 | +#define ISPCCDC_VERT_START_SLV1_SHIFT 0 | ||
3765 | + | ||
3766 | +#define ISPCCDC_VERT_LINES_NLV_MASK 0xFFFF8000 | ||
3767 | +#define ISPCCDC_VERT_LINES_NLV_SHIFT 0 | ||
3768 | + | ||
3769 | +#define ISPCCDC_CULLING_CULV_SHIFT 0 | ||
3770 | +#define ISPCCDC_CULLING_CULHODD_SHIFT 16 | ||
3771 | +#define ISPCCDC_CULLING_CULHEVN_SHIFT 24 | ||
3772 | + | ||
3773 | +#define ISPCCDC_HSIZE_OFF_SHIFT 0 | ||
3774 | + | ||
3775 | +#define ISPCCDC_SDOFST_FINV (1 << 14) | ||
3776 | +#define ISPCCDC_SDOFST_FOFST_1L 0 | ||
3777 | +#define ISPCCDC_SDOFST_FOFST_4L (3 << 12) | ||
3778 | +#define ISPCCDC_SDOFST_LOFST3_SHIFT 0 | ||
3779 | +#define ISPCCDC_SDOFST_LOFST2_SHIFT 3 | ||
3780 | +#define ISPCCDC_SDOFST_LOFST1_SHIFT 6 | ||
3781 | +#define ISPCCDC_SDOFST_LOFST0_SHIFT 9 | ||
3782 | +#define EVENEVEN 1 | ||
3783 | +#define ODDEVEN 2 | ||
3784 | +#define EVENODD 3 | ||
3785 | +#define ODDODD 4 | ||
3786 | + | ||
3787 | +#define ISPCCDC_CLAMP_OBGAIN_SHIFT 0 | ||
3788 | +#define ISPCCDC_CLAMP_OBST_SHIFT 10 | ||
3789 | +#define ISPCCDC_CLAMP_OBSLN_SHIFT 25 | ||
3790 | +#define ISPCCDC_CLAMP_OBSLEN_SHIFT 28 | ||
3791 | +#define ISPCCDC_CLAMP_CLAMPEN (1 << 31) | ||
3792 | + | ||
3793 | +#define ISPCCDC_COLPTN_R_Ye 0x0 | ||
3794 | +#define ISPCCDC_COLPTN_Gr_Cy 0x1 | ||
3795 | +#define ISPCCDC_COLPTN_Gb_G 0x2 | ||
3796 | +#define ISPCCDC_COLPTN_B_Mg 0x3 | ||
3797 | +#define ISPCCDC_COLPTN_CP0PLC0_SHIFT 0 | ||
3798 | +#define ISPCCDC_COLPTN_CP0PLC1_SHIFT 2 | ||
3799 | +#define ISPCCDC_COLPTN_CP0PLC2_SHIFT 4 | ||
3800 | +#define ISPCCDC_COLPTN_CP0PLC3_SHIFT 6 | ||
3801 | +#define ISPCCDC_COLPTN_CP1PLC0_SHIFT 8 | ||
3802 | +#define ISPCCDC_COLPTN_CP1PLC1_SHIFT 10 | ||
3803 | +#define ISPCCDC_COLPTN_CP1PLC2_SHIFT 12 | ||
3804 | +#define ISPCCDC_COLPTN_CP1PLC3_SHIFT 14 | ||
3805 | +#define ISPCCDC_COLPTN_CP2PLC0_SHIFT 16 | ||
3806 | +#define ISPCCDC_COLPTN_CP2PLC1_SHIFT 18 | ||
3807 | +#define ISPCCDC_COLPTN_CP2PLC2_SHIFT 20 | ||
3808 | +#define ISPCCDC_COLPTN_CP2PLC3_SHIFT 22 | ||
3809 | +#define ISPCCDC_COLPTN_CP3PLC0_SHIFT 24 | ||
3810 | +#define ISPCCDC_COLPTN_CP3PLC1_SHIFT 26 | ||
3811 | +#define ISPCCDC_COLPTN_CP3PLC2_SHIFT 28 | ||
3812 | +#define ISPCCDC_COLPTN_CP3PLC3_SHIFT 30 | ||
3813 | + | ||
3814 | +#define ISPCCDC_BLKCMP_B_MG_SHIFT 0 | ||
3815 | +#define ISPCCDC_BLKCMP_GB_G_SHIFT 8 | ||
3816 | +#define ISPCCDC_BLKCMP_GR_CY_SHIFT 16 | ||
3817 | +#define ISPCCDC_BLKCMP_R_YE_SHIFT 24 | ||
3818 | + | ||
3819 | +#define ISPCCDC_FPC_FPNUM_SHIFT 0 | ||
3820 | +#define ISPCCDC_FPC_FPCEN (1 << 15) | ||
3821 | +#define ISPCCDC_FPC_FPERR (1 << 16) | ||
3822 | + | ||
3823 | +#define ISPCCDC_VDINT_1_SHIFT 0 | ||
3824 | +#define ISPCCDC_VDINT_0_SHIFT 16 | ||
3825 | +#define ISPCCDC_VDINT_0_MASK 0x7FFF | ||
3826 | +#define ISPCCDC_VDINT_1_MASK 0x7FFF | ||
3827 | + | ||
3828 | +#define ISPCCDC_ALAW_GWDI_SHIFT 0 | ||
3829 | +#define ISPCCDC_ALAW_CCDTBL (1 << 3) | ||
3830 | + | ||
3831 | +#define ISPCCDC_REC656IF_R656ON 1 | ||
3832 | +#define ISPCCDC_REC656IF_ECCFVH (1 << 1) | ||
3833 | + | ||
3834 | +#define ISPCCDC_CFG_BW656 (1 << 5) | ||
3835 | +#define ISPCCDC_CFG_FIDMD_SHIFT 6 | ||
3836 | +#define ISPCCDC_CFG_WENLOG (1 << 8) | ||
3837 | +#define ISPCCDC_CFG_WENLOG_AND (0 << 8) | ||
3838 | +#define ISPCCDC_CFG_WENLOG_OR (1 << 8) | ||
3839 | +#define ISPCCDC_CFG_Y8POS (1 << 11) | ||
3840 | +#define ISPCCDC_CFG_BSWD (1 << 12) | ||
3841 | +#define ISPCCDC_CFG_MSBINVI (1 << 13) | ||
3842 | +#define ISPCCDC_CFG_VDLC (1 << 15) | ||
3843 | + | ||
3844 | +#define ISPCCDC_FMTCFG_FMTEN 0x1 | ||
3845 | +#define ISPCCDC_FMTCFG_LNALT (1 << 1) | ||
3846 | +#define ISPCCDC_FMTCFG_LNUM_SHIFT 2 | ||
3847 | +#define ISPCCDC_FMTCFG_PLEN_ODD_SHIFT 4 | ||
3848 | +#define ISPCCDC_FMTCFG_PLEN_EVEN_SHIFT 8 | ||
3849 | +#define ISPCCDC_FMTCFG_VPIN_MASK 0xFFFF8000 | ||
3850 | +#define ISPCCDC_FMTCFG_VPIN_12_3 (0x3 << 12) | ||
3851 | +#define ISPCCDC_FMTCFG_VPIN_11_2 (0x4 << 12) | ||
3852 | +#define ISPCCDC_FMTCFG_VPIN_10_1 (0x5 << 12) | ||
3853 | +#define ISPCCDC_FMTCFG_VPIN_9_0 (0x6 << 12) | ||
3854 | +#define ISPCCDC_FMTCFG_VPEN (1 << 15) | ||
3855 | + | ||
3856 | +#define ISPCCDC_FMTCF_VPIF_FRQ_MASK 0xFFF8FFFF | ||
3857 | +#define ISPCCDC_FMTCF_VPIF_FRQ_BY2 (0x0 << 16) | ||
3858 | +#define ISPCCDC_FMTCF_VPIF_FRQ_BY3 (0x1 << 16) | ||
3859 | +#define ISPCCDC_FMTCF_VPIF_FRQ_BY4 (0x2 << 16) | ||
3860 | +#define ISPCCDC_FMTCF_VPIF_FRQ_BY5 (0x3 << 16) | ||
3861 | +#define ISPCCDC_FMTCF_VPIF_FRQ_BY6 (0x4 << 16) | ||
3862 | + | ||
3863 | +#define ISPCCDC_FMT_HORZ_FMTLNH_SHIFT 0 | ||
3864 | +#define ISPCCDC_FMT_HORZ_FMTSPH_SHIFT 16 | ||
3865 | + | ||
3866 | +#define ISPCCDC_FMT_VERT_FMTLNV_SHIFT 0 | ||
3867 | +#define ISPCCDC_FMT_VERT_FMTSLV_SHIFT 16 | ||
3868 | + | ||
3869 | +#define ISPCCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF0000 | ||
3870 | +#define ISPCCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF | ||
3871 | + | ||
3872 | +#define ISPCCDC_FMT_VERT_FMTSLV_MASK 0x1FFF0000 | ||
3873 | +#define ISPCCDC_FMT_VERT_FMTLNV_MASK 0x1FFF | ||
3874 | + | ||
3875 | +#define ISPCCDC_VP_OUT_HORZ_ST_SHIFT 0 | ||
3876 | +#define ISPCCDC_VP_OUT_HORZ_NUM_SHIFT 4 | ||
3877 | +#define ISPCCDC_VP_OUT_VERT_NUM_SHIFT 17 | ||
3878 | + | ||
3879 | +#define ISPRSZ_PID_PREV_SHIFT 0 | ||
3880 | +#define ISPRSZ_PID_CID_SHIFT 8 | ||
3881 | +#define ISPRSZ_PID_TID_SHIFT 16 | ||
3882 | + | ||
3883 | +#define ISPRSZ_PCR_ENABLE 0x5 | ||
3884 | +#define ISPRSZ_PCR_BUSY (1 << 1) | ||
3885 | + | ||
3886 | +#define ISPRSZ_CNT_HRSZ_SHIFT 0 | ||
3887 | +#define ISPRSZ_CNT_HRSZ_MASK 0x3FF | ||
3888 | +#define ISPRSZ_CNT_VRSZ_SHIFT 10 | ||
3889 | +#define ISPRSZ_CNT_VRSZ_MASK 0xFFC00 | ||
3890 | +#define ISPRSZ_CNT_HSTPH_SHIFT 20 | ||
3891 | +#define ISPRSZ_CNT_HSTPH_MASK 0x700000 | ||
3892 | +#define ISPRSZ_CNT_VSTPH_SHIFT 23 | ||
3893 | +#define ISPRSZ_CNT_VSTPH_MASK 0x3800000 | ||
3894 | +#define ISPRSZ_CNT_CBILIN_MASK 0x20000000 | ||
3895 | +#define ISPRSZ_CNT_INPTYP_MASK 0x08000000 | ||
3896 | +#define ISPRSZ_CNT_PIXFMT_MASK 0x04000000 | ||
3897 | +#define ISPRSZ_CNT_YCPOS (1 << 26) | ||
3898 | +#define ISPRSZ_CNT_INPTYP (1 << 27) | ||
3899 | +#define ISPRSZ_CNT_INPSRC (1 << 28) | ||
3900 | +#define ISPRSZ_CNT_CBILIN (1 << 29) | ||
3901 | + | ||
3902 | +#define ISPRSZ_OUT_SIZE_HORZ_SHIFT 0 | ||
3903 | +#define ISPRSZ_OUT_SIZE_HORZ_MASK 0x7FF | ||
3904 | +#define ISPRSZ_OUT_SIZE_VERT_SHIFT 16 | ||
3905 | +#define ISPRSZ_OUT_SIZE_VERT_MASK 0x7FF0000 | ||
3906 | + | ||
3907 | + | ||
3908 | +#define ISPRSZ_IN_START_HORZ_ST_SHIFT 0 | ||
3909 | +#define ISPRSZ_IN_START_HORZ_ST_MASK 0x1FFF | ||
3910 | +#define ISPRSZ_IN_START_VERT_ST_SHIFT 16 | ||
3911 | +#define ISPRSZ_IN_START_VERT_ST_MASK 0x1FFF0000 | ||
3912 | + | ||
3913 | + | ||
3914 | +#define ISPRSZ_IN_SIZE_HORZ_SHIFT 0 | ||
3915 | +#define ISPRSZ_IN_SIZE_HORZ_MASK 0x1FFF | ||
3916 | +#define ISPRSZ_IN_SIZE_VERT_SHIFT 16 | ||
3917 | +#define ISPRSZ_IN_SIZE_VERT_MASK 0x1FFF0000 | ||
3918 | + | ||
3919 | +#define ISPRSZ_SDR_INADD_ADDR_SHIFT 0 | ||
3920 | +#define ISPRSZ_SDR_INADD_ADDR_MASK 0xFFFFFFFF | ||
3921 | + | ||
3922 | +#define ISPRSZ_SDR_INOFF_OFFSET_SHIFT 0 | ||
3923 | +#define ISPRSZ_SDR_INOFF_OFFSET_MASK 0xFFFF | ||
3924 | + | ||
3925 | +#define ISPRSZ_SDR_OUTADD_ADDR_SHIFT 0 | ||
3926 | +#define ISPRSZ_SDR_OUTADD_ADDR_MASK 0xFFFFFFFF | ||
3927 | + | ||
3928 | + | ||
3929 | +#define ISPRSZ_SDR_OUTOFF_OFFSET_SHIFT 0 | ||
3930 | +#define ISPRSZ_SDR_OUTOFF_OFFSET_MASK 0xFFFF | ||
3931 | + | ||
3932 | +#define ISPRSZ_HFILT10_COEF0_SHIFT 0 | ||
3933 | +#define ISPRSZ_HFILT10_COEF0_MASK 0x3FF | ||
3934 | +#define ISPRSZ_HFILT10_COEF1_SHIFT 16 | ||
3935 | +#define ISPRSZ_HFILT10_COEF1_MASK 0x3FF0000 | ||
3936 | + | ||
3937 | +#define ISPRSZ_HFILT32_COEF2_SHIFT 0 | ||
3938 | +#define ISPRSZ_HFILT32_COEF2_MASK 0x3FF | ||
3939 | +#define ISPRSZ_HFILT32_COEF3_SHIFT 16 | ||
3940 | +#define ISPRSZ_HFILT32_COEF3_MASK 0x3FF0000 | ||
3941 | + | ||
3942 | +#define ISPRSZ_HFILT54_COEF4_SHIFT 0 | ||
3943 | +#define ISPRSZ_HFILT54_COEF4_MASK 0x3FF | ||
3944 | +#define ISPRSZ_HFILT54_COEF5_SHIFT 16 | ||
3945 | +#define ISPRSZ_HFILT54_COEF5_MASK 0x3FF0000 | ||
3946 | + | ||
3947 | +#define ISPRSZ_HFILT76_COEFF6_SHIFT 0 | ||
3948 | +#define ISPRSZ_HFILT76_COEFF6_MASK 0x3FF | ||
3949 | +#define ISPRSZ_HFILT76_COEFF7_SHIFT 16 | ||
3950 | +#define ISPRSZ_HFILT76_COEFF7_MASK 0x3FF0000 | ||
3951 | + | ||
3952 | +#define ISPRSZ_HFILT98_COEFF8_SHIFT 0 | ||
3953 | +#define ISPRSZ_HFILT98_COEFF8_MASK 0x3FF | ||
3954 | +#define ISPRSZ_HFILT98_COEFF9_SHIFT 16 | ||
3955 | +#define ISPRSZ_HFILT98_COEFF9_MASK 0x3FF0000 | ||
3956 | + | ||
3957 | +#define ISPRSZ_HFILT1110_COEF10_SHIFT 0 | ||
3958 | +#define ISPRSZ_HFILT1110_COEF10_MASK 0x3FF | ||
3959 | +#define ISPRSZ_HFILT1110_COEF11_SHIFT 16 | ||
3960 | +#define ISPRSZ_HFILT1110_COEF11_MASK 0x3FF0000 | ||
3961 | + | ||
3962 | +#define ISPRSZ_HFILT1312_COEFF12_SHIFT 0 | ||
3963 | +#define ISPRSZ_HFILT1312_COEFF12_MASK 0x3FF | ||
3964 | +#define ISPRSZ_HFILT1312_COEFF13_SHIFT 16 | ||
3965 | +#define ISPRSZ_HFILT1312_COEFF13_MASK 0x3FF0000 | ||
3966 | + | ||
3967 | +#define ISPRSZ_HFILT1514_COEFF14_SHIFT 0 | ||
3968 | +#define ISPRSZ_HFILT1514_COEFF14_MASK 0x3FF | ||
3969 | +#define ISPRSZ_HFILT1514_COEFF15_SHIFT 16 | ||
3970 | +#define ISPRSZ_HFILT1514_COEFF15_MASK 0x3FF0000 | ||
3971 | + | ||
3972 | +#define ISPRSZ_HFILT1716_COEF16_SHIFT 0 | ||
3973 | +#define ISPRSZ_HFILT1716_COEF16_MASK 0x3FF | ||
3974 | +#define ISPRSZ_HFILT1716_COEF17_SHIFT 16 | ||
3975 | +#define ISPRSZ_HFILT1716_COEF17_MASK 0x3FF0000 | ||
3976 | + | ||
3977 | +#define ISPRSZ_HFILT1918_COEF18_SHIFT 0 | ||
3978 | +#define ISPRSZ_HFILT1918_COEF18_MASK 0x3FF | ||
3979 | +#define ISPRSZ_HFILT1918_COEF19_SHIFT 16 | ||
3980 | +#define ISPRSZ_HFILT1918_COEF19_MASK 0x3FF0000 | ||
3981 | + | ||
3982 | +#define ISPRSZ_HFILT2120_COEF20_SHIFT 0 | ||
3983 | +#define ISPRSZ_HFILT2120_COEF20_MASK 0x3FF | ||
3984 | +#define ISPRSZ_HFILT2120_COEF21_SHIFT 16 | ||
3985 | +#define ISPRSZ_HFILT2120_COEF21_MASK 0x3FF0000 | ||
3986 | + | ||
3987 | +#define ISPRSZ_HFILT2322_COEF22_SHIFT 0 | ||
3988 | +#define ISPRSZ_HFILT2322_COEF22_MASK 0x3FF | ||
3989 | +#define ISPRSZ_HFILT2322_COEF23_SHIFT 16 | ||
3990 | +#define ISPRSZ_HFILT2322_COEF23_MASK 0x3FF0000 | ||
3991 | + | ||
3992 | +#define ISPRSZ_HFILT2524_COEF24_SHIFT 0 | ||
3993 | +#define ISPRSZ_HFILT2524_COEF24_MASK 0x3FF | ||
3994 | +#define ISPRSZ_HFILT2524_COEF25_SHIFT 16 | ||
3995 | +#define ISPRSZ_HFILT2524_COEF25_MASK 0x3FF0000 | ||
3996 | + | ||
3997 | +#define ISPRSZ_HFILT2726_COEF26_SHIFT 0 | ||
3998 | +#define ISPRSZ_HFILT2726_COEF26_MASK 0x3FF | ||
3999 | +#define ISPRSZ_HFILT2726_COEF27_SHIFT 16 | ||
4000 | +#define ISPRSZ_HFILT2726_COEF27_MASK 0x3FF0000 | ||
4001 | + | ||
4002 | +#define ISPRSZ_HFILT2928_COEF28_SHIFT 0 | ||
4003 | +#define ISPRSZ_HFILT2928_COEF28_MASK 0x3FF | ||
4004 | +#define ISPRSZ_HFILT2928_COEF29_SHIFT 16 | ||
4005 | +#define ISPRSZ_HFILT2928_COEF29_MASK 0x3FF0000 | ||
4006 | + | ||
4007 | +#define ISPRSZ_HFILT3130_COEF30_SHIFT 0 | ||
4008 | +#define ISPRSZ_HFILT3130_COEF30_MASK 0x3FF | ||
4009 | +#define ISPRSZ_HFILT3130_COEF31_SHIFT 16 | ||
4010 | +#define ISPRSZ_HFILT3130_COEF31_MASK 0x3FF0000 | ||
4011 | + | ||
4012 | +#define ISPRSZ_VFILT10_COEF0_SHIFT 0 | ||
4013 | +#define ISPRSZ_VFILT10_COEF0_MASK 0x3FF | ||
4014 | +#define ISPRSZ_VFILT10_COEF1_SHIFT 16 | ||
4015 | +#define ISPRSZ_VFILT10_COEF1_MASK 0x3FF0000 | ||
4016 | + | ||
4017 | +#define ISPRSZ_VFILT32_COEF2_SHIFT 0 | ||
4018 | +#define ISPRSZ_VFILT32_COEF2_MASK 0x3FF | ||
4019 | +#define ISPRSZ_VFILT32_COEF3_SHIFT 16 | ||
4020 | +#define ISPRSZ_VFILT32_COEF3_MASK 0x3FF0000 | ||
4021 | + | ||
4022 | +#define ISPRSZ_VFILT54_COEF4_SHIFT 0 | ||
4023 | +#define ISPRSZ_VFILT54_COEF4_MASK 0x3FF | ||
4024 | +#define ISPRSZ_VFILT54_COEF5_SHIFT 16 | ||
4025 | +#define ISPRSZ_VFILT54_COEF5_MASK 0x3FF0000 | ||
4026 | + | ||
4027 | +#define ISPRSZ_VFILT76_COEFF6_SHIFT 0 | ||
4028 | +#define ISPRSZ_VFILT76_COEFF6_MASK 0x3FF | ||
4029 | +#define ISPRSZ_VFILT76_COEFF7_SHIFT 16 | ||
4030 | +#define ISPRSZ_VFILT76_COEFF7_MASK 0x3FF0000 | ||
4031 | + | ||
4032 | +#define ISPRSZ_VFILT98_COEFF8_SHIFT 0 | ||
4033 | +#define ISPRSZ_VFILT98_COEFF8_MASK 0x3FF | ||
4034 | +#define ISPRSZ_VFILT98_COEFF9_SHIFT 16 | ||
4035 | +#define ISPRSZ_VFILT98_COEFF9_MASK 0x3FF0000 | ||
4036 | + | ||
4037 | +#define ISPRSZ_VFILT1110_COEF10_SHIFT 0 | ||
4038 | +#define ISPRSZ_VFILT1110_COEF10_MASK 0x3FF | ||
4039 | +#define ISPRSZ_VFILT1110_COEF11_SHIFT 16 | ||
4040 | +#define ISPRSZ_VFILT1110_COEF11_MASK 0x3FF0000 | ||
4041 | + | ||
4042 | +#define ISPRSZ_VFILT1312_COEFF12_SHIFT 0 | ||
4043 | +#define ISPRSZ_VFILT1312_COEFF12_MASK 0x3FF | ||
4044 | +#define ISPRSZ_VFILT1312_COEFF13_SHIFT 16 | ||
4045 | +#define ISPRSZ_VFILT1312_COEFF13_MASK 0x3FF0000 | ||
4046 | + | ||
4047 | +#define ISPRSZ_VFILT1514_COEFF14_SHIFT 0 | ||
4048 | +#define ISPRSZ_VFILT1514_COEFF14_MASK 0x3FF | ||
4049 | +#define ISPRSZ_VFILT1514_COEFF15_SHIFT 16 | ||
4050 | +#define ISPRSZ_VFILT1514_COEFF15_MASK 0x3FF0000 | ||
4051 | + | ||
4052 | +#define ISPRSZ_VFILT1716_COEF16_SHIFT 0 | ||
4053 | +#define ISPRSZ_VFILT1716_COEF16_MASK 0x3FF | ||
4054 | +#define ISPRSZ_VFILT1716_COEF17_SHIFT 16 | ||
4055 | +#define ISPRSZ_VFILT1716_COEF17_MASK 0x3FF0000 | ||
4056 | + | ||
4057 | +#define ISPRSZ_VFILT1918_COEF18_SHIFT 0 | ||
4058 | +#define ISPRSZ_VFILT1918_COEF18_MASK 0x3FF | ||
4059 | +#define ISPRSZ_VFILT1918_COEF19_SHIFT 16 | ||
4060 | +#define ISPRSZ_VFILT1918_COEF19_MASK 0x3FF0000 | ||
4061 | + | ||
4062 | +#define ISPRSZ_VFILT2120_COEF20_SHIFT 0 | ||
4063 | +#define ISPRSZ_VFILT2120_COEF20_MASK 0x3FF | ||
4064 | +#define ISPRSZ_VFILT2120_COEF21_SHIFT 16 | ||
4065 | +#define ISPRSZ_VFILT2120_COEF21_MASK 0x3FF0000 | ||
4066 | + | ||
4067 | +#define ISPRSZ_VFILT2322_COEF22_SHIFT 0 | ||
4068 | +#define ISPRSZ_VFILT2322_COEF22_MASK 0x3FF | ||
4069 | +#define ISPRSZ_VFILT2322_COEF23_SHIFT 16 | ||
4070 | +#define ISPRSZ_VFILT2322_COEF23_MASK 0x3FF0000 | ||
4071 | + | ||
4072 | +#define ISPRSZ_VFILT2524_COEF24_SHIFT 0 | ||
4073 | +#define ISPRSZ_VFILT2524_COEF24_MASK 0x3FF | ||
4074 | +#define ISPRSZ_VFILT2524_COEF25_SHIFT 16 | ||
4075 | +#define ISPRSZ_VFILT2524_COEF25_MASK 0x3FF0000 | ||
4076 | + | ||
4077 | +#define ISPRSZ_VFILT2726_COEF26_SHIFT 0 | ||
4078 | +#define ISPRSZ_VFILT2726_COEF26_MASK 0x3FF | ||
4079 | +#define ISPRSZ_VFILT2726_COEF27_SHIFT 16 | ||
4080 | +#define ISPRSZ_VFILT2726_COEF27_MASK 0x3FF0000 | ||
4081 | + | ||
4082 | +#define ISPRSZ_VFILT2928_COEF28_SHIFT 0 | ||
4083 | +#define ISPRSZ_VFILT2928_COEF28_MASK 0x3FF | ||
4084 | +#define ISPRSZ_VFILT2928_COEF29_SHIFT 16 | ||
4085 | +#define ISPRSZ_VFILT2928_COEF29_MASK 0x3FF0000 | ||
4086 | + | ||
4087 | +#define ISPRSZ_VFILT3130_COEF30_SHIFT 0 | ||
4088 | +#define ISPRSZ_VFILT3130_COEF30_MASK 0x3FF | ||
4089 | +#define ISPRSZ_VFILT3130_COEF31_SHIFT 16 | ||
4090 | +#define ISPRSZ_VFILT3130_COEF31_MASK 0x3FF0000 | ||
4091 | + | ||
4092 | +#define ISPRSZ_YENH_CORE_SHIFT 0 | ||
4093 | +#define ISPRSZ_YENH_CORE_MASK 0xFF | ||
4094 | +#define ISPRSZ_YENH_SLOP_SHIFT 8 | ||
4095 | +#define ISPRSZ_YENH_SLOP_MASK 0xF00 | ||
4096 | +#define ISPRSZ_YENH_GAIN_SHIFT 12 | ||
4097 | +#define ISPRSZ_YENH_GAIN_MASK 0xF000 | ||
4098 | +#define ISPRSZ_YENH_ALGO_SHIFT 16 | ||
4099 | +#define ISPRSZ_YENH_ALGO_MASK 0x30000 | ||
4100 | + | ||
4101 | +#define ISPH3A_PCR_AEW_ALAW_EN_SHIFT 1 | ||
4102 | +#define ISPH3A_PCR_AF_MED_TH_SHIFT 3 | ||
4103 | +#define ISPH3A_PCR_AF_RGBPOS_SHIFT 11 | ||
4104 | +#define ISPH3A_PCR_AEW_AVE2LMT_SHIFT 22 | ||
4105 | +#define ISPH3A_PCR_AEW_AVE2LMT_MASK 0xFFC00000 | ||
4106 | +#define ISPH3A_PCR_BUSYAF (1 << 15) | ||
4107 | +#define ISPH3A_PCR_BUSYAEAWB (1 << 18) | ||
4108 | + | ||
4109 | +#define ISPH3A_AEWWIN1_WINHC_SHIFT 0 | ||
4110 | +#define ISPH3A_AEWWIN1_WINHC_MASK 0x3F | ||
4111 | +#define ISPH3A_AEWWIN1_WINVC_SHIFT 6 | ||
4112 | +#define ISPH3A_AEWWIN1_WINVC_MASK 0x1FC0 | ||
4113 | +#define ISPH3A_AEWWIN1_WINW_SHIFT 13 | ||
4114 | +#define ISPH3A_AEWWIN1_WINW_MASK 0xFE000 | ||
4115 | +#define ISPH3A_AEWWIN1_WINH_SHIFT 24 | ||
4116 | +#define ISPH3A_AEWWIN1_WINH_MASK 0x7F000000 | ||
4117 | + | ||
4118 | +#define ISPH3A_AEWINSTART_WINSH_SHIFT 0 | ||
4119 | +#define ISPH3A_AEWINSTART_WINSH_MASK 0x0FFF | ||
4120 | +#define ISPH3A_AEWINSTART_WINSV_SHIFT 16 | ||
4121 | +#define ISPH3A_AEWINSTART_WINSV_MASK 0x0FFF0000 | ||
4122 | + | ||
4123 | +#define ISPH3A_AEWINBLK_WINH_SHIFT 0 | ||
4124 | +#define ISPH3A_AEWINBLK_WINH_MASK 0x7F | ||
4125 | +#define ISPH3A_AEWINBLK_WINSV_SHIFT 16 | ||
4126 | +#define ISPH3A_AEWINBLK_WINSV_MASK 0x0FFF0000 | ||
4127 | + | ||
4128 | +#define ISPH3A_AEWSUBWIN_AEWINCH_SHIFT 0 | ||
4129 | +#define ISPH3A_AEWSUBWIN_AEWINCH_MASK 0x0F | ||
4130 | +#define ISPH3A_AEWSUBWIN_AEWINCV_SHIFT 8 | ||
4131 | +#define ISPH3A_AEWSUBWIN_AEWINCV_MASK 0x0F00 | ||
4132 | + | ||
4133 | +#define ISPHIST_PCR_ENABLE_SHIFT 0 | ||
4134 | +#define ISPHIST_PCR_ENABLE_MASK 0x01 | ||
4135 | +#define ISPHIST_PCR_BUSY 0x02 | ||
4136 | + | ||
4137 | +#define ISPHIST_CNT_DATASIZE_SHIFT 8 | ||
4138 | +#define ISPHIST_CNT_DATASIZE_MASK 0x0100 | ||
4139 | +#define ISPHIST_CNT_CLEAR_SHIFT 7 | ||
4140 | +#define ISPHIST_CNT_CLEAR_MASK 0x080 | ||
4141 | +#define ISPHIST_CNT_CFA_SHIFT 6 | ||
4142 | +#define ISPHIST_CNT_CFA_MASK 0x040 | ||
4143 | +#define ISPHIST_CNT_BINS_SHIFT 4 | ||
4144 | +#define ISPHIST_CNT_BINS_MASK 0x030 | ||
4145 | +#define ISPHIST_CNT_SOURCE_SHIFT 3 | ||
4146 | +#define ISPHIST_CNT_SOURCE_MASK 0x08 | ||
4147 | +#define ISPHIST_CNT_SHIFT_SHIFT 0 | ||
4148 | +#define ISPHIST_CNT_SHIFT_MASK 0x07 | ||
4149 | + | ||
4150 | +#define ISPHIST_WB_GAIN_WG00_SHIFT 24 | ||
4151 | +#define ISPHIST_WB_GAIN_WG00_MASK 0xFF000000 | ||
4152 | +#define ISPHIST_WB_GAIN_WG01_SHIFT 16 | ||
4153 | +#define ISPHIST_WB_GAIN_WG01_MASK 0xFF0000 | ||
4154 | +#define ISPHIST_WB_GAIN_WG02_SHIFT 8 | ||
4155 | +#define ISPHIST_WB_GAIN_WG02_MASK 0xFF00 | ||
4156 | +#define ISPHIST_WB_GAIN_WG03_SHIFT 0 | ||
4157 | +#define ISPHIST_WB_GAIN_WG03_MASK 0xFF | ||
4158 | + | ||
4159 | +#define ISPHIST_REGHORIZ_HSTART_SHIFT 16 /* | ||
4160 | + * REGION 0 to 3 HORZ | ||
4161 | + * and VERT | ||
4162 | + */ | ||
4163 | +#define ISPHIST_REGHORIZ_HSTART_MASK 0x3FFF0000 | ||
4164 | +#define ISPHIST_REGHORIZ_HEND_SHIFT 0 | ||
4165 | +#define ISPHIST_REGHORIZ_HEND_MASK 0x3FFF | ||
4166 | +#define ISPHIST_REGVERT_VSTART_SHIFT 16 | ||
4167 | +#define ISPHIST_REGVERT_VSTART_MASK 0x3FFF0000 | ||
4168 | +#define ISPHIST_REGVERT_VEND_SHIFT 0 | ||
4169 | +#define ISPHIST_REGVERT_VEND_MASK 0x3FFF | ||
4170 | + | ||
4171 | +#define ISPHIST_REGHORIZ_MASK 0x3FFF3FFF | ||
4172 | +#define ISPHIST_REGVERT_MASK 0x3FFF3FFF | ||
4173 | + | ||
4174 | +#define ISPHIST_ADDR_SHIFT 0 | ||
4175 | +#define ISPHIST_ADDR_MASK 0x3FF | ||
4176 | + | ||
4177 | +#define ISPHIST_DATA_SHIFT 0 | ||
4178 | +#define ISPHIST_DATA_MASK 0xFFFFF | ||
4179 | + | ||
4180 | +#define ISPHIST_RADD_SHIFT 0 | ||
4181 | +#define ISPHIST_RADD_MASK 0xFFFFFFFF | ||
4182 | + | ||
4183 | +#define ISPHIST_RADD_OFF_SHIFT 0 | ||
4184 | +#define ISPHIST_RADD_OFF_MASK 0xFFFF | ||
4185 | + | ||
4186 | +#define ISPHIST_HV_INFO_HSIZE_SHIFT 16 | ||
4187 | +#define ISPHIST_HV_INFO_HSIZE_MASK 0x3FFF0000 | ||
4188 | +#define ISPHIST_HV_INFO_VSIZE_SHIFT 0 | ||
4189 | +#define ISPHIST_HV_INFO_VSIZE_MASK 0x3FFF | ||
4190 | + | ||
4191 | +#define ISPHIST_HV_INFO_MASK 0x3FFF3FFF | ||
4192 | + | ||
4193 | +#define ISPCCDC_LSC_GAIN_MODE_N_MASK 0x700 | ||
4194 | +#define ISPCCDC_LSC_GAIN_MODE_N_SHIFT 8 | ||
4195 | +#define ISPCCDC_LSC_GAIN_MODE_M_MASK 0x3800 | ||
4196 | +#define ISPCCDC_LSC_GAIN_MODE_M_SHIFT 12 | ||
4197 | +#define ISPCCDC_LSC_GAIN_FORMAT_MASK 0xE | ||
4198 | +#define ISPCCDC_LSC_GAIN_FORMAT_SHIFT 1 | ||
4199 | +#define ISPCCDC_LSC_AFTER_REFORMATTER_MASK (1<<6) | ||
4200 | + | ||
4201 | +#define ISPCCDC_LSC_INITIAL_X_MASK 0x3F | ||
4202 | +#define ISPCCDC_LSC_INITIAL_X_SHIFT 0 | ||
4203 | +#define ISPCCDC_LSC_INITIAL_Y_MASK 0x3F0000 | ||
4204 | +#define ISPCCDC_LSC_INITIAL_Y_SHIFT 16 | ||
4205 | + | ||
4206 | +#define ISPMMU_REVISION_REV_MINOR_MASK 0xF | ||
4207 | +#define ISPMMU_REVISION_REV_MAJOR_SHIFT 0x4 | ||
4208 | + | ||
4209 | +#define IRQENABLE_MULTIHITFAULT (1<<4) | ||
4210 | +#define IRQENABLE_TWFAULT (1<<3) | ||
4211 | +#define IRQENABLE_EMUMISS (1<<2) | ||
4212 | +#define IRQENABLE_TRANSLNFAULT (1<<1) | ||
4213 | +#define IRQENABLE_TLBMISS (1) | ||
4214 | + | ||
4215 | +#define ISPMMU_MMUCNTL_MMU_EN (1<<1) | ||
4216 | +#define ISPMMU_MMUCNTL_TWL_EN (1<<2) | ||
4217 | +#define ISPMMU_MMUCNTL_EMUTLBUPDATE (1<<3) | ||
4218 | +#define ISPMMU_AUTOIDLE 0x1 | ||
4219 | +#define ISPMMU_SIDLEMODE_FORCEIDLE 0 | ||
4220 | +#define ISPMMU_SIDLEMODE_NOIDLE 1 | ||
4221 | +#define ISPMMU_SIDLEMODE_SMARTIDLE 2 | ||
4222 | +#define ISPMMU_SIDLEMODE_SHIFT 3 | ||
4223 | + | ||
4224 | +#define ISPCSI1_AUTOIDLE 0x1 | ||
4225 | +#define ISPCSI1_MIDLEMODE_SHIFT 12 | ||
4226 | +#define ISPCSI1_MIDLEMODE_FORCESTANDBY 0x0 | ||
4227 | +#define ISPCSI1_MIDLEMODE_NOSTANDBY 0x1 | ||
4228 | +#define ISPCSI1_MIDLEMODE_SMARTSTANDBY 0x2 | ||
4229 | + | ||
4230 | +/* CSI2 receiver registers (ES2.0) */ | ||
4231 | +#define ISPCSI2_REVISION (0x000) | ||
4232 | +#define ISPCSI2_SYSCONFIG (0x010) | ||
4233 | +#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT 12 | ||
4234 | +#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK \ | ||
4235 | + (0x3 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT) | ||
4236 | +#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_FORCE \ | ||
4237 | + (0x0 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT) | ||
4238 | +#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO \ | ||
4239 | + (0x1 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT) | ||
4240 | +#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART \ | ||
4241 | + (0x2 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT) | ||
4242 | +#define ISPCSI2_SYSCONFIG_SOFT_RESET_SHIFT 1 | ||
4243 | +#define ISPCSI2_SYSCONFIG_SOFT_RESET_MASK \ | ||
4244 | + (0x1 << ISPCSI2_SYSCONFIG_SOFT_RESET_SHIFT) | ||
4245 | +#define ISPCSI2_SYSCONFIG_SOFT_RESET_NORMAL \ | ||
4246 | + (0x0 << ISPCSI2_SYSCONFIG_SOFT_RESET_SHIFT) | ||
4247 | +#define ISPCSI2_SYSCONFIG_SOFT_RESET_RESET \ | ||
4248 | + (0x1 << ISPCSI2_SYSCONFIG_SOFT_RESET_SHIFT) | ||
4249 | +#define ISPCSI2_SYSCONFIG_AUTO_IDLE_SHIFT 0 | ||
4250 | +#define ISPCSI2_SYSCONFIG_AUTO_IDLE_MASK \ | ||
4251 | + (0x1 << ISPCSI2_SYSCONFIG_AUTO_IDLE_SHIFT) | ||
4252 | +#define ISPCSI2_SYSCONFIG_AUTO_IDLE_FREE \ | ||
4253 | + (0x0 << ISPCSI2_SYSCONFIG_AUTO_IDLE_SHIFT) | ||
4254 | +#define ISPCSI2_SYSCONFIG_AUTO_IDLE_AUTO \ | ||
4255 | + (0x1 << ISPCSI2_SYSCONFIG_AUTO_IDLE_SHIFT) | ||
4256 | +#define ISPCSI2_SYSSTATUS (0x014) | ||
4257 | +#define ISPCSI2_SYSSTATUS_RESET_DONE_SHIFT 0 | ||
4258 | +#define ISPCSI2_SYSSTATUS_RESET_DONE_MASK \ | ||
4259 | + (0x1 << ISPCSI2_SYSSTATUS_RESET_DONE_SHIFT) | ||
4260 | +#define ISPCSI2_SYSSTATUS_RESET_DONE_ONGOING \ | ||
4261 | + (0x0 << ISPCSI2_SYSSTATUS_RESET_DONE_SHIFT) | ||
4262 | +#define ISPCSI2_SYSSTATUS_RESET_DONE_DONE \ | ||
4263 | + (0x1 << ISPCSI2_SYSSTATUS_RESET_DONE_SHIFT) | ||
4264 | +#define ISPCSI2_IRQSTATUS (0x018) | ||
4265 | +#define ISPCSI2_IRQSTATUS_OCP_ERR_IRQ (1 << 14) | ||
4266 | +#define ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ (1 << 13) | ||
4267 | +#define ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 12) | ||
4268 | +#define ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ (1 << 11) | ||
4269 | +#define ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ (1 << 10) | ||
4270 | +#define ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ (1 << 9) | ||
4271 | +#define ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ (1 << 8) | ||
4272 | +#define ISPCSI2_IRQSTATUS_CONTEXT(n) (1 << (n)) | ||
4273 | + | ||
4274 | +#define ISPCSI2_IRQENABLE (0x01C) | ||
4275 | +#define ISPCSI2_CTRL (0x040) | ||
4276 | +#define ISPCSI2_CTRL_VP_CLK_EN_SHIFT 15 | ||
4277 | +#define ISPCSI2_CTRL_VP_CLK_EN_MASK (0x1 << ISPCSI2_CTRL_VP_CLK_EN_SHIFT) | ||
4278 | +#define ISPCSI2_CTRL_VP_CLK_EN_DISABLE (0x0 << ISPCSI2_CTRL_VP_CLK_EN_SHIFT) | ||
4279 | +#define ISPCSI2_CTRL_VP_CLK_EN_ENABLE (0x1 << ISPCSI2_CTRL_VP_CLK_EN_SHIFT) | ||
4280 | + | ||
4281 | +#define ISPCSI2_CTRL_VP_ONLY_EN_SHIFT 11 | ||
4282 | +#define ISPCSI2_CTRL_VP_ONLY_EN_MASK (0x1 << ISPCSI2_CTRL_VP_ONLY_EN_SHIFT) | ||
4283 | +#define ISPCSI2_CTRL_VP_ONLY_EN_DISABLE (0x0 << ISPCSI2_CTRL_VP_ONLY_EN_SHIFT) | ||
4284 | +#define ISPCSI2_CTRL_VP_ONLY_EN_ENABLE (0x1 << ISPCSI2_CTRL_VP_ONLY_EN_SHIFT) | ||
4285 | + | ||
4286 | +#define ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT 8 | ||
4287 | +#define ISPCSI2_CTRL_VP_OUT_CTRL_MASK (0x3 << \ | ||
4288 | + ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT) | ||
4289 | +#define ISPCSI2_CTRL_VP_OUT_CTRL_DISABLE (0x0 << \ | ||
4290 | + ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT) | ||
4291 | +#define ISPCSI2_CTRL_VP_OUT_CTRL_DIV2 (0x1 << \ | ||
4292 | + ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT) | ||
4293 | +#define ISPCSI2_CTRL_VP_OUT_CTRL_DIV3 (0x2 << \ | ||
4294 | + ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT) | ||
4295 | +#define ISPCSI2_CTRL_VP_OUT_CTRL_DIV4 (0x3 << \ | ||
4296 | + ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT) | ||
4297 | + | ||
4298 | +#define ISPCSI2_CTRL_DBG_EN_SHIFT 7 | ||
4299 | +#define ISPCSI2_CTRL_DBG_EN_MASK (0x1 << ISPCSI2_CTRL_DBG_EN_SHIFT) | ||
4300 | +#define ISPCSI2_CTRL_DBG_EN_DISABLE (0x0 << ISPCSI2_CTRL_DBG_EN_SHIFT) | ||
4301 | +#define ISPCSI2_CTRL_DBG_EN_ENABLE (0x1 << ISPCSI2_CTRL_DBG_EN_SHIFT) | ||
4302 | + | ||
4303 | +#define ISPCSI2_CTRL_BURST_SIZE_SHIFT 5 | ||
4304 | +#define ISPCSI2_CTRL_BURST_SIZE_MASK (0x3 << \ | ||
4305 | + ISPCSI2_CTRL_BURST_SIZE_SHIFT) | ||
4306 | +#define ISPCSI2_CTRL_BURST_SIZE_MYSTERY_VAL (0x2 << \ | ||
4307 | + ISPCSI2_CTRL_BURST_SIZE_SHIFT) | ||
4308 | + | ||
4309 | +#define ISPCSI2_CTRL_FRAME_SHIFT 3 | ||
4310 | +#define ISPCSI2_CTRL_FRAME_MASK (0x1 << ISPCSI2_CTRL_FRAME_SHIFT) | ||
4311 | +#define ISPCSI2_CTRL_FRAME_DISABLE_IMM (0x0 << ISPCSI2_CTRL_FRAME_SHIFT) | ||
4312 | +#define ISPCSI2_CTRL_FRAME_DISABLE_FEC (0x1 << ISPCSI2_CTRL_FRAME_SHIFT) | ||
4313 | + | ||
4314 | +#define ISPCSI2_CTRL_ECC_EN_SHIFT 2 | ||
4315 | +#define ISPCSI2_CTRL_ECC_EN_MASK (0x1 << ISPCSI2_CTRL_ECC_EN_SHIFT) | ||
4316 | +#define ISPCSI2_CTRL_ECC_EN_DISABLE (0x0 << ISPCSI2_CTRL_ECC_EN_SHIFT) | ||
4317 | +#define ISPCSI2_CTRL_ECC_EN_ENABLE (0x1 << ISPCSI2_CTRL_ECC_EN_SHIFT) | ||
4318 | + | ||
4319 | +#define ISPCSI2_CTRL_SECURE_SHIFT 1 | ||
4320 | +#define ISPCSI2_CTRL_SECURE_MASK (0x1 << ISPCSI2_CTRL_SECURE_SHIFT) | ||
4321 | +#define ISPCSI2_CTRL_SECURE_DISABLE (0x0 << ISPCSI2_CTRL_SECURE_SHIFT) | ||
4322 | +#define ISPCSI2_CTRL_SECURE_ENABLE (0x1 << ISPCSI2_CTRL_SECURE_SHIFT) | ||
4323 | + | ||
4324 | +#define ISPCSI2_CTRL_IF_EN_SHIFT 0 | ||
4325 | +#define ISPCSI2_CTRL_IF_EN_MASK (0x1 << ISPCSI2_CTRL_IF_EN_SHIFT) | ||
4326 | +#define ISPCSI2_CTRL_IF_EN_DISABLE (0x0 << ISPCSI2_CTRL_IF_EN_SHIFT) | ||
4327 | +#define ISPCSI2_CTRL_IF_EN_ENABLE (0x1 << ISPCSI2_CTRL_IF_EN_SHIFT) | ||
4328 | + | ||
4329 | +#define ISPCSI2_DBG_H (0x044) | ||
4330 | +#define ISPCSI2_GNQ (0x048) | ||
4331 | +#define ISPCSI2_COMPLEXIO_CFG1 (0x050) | ||
4332 | +#define ISPCSI2_COMPLEXIO_CFG1_RESET_DONE_SHIFT 29 | ||
4333 | +#define ISPCSI2_COMPLEXIO_CFG1_RESET_DONE_MASK \ | ||
4334 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_RESET_DONE_SHIFT) | ||
4335 | +#define ISPCSI2_COMPLEXIO_CFG1_RESET_DONE_ONGOING \ | ||
4336 | + (0x0 << ISPCSI2_COMPLEXIO_CFG1_RESET_DONE_SHIFT) | ||
4337 | +#define ISPCSI2_COMPLEXIO_CFG1_RESET_DONE_DONE \ | ||
4338 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_RESET_DONE_SHIFT) | ||
4339 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_SHIFT 27 | ||
4340 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_MASK \ | ||
4341 | + (0x3 << ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_SHIFT) | ||
4342 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_OFF \ | ||
4343 | + (0x0 << ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_SHIFT) | ||
4344 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_ON \ | ||
4345 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_SHIFT) | ||
4346 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_ULPW \ | ||
4347 | + (0x2 << ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_SHIFT) | ||
4348 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_SHIFT 25 | ||
4349 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_MASK \ | ||
4350 | + (0x3 << ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_SHIFT) | ||
4351 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_OFF \ | ||
4352 | + (0x0 << ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_SHIFT) | ||
4353 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_ON \ | ||
4354 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_SHIFT) | ||
4355 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_ULPW \ | ||
4356 | + (0x2 << ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_SHIFT) | ||
4357 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_SHIFT 24 | ||
4358 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_MASK \ | ||
4359 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_SHIFT) | ||
4360 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_DISABLE \ | ||
4361 | + (0x0 << ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_SHIFT) | ||
4362 | +#define ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_ENABLE \ | ||
4363 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_SHIFT) | ||
4364 | + | ||
4365 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POL_SHIFT(n) (3 + ((n) * 4)) | ||
4366 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POL_MASK(n) \ | ||
4367 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_DATA_POL_SHIFT(n)) | ||
4368 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POL_PN(n) \ | ||
4369 | + (0x0 << ISPCSI2_COMPLEXIO_CFG1_DATA_POL_SHIFT(n)) | ||
4370 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POL_NP(n) \ | ||
4371 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_DATA_POL_SHIFT(n)) | ||
4372 | + | ||
4373 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(n) ((n) * 4) | ||
4374 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_MASK(n) \ | ||
4375 | + (0x7 << ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(n)) | ||
4376 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_NC(n) \ | ||
4377 | + (0x0 << ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(n)) | ||
4378 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_1(n) \ | ||
4379 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(n)) | ||
4380 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_2(n) \ | ||
4381 | + (0x2 << ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(n)) | ||
4382 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_3(n) \ | ||
4383 | + (0x3 << ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(n)) | ||
4384 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_4(n) \ | ||
4385 | + (0x4 << ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(n)) | ||
4386 | +#define ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_5(n) \ | ||
4387 | + (0x5 << ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(n)) | ||
4388 | + | ||
4389 | +#define ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_SHIFT 3 | ||
4390 | +#define ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_MASK \ | ||
4391 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_SHIFT) | ||
4392 | +#define ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_PN \ | ||
4393 | + (0x0 << ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_SHIFT) | ||
4394 | +#define ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_NP \ | ||
4395 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_SHIFT) | ||
4396 | + | ||
4397 | +#define ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT 0 | ||
4398 | +#define ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_MASK \ | ||
4399 | + (0x7 << ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT) | ||
4400 | +#define ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_1 \ | ||
4401 | + (0x1 << ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT) | ||
4402 | +#define ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_2 \ | ||
4403 | + (0x2 << ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT) | ||
4404 | +#define ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_3 \ | ||
4405 | + (0x3 << ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT) | ||
4406 | +#define ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_4 \ | ||
4407 | + (0x4 << ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT) | ||
4408 | +#define ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_5 \ | ||
4409 | + (0x5 << ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT) | ||
4410 | + | ||
4411 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS (0x054) | ||
4412 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_STATEALLULPMEXIT (1 << 26) | ||
4413 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_STATEALLULPMENTER (1 << 25) | ||
4414 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_STATEULPM5 (1 << 24) | ||
4415 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_STATEULPM4 (1 << 23) | ||
4416 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_STATEULPM3 (1 << 22) | ||
4417 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_STATEULPM2 (1 << 21) | ||
4418 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_STATEULPM1 (1 << 20) | ||
4419 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRCONTROL5 (1 << 19) | ||
4420 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRCONTROL4 (1 << 18) | ||
4421 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRCONTROL3 (1 << 17) | ||
4422 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRCONTROL2 (1 << 16) | ||
4423 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRCONTROL1 (1 << 15) | ||
4424 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRESC5 (1 << 14) | ||
4425 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRESC4 (1 << 13) | ||
4426 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRESC3 (1 << 12) | ||
4427 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRESC2 (1 << 11) | ||
4428 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRESC1 (1 << 10) | ||
4429 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRSOTSYNCHS5 (1 << 9) | ||
4430 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRSOTSYNCHS4 (1 << 8) | ||
4431 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRSOTSYNCHS3 (1 << 7) | ||
4432 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRSOTSYNCHS2 (1 << 6) | ||
4433 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRSOTSYNCHS1 (1 << 5) | ||
4434 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRSOTHS5 (1 << 4) | ||
4435 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRSOTHS4 (1 << 3) | ||
4436 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRSOTHS3 (1 << 2) | ||
4437 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRSOTHS2 (1 << 1) | ||
4438 | +#define ISPCSI2_COMPLEXIO1_IRQSTATUS_ERRSOTHS1 1 | ||
4439 | + | ||
4440 | +#define ISPCSI2_SHORT_PACKET (0x05C) | ||
4441 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE (0x060) | ||
4442 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_STATEALLULPMEXIT (1 << 26) | ||
4443 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_STATEALLULPMENTER (1 << 25) | ||
4444 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM5 (1 << 24) | ||
4445 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM4 (1 << 23) | ||
4446 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM3 (1 << 22) | ||
4447 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM2 (1 << 21) | ||
4448 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM1 (1 << 20) | ||
4449 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL5 (1 << 19) | ||
4450 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL4 (1 << 18) | ||
4451 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL3 (1 << 17) | ||
4452 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL2 (1 << 16) | ||
4453 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL1 (1 << 15) | ||
4454 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC5 (1 << 14) | ||
4455 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC4 (1 << 13) | ||
4456 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC3 (1 << 12) | ||
4457 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC2 (1 << 11) | ||
4458 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC1 (1 << 10) | ||
4459 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS5 (1 << 9) | ||
4460 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS4 (1 << 8) | ||
4461 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS3 (1 << 7) | ||
4462 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS2 (1 << 6) | ||
4463 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS1 (1 << 5) | ||
4464 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS5 (1 << 4) | ||
4465 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS4 (1 << 3) | ||
4466 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS3 (1 << 2) | ||
4467 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS2 (1 << 1) | ||
4468 | +#define ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS1 1 | ||
4469 | +#define ISPCSI2_DBG_P (0x068) | ||
4470 | +#define ISPCSI2_TIMING (0x06C) | ||
4471 | + | ||
4472 | + | ||
4473 | +#define ISPCSI2_TIMING_FORCE_RX_MODE_IO_SHIFT(n) \ | ||
4474 | + ((16 * ((n) - 1)) + 15) | ||
4475 | +#define ISPCSI2_TIMING_FORCE_RX_MODE_IO_MASK(n) \ | ||
4476 | + (0x1 << ISPCSI2_TIMING_FORCE_RX_MODE_IO_SHIFT(n)) | ||
4477 | +#define ISPCSI2_TIMING_FORCE_RX_MODE_IO_DISABLE(n) \ | ||
4478 | + (0x0 << ISPCSI2_TIMING_FORCE_RX_MODE_IO_SHIFT(n)) | ||
4479 | +#define ISPCSI2_TIMING_FORCE_RX_MODE_IO_ENABLE(n) \ | ||
4480 | + (0x1 << ISPCSI2_TIMING_FORCE_RX_MODE_IO_SHIFT(n)) | ||
4481 | +#define ISPCSI2_TIMING_STOP_STATE_X16_IO_SHIFT(n) ((16 * ((n) - 1)) + 14) | ||
4482 | +#define ISPCSI2_TIMING_STOP_STATE_X16_IO_MASK(n) \ | ||
4483 | + (0x1 << ISPCSI2_TIMING_STOP_STATE_X16_IO_SHIFT(n)) | ||
4484 | +#define ISPCSI2_TIMING_STOP_STATE_X16_IO_DISABLE(n) \ | ||
4485 | + (0x0 << ISPCSI2_TIMING_STOP_STATE_X16_IO_SHIFT(n)) | ||
4486 | +#define ISPCSI2_TIMING_STOP_STATE_X16_IO_ENABLE(n) \ | ||
4487 | + (0x1 << ISPCSI2_TIMING_STOP_STATE_X16_IO_SHIFT(n)) | ||
4488 | +#define ISPCSI2_TIMING_STOP_STATE_X4_IO_SHIFT(n) ((16 * ((n) - 1)) + 13) | ||
4489 | +#define ISPCSI2_TIMING_STOP_STATE_X4_IO_MASK(n) \ | ||
4490 | + (0x1 << ISPCSI2_TIMING_STOP_STATE_X4_IO_SHIFT(n)) | ||
4491 | +#define ISPCSI2_TIMING_STOP_STATE_X4_IO_DISABLE(n) \ | ||
4492 | + (0x0 << ISPCSI2_TIMING_STOP_STATE_X4_IO_SHIFT(n)) | ||
4493 | +#define ISPCSI2_TIMING_STOP_STATE_X4_IO_ENABLE(n) \ | ||
4494 | + (0x1 << ISPCSI2_TIMING_STOP_STATE_X4_IO_SHIFT(n)) | ||
4495 | +#define ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(n) (16 * ((n) - 1)) | ||
4496 | +#define ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(n) \ | ||
4497 | + (0x1fff << ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(n)) | ||
4498 | + | ||
4499 | +#define ISPCSI2_CTX_CTRL1(n) ((0x070) + 0x20 * (n)) | ||
4500 | +#define ISPCSI2_CTX_CTRL1_COUNT_SHIFT 8 | ||
4501 | +#define ISPCSI2_CTX_CTRL1_COUNT_MASK (0xFF << \ | ||
4502 | + ISPCSI2_CTX_CTRL1_COUNT_SHIFT) | ||
4503 | +#define ISPCSI2_CTX_CTRL1_EOF_EN_SHIFT 7 | ||
4504 | +#define ISPCSI2_CTX_CTRL1_EOF_EN_MASK \ | ||
4505 | + (0x1 << ISPCSI2_CTX_CTRL1_EOF_EN_SHIFT) | ||
4506 | +#define ISPCSI2_CTX_CTRL1_EOF_EN_DISABLE \ | ||
4507 | + (0x0 << ISPCSI2_CTX_CTRL1_EOF_EN_SHIFT) | ||
4508 | +#define ISPCSI2_CTX_CTRL1_EOF_EN_ENABLE \ | ||
4509 | + (0x1 << ISPCSI2_CTX_CTRL1_EOF_EN_SHIFT) | ||
4510 | +#define ISPCSI2_CTX_CTRL1_EOL_EN_SHIFT 6 | ||
4511 | +#define ISPCSI2_CTX_CTRL1_EOL_EN_MASK \ | ||
4512 | + (0x1 << ISPCSI2_CTX_CTRL1_EOL_EN_SHIFT) | ||
4513 | +#define ISPCSI2_CTX_CTRL1_EOL_EN_DISABLE \ | ||
4514 | + (0x0 << ISPCSI2_CTX_CTRL1_EOL_EN_SHIFT) | ||
4515 | +#define ISPCSI2_CTX_CTRL1_EOL_EN_ENABLE \ | ||
4516 | + (0x1 << ISPCSI2_CTX_CTRL1_EOL_EN_SHIFT) | ||
4517 | +#define ISPCSI2_CTX_CTRL1_CS_EN_SHIFT 5 | ||
4518 | +#define ISPCSI2_CTX_CTRL1_CS_EN_MASK \ | ||
4519 | + (0x1 << ISPCSI2_CTX_CTRL1_CS_EN_SHIFT) | ||
4520 | +#define ISPCSI2_CTX_CTRL1_CS_EN_DISABLE \ | ||
4521 | + (0x0 << ISPCSI2_CTX_CTRL1_CS_EN_SHIFT) | ||
4522 | +#define ISPCSI2_CTX_CTRL1_CS_EN_ENABLE \ | ||
4523 | + (0x1 << ISPCSI2_CTX_CTRL1_CS_EN_SHIFT) | ||
4524 | +#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK_EN_SHIFT 4 | ||
4525 | +#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK_EN_MASK \ | ||
4526 | + (0x1 << ISPCSI2_CTX_CTRL1_COUNT_UNLOCK_EN_SHIFT) | ||
4527 | +#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK_EN_DISABLE \ | ||
4528 | + (0x0 << ISPCSI2_CTX_CTRL1_COUNT_UNLOCK_EN_SHIFT) | ||
4529 | +#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK_EN_ENABLE \ | ||
4530 | + (0x1 << ISPCSI2_CTX_CTRL1_COUNT_UNLOCK_EN_SHIFT) | ||
4531 | +#define ISPCSI2_CTX_CTRL1_PING_PONG_SHIFT 3 | ||
4532 | +#define ISPCSI2_CTX_CTRL1_PING_PONG_MASK \ | ||
4533 | + (0x1 << ISPCSI2_CTX_CTRL1_PING_PONG_SHIFT) | ||
4534 | +#define ISPCSI2_CTX_CTRL1_CTX_EN_SHIFT 0 | ||
4535 | +#define ISPCSI2_CTX_CTRL1_CTX_EN_MASK \ | ||
4536 | + (0x1 << ISPCSI2_CTX_CTRL1_CTX_EN_SHIFT) | ||
4537 | +#define ISPCSI2_CTX_CTRL1_CTX_EN_DISABLE \ | ||
4538 | + (0x0 << ISPCSI2_CTX_CTRL1_CTX_EN_SHIFT) | ||
4539 | +#define ISPCSI2_CTX_CTRL1_CTX_EN_ENABLE \ | ||
4540 | + (0x1 << ISPCSI2_CTX_CTRL1_CTX_EN_SHIFT) | ||
4541 | + | ||
4542 | +#define ISPCSI2_CTX_CTRL2(n) ((0x074) + 0x20 * (n)) | ||
4543 | +#define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT 11 | ||
4544 | +#define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK \ | ||
4545 | + (0x3 << ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT) | ||
4546 | +#define ISPCSI2_CTX_CTRL2_FORMAT_SHIFT 0 | ||
4547 | +#define ISPCSI2_CTX_CTRL2_FORMAT_MASK (0x3FF << \ | ||
4548 | + ISPCSI2_CTX_CTRL2_FORMAT_SHIFT) | ||
4549 | + | ||
4550 | +#define ISPCSI2_CTX_DAT_OFST(n) ((0x078) + 0x20 * (n)) | ||
4551 | +#define ISPCSI2_CTX_DAT_OFST_OFST_SHIFT 5 | ||
4552 | +#define ISPCSI2_CTX_DAT_OFST_OFST_MASK (0x7FF << \ | ||
4553 | + ISPCSI2_CTX_DAT_OFST_OFST_SHIFT) | ||
4554 | + | ||
4555 | +#define ISPCSI2_CTX_DAT_PING_ADDR(n) ((0x07C) + 0x20 * (n)) | ||
4556 | +#define ISPCSI2_CTX_DAT_PONG_ADDR(n) ((0x080) + 0x20 * (n)) | ||
4557 | +#define ISPCSI2_CTX_IRQENABLE(n) ((0x084) + 0x20 * (n)) | ||
4558 | +#define ISPCSI2_CTX_IRQENABLE_ECC_CORRECTION_IRQ (1 << 8) | ||
4559 | +#define ISPCSI2_CTX_IRQENABLE_LINE_NUMBER_IRQ (1 << 7) | ||
4560 | +#define ISPCSI2_CTX_IRQENABLE_FRAME_NUMBER_IRQ (1 << 6) | ||
4561 | +#define ISPCSI2_CTX_IRQENABLE_CS_IRQ (1 << 5) | ||
4562 | +#define ISPCSI2_CTX_IRQENABLE_LE_IRQ (1 << 3) | ||
4563 | +#define ISPCSI2_CTX_IRQENABLE_LS_IRQ (1 << 2) | ||
4564 | +#define ISPCSI2_CTX_IRQENABLE_FE_IRQ (1 << 1) | ||
4565 | +#define ISPCSI2_CTX_IRQENABLE_FS_IRQ 1 | ||
4566 | +#define ISPCSI2_CTX_IRQSTATUS(n) ((0x088) + 0x20 * (n)) | ||
4567 | +#define ISPCSI2_CTX_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 8) | ||
4568 | +#define ISPCSI2_CTX_IRQSTATUS_LINE_NUMBER_IRQ (1 << 7) | ||
4569 | +#define ISPCSI2_CTX_IRQSTATUS_FRAME_NUMBER_IRQ (1 << 6) | ||
4570 | +#define ISPCSI2_CTX_IRQSTATUS_CS_IRQ (1 << 5) | ||
4571 | +#define ISPCSI2_CTX_IRQSTATUS_LE_IRQ (1 << 3) | ||
4572 | +#define ISPCSI2_CTX_IRQSTATUS_LS_IRQ (1 << 2) | ||
4573 | +#define ISPCSI2_CTX_IRQSTATUS_FE_IRQ (1 << 1) | ||
4574 | +#define ISPCSI2_CTX_IRQSTATUS_FS_IRQ 1 | ||
4575 | + | ||
4576 | +#define ISPCSI2_CTX_CTRL3(n) ((0x08C) + 0x20 * (n)) | ||
4577 | +#define ISPCSI2_CTX_CTRL3_ALPHA_SHIFT 5 | ||
4578 | +#define ISPCSI2_CTX_CTRL3_ALPHA_MASK (0x3FFF << \ | ||
4579 | + ISPCSI2_CTX_CTRL3_ALPHA_SHIFT) | ||
4580 | + | ||
4581 | +#define ISPCSI2PHY_CFG0 (0x000) | ||
4582 | +#define ISPCSI2PHY_CFG0_THS_TERM_SHIFT 8 | ||
4583 | +#define ISPCSI2PHY_CFG0_THS_TERM_MASK \ | ||
4584 | + (0xFF << ISPCSI2PHY_CFG0_THS_TERM_SHIFT) | ||
4585 | +#define ISPCSI2PHY_CFG0_THS_TERM_RESETVAL \ | ||
4586 | + (0x04 << ISPCSI2PHY_CFG0_THS_TERM_SHIFT) | ||
4587 | +#define ISPCSI2PHY_CFG0_THS_SETTLE_SHIFT 0 | ||
4588 | +#define ISPCSI2PHY_CFG0_THS_SETTLE_MASK \ | ||
4589 | + (0xFF << ISPCSI2PHY_CFG0_THS_SETTLE_SHIFT) | ||
4590 | +#define ISPCSI2PHY_CFG0_THS_SETTLE_RESETVAL \ | ||
4591 | + (0x27 << ISPCSI2PHY_CFG0_THS_SETTLE_SHIFT) | ||
4592 | +#define ISPCSI2PHY_CFG1 (0x004) | ||
4593 | +#define ISPCSI2PHY_CFG1_TCLK_TERM_SHIFT 18 | ||
4594 | +#define ISPCSI2PHY_CFG1_TCLK_TERM_MASK \ | ||
4595 | + (0x7F << ISPCSI2PHY_CFG1_TCLK_TERM_SHIFT) | ||
4596 | +#define ISPCSI2PHY_CFG1_TCLK_TERM__RESETVAL \ | ||
4597 | + (0x00 << ISPCSI2PHY_CFG1_TCLK_TERM_SHIFT) | ||
4598 | +#define ISPCSI2PHY_CFG1_RESERVED1_SHIFT 10 | ||
4599 | +#define ISPCSI2PHY_CFG1_RESERVED1_MASK \ | ||
4600 | + (0xFF << ISPCSI2PHY_CFG1_RESERVED1_SHIFT) | ||
4601 | +#define ISPCSI2PHY_CFG1_RESERVED1__RESETVAL \ | ||
4602 | + (0xB8 << ISPCSI2PHY_CFG1_RESERVED1_SHIFT) | ||
4603 | +#define ISPCSI2PHY_CFG1_TCLK_MISS_SHIFT 8 | ||
4604 | +#define ISPCSI2PHY_CFG1_TCLK_MISS_MASK \ | ||
4605 | + (0x3 << ISPCSI2PHY_CFG1_TCLK_MISS_SHIFT) | ||
4606 | +#define ISPCSI2PHY_CFG1_TCLK_MISS__RESETVAL \ | ||
4607 | + (0x1 << ISPCSI2PHY_CFG1_TCLK_MISS_SHIFT) | ||
4608 | +#define ISPCSI2PHY_CFG1_TCLK_SETTLE_SHIFT 0 | ||
4609 | +#define ISPCSI2PHY_CFG1_TCLK_SETTLE_MASK \ | ||
4610 | + (0xFF << ISPCSI2PHY_CFG1_TCLK_TERM_SHIFT) | ||
4611 | +#define ISPCSI2PHY_CFG1_TCLK_SETTLE__RESETVAL \ | ||
4612 | + (0x0E << ISPCSI2PHY_CFG1_TCLK_TERM_SHIFT) | ||
4613 | +#define ISPCSI2PHY_CFG1__RESETVAL (ISPCSI2PHY_CFG1_TCLK_TERM__RESETVAL | \ | ||
4614 | + ISPCSI2PHY_CFG1_RESERVED1__RESETVAL | \ | ||
4615 | + ISPCSI2PHY_CFG1_TCLK_MISS__RESETVAL | \ | ||
4616 | + ISPCSI2PHY_CFG1_TCLK_SETTLE__RESETVAL) | ||
4617 | +#define ISPCSI2PHY_CFG1__EDITABLE_MASK (ISPCSI2PHY_CFG1_TCLK_TERM_MASK | \ | ||
4618 | + ISPCSI2PHY_CFG1_RESERVED1_MASK | \ | ||
4619 | + ISPCSI2PHY_CFG1_TCLK_MISS_MASK | \ | ||
4620 | + ISPCSI2PHY_CFG1_TCLK_SETTLE_MASK) | ||
4621 | + | ||
4622 | +#endif /* __ISPREG_H__ */ | ||
4623 | -- | ||
4624 | 1.5.6.5 | ||
4625 | |||
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0002-omap3isp-Add-ISP-MMU-wrapper.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0002-omap3isp-Add-ISP-MMU-wrapper.patch new file mode 100644 index 0000000000..cfca26723a --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0002-omap3isp-Add-ISP-MMU-wrapper.patch | |||
@@ -0,0 +1,209 @@ | |||
1 | From 731527a7dc26533a878c7c5f36fc148fdcaa21b8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
3 | Date: Tue, 10 Mar 2009 10:49:02 +0200 | ||
4 | Subject: [PATCH] omap3isp: Add ISP MMU wrapper | ||
5 | |||
6 | TODO: | ||
7 | |||
8 | - The ISP driver should start using the IOMMU directly without this wrapper. | ||
9 | |||
10 | Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
11 | --- | ||
12 | drivers/media/video/isp/ispmmu.c | 141 ++++++++++++++++++++++++++++++++++++++ | ||
13 | drivers/media/video/isp/ispmmu.h | 36 ++++++++++ | ||
14 | 2 files changed, 177 insertions(+), 0 deletions(-) | ||
15 | create mode 100644 drivers/media/video/isp/ispmmu.c | ||
16 | create mode 100644 drivers/media/video/isp/ispmmu.h | ||
17 | |||
18 | diff --git a/drivers/media/video/isp/ispmmu.c b/drivers/media/video/isp/ispmmu.c | ||
19 | new file mode 100644 | ||
20 | index 0000000..f872c71 | ||
21 | --- /dev/null | ||
22 | +++ b/drivers/media/video/isp/ispmmu.c | ||
23 | @@ -0,0 +1,141 @@ | ||
24 | +/* | ||
25 | + * omap iommu wrapper for TI's OMAP3430 Camera ISP | ||
26 | + * | ||
27 | + * Copyright (C) 2008--2009 Nokia. | ||
28 | + * | ||
29 | + * Contributors: | ||
30 | + * Hiroshi Doyu <hiroshi.doyu@nokia.com> | ||
31 | + * Sakari Ailus <sakari.ailus@nokia.com> | ||
32 | + * | ||
33 | + * This package is free software; you can redistribute it and/or modify | ||
34 | + * it under the terms of the GNU General Public License version 2 as | ||
35 | + * published by the Free Software Foundation. | ||
36 | + * | ||
37 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
38 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
39 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
40 | + */ | ||
41 | + | ||
42 | +#include <linux/module.h> | ||
43 | + | ||
44 | +#include "ispmmu.h" | ||
45 | +#include "isp.h" | ||
46 | + | ||
47 | +#include <mach/iommu.h> | ||
48 | +#include <mach/iovmm.h> | ||
49 | + | ||
50 | +#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8) | ||
51 | + | ||
52 | +static struct iommu *isp_iommu; | ||
53 | + | ||
54 | +dma_addr_t ispmmu_vmalloc(size_t bytes) | ||
55 | +{ | ||
56 | + return (dma_addr_t)iommu_vmalloc(isp_iommu, 0, bytes, IOMMU_FLAG); | ||
57 | +} | ||
58 | + | ||
59 | +void ispmmu_vfree(const dma_addr_t da) | ||
60 | +{ | ||
61 | + iommu_vfree(isp_iommu, (u32)da); | ||
62 | +} | ||
63 | + | ||
64 | +dma_addr_t ispmmu_kmap(u32 pa, int size) | ||
65 | +{ | ||
66 | + void *da; | ||
67 | + | ||
68 | + da = (void *)iommu_kmap(isp_iommu, 0, pa, size, IOMMU_FLAG); | ||
69 | + if (IS_ERR(da)) | ||
70 | + return PTR_ERR(da); | ||
71 | + | ||
72 | + return (dma_addr_t)da; | ||
73 | +} | ||
74 | + | ||
75 | +void ispmmu_kunmap(dma_addr_t da) | ||
76 | +{ | ||
77 | + iommu_kunmap(isp_iommu, (u32)da); | ||
78 | +} | ||
79 | + | ||
80 | +dma_addr_t ispmmu_vmap(const struct scatterlist *sglist, | ||
81 | + int sglen) | ||
82 | +{ | ||
83 | + int err; | ||
84 | + void *da; | ||
85 | + struct sg_table *sgt; | ||
86 | + unsigned int i; | ||
87 | + struct scatterlist *sg, *src = (struct scatterlist *)sglist; | ||
88 | + | ||
89 | + /* | ||
90 | + * convert isp sglist to iommu sgt | ||
91 | + * FIXME: should be fixed in the upper layer? | ||
92 | + */ | ||
93 | + sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); | ||
94 | + if (!sgt) | ||
95 | + return -ENOMEM; | ||
96 | + err = sg_alloc_table(sgt, sglen, GFP_KERNEL); | ||
97 | + if (err) | ||
98 | + goto err_sg_alloc; | ||
99 | + | ||
100 | + for_each_sg(sgt->sgl, sg, sgt->nents, i) | ||
101 | + sg_set_buf(sg, phys_to_virt(sg_dma_address(src + i)), | ||
102 | + sg_dma_len(src + i)); | ||
103 | + | ||
104 | + da = (void *)iommu_vmap(isp_iommu, 0, sgt, IOMMU_FLAG); | ||
105 | + if (IS_ERR(da)) | ||
106 | + goto err_vmap; | ||
107 | + | ||
108 | + return (dma_addr_t)da; | ||
109 | + | ||
110 | +err_vmap: | ||
111 | + sg_free_table(sgt); | ||
112 | +err_sg_alloc: | ||
113 | + kfree(sgt); | ||
114 | + return -ENOMEM; | ||
115 | +} | ||
116 | +EXPORT_SYMBOL_GPL(ispmmu_vmap); | ||
117 | + | ||
118 | +void ispmmu_vunmap(dma_addr_t da) | ||
119 | +{ | ||
120 | + struct sg_table *sgt; | ||
121 | + | ||
122 | + sgt = iommu_vunmap(isp_iommu, (u32)da); | ||
123 | + if (!sgt) | ||
124 | + return; | ||
125 | + sg_free_table(sgt); | ||
126 | + kfree(sgt); | ||
127 | +} | ||
128 | +EXPORT_SYMBOL_GPL(ispmmu_vunmap); | ||
129 | + | ||
130 | +void ispmmu_save_context(void) | ||
131 | +{ | ||
132 | + if (isp_iommu) | ||
133 | + iommu_save_ctx(isp_iommu); | ||
134 | +} | ||
135 | + | ||
136 | +void ispmmu_restore_context(void) | ||
137 | +{ | ||
138 | + if (isp_iommu) | ||
139 | + iommu_restore_ctx(isp_iommu); | ||
140 | +} | ||
141 | + | ||
142 | +int __init ispmmu_init(void) | ||
143 | +{ | ||
144 | + int err = 0; | ||
145 | + | ||
146 | + isp_get(); | ||
147 | + isp_iommu = iommu_get("isp"); | ||
148 | + if (IS_ERR(isp_iommu)) { | ||
149 | + err = PTR_ERR(isp_iommu); | ||
150 | + isp_iommu = NULL; | ||
151 | + } | ||
152 | + isp_put(); | ||
153 | + | ||
154 | + return err; | ||
155 | +} | ||
156 | + | ||
157 | +void ispmmu_cleanup(void) | ||
158 | +{ | ||
159 | + isp_get(); | ||
160 | + if (isp_iommu) | ||
161 | + iommu_put(isp_iommu); | ||
162 | + isp_put(); | ||
163 | + isp_iommu = NULL; | ||
164 | +} | ||
165 | diff --git a/drivers/media/video/isp/ispmmu.h b/drivers/media/video/isp/ispmmu.h | ||
166 | new file mode 100644 | ||
167 | index 0000000..0bc5bcb | ||
168 | --- /dev/null | ||
169 | +++ b/drivers/media/video/isp/ispmmu.h | ||
170 | @@ -0,0 +1,36 @@ | ||
171 | +/* | ||
172 | + * omap iommu wrapper for TI's OMAP3430 Camera ISP | ||
173 | + * | ||
174 | + * Copyright (C) 2008--2009 Nokia. | ||
175 | + * | ||
176 | + * Contributors: | ||
177 | + * Hiroshi Doyu <hiroshi.doyu@nokia.com> | ||
178 | + * Sakari Ailus <sakari.ailus@nokia.com> | ||
179 | + * | ||
180 | + * This package is free software; you can redistribute it and/or modify | ||
181 | + * it under the terms of the GNU General Public License version 2 as | ||
182 | + * published by the Free Software Foundation. | ||
183 | + * | ||
184 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
185 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
186 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
187 | + */ | ||
188 | + | ||
189 | +#ifndef OMAP_ISP_MMU_H | ||
190 | +#define OMAP_ISP_MMU_H | ||
191 | + | ||
192 | +#include <linux/err.h> | ||
193 | +#include <linux/scatterlist.h> | ||
194 | + | ||
195 | +dma_addr_t ispmmu_vmalloc(size_t bytes); | ||
196 | +void ispmmu_vfree(const dma_addr_t da); | ||
197 | +dma_addr_t ispmmu_kmap(u32 pa, int size); | ||
198 | +void ispmmu_kunmap(dma_addr_t da); | ||
199 | +dma_addr_t ispmmu_vmap(const struct scatterlist *sglist, int sglen); | ||
200 | +void ispmmu_vunmap(dma_addr_t da); | ||
201 | +void ispmmu_save_context(void); | ||
202 | +void ispmmu_restore_context(void); | ||
203 | +int ispmmu_init(void); | ||
204 | +void ispmmu_cleanup(void); | ||
205 | + | ||
206 | +#endif /* OMAP_ISP_MMU_H */ | ||
207 | -- | ||
208 | 1.5.6.5 | ||
209 | |||
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0003-omap3isp-Add-userspace-header.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0003-omap3isp-Add-userspace-header.patch new file mode 100644 index 0000000000..66c171f544 --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0003-omap3isp-Add-userspace-header.patch | |||
@@ -0,0 +1,696 @@ | |||
1 | From 98ca1ef8c6e2561989aeef981131cf5077eab1d1 Mon Sep 17 00:00:00 2001 | ||
2 | From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
3 | Date: Tue, 10 Mar 2009 10:49:02 +0200 | ||
4 | Subject: [PATCH] omap3isp: Add userspace header | ||
5 | |||
6 | Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
7 | --- | ||
8 | arch/arm/plat-omap/include/mach/isp_user.h | 676 ++++++++++++++++++++++++++++ | ||
9 | 1 files changed, 676 insertions(+), 0 deletions(-) | ||
10 | create mode 100644 arch/arm/plat-omap/include/mach/isp_user.h | ||
11 | |||
12 | diff --git a/arch/arm/plat-omap/include/mach/isp_user.h b/arch/arm/plat-omap/include/mach/isp_user.h | ||
13 | new file mode 100644 | ||
14 | index 0000000..b819e26 | ||
15 | --- /dev/null | ||
16 | +++ b/arch/arm/plat-omap/include/mach/isp_user.h | ||
17 | @@ -0,0 +1,676 @@ | ||
18 | +/* | ||
19 | + * isp_user.h | ||
20 | + * | ||
21 | + * Include file for OMAP ISP module in TI's OMAP3. | ||
22 | + * | ||
23 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
24 | + * | ||
25 | + * Contributors: | ||
26 | + * Mohit Jalori <mjalori@ti.com> | ||
27 | + * Sergio Aguirre <saaguirre@ti.com> | ||
28 | + * | ||
29 | + * This package is free software; you can redistribute it and/or modify | ||
30 | + * it under the terms of the GNU General Public License version 2 as | ||
31 | + * published by the Free Software Foundation. | ||
32 | + * | ||
33 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
34 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
35 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
36 | + */ | ||
37 | + | ||
38 | +#ifndef OMAP_ISP_USER_H | ||
39 | +#define OMAP_ISP_USER_H | ||
40 | + | ||
41 | +/* ISP Private IOCTLs */ | ||
42 | +#define VIDIOC_PRIVATE_ISP_CCDC_CFG \ | ||
43 | + _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct ispccdc_update_config) | ||
44 | +#define VIDIOC_PRIVATE_ISP_PRV_CFG \ | ||
45 | + _IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct ispprv_update_config) | ||
46 | +#define VIDIOC_PRIVATE_ISP_AEWB_CFG \ | ||
47 | + _IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct isph3a_aewb_config) | ||
48 | +#define VIDIOC_PRIVATE_ISP_AEWB_REQ \ | ||
49 | + _IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct isph3a_aewb_data) | ||
50 | +#define VIDIOC_PRIVATE_ISP_HIST_CFG \ | ||
51 | + _IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct isp_hist_config) | ||
52 | +#define VIDIOC_PRIVATE_ISP_HIST_REQ \ | ||
53 | + _IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct isp_hist_data) | ||
54 | +#define VIDIOC_PRIVATE_ISP_AF_CFG \ | ||
55 | + _IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct af_configuration) | ||
56 | +#define VIDIOC_PRIVATE_ISP_AF_REQ \ | ||
57 | + _IOWR('V', BASE_VIDIOC_PRIVATE + 9, struct isp_af_data) | ||
58 | + | ||
59 | +/* AE/AWB related structures and flags*/ | ||
60 | + | ||
61 | +/* Flags for update field */ | ||
62 | +#define REQUEST_STATISTICS (1 << 0) | ||
63 | +#define SET_COLOR_GAINS (1 << 1) | ||
64 | +#define SET_DIGITAL_GAIN (1 << 2) | ||
65 | +#define SET_EXPOSURE (1 << 3) | ||
66 | +#define SET_ANALOG_GAIN (1 << 4) | ||
67 | + | ||
68 | +#define MAX_FRAME_COUNT 0x0FFF | ||
69 | +#define MAX_FUTURE_FRAMES 10 | ||
70 | + | ||
71 | +#define MAX_SATURATION_LIM 1023 | ||
72 | +#define MIN_WIN_H 2 | ||
73 | +#define MAX_WIN_H 256 | ||
74 | +#define MIN_WIN_W 6 | ||
75 | +#define MAX_WIN_W 256 | ||
76 | +#define MAX_WINVC 128 | ||
77 | +#define MAX_WINHC 36 | ||
78 | +#define MAX_WINSTART 4095 | ||
79 | +#define MIN_SUB_INC 2 | ||
80 | +#define MAX_SUB_INC 32 | ||
81 | + | ||
82 | +/* Range Constants */ | ||
83 | +#define AF_IIRSH_MIN 0 | ||
84 | +#define AF_IIRSH_MAX 4094 | ||
85 | +#define AF_PAXEL_HORIZONTAL_COUNT_MIN 0 | ||
86 | +#define AF_PAXEL_HORIZONTAL_COUNT_MAX 35 | ||
87 | +#define AF_PAXEL_VERTICAL_COUNT_MIN 0 | ||
88 | +#define AF_PAXEL_VERTICAL_COUNT_MAX 127 | ||
89 | +#define AF_PAXEL_INCREMENT_MIN 0 | ||
90 | +#define AF_PAXEL_INCREMENT_MAX 14 | ||
91 | +#define AF_PAXEL_HEIGHT_MIN 0 | ||
92 | +#define AF_PAXEL_HEIGHT_MAX 127 | ||
93 | +#define AF_PAXEL_WIDTH_MIN 0 | ||
94 | +#define AF_PAXEL_WIDTH_MAX 127 | ||
95 | +#define AF_PAXEL_HZSTART_MIN 2 | ||
96 | +#define AF_PAXEL_HZSTART_MAX 4094 | ||
97 | + | ||
98 | +#define AF_PAXEL_VTSTART_MIN 0 | ||
99 | +#define AF_PAXEL_VTSTART_MAX 4095 | ||
100 | +#define AF_THRESHOLD_MAX 255 | ||
101 | +#define AF_COEF_MAX 4095 | ||
102 | +#define AF_PAXEL_SIZE 48 | ||
103 | + | ||
104 | +/** | ||
105 | + * struct isph3a_aewb_config - AE AWB configuration reset values. | ||
106 | + * saturation_limit: Saturation limit. | ||
107 | + * @win_height: Window Height. Range 2 - 256, even values only. | ||
108 | + * @win_width: Window Width. Range 6 - 256, even values only. | ||
109 | + * @ver_win_count: Vertical Window Count. Range 1 - 128. | ||
110 | + * @hor_win_count: Horizontal Window Count. Range 1 - 36. | ||
111 | + * @ver_win_start: Vertical Window Start. Range 0 - 4095. | ||
112 | + * @hor_win_start: Horizontal Window Start. Range 0 - 4095. | ||
113 | + * @blk_ver_win_start: Black Vertical Windows Start. Range 0 - 4095. | ||
114 | + * @blk_win_height: Black Window Height. Range 2 - 256, even values only. | ||
115 | + * @subsample_ver_inc: Subsample Vertical points increment Range 2 - 32, even | ||
116 | + * values only. | ||
117 | + * @subsample_hor_inc: Subsample Horizontal points increment Range 2 - 32, even | ||
118 | + * values only. | ||
119 | + * @alaw_enable: AEW ALAW EN flag. | ||
120 | + * @aewb_enable: AE AWB stats generation EN flag. | ||
121 | + */ | ||
122 | +struct isph3a_aewb_config { | ||
123 | + __u16 saturation_limit; | ||
124 | + __u16 win_height; | ||
125 | + __u16 win_width; | ||
126 | + __u16 ver_win_count; | ||
127 | + __u16 hor_win_count; | ||
128 | + __u16 ver_win_start; | ||
129 | + __u16 hor_win_start; | ||
130 | + __u16 blk_ver_win_start; | ||
131 | + __u16 blk_win_height; | ||
132 | + __u16 subsample_ver_inc; | ||
133 | + __u16 subsample_hor_inc; | ||
134 | + __u8 alaw_enable; | ||
135 | + __u8 aewb_enable; | ||
136 | +}; | ||
137 | + | ||
138 | +/** | ||
139 | + * struct isph3a_aewb_data - Structure of data sent to or received from user | ||
140 | + * @h3a_aewb_statistics_buf: Pointer to pass to user. | ||
141 | + * @shutter: Shutter speed. | ||
142 | + * @gain: Sensor analog Gain. | ||
143 | + * @shutter_cap: Shutter speed for capture. | ||
144 | + * @gain_cap: Sensor Gain for capture. | ||
145 | + * @dgain: White balance digital gain. | ||
146 | + * @wb_gain_b: White balance color gain blue. | ||
147 | + * @wb_gain_r: White balance color gain red. | ||
148 | + * @wb_gain_gb: White balance color gain green blue. | ||
149 | + * @wb_gain_gr: White balance color gain green red. | ||
150 | + * @frame_number: Frame number of requested stats. | ||
151 | + * @curr_frame: Current frame number being processed. | ||
152 | + * @update: Bitwise flags to update parameters. | ||
153 | + * @ts: Timestamp of returned framestats. | ||
154 | + * @field_count: Sequence number of returned framestats. | ||
155 | + */ | ||
156 | +struct isph3a_aewb_data { | ||
157 | + void *h3a_aewb_statistics_buf; | ||
158 | + __u32 shutter; | ||
159 | + __u16 gain; | ||
160 | + __u32 shutter_cap; | ||
161 | + __u16 gain_cap; | ||
162 | + __u16 dgain; | ||
163 | + __u16 wb_gain_b; | ||
164 | + __u16 wb_gain_r; | ||
165 | + __u16 wb_gain_gb; | ||
166 | + __u16 wb_gain_gr; | ||
167 | + __u16 frame_number; | ||
168 | + __u16 curr_frame; | ||
169 | + __u8 update; | ||
170 | + struct timeval ts; | ||
171 | + __u32 config_counter; | ||
172 | + unsigned long field_count; | ||
173 | +}; | ||
174 | + | ||
175 | + | ||
176 | +/* Histogram related structs */ | ||
177 | +/* Flags for number of bins */ | ||
178 | +#define BINS_32 0x0 | ||
179 | +#define BINS_64 0x1 | ||
180 | +#define BINS_128 0x2 | ||
181 | +#define BINS_256 0x3 | ||
182 | + | ||
183 | +struct isp_hist_config { | ||
184 | + __u8 hist_source; /* CCDC or Memory */ | ||
185 | + __u8 input_bit_width; /* Needed o know the size per pixel */ | ||
186 | + __u8 hist_frames; /* Num of frames to be processed and | ||
187 | + * accumulated | ||
188 | + */ | ||
189 | + __u8 hist_h_v_info; /* frame-input width and height if source is | ||
190 | + * memory | ||
191 | + */ | ||
192 | + __u16 hist_radd; /* frame-input address in memory */ | ||
193 | + __u16 hist_radd_off; /* line-offset for frame-input */ | ||
194 | + __u16 hist_bins; /* number of bins: 32, 64, 128, or 256 */ | ||
195 | + __u16 wb_gain_R; /* White Balance Field-to-Pattern Assignments */ | ||
196 | + __u16 wb_gain_RG; /* White Balance Field-to-Pattern Assignments */ | ||
197 | + __u16 wb_gain_B; /* White Balance Field-to-Pattern Assignments */ | ||
198 | + __u16 wb_gain_BG; /* White Balance Field-to-Pattern Assignments */ | ||
199 | + __u8 num_regions; /* number of regions to be configured */ | ||
200 | + __u16 reg0_hor; /* Region 0 size and position */ | ||
201 | + __u16 reg0_ver; /* Region 0 size and position */ | ||
202 | + __u16 reg1_hor; /* Region 1 size and position */ | ||
203 | + __u16 reg1_ver; /* Region 1 size and position */ | ||
204 | + __u16 reg2_hor; /* Region 2 size and position */ | ||
205 | + __u16 reg2_ver; /* Region 2 size and position */ | ||
206 | + __u16 reg3_hor; /* Region 3 size and position */ | ||
207 | + __u16 reg3_ver; /* Region 3 size and position */ | ||
208 | +}; | ||
209 | + | ||
210 | +struct isp_hist_data { | ||
211 | + __u32 *hist_statistics_buf; /* Pointer to pass to user */ | ||
212 | +}; | ||
213 | + | ||
214 | +/* Auto Focus related structs */ | ||
215 | + | ||
216 | +#define AF_NUMBER_OF_COEF 11 | ||
217 | + | ||
218 | +/* Flags for update field */ | ||
219 | +#define REQUEST_STATISTICS (1 << 0) | ||
220 | +#define LENS_DESIRED_POSITION (1 << 1) | ||
221 | +#define LENS_CURRENT_POSITION (1 << 2) | ||
222 | + | ||
223 | +/** | ||
224 | + * struct isp_af_xtrastats - Extra statistics related to AF generated stats. | ||
225 | + * @ts: Timestamp when the frame gets delivered to the user. | ||
226 | + * @field_count: Field count of the frame delivered to the user. | ||
227 | + * @lens_position: Lens position when the stats are being generated. | ||
228 | + */ | ||
229 | +struct isp_af_xtrastats { | ||
230 | + struct timeval ts; | ||
231 | + unsigned long field_count; | ||
232 | + __u16 lens_position; /* deprecated */ | ||
233 | +}; | ||
234 | + | ||
235 | +/** | ||
236 | + * struct isp_af_data - AF statistics data to transfer between driver and user. | ||
237 | + * @af_statistics_buf: Pointer to pass to user. | ||
238 | + * @lens_current_position: Read value of lens absolute position. | ||
239 | + * @desired_lens_direction: Lens desired location. | ||
240 | + * @update: Bitwise flags to update parameters. | ||
241 | + * @frame_number: Data for which frame is desired/given. | ||
242 | + * @curr_frame: Current frame number being processed by AF module. | ||
243 | + * @xtrastats: Extra statistics structure. | ||
244 | + */ | ||
245 | +struct isp_af_data { | ||
246 | + void *af_statistics_buf; | ||
247 | + __u16 lens_current_position; /* deprecated */ | ||
248 | + __u16 desired_lens_direction; /* deprecated */ | ||
249 | + __u16 update; | ||
250 | + __u16 frame_number; | ||
251 | + __u16 curr_frame; | ||
252 | + __u32 config_counter; | ||
253 | + struct isp_af_xtrastats xtrastats; | ||
254 | +}; | ||
255 | + | ||
256 | +/* enum used for status of specific feature */ | ||
257 | +enum af_alaw_enable { | ||
258 | + H3A_AF_ALAW_DISABLE = 0, | ||
259 | + H3A_AF_ALAW_ENABLE = 1 | ||
260 | +}; | ||
261 | + | ||
262 | +enum af_hmf_enable { | ||
263 | + H3A_AF_HMF_DISABLE = 0, | ||
264 | + H3A_AF_HMF_ENABLE = 1 | ||
265 | +}; | ||
266 | + | ||
267 | +enum af_config_flag { | ||
268 | + H3A_AF_CFG_DISABLE = 0, | ||
269 | + H3A_AF_CFG_ENABLE = 1 | ||
270 | +}; | ||
271 | + | ||
272 | +enum af_mode { | ||
273 | + ACCUMULATOR_SUMMED = 0, | ||
274 | + ACCUMULATOR_PEAK = 1 | ||
275 | +}; | ||
276 | + | ||
277 | +/* Red, Green, and blue pixel location in the AF windows */ | ||
278 | +enum rgbpos { | ||
279 | + GR_GB_BAYER = 0, /* GR and GB as Bayer pattern */ | ||
280 | + RG_GB_BAYER = 1, /* RG and GB as Bayer pattern */ | ||
281 | + GR_BG_BAYER = 2, /* GR and BG as Bayer pattern */ | ||
282 | + RG_BG_BAYER = 3, /* RG and BG as Bayer pattern */ | ||
283 | + GG_RB_CUSTOM = 4, /* GG and RB as custom pattern */ | ||
284 | + RB_GG_CUSTOM = 5 /* RB and GG as custom pattern */ | ||
285 | +}; | ||
286 | + | ||
287 | +/* Contains the information regarding the Horizontal Median Filter */ | ||
288 | +struct af_hmf { | ||
289 | + enum af_hmf_enable enable; /* Status of Horizontal Median Filter */ | ||
290 | + unsigned int threshold; /* Threshhold Value for Horizontal Median | ||
291 | + * Filter | ||
292 | + */ | ||
293 | +}; | ||
294 | + | ||
295 | +/* Contains the information regarding the IIR Filters */ | ||
296 | +struct af_iir { | ||
297 | + unsigned int hz_start_pos; /* IIR Start Register Value */ | ||
298 | + int coeff_set0[AF_NUMBER_OF_COEF]; /* | ||
299 | + * IIR Filter Coefficient for | ||
300 | + * Set 0 | ||
301 | + */ | ||
302 | + int coeff_set1[AF_NUMBER_OF_COEF]; /* | ||
303 | + * IIR Filter Coefficient for | ||
304 | + * Set 1 | ||
305 | + */ | ||
306 | +}; | ||
307 | + | ||
308 | +/* Contains the information regarding the Paxels Structure in AF Engine */ | ||
309 | +struct af_paxel { | ||
310 | + unsigned int width; /* Width of the Paxel */ | ||
311 | + unsigned int height; /* Height of the Paxel */ | ||
312 | + unsigned int hz_start; /* Horizontal Start Position */ | ||
313 | + unsigned int vt_start; /* Vertical Start Position */ | ||
314 | + unsigned int hz_cnt; /* Horizontal Count */ | ||
315 | + unsigned int vt_cnt; /* vertical Count */ | ||
316 | + unsigned int line_incr; /* Line Increment */ | ||
317 | +}; | ||
318 | +/* Contains the parameters required for hardware set up of AF Engine */ | ||
319 | +struct af_configuration { | ||
320 | + enum af_alaw_enable alaw_enable; /*ALWAW status */ | ||
321 | + struct af_hmf hmf_config; /*HMF configurations */ | ||
322 | + enum rgbpos rgb_pos; /*RGB Positions */ | ||
323 | + struct af_iir iir_config; /*IIR filter configurations */ | ||
324 | + struct af_paxel paxel_config; /*Paxel parameters */ | ||
325 | + enum af_mode mode; /*Accumulator mode */ | ||
326 | + enum af_config_flag af_config; /*Flag indicates Engine is configured */ | ||
327 | +}; | ||
328 | + | ||
329 | +/* ISP CCDC structs */ | ||
330 | + | ||
331 | +/* Abstraction layer CCDC configurations */ | ||
332 | +#define ISP_ABS_CCDC_ALAW (1 << 0) | ||
333 | +#define ISP_ABS_CCDC_LPF (1 << 1) | ||
334 | +#define ISP_ABS_CCDC_BLCLAMP (1 << 2) | ||
335 | +#define ISP_ABS_CCDC_BCOMP (1 << 3) | ||
336 | +#define ISP_ABS_CCDC_FPC (1 << 4) | ||
337 | +#define ISP_ABS_CCDC_CULL (1 << 5) | ||
338 | +#define ISP_ABS_CCDC_COLPTN (1 << 6) | ||
339 | +#define ISP_ABS_CCDC_CONFIG_LSC (1 << 7) | ||
340 | +#define ISP_ABS_TBL_LSC (1 << 8) | ||
341 | + | ||
342 | +#define RGB_MAX 3 | ||
343 | + | ||
344 | +/* Enumeration constants for Alaw input width */ | ||
345 | +enum alaw_ipwidth { | ||
346 | + ALAW_BIT12_3 = 0x3, | ||
347 | + ALAW_BIT11_2 = 0x4, | ||
348 | + ALAW_BIT10_1 = 0x5, | ||
349 | + ALAW_BIT9_0 = 0x6 | ||
350 | +}; | ||
351 | + | ||
352 | +/* Enumeration constants for Video Port */ | ||
353 | +enum vpin { | ||
354 | + BIT12_3 = 3, | ||
355 | + BIT11_2 = 4, | ||
356 | + BIT10_1 = 5, | ||
357 | + BIT9_0 = 6 | ||
358 | +}; | ||
359 | + | ||
360 | +enum vpif_freq { | ||
361 | + PIXCLKBY2, | ||
362 | + PIXCLKBY3_5, | ||
363 | + PIXCLKBY4_5, | ||
364 | + PIXCLKBY5_5, | ||
365 | + PIXCLKBY6_5 | ||
366 | +}; | ||
367 | + | ||
368 | +/** | ||
369 | + * struct ispccdc_lsc_config - Structure for LSC configuration. | ||
370 | + * @offset: Table Offset of the gain table. | ||
371 | + * @gain_mode_n: Vertical dimension of a paxel in LSC configuration. | ||
372 | + * @gain_mode_m: Horizontal dimension of a paxel in LSC configuration. | ||
373 | + * @gain_format: Gain table format. | ||
374 | + * @fmtsph: Start pixel horizontal from start of the HS sync pulse. | ||
375 | + * @fmtlnh: Number of pixels in horizontal direction to use for the data | ||
376 | + * reformatter. | ||
377 | + * @fmtslv: Start line from start of VS sync pulse for the data reformatter. | ||
378 | + * @fmtlnv: Number of lines in vertical direction for the data reformatter. | ||
379 | + * @initial_x: X position, in pixels, of the first active pixel in reference | ||
380 | + * to the first active paxel. Must be an even number. | ||
381 | + * @initial_y: Y position, in pixels, of the first active pixel in reference | ||
382 | + * to the first active paxel. Must be an even number. | ||
383 | + * @size: Size of LSC gain table. Filled when loaded from userspace. | ||
384 | + */ | ||
385 | +struct ispccdc_lsc_config { | ||
386 | + __u16 offset; | ||
387 | + __u8 gain_mode_n; | ||
388 | + __u8 gain_mode_m; | ||
389 | + __u8 gain_format; | ||
390 | + __u16 fmtsph; | ||
391 | + __u16 fmtlnh; | ||
392 | + __u16 fmtslv; | ||
393 | + __u16 fmtlnv; | ||
394 | + __u8 initial_x; | ||
395 | + __u8 initial_y; | ||
396 | + __u32 size; | ||
397 | +}; | ||
398 | + | ||
399 | +/** | ||
400 | + * struct ispccdc_bclamp - Structure for Optical & Digital black clamp subtract | ||
401 | + * @obgain: Optical black average gain. | ||
402 | + * @obstpixel: Start Pixel w.r.t. HS pulse in Optical black sample. | ||
403 | + * @oblines: Optical Black Sample lines. | ||
404 | + * @oblen: Optical Black Sample Length. | ||
405 | + * @dcsubval: Digital Black Clamp subtract value. | ||
406 | + */ | ||
407 | +struct ispccdc_bclamp { | ||
408 | + __u8 obgain; | ||
409 | + __u8 obstpixel; | ||
410 | + __u8 oblines; | ||
411 | + __u8 oblen; | ||
412 | + __u16 dcsubval; | ||
413 | +}; | ||
414 | + | ||
415 | +/** | ||
416 | + * ispccdc_fpc - Structure for FPC | ||
417 | + * @fpnum: Number of faulty pixels to be corrected in the frame. | ||
418 | + * @fpcaddr: Memory address of the FPC Table | ||
419 | + */ | ||
420 | +struct ispccdc_fpc { | ||
421 | + __u16 fpnum; | ||
422 | + __u32 fpcaddr; | ||
423 | +}; | ||
424 | + | ||
425 | +/** | ||
426 | + * ispccdc_blcomp - Structure for Black Level Compensation parameters. | ||
427 | + * @b_mg: B/Mg pixels. 2's complement. -128 to +127. | ||
428 | + * @gb_g: Gb/G pixels. 2's complement. -128 to +127. | ||
429 | + * @gr_cy: Gr/Cy pixels. 2's complement. -128 to +127. | ||
430 | + * @r_ye: R/Ye pixels. 2's complement. -128 to +127. | ||
431 | + */ | ||
432 | +struct ispccdc_blcomp { | ||
433 | + __u8 b_mg; | ||
434 | + __u8 gb_g; | ||
435 | + __u8 gr_cy; | ||
436 | + __u8 r_ye; | ||
437 | +}; | ||
438 | + | ||
439 | +/** | ||
440 | + * struct ispccdc_vp - Structure for Video Port parameters | ||
441 | + * @bitshift_sel: Video port input select. 3 - bits 12-3, 4 - bits 11-2, | ||
442 | + * 5 - bits 10-1, 6 - bits 9-0. | ||
443 | + * @freq_sel: Video port data ready frequency. 1 - 1/3.5, 2 - 1/4.5, | ||
444 | + * 3 - 1/5.5, 4 - 1/6.5. | ||
445 | + */ | ||
446 | +struct ispccdc_vp { | ||
447 | + enum vpin bitshift_sel; | ||
448 | + enum vpif_freq freq_sel; | ||
449 | +}; | ||
450 | + | ||
451 | +/** | ||
452 | + * ispccdc_culling - Structure for Culling parameters. | ||
453 | + * @v_pattern: Vertical culling pattern. | ||
454 | + * @h_odd: Horizontal Culling pattern for odd lines. | ||
455 | + * @h_even: Horizontal Culling pattern for even lines. | ||
456 | + */ | ||
457 | +struct ispccdc_culling { | ||
458 | + __u8 v_pattern; | ||
459 | + __u16 h_odd; | ||
460 | + __u16 h_even; | ||
461 | +}; | ||
462 | + | ||
463 | +/** | ||
464 | + * ispccdc_update_config - Structure for CCDC configuration. | ||
465 | + * @update: Specifies which CCDC registers should be updated. | ||
466 | + * @flag: Specifies which CCDC functions should be enabled. | ||
467 | + * @alawip: Enable/Disable A-Law compression. | ||
468 | + * @bclamp: Black clamp control register. | ||
469 | + * @blcomp: Black level compensation value for RGrGbB Pixels. 2's complement. | ||
470 | + * @fpc: Number of faulty pixels corrected in the frame, address of FPC table. | ||
471 | + * @cull: Cull control register. | ||
472 | + * @colptn: Color pattern of the sensor. | ||
473 | + * @lsc: Pointer to LSC gain table. | ||
474 | + */ | ||
475 | +struct ispccdc_update_config { | ||
476 | + __u16 update; | ||
477 | + __u16 flag; | ||
478 | + enum alaw_ipwidth alawip; | ||
479 | + struct ispccdc_bclamp *bclamp; | ||
480 | + struct ispccdc_blcomp *blcomp; | ||
481 | + struct ispccdc_fpc *fpc; | ||
482 | + struct ispccdc_lsc_config *lsc_cfg; | ||
483 | + struct ispccdc_culling *cull; | ||
484 | + __u32 colptn; | ||
485 | + __u8 *lsc; | ||
486 | +}; | ||
487 | + | ||
488 | +/* Preview configuration */ | ||
489 | + | ||
490 | +/*Abstraction layer preview configurations*/ | ||
491 | +#define ISP_ABS_PREV_LUMAENH (1 << 0) | ||
492 | +#define ISP_ABS_PREV_INVALAW (1 << 1) | ||
493 | +#define ISP_ABS_PREV_HRZ_MED (1 << 2) | ||
494 | +#define ISP_ABS_PREV_CFA (1 << 3) | ||
495 | +#define ISP_ABS_PREV_CHROMA_SUPP (1 << 4) | ||
496 | +#define ISP_ABS_PREV_WB (1 << 5) | ||
497 | +#define ISP_ABS_PREV_BLKADJ (1 << 6) | ||
498 | +#define ISP_ABS_PREV_RGB2RGB (1 << 7) | ||
499 | +#define ISP_ABS_PREV_COLOR_CONV (1 << 8) | ||
500 | +#define ISP_ABS_PREV_YC_LIMIT (1 << 9) | ||
501 | +#define ISP_ABS_PREV_DEFECT_COR (1 << 10) | ||
502 | +#define ISP_ABS_PREV_GAMMABYPASS (1 << 11) | ||
503 | +#define ISP_ABS_TBL_NF (1 << 12) | ||
504 | +#define ISP_ABS_TBL_REDGAMMA (1 << 13) | ||
505 | +#define ISP_ABS_TBL_GREENGAMMA (1 << 14) | ||
506 | +#define ISP_ABS_TBL_BLUEGAMMA (1 << 15) | ||
507 | + | ||
508 | +#define ISPPRV_NF_TBL_SIZE 64 | ||
509 | +#define ISPPRV_CFA_TBL_SIZE 576 | ||
510 | +#define ISPPRV_GAMMA_TBL_SIZE 1024 | ||
511 | +#define ISPPRV_YENH_TBL_SIZE 128 | ||
512 | + | ||
513 | +/** | ||
514 | + * struct ispprev_hmed - Structure for Horizontal Median Filter. | ||
515 | + * @odddist: Distance between consecutive pixels of same color in the odd line. | ||
516 | + * @evendist: Distance between consecutive pixels of same color in the even | ||
517 | + * line. | ||
518 | + * @thres: Horizontal median filter threshold. | ||
519 | + */ | ||
520 | +struct ispprev_hmed { | ||
521 | + __u8 odddist; | ||
522 | + __u8 evendist; | ||
523 | + __u8 thres; | ||
524 | +}; | ||
525 | + | ||
526 | +/* | ||
527 | + * Enumeration for CFA Formats supported by preview | ||
528 | + */ | ||
529 | +enum cfa_fmt { | ||
530 | + CFAFMT_BAYER, CFAFMT_SONYVGA, CFAFMT_RGBFOVEON, | ||
531 | + CFAFMT_DNSPL, CFAFMT_HONEYCOMB, CFAFMT_RRGGBBFOVEON | ||
532 | +}; | ||
533 | + | ||
534 | +/** | ||
535 | + * struct ispprev_cfa - Structure for CFA Inpterpolation. | ||
536 | + * @cfafmt: CFA Format Enum value supported by preview. | ||
537 | + * @cfa_gradthrs_vert: CFA Gradient Threshold - Vertical. | ||
538 | + * @cfa_gradthrs_horz: CFA Gradient Threshold - Horizontal. | ||
539 | + * @cfa_table: Pointer to the CFA table. | ||
540 | + */ | ||
541 | +struct ispprev_cfa { | ||
542 | + enum cfa_fmt cfafmt; | ||
543 | + __u8 cfa_gradthrs_vert; | ||
544 | + __u8 cfa_gradthrs_horz; | ||
545 | + __u32 *cfa_table; | ||
546 | +}; | ||
547 | + | ||
548 | +/** | ||
549 | + * struct ispprev_csup - Structure for Chrominance Suppression. | ||
550 | + * @gain: Gain. | ||
551 | + * @thres: Threshold. | ||
552 | + * @hypf_en: Flag to enable/disable the High Pass Filter. | ||
553 | + */ | ||
554 | +struct ispprev_csup { | ||
555 | + __u8 gain; | ||
556 | + __u8 thres; | ||
557 | + __u8 hypf_en; | ||
558 | +}; | ||
559 | + | ||
560 | +/** | ||
561 | + * struct ispprev_wbal - Structure for White Balance. | ||
562 | + * @dgain: Digital gain (U10Q8). | ||
563 | + * @coef3: White balance gain - COEF 3 (U8Q5). | ||
564 | + * @coef2: White balance gain - COEF 2 (U8Q5). | ||
565 | + * @coef1: White balance gain - COEF 1 (U8Q5). | ||
566 | + * @coef0: White balance gain - COEF 0 (U8Q5). | ||
567 | + */ | ||
568 | +struct ispprev_wbal { | ||
569 | + __u16 dgain; | ||
570 | + __u8 coef3; | ||
571 | + __u8 coef2; | ||
572 | + __u8 coef1; | ||
573 | + __u8 coef0; | ||
574 | +}; | ||
575 | + | ||
576 | +/** | ||
577 | + * struct ispprev_blkadj - Structure for Black Adjustment. | ||
578 | + * @red: Black level offset adjustment for Red in 2's complement format | ||
579 | + * @green: Black level offset adjustment for Green in 2's complement format | ||
580 | + * @blue: Black level offset adjustment for Blue in 2's complement format | ||
581 | + */ | ||
582 | +struct ispprev_blkadj { | ||
583 | + /*Black level offset adjustment for Red in 2's complement format */ | ||
584 | + __u8 red; | ||
585 | + /*Black level offset adjustment for Green in 2's complement format */ | ||
586 | + __u8 green; | ||
587 | + /* Black level offset adjustment for Blue in 2's complement format */ | ||
588 | + __u8 blue; | ||
589 | +}; | ||
590 | + | ||
591 | +/** | ||
592 | + * struct ispprev_rgbtorgb - Structure for RGB to RGB Blending. | ||
593 | + * @matrix: Blending values(S12Q8 format) | ||
594 | + * [RR] [GR] [BR] | ||
595 | + * [RG] [GG] [BG] | ||
596 | + * [RB] [GB] [BB] | ||
597 | + * @offset: Blending offset value for R,G,B in 2's complement integer format. | ||
598 | + */ | ||
599 | +struct ispprev_rgbtorgb { | ||
600 | + __u16 matrix[3][3]; | ||
601 | + __u16 offset[3]; | ||
602 | +}; | ||
603 | + | ||
604 | +/** | ||
605 | + * struct ispprev_csc - Structure for Color Space Conversion from RGB-YCbYCr | ||
606 | + * @matrix: Color space conversion coefficients(S10Q8) | ||
607 | + * [CSCRY] [CSCGY] [CSCBY] | ||
608 | + * [CSCRCB] [CSCGCB] [CSCBCB] | ||
609 | + * [CSCRCR] [CSCGCR] [CSCBCR] | ||
610 | + * @offset: CSC offset values for Y offset, CB offset and CR offset respectively | ||
611 | + */ | ||
612 | +struct ispprev_csc { | ||
613 | + __u16 matrix[RGB_MAX][RGB_MAX]; | ||
614 | + __s16 offset[RGB_MAX]; | ||
615 | +}; | ||
616 | + | ||
617 | +/** | ||
618 | + * struct ispprev_yclimit - Structure for Y, C Value Limit. | ||
619 | + * @minC: Minimum C value | ||
620 | + * @maxC: Maximum C value | ||
621 | + * @minY: Minimum Y value | ||
622 | + * @maxY: Maximum Y value | ||
623 | + */ | ||
624 | +struct ispprev_yclimit { | ||
625 | + __u8 minC; | ||
626 | + __u8 maxC; | ||
627 | + __u8 minY; | ||
628 | + __u8 maxY; | ||
629 | +}; | ||
630 | + | ||
631 | +/** | ||
632 | + * struct ispprev_dcor - Structure for Defect correction. | ||
633 | + * @couplet_mode_en: Flag to enable or disable the couplet dc Correction in NF | ||
634 | + * @detect_correct: Thresholds for correction bit 0:10 detect 16:25 correct | ||
635 | + */ | ||
636 | +struct ispprev_dcor { | ||
637 | + __u8 couplet_mode_en; | ||
638 | + __u32 detect_correct[4]; | ||
639 | +}; | ||
640 | + | ||
641 | +/** | ||
642 | + * struct ispprev_nf - Structure for Noise Filter | ||
643 | + * @spread: Spread value to be used in Noise Filter | ||
644 | + * @table: Pointer to the Noise Filter table | ||
645 | + */ | ||
646 | +struct ispprev_nf { | ||
647 | + __u8 spread; | ||
648 | + __u32 table[ISPPRV_NF_TBL_SIZE]; | ||
649 | +}; | ||
650 | + | ||
651 | +/** | ||
652 | + * struct ispprv_update_config - Structure for Preview Configuration (user). | ||
653 | + * @update: Specifies which ISP Preview registers should be updated. | ||
654 | + * @flag: Specifies which ISP Preview functions should be enabled. | ||
655 | + * @yen: Pointer to luma enhancement table. | ||
656 | + * @shading_shift: 3bit value of shift used in shading compensation. | ||
657 | + * @prev_hmed: Pointer to structure containing the odd and even distance. | ||
658 | + * between the pixels in the image along with the filter threshold. | ||
659 | + * @prev_cfa: Pointer to structure containing the CFA interpolation table, CFA. | ||
660 | + * format in the image, vertical and horizontal gradient threshold. | ||
661 | + * @csup: Pointer to Structure for Chrominance Suppression coefficients. | ||
662 | + * @prev_wbal: Pointer to structure for White Balance. | ||
663 | + * @prev_blkadj: Pointer to structure for Black Adjustment. | ||
664 | + * @rgb2rgb: Pointer to structure for RGB to RGB Blending. | ||
665 | + * @prev_csc: Pointer to structure for Color Space Conversion from RGB-YCbYCr. | ||
666 | + * @yclimit: Pointer to structure for Y, C Value Limit. | ||
667 | + * @prev_dcor: Pointer to structure for defect correction. | ||
668 | + * @prev_nf: Pointer to structure for Noise Filter | ||
669 | + * @red_gamma: Pointer to red gamma correction table. | ||
670 | + * @green_gamma: Pointer to green gamma correction table. | ||
671 | + * @blue_gamma: Pointer to blue gamma correction table. | ||
672 | + */ | ||
673 | +struct ispprv_update_config { | ||
674 | + __u16 update; | ||
675 | + __u16 flag; | ||
676 | + void *yen; | ||
677 | + __u32 shading_shift; | ||
678 | + struct ispprev_hmed *prev_hmed; | ||
679 | + struct ispprev_cfa *prev_cfa; | ||
680 | + struct ispprev_csup *csup; | ||
681 | + struct ispprev_wbal *prev_wbal; | ||
682 | + struct ispprev_blkadj *prev_blkadj; | ||
683 | + struct ispprev_rgbtorgb *rgb2rgb; | ||
684 | + struct ispprev_csc *prev_csc; | ||
685 | + struct ispprev_yclimit *yclimit; | ||
686 | + struct ispprev_dcor *prev_dcor; | ||
687 | + struct ispprev_nf *prev_nf; | ||
688 | + __u32 *red_gamma; | ||
689 | + __u32 *green_gamma; | ||
690 | + __u32 *blue_gamma; | ||
691 | +}; | ||
692 | + | ||
693 | +#endif /* OMAP_ISP_USER_H */ | ||
694 | -- | ||
695 | 1.5.6.5 | ||
696 | |||
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0004-omap3isp-Add-ISP-frontend-CCDC.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0004-omap3isp-Add-ISP-frontend-CCDC.patch new file mode 100644 index 0000000000..4a161729fd --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0004-omap3isp-Add-ISP-frontend-CCDC.patch | |||
@@ -0,0 +1,1875 @@ | |||
1 | From 9ea796fe5383a6961125a6a18185a901fe8627d7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
3 | Date: Tue, 10 Mar 2009 10:49:02 +0200 | ||
4 | Subject: [PATCH] omap3isp: Add ISP frontend (CCDC) | ||
5 | |||
6 | Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
7 | --- | ||
8 | drivers/media/video/isp/ispccdc.c | 1638 +++++++++++++++++++++++++++++++++++++ | ||
9 | drivers/media/video/isp/ispccdc.h | 209 +++++ | ||
10 | 2 files changed, 1847 insertions(+), 0 deletions(-) | ||
11 | create mode 100644 drivers/media/video/isp/ispccdc.c | ||
12 | create mode 100644 drivers/media/video/isp/ispccdc.h | ||
13 | |||
14 | diff --git a/drivers/media/video/isp/ispccdc.c b/drivers/media/video/isp/ispccdc.c | ||
15 | new file mode 100644 | ||
16 | index 0000000..2574ea2 | ||
17 | --- /dev/null | ||
18 | +++ b/drivers/media/video/isp/ispccdc.c | ||
19 | @@ -0,0 +1,1638 @@ | ||
20 | +/* | ||
21 | + * ispccdc.c | ||
22 | + * | ||
23 | + * Driver Library for CCDC module in TI's OMAP3 Camera ISP | ||
24 | + * | ||
25 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
26 | + * | ||
27 | + * Contributors: | ||
28 | + * Senthilvadivu Guruswamy <svadivu@ti.com> | ||
29 | + * Pallavi Kulkarni <p-kulkarni@ti.com> | ||
30 | + * Sergio Aguirre <saaguirre@ti.com> | ||
31 | + * | ||
32 | + * This package is free software; you can redistribute it and/or modify | ||
33 | + * it under the terms of the GNU General Public License version 2 as | ||
34 | + * published by the Free Software Foundation. | ||
35 | + * | ||
36 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
37 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
38 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
39 | + */ | ||
40 | + | ||
41 | +#include <linux/mutex.h> | ||
42 | +#include <linux/module.h> | ||
43 | +#include <linux/uaccess.h> | ||
44 | + | ||
45 | +#include "isp.h" | ||
46 | +#include "ispreg.h" | ||
47 | +#include "ispccdc.h" | ||
48 | +#include "ispmmu.h" | ||
49 | + | ||
50 | +#define LSC_TABLE_INIT_SIZE 50052 | ||
51 | + | ||
52 | +static u32 *fpc_table_add; | ||
53 | +static unsigned long fpc_table_add_m; | ||
54 | + | ||
55 | +/** | ||
56 | + * struct isp_ccdc - Structure for the CCDC module to store its own information | ||
57 | + * @ccdc_inuse: Flag to determine if CCDC has been reserved or not (0 or 1). | ||
58 | + * @ccdcout_w: CCDC output width. | ||
59 | + * @ccdcout_h: CCDC output height. | ||
60 | + * @ccdcin_w: CCDC input width. | ||
61 | + * @ccdcin_h: CCDC input height. | ||
62 | + * @ccdcin_woffset: CCDC input horizontal offset. | ||
63 | + * @ccdcin_hoffset: CCDC input vertical offset. | ||
64 | + * @crop_w: Crop width. | ||
65 | + * @crop_h: Crop weight. | ||
66 | + * @ccdc_inpfmt: CCDC input format. | ||
67 | + * @ccdc_outfmt: CCDC output format. | ||
68 | + * @vpout_en: Video port output enable. | ||
69 | + * @wen: Data write enable. | ||
70 | + * @exwen: External data write enable. | ||
71 | + * @refmt_en: Reformatter enable. | ||
72 | + * @ccdcslave: CCDC slave mode enable. | ||
73 | + * @syncif_ipmod: Image | ||
74 | + * @obclamp_en: Data input format. | ||
75 | + * @mutexlock: Mutex used to get access to the CCDC. | ||
76 | + */ | ||
77 | +static struct isp_ccdc { | ||
78 | + u8 ccdc_inuse; | ||
79 | + u32 ccdcout_w; | ||
80 | + u32 ccdcout_h; | ||
81 | + u32 ccdcin_w; | ||
82 | + u32 ccdcin_h; | ||
83 | + u32 ccdcin_woffset; | ||
84 | + u32 ccdcin_hoffset; | ||
85 | + u32 crop_w; | ||
86 | + u32 crop_h; | ||
87 | + u8 ccdc_inpfmt; | ||
88 | + u8 ccdc_outfmt; | ||
89 | + u8 vpout_en; | ||
90 | + u8 wen; | ||
91 | + u8 exwen; | ||
92 | + u8 refmt_en; | ||
93 | + u8 ccdcslave; | ||
94 | + u8 syncif_ipmod; | ||
95 | + u8 obclamp_en; | ||
96 | + u8 pm_state; | ||
97 | + u8 lsc_enable; | ||
98 | + int lsc_state; | ||
99 | + struct mutex mutexlock; /* For checking/modifying ccdc_inuse */ | ||
100 | + u32 wenlog; | ||
101 | +} ispccdc_obj; | ||
102 | + | ||
103 | +static struct ispccdc_lsc_config lsc_config; | ||
104 | +static u8 *lsc_gain_table; | ||
105 | +static unsigned long lsc_ispmmu_addr; | ||
106 | +static int lsc_initialized; | ||
107 | +static u8 *lsc_gain_table_tmp; | ||
108 | + | ||
109 | +/* Structure for saving/restoring CCDC module registers*/ | ||
110 | +static struct isp_reg ispccdc_reg_list[] = { | ||
111 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE, 0}, | ||
112 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HD_VD_WID, 0}, | ||
113 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PIX_LINES, 0}, | ||
114 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO, 0}, | ||
115 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START, 0}, | ||
116 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES, 0}, | ||
117 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CULLING, 0}, | ||
118 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF, 0}, | ||
119 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, 0}, | ||
120 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR, 0}, | ||
121 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP, 0}, | ||
122 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_DCSUB, 0}, | ||
123 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_COLPTN, 0}, | ||
124 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_BLKCMP, 0}, | ||
125 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC, 0}, | ||
126 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC_ADDR, 0}, | ||
127 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT, 0}, | ||
128 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_ALAW, 0}, | ||
129 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_REC656IF, 0}, | ||
130 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, 0}, | ||
131 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG, 0}, | ||
132 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_HORZ, 0}, | ||
133 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_VERT, 0}, | ||
134 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_ADDR0, 0}, | ||
135 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_ADDR1, 0}, | ||
136 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_ADDR2, 0}, | ||
137 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_ADDR3, 0}, | ||
138 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_ADDR4, 0}, | ||
139 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_ADDR5, 0}, | ||
140 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_ADDR6, 0}, | ||
141 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_ADDR7, 0}, | ||
142 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PRGEVEN0, 0}, | ||
143 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PRGEVEN1, 0}, | ||
144 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PRGODD0, 0}, | ||
145 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PRGODD1, 0}, | ||
146 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT, 0}, | ||
147 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG, 0}, | ||
148 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_INITIAL, 0}, | ||
149 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_TABLE_BASE, 0}, | ||
150 | + {OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_TABLE_OFFSET, 0}, | ||
151 | + {0, ISP_TOK_TERM, 0} | ||
152 | +}; | ||
153 | + | ||
154 | +/** | ||
155 | + * omap34xx_isp_ccdc_config - Sets CCDC configuration from userspace | ||
156 | + * @userspace_add: Structure containing CCDC configuration sent from userspace. | ||
157 | + * | ||
158 | + * Returns 0 if successful, -EINVAL if the pointer to the configuration | ||
159 | + * structure is null, or the copy_from_user function fails to copy user space | ||
160 | + * memory to kernel space memory. | ||
161 | + **/ | ||
162 | +int omap34xx_isp_ccdc_config(void *userspace_add) | ||
163 | +{ | ||
164 | + struct ispccdc_bclamp bclamp_t; | ||
165 | + struct ispccdc_blcomp blcomp_t; | ||
166 | + struct ispccdc_fpc fpc_t; | ||
167 | + struct ispccdc_culling cull_t; | ||
168 | + struct ispccdc_update_config *ccdc_struct; | ||
169 | + | ||
170 | + if (userspace_add == NULL) | ||
171 | + return -EINVAL; | ||
172 | + | ||
173 | + ccdc_struct = userspace_add; | ||
174 | + | ||
175 | + if (ISP_ABS_CCDC_ALAW & ccdc_struct->flag) { | ||
176 | + if (ISP_ABS_CCDC_ALAW & ccdc_struct->update) | ||
177 | + ispccdc_config_alaw(ccdc_struct->alawip); | ||
178 | + ispccdc_enable_alaw(1); | ||
179 | + } else if (ISP_ABS_CCDC_ALAW & ccdc_struct->update) | ||
180 | + ispccdc_enable_alaw(0); | ||
181 | + | ||
182 | + if (ISP_ABS_CCDC_LPF & ccdc_struct->flag) | ||
183 | + ispccdc_enable_lpf(1); | ||
184 | + else | ||
185 | + ispccdc_enable_lpf(0); | ||
186 | + | ||
187 | + if (ISP_ABS_CCDC_BLCLAMP & ccdc_struct->flag) { | ||
188 | + if (ISP_ABS_CCDC_BLCLAMP & ccdc_struct->update) { | ||
189 | + if (copy_from_user(&bclamp_t, (struct ispccdc_bclamp *) | ||
190 | + ccdc_struct->bclamp, | ||
191 | + sizeof(struct ispccdc_bclamp))) | ||
192 | + goto copy_from_user_err; | ||
193 | + | ||
194 | + ispccdc_enable_black_clamp(1); | ||
195 | + ispccdc_config_black_clamp(bclamp_t); | ||
196 | + } else | ||
197 | + ispccdc_enable_black_clamp(1); | ||
198 | + } else { | ||
199 | + if (ISP_ABS_CCDC_BLCLAMP & ccdc_struct->update) { | ||
200 | + if (copy_from_user(&bclamp_t, (struct ispccdc_bclamp *) | ||
201 | + ccdc_struct->bclamp, | ||
202 | + sizeof(struct ispccdc_bclamp))) | ||
203 | + goto copy_from_user_err; | ||
204 | + | ||
205 | + ispccdc_enable_black_clamp(0); | ||
206 | + ispccdc_config_black_clamp(bclamp_t); | ||
207 | + } | ||
208 | + } | ||
209 | + | ||
210 | + if (ISP_ABS_CCDC_BCOMP & ccdc_struct->update) { | ||
211 | + if (copy_from_user(&blcomp_t, (struct ispccdc_blcomp *) | ||
212 | + ccdc_struct->blcomp, | ||
213 | + sizeof(blcomp_t))) | ||
214 | + goto copy_from_user_err; | ||
215 | + | ||
216 | + ispccdc_config_black_comp(blcomp_t); | ||
217 | + } | ||
218 | + | ||
219 | + if (ISP_ABS_CCDC_FPC & ccdc_struct->flag) { | ||
220 | + if (ISP_ABS_CCDC_FPC & ccdc_struct->update) { | ||
221 | + if (copy_from_user(&fpc_t, (struct ispccdc_fpc *) | ||
222 | + ccdc_struct->fpc, | ||
223 | + sizeof(fpc_t))) | ||
224 | + goto copy_from_user_err; | ||
225 | + fpc_table_add = kmalloc(64 + fpc_t.fpnum * 4, | ||
226 | + GFP_KERNEL | GFP_DMA); | ||
227 | + if (!fpc_table_add) { | ||
228 | + printk(KERN_ERR "Cannot allocate memory for" | ||
229 | + " FPC table"); | ||
230 | + return -ENOMEM; | ||
231 | + } | ||
232 | + while (((unsigned long)fpc_table_add & 0xFFFFFFC0) | ||
233 | + != (unsigned long)fpc_table_add) | ||
234 | + fpc_table_add++; | ||
235 | + | ||
236 | + fpc_table_add_m = ispmmu_kmap(virt_to_phys | ||
237 | + (fpc_table_add), | ||
238 | + fpc_t.fpnum * 4); | ||
239 | + | ||
240 | + if (copy_from_user(fpc_table_add, (u32 *)fpc_t.fpcaddr, | ||
241 | + fpc_t.fpnum * 4)) | ||
242 | + goto copy_from_user_err; | ||
243 | + | ||
244 | + fpc_t.fpcaddr = fpc_table_add_m; | ||
245 | + ispccdc_config_fpc(fpc_t); | ||
246 | + } | ||
247 | + ispccdc_enable_fpc(1); | ||
248 | + } else if (ISP_ABS_CCDC_FPC & ccdc_struct->update) | ||
249 | + ispccdc_enable_fpc(0); | ||
250 | + | ||
251 | + if (ISP_ABS_CCDC_CULL & ccdc_struct->update) { | ||
252 | + if (copy_from_user(&cull_t, (struct ispccdc_culling *) | ||
253 | + ccdc_struct->cull, | ||
254 | + sizeof(cull_t))) | ||
255 | + goto copy_from_user_err; | ||
256 | + ispccdc_config_culling(cull_t); | ||
257 | + } | ||
258 | + | ||
259 | + if (is_isplsc_activated()) { | ||
260 | + if (ISP_ABS_CCDC_CONFIG_LSC & ccdc_struct->flag) { | ||
261 | + if (ISP_ABS_CCDC_CONFIG_LSC & ccdc_struct->update) { | ||
262 | + if (copy_from_user( | ||
263 | + &lsc_config, | ||
264 | + (struct ispccdc_lsc_config *) | ||
265 | + ccdc_struct->lsc_cfg, | ||
266 | + sizeof(struct ispccdc_lsc_config))) | ||
267 | + goto copy_from_user_err; | ||
268 | + ispccdc_config_lsc(&lsc_config); | ||
269 | + } | ||
270 | + ispccdc_enable_lsc(1); | ||
271 | + } else if (ISP_ABS_CCDC_CONFIG_LSC & ccdc_struct->update) { | ||
272 | + ispccdc_enable_lsc(0); | ||
273 | + } | ||
274 | + if (ISP_ABS_TBL_LSC & ccdc_struct->update) { | ||
275 | + if (copy_from_user(lsc_gain_table, | ||
276 | + ccdc_struct->lsc, lsc_config.size)) | ||
277 | + goto copy_from_user_err; | ||
278 | + ispccdc_load_lsc(lsc_gain_table, lsc_config.size); | ||
279 | + } | ||
280 | + } | ||
281 | + | ||
282 | + if (ISP_ABS_CCDC_COLPTN & ccdc_struct->update) | ||
283 | + ispccdc_config_imgattr(ccdc_struct->colptn); | ||
284 | + | ||
285 | + return 0; | ||
286 | + | ||
287 | +copy_from_user_err: | ||
288 | + printk(KERN_ERR "CCDC Config:Copy From User Error"); | ||
289 | + return -EINVAL ; | ||
290 | +} | ||
291 | +EXPORT_SYMBOL(omap34xx_isp_ccdc_config); | ||
292 | + | ||
293 | +/** | ||
294 | + * Set the value to be used for CCDC_CFG.WENLOG. | ||
295 | + * w - Value of wenlog. | ||
296 | + */ | ||
297 | +void ispccdc_set_wenlog(u32 wenlog) | ||
298 | +{ | ||
299 | + ispccdc_obj.wenlog = wenlog; | ||
300 | +} | ||
301 | +EXPORT_SYMBOL(ispccdc_set_wenlog); | ||
302 | + | ||
303 | +/** | ||
304 | + * ispccdc_request - Reserves the CCDC module. | ||
305 | + * | ||
306 | + * Reserves the CCDC module and assures that is used only once at a time. | ||
307 | + * | ||
308 | + * Returns 0 if successful, or -EBUSY if CCDC module is busy. | ||
309 | + **/ | ||
310 | +int ispccdc_request(void) | ||
311 | +{ | ||
312 | + mutex_lock(&ispccdc_obj.mutexlock); | ||
313 | + if (ispccdc_obj.ccdc_inuse) { | ||
314 | + mutex_unlock(&ispccdc_obj.mutexlock); | ||
315 | + DPRINTK_ISPCCDC("ISP_ERR : CCDC Module Busy\n"); | ||
316 | + return -EBUSY; | ||
317 | + } | ||
318 | + | ||
319 | + ispccdc_obj.ccdc_inuse = 1; | ||
320 | + mutex_unlock(&ispccdc_obj.mutexlock); | ||
321 | + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, ISPCTRL_CCDC_RAM_EN | | ||
322 | + ISPCTRL_CCDC_CLK_EN | | ||
323 | + ISPCTRL_SBL_WR1_RAM_EN); | ||
324 | + isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_VDLC); | ||
325 | + return 0; | ||
326 | +} | ||
327 | +EXPORT_SYMBOL(ispccdc_request); | ||
328 | + | ||
329 | +/** | ||
330 | + * ispccdc_free - Frees the CCDC module. | ||
331 | + * | ||
332 | + * Frees the CCDC module so it can be used by another process. | ||
333 | + * | ||
334 | + * Returns 0 if successful, or -EINVAL if module has been already freed. | ||
335 | + **/ | ||
336 | +int ispccdc_free(void) | ||
337 | +{ | ||
338 | + mutex_lock(&ispccdc_obj.mutexlock); | ||
339 | + if (!ispccdc_obj.ccdc_inuse) { | ||
340 | + mutex_unlock(&ispccdc_obj.mutexlock); | ||
341 | + DPRINTK_ISPCCDC("ISP_ERR: CCDC Module already freed\n"); | ||
342 | + return -EINVAL; | ||
343 | + } | ||
344 | + | ||
345 | + ispccdc_obj.ccdc_inuse = 0; | ||
346 | + mutex_unlock(&ispccdc_obj.mutexlock); | ||
347 | + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, | ||
348 | + ~(ISPCTRL_CCDC_CLK_EN | | ||
349 | + ISPCTRL_CCDC_RAM_EN | | ||
350 | + ISPCTRL_SBL_WR1_RAM_EN)); | ||
351 | + return 0; | ||
352 | +} | ||
353 | +EXPORT_SYMBOL(ispccdc_free); | ||
354 | + | ||
355 | +/** | ||
356 | + * ispccdc_free_lsc - Frees Lens Shading Compensation table | ||
357 | + * | ||
358 | + * Always returns 0. | ||
359 | + **/ | ||
360 | +static int ispccdc_free_lsc(void) | ||
361 | +{ | ||
362 | + if (!lsc_ispmmu_addr) | ||
363 | + return 0; | ||
364 | + | ||
365 | + ispccdc_enable_lsc(0); | ||
366 | + lsc_initialized = 0; | ||
367 | + isp_reg_writel(0, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_TABLE_BASE); | ||
368 | + ispmmu_kunmap(lsc_ispmmu_addr); | ||
369 | + kfree(lsc_gain_table); | ||
370 | + return 0; | ||
371 | +} | ||
372 | + | ||
373 | +/** | ||
374 | + * ispccdc_allocate_lsc - Allocate space for Lens Shading Compensation table | ||
375 | + * @table_size: LSC gain table size. | ||
376 | + * | ||
377 | + * Returns 0 if successful, -ENOMEM of its no memory available, or -EINVAL if | ||
378 | + * table_size is zero. | ||
379 | + **/ | ||
380 | +static int ispccdc_allocate_lsc(u32 table_size) | ||
381 | +{ | ||
382 | + if (table_size == 0) | ||
383 | + return -EINVAL; | ||
384 | + | ||
385 | + if ((lsc_config.size >= table_size) && lsc_gain_table) | ||
386 | + return 0; | ||
387 | + | ||
388 | + ispccdc_free_lsc(); | ||
389 | + | ||
390 | + lsc_gain_table = kmalloc(table_size, GFP_KERNEL | GFP_DMA); | ||
391 | + | ||
392 | + if (!lsc_gain_table) { | ||
393 | + printk(KERN_ERR "Cannot allocate memory for gain tables \n"); | ||
394 | + return -ENOMEM; | ||
395 | + } | ||
396 | + | ||
397 | + lsc_ispmmu_addr = ispmmu_kmap(virt_to_phys(lsc_gain_table), table_size); | ||
398 | + if (lsc_ispmmu_addr <= 0) { | ||
399 | + printk(KERN_ERR "Cannot map memory for gain tables \n"); | ||
400 | + kfree(lsc_gain_table); | ||
401 | + return -ENOMEM; | ||
402 | + } | ||
403 | + | ||
404 | + return 0; | ||
405 | +} | ||
406 | + | ||
407 | +/** | ||
408 | + * ispccdc_program_lsc - Program Lens Shading Compensation table. | ||
409 | + * @table_size: LSC gain table size. | ||
410 | + * | ||
411 | + * Returns 0 if successful, or -EINVAL if there's no mapped address for the | ||
412 | + * table yet. | ||
413 | + **/ | ||
414 | +static int ispccdc_program_lsc(void) | ||
415 | +{ | ||
416 | + if (!lsc_ispmmu_addr) | ||
417 | + return -EINVAL; | ||
418 | + | ||
419 | + if (lsc_initialized) | ||
420 | + return 0; | ||
421 | + | ||
422 | + isp_reg_writel(lsc_ispmmu_addr, OMAP3_ISP_IOMEM_CCDC, | ||
423 | + ISPCCDC_LSC_TABLE_BASE); | ||
424 | + lsc_initialized = 1; | ||
425 | + return 0; | ||
426 | +} | ||
427 | + | ||
428 | +/** | ||
429 | + * ispccdc_load_lsc - Load Lens Shading Compensation table. | ||
430 | + * @table_addr: LSC gain table MMU Mapped address. | ||
431 | + * @table_size: LSC gain table size. | ||
432 | + * | ||
433 | + * Returns 0 if successful, -ENOMEM of its no memory available, or -EINVAL if | ||
434 | + * table_size is zero. | ||
435 | + **/ | ||
436 | +int ispccdc_load_lsc(u8 *table_addr, u32 table_size) | ||
437 | +{ | ||
438 | + int ret; | ||
439 | + | ||
440 | + if (!is_isplsc_activated()) | ||
441 | + return 0; | ||
442 | + | ||
443 | + if (!table_addr) | ||
444 | + return -EINVAL; | ||
445 | + | ||
446 | + ret = ispccdc_allocate_lsc(table_size); | ||
447 | + if (ret) | ||
448 | + return ret; | ||
449 | + | ||
450 | + if (table_addr != lsc_gain_table) | ||
451 | + memcpy(lsc_gain_table, table_addr, table_size); | ||
452 | + ret = ispccdc_program_lsc(); | ||
453 | + if (ret) | ||
454 | + return ret; | ||
455 | + return 0; | ||
456 | +} | ||
457 | +EXPORT_SYMBOL(ispccdc_load_lsc); | ||
458 | + | ||
459 | +/** | ||
460 | + * ispccdc_config_lsc - Configures the lens shading compensation module | ||
461 | + * @lsc_cfg: LSC configuration structure | ||
462 | + **/ | ||
463 | +void ispccdc_config_lsc(struct ispccdc_lsc_config *lsc_cfg) | ||
464 | +{ | ||
465 | + int reg; | ||
466 | + | ||
467 | + if (!is_isplsc_activated()) | ||
468 | + return; | ||
469 | + | ||
470 | + ispccdc_enable_lsc(0); | ||
471 | + isp_reg_writel(lsc_cfg->offset, OMAP3_ISP_IOMEM_CCDC, | ||
472 | + ISPCCDC_LSC_TABLE_OFFSET); | ||
473 | + | ||
474 | + reg = 0; | ||
475 | + reg |= lsc_cfg->gain_mode_n << ISPCCDC_LSC_GAIN_MODE_N_SHIFT; | ||
476 | + reg |= lsc_cfg->gain_mode_m << ISPCCDC_LSC_GAIN_MODE_M_SHIFT; | ||
477 | + reg |= lsc_cfg->gain_format << ISPCCDC_LSC_GAIN_FORMAT_SHIFT; | ||
478 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG); | ||
479 | + | ||
480 | + reg = 0; | ||
481 | + reg &= ~ISPCCDC_LSC_INITIAL_X_MASK; | ||
482 | + reg |= lsc_cfg->initial_x << ISPCCDC_LSC_INITIAL_X_SHIFT; | ||
483 | + reg &= ~ISPCCDC_LSC_INITIAL_Y_MASK; | ||
484 | + reg |= lsc_cfg->initial_y << ISPCCDC_LSC_INITIAL_Y_SHIFT; | ||
485 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_INITIAL); | ||
486 | +} | ||
487 | +EXPORT_SYMBOL(ispccdc_config_lsc); | ||
488 | + | ||
489 | +int __ispccdc_enable_lsc(u8 enable) | ||
490 | +{ | ||
491 | + if (!is_isplsc_activated()) | ||
492 | + return -ENODEV; | ||
493 | + | ||
494 | + if (enable) { | ||
495 | + if (!ispccdc_busy()) { | ||
496 | + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, | ||
497 | + ISPCTRL_SBL_SHARED_RPORTB | ||
498 | + | ISPCTRL_SBL_RD_RAM_EN); | ||
499 | + | ||
500 | + isp_reg_or(OMAP3_ISP_IOMEM_CCDC, | ||
501 | + ISPCCDC_LSC_CONFIG, 0x1); | ||
502 | + | ||
503 | + ispccdc_obj.lsc_state = 1; | ||
504 | + } else { | ||
505 | + /* Postpone enabling LSC */ | ||
506 | + ispccdc_obj.lsc_enable = 1; | ||
507 | + return -EBUSY; | ||
508 | + } | ||
509 | + } else { | ||
510 | + isp_reg_and(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG, 0xFFFE); | ||
511 | + ispccdc_obj.lsc_state = ispccdc_obj.lsc_enable = 0; | ||
512 | + } | ||
513 | + | ||
514 | + return 0; | ||
515 | +} | ||
516 | + | ||
517 | +/** | ||
518 | + * ispccdc_enable_lsc - Enables/Disables the Lens Shading Compensation module. | ||
519 | + * @enable: 0 Disables LSC, 1 Enables LSC. | ||
520 | + **/ | ||
521 | +void ispccdc_enable_lsc(u8 enable) | ||
522 | +{ | ||
523 | + if (__ispccdc_enable_lsc(enable)) { | ||
524 | + if (enable) | ||
525 | + ispccdc_obj.lsc_state = 1; | ||
526 | + else | ||
527 | + ispccdc_obj.lsc_state = ispccdc_obj.lsc_enable = 0; | ||
528 | + } | ||
529 | +} | ||
530 | +EXPORT_SYMBOL(ispccdc_enable_lsc); | ||
531 | + | ||
532 | +void ispccdc_lsc_error_handler(void) | ||
533 | +{ | ||
534 | + int lsc_enable = ispccdc_obj.lsc_state; | ||
535 | + | ||
536 | + ispccdc_enable_lsc(0); | ||
537 | + | ||
538 | + ispccdc_obj.lsc_enable = lsc_enable; | ||
539 | +} | ||
540 | + | ||
541 | +/** | ||
542 | + * ispccdc_config_crop - Configures crop parameters for the ISP CCDC. | ||
543 | + * @left: Left offset of the crop area. | ||
544 | + * @top: Top offset of the crop area. | ||
545 | + * @height: Height of the crop area. | ||
546 | + * @width: Width of the crop area. | ||
547 | + * | ||
548 | + * The following restrictions are applied for the crop settings. If incoming | ||
549 | + * values do not follow these restrictions then we map the settings to the | ||
550 | + * closest acceptable crop value. | ||
551 | + * 1) Left offset is always odd. This can be avoided if we enable byte swap | ||
552 | + * option for incoming data into CCDC. | ||
553 | + * 2) Top offset is always even. | ||
554 | + * 3) Crop height is always even. | ||
555 | + * 4) Crop width is always a multiple of 16 pixels | ||
556 | + **/ | ||
557 | +void ispccdc_config_crop(u32 left, u32 top, u32 height, u32 width) | ||
558 | +{ | ||
559 | + ispccdc_obj.ccdcin_woffset = left + (left % 2); | ||
560 | + ispccdc_obj.ccdcin_hoffset = top + (top % 2); | ||
561 | + | ||
562 | + ispccdc_obj.crop_w = width - (width % 16); | ||
563 | + ispccdc_obj.crop_h = height + (height % 2); | ||
564 | + | ||
565 | + DPRINTK_ISPCCDC("\n\tOffsets L %d T %d W %d H %d\n", | ||
566 | + ispccdc_obj.ccdcin_woffset, | ||
567 | + ispccdc_obj.ccdcin_hoffset, | ||
568 | + ispccdc_obj.crop_w, | ||
569 | + ispccdc_obj.crop_h); | ||
570 | +} | ||
571 | + | ||
572 | +/** | ||
573 | + * ispccdc_config_datapath - Specifies the input and output modules for CCDC. | ||
574 | + * @input: Indicates the module that inputs the image to the CCDC. | ||
575 | + * @output: Indicates the module to which the CCDC outputs the image. | ||
576 | + * | ||
577 | + * Configures the default configuration for the CCDC to work with. | ||
578 | + * | ||
579 | + * The valid values for the input are CCDC_RAW (0), CCDC_YUV_SYNC (1), | ||
580 | + * CCDC_YUV_BT (2), and CCDC_OTHERS (3). | ||
581 | + * | ||
582 | + * The valid values for the output are CCDC_YUV_RSZ (0), CCDC_YUV_MEM_RSZ (1), | ||
583 | + * CCDC_OTHERS_VP (2), CCDC_OTHERS_MEM (3), CCDC_OTHERS_VP_MEM (4). | ||
584 | + * | ||
585 | + * Returns 0 if successful, or -EINVAL if wrong I/O combination or wrong input | ||
586 | + * or output values. | ||
587 | + **/ | ||
588 | +int ispccdc_config_datapath(enum ccdc_input input, enum ccdc_output output) | ||
589 | +{ | ||
590 | + u32 syn_mode = 0; | ||
591 | + struct ispccdc_vp vpcfg; | ||
592 | + struct ispccdc_syncif syncif; | ||
593 | + struct ispccdc_bclamp blkcfg; | ||
594 | + | ||
595 | + u32 colptn = ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC0_SHIFT | | ||
596 | + ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC1_SHIFT | | ||
597 | + ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC2_SHIFT | | ||
598 | + ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC3_SHIFT | | ||
599 | + ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC0_SHIFT | | ||
600 | + ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC1_SHIFT | | ||
601 | + ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC2_SHIFT | | ||
602 | + ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC3_SHIFT | | ||
603 | + ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC0_SHIFT | | ||
604 | + ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC1_SHIFT | | ||
605 | + ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC2_SHIFT | | ||
606 | + ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC3_SHIFT | | ||
607 | + ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC0_SHIFT | | ||
608 | + ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC1_SHIFT | | ||
609 | + ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC2_SHIFT | | ||
610 | + ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC3_SHIFT; | ||
611 | + | ||
612 | + /* CCDC does not convert the image format */ | ||
613 | + if ((input == CCDC_RAW || input == CCDC_OTHERS) && | ||
614 | + output == CCDC_YUV_RSZ) { | ||
615 | + DPRINTK_ISPCCDC("ISP_ERR: Wrong CCDC I/O Combination\n"); | ||
616 | + return -EINVAL; | ||
617 | + } | ||
618 | + | ||
619 | + syn_mode = isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); | ||
620 | + | ||
621 | + switch (output) { | ||
622 | + case CCDC_YUV_RSZ: | ||
623 | + syn_mode |= ISPCCDC_SYN_MODE_SDR2RSZ; | ||
624 | + syn_mode &= ~ISPCCDC_SYN_MODE_WEN; | ||
625 | + break; | ||
626 | + | ||
627 | + case CCDC_YUV_MEM_RSZ: | ||
628 | + syn_mode |= ISPCCDC_SYN_MODE_SDR2RSZ; | ||
629 | + ispccdc_obj.wen = 1; | ||
630 | + syn_mode |= ISPCCDC_SYN_MODE_WEN; | ||
631 | + break; | ||
632 | + | ||
633 | + case CCDC_OTHERS_VP: | ||
634 | + syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR; | ||
635 | + syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ; | ||
636 | + syn_mode &= ~ISPCCDC_SYN_MODE_WEN; | ||
637 | + vpcfg.bitshift_sel = BIT9_0; | ||
638 | + vpcfg.freq_sel = PIXCLKBY2; | ||
639 | + ispccdc_config_vp(vpcfg); | ||
640 | + ispccdc_enable_vp(1); | ||
641 | + break; | ||
642 | + | ||
643 | + case CCDC_OTHERS_MEM: | ||
644 | + syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR; | ||
645 | + syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ; | ||
646 | + syn_mode |= ISPCCDC_SYN_MODE_WEN; | ||
647 | + syn_mode &= ~ISPCCDC_SYN_MODE_EXWEN; | ||
648 | + isp_reg_and(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, | ||
649 | + ~ISPCCDC_CFG_WENLOG); | ||
650 | + vpcfg.bitshift_sel = BIT11_2; | ||
651 | + vpcfg.freq_sel = PIXCLKBY2; | ||
652 | + ispccdc_config_vp(vpcfg); | ||
653 | + ispccdc_enable_vp(0); | ||
654 | + break; | ||
655 | + | ||
656 | + case CCDC_OTHERS_VP_MEM: | ||
657 | + syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR; | ||
658 | + syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ; | ||
659 | + syn_mode |= ISPCCDC_SYN_MODE_WEN; | ||
660 | + syn_mode &= ~ISPCCDC_SYN_MODE_EXWEN; | ||
661 | + | ||
662 | + isp_reg_and_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, | ||
663 | + ~ISPCCDC_CFG_WENLOG, | ||
664 | + ispccdc_obj.wenlog); | ||
665 | + vpcfg.bitshift_sel = BIT9_0; | ||
666 | + vpcfg.freq_sel = PIXCLKBY2; | ||
667 | + ispccdc_config_vp(vpcfg); | ||
668 | + ispccdc_enable_vp(1); | ||
669 | + break; | ||
670 | + default: | ||
671 | + DPRINTK_ISPCCDC("ISP_ERR: Wrong CCDC Output\n"); | ||
672 | + return -EINVAL; | ||
673 | + }; | ||
674 | + | ||
675 | + isp_reg_writel(syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); | ||
676 | + | ||
677 | + switch (input) { | ||
678 | + case CCDC_RAW: | ||
679 | + syncif.ccdc_mastermode = 0; | ||
680 | + syncif.datapol = 0; | ||
681 | + syncif.datsz = DAT10; | ||
682 | + syncif.fldmode = 0; | ||
683 | + syncif.fldout = 0; | ||
684 | + syncif.fldpol = 0; | ||
685 | + syncif.fldstat = 0; | ||
686 | + syncif.hdpol = 0; | ||
687 | + syncif.ipmod = RAW; | ||
688 | + syncif.vdpol = 0; | ||
689 | + ispccdc_config_sync_if(syncif); | ||
690 | + ispccdc_config_imgattr(colptn); | ||
691 | + blkcfg.dcsubval = 64; | ||
692 | + ispccdc_config_black_clamp(blkcfg); | ||
693 | + if (is_isplsc_activated()) { | ||
694 | + ispccdc_config_lsc(&lsc_config); | ||
695 | + ispccdc_load_lsc(lsc_gain_table_tmp, | ||
696 | + LSC_TABLE_INIT_SIZE); | ||
697 | + } | ||
698 | + | ||
699 | + break; | ||
700 | + case CCDC_YUV_SYNC: | ||
701 | + syncif.ccdc_mastermode = 0; | ||
702 | + syncif.datapol = 0; | ||
703 | + syncif.datsz = DAT8; | ||
704 | + syncif.fldmode = 0; | ||
705 | + syncif.fldout = 0; | ||
706 | + syncif.fldpol = 0; | ||
707 | + syncif.fldstat = 0; | ||
708 | + syncif.hdpol = 0; | ||
709 | + syncif.ipmod = YUV16; | ||
710 | + syncif.vdpol = 1; | ||
711 | + ispccdc_config_imgattr(0); | ||
712 | + ispccdc_config_sync_if(syncif); | ||
713 | + blkcfg.dcsubval = 0; | ||
714 | + ispccdc_config_black_clamp(blkcfg); | ||
715 | + break; | ||
716 | + case CCDC_YUV_BT: | ||
717 | + break; | ||
718 | + case CCDC_OTHERS: | ||
719 | + break; | ||
720 | + default: | ||
721 | + DPRINTK_ISPCCDC("ISP_ERR: Wrong CCDC Input\n"); | ||
722 | + return -EINVAL; | ||
723 | + } | ||
724 | + | ||
725 | + ispccdc_obj.ccdc_inpfmt = input; | ||
726 | + ispccdc_obj.ccdc_outfmt = output; | ||
727 | + ispccdc_print_status(); | ||
728 | + isp_print_status(); | ||
729 | + return 0; | ||
730 | +} | ||
731 | +EXPORT_SYMBOL(ispccdc_config_datapath); | ||
732 | + | ||
733 | +/** | ||
734 | + * ispccdc_config_sync_if - Sets the sync i/f params between sensor and CCDC. | ||
735 | + * @syncif: Structure containing the sync parameters like field state, CCDC in | ||
736 | + * master/slave mode, raw/yuv data, polarity of data, field, hs, vs | ||
737 | + * signals. | ||
738 | + **/ | ||
739 | +void ispccdc_config_sync_if(struct ispccdc_syncif syncif) | ||
740 | +{ | ||
741 | + u32 syn_mode = isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); | ||
742 | + | ||
743 | + syn_mode |= ISPCCDC_SYN_MODE_VDHDEN; | ||
744 | + | ||
745 | + if (syncif.fldstat) | ||
746 | + syn_mode |= ISPCCDC_SYN_MODE_FLDSTAT; | ||
747 | + else | ||
748 | + syn_mode &= ~ISPCCDC_SYN_MODE_FLDSTAT; | ||
749 | + | ||
750 | + syn_mode &= ISPCCDC_SYN_MODE_INPMOD_MASK; | ||
751 | + ispccdc_obj.syncif_ipmod = syncif.ipmod; | ||
752 | + | ||
753 | + switch (syncif.ipmod) { | ||
754 | + case RAW: | ||
755 | + break; | ||
756 | + case YUV16: | ||
757 | + syn_mode |= ISPCCDC_SYN_MODE_INPMOD_YCBCR16; | ||
758 | + break; | ||
759 | + case YUV8: | ||
760 | + syn_mode |= ISPCCDC_SYN_MODE_INPMOD_YCBCR8; | ||
761 | + break; | ||
762 | + }; | ||
763 | + | ||
764 | + syn_mode &= ISPCCDC_SYN_MODE_DATSIZ_MASK; | ||
765 | + switch (syncif.datsz) { | ||
766 | + case DAT8: | ||
767 | + syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_8; | ||
768 | + break; | ||
769 | + case DAT10: | ||
770 | + syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_10; | ||
771 | + break; | ||
772 | + case DAT11: | ||
773 | + syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_11; | ||
774 | + break; | ||
775 | + case DAT12: | ||
776 | + syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_12; | ||
777 | + break; | ||
778 | + }; | ||
779 | + | ||
780 | + if (syncif.fldmode) | ||
781 | + syn_mode |= ISPCCDC_SYN_MODE_FLDMODE; | ||
782 | + else | ||
783 | + syn_mode &= ~ISPCCDC_SYN_MODE_FLDMODE; | ||
784 | + | ||
785 | + if (syncif.datapol) | ||
786 | + syn_mode |= ISPCCDC_SYN_MODE_DATAPOL; | ||
787 | + else | ||
788 | + syn_mode &= ~ISPCCDC_SYN_MODE_DATAPOL; | ||
789 | + | ||
790 | + if (syncif.fldpol) | ||
791 | + syn_mode |= ISPCCDC_SYN_MODE_FLDPOL; | ||
792 | + else | ||
793 | + syn_mode &= ~ISPCCDC_SYN_MODE_FLDPOL; | ||
794 | + | ||
795 | + if (syncif.hdpol) | ||
796 | + syn_mode |= ISPCCDC_SYN_MODE_HDPOL; | ||
797 | + else | ||
798 | + syn_mode &= ~ISPCCDC_SYN_MODE_HDPOL; | ||
799 | + | ||
800 | + if (syncif.vdpol) | ||
801 | + syn_mode |= ISPCCDC_SYN_MODE_VDPOL; | ||
802 | + else | ||
803 | + syn_mode &= ~ISPCCDC_SYN_MODE_VDPOL; | ||
804 | + | ||
805 | + if (syncif.ccdc_mastermode) { | ||
806 | + syn_mode |= ISPCCDC_SYN_MODE_FLDOUT | ISPCCDC_SYN_MODE_VDHDOUT; | ||
807 | + isp_reg_writel(syncif.hs_width << ISPCCDC_HD_VD_WID_HDW_SHIFT | ||
808 | + | syncif.vs_width << ISPCCDC_HD_VD_WID_VDW_SHIFT, | ||
809 | + OMAP3_ISP_IOMEM_CCDC, | ||
810 | + ISPCCDC_HD_VD_WID); | ||
811 | + | ||
812 | + isp_reg_writel(syncif.ppln << ISPCCDC_PIX_LINES_PPLN_SHIFT | ||
813 | + | syncif.hlprf << ISPCCDC_PIX_LINES_HLPRF_SHIFT, | ||
814 | + OMAP3_ISP_IOMEM_CCDC, | ||
815 | + ISPCCDC_PIX_LINES); | ||
816 | + } else | ||
817 | + syn_mode &= ~(ISPCCDC_SYN_MODE_FLDOUT | | ||
818 | + ISPCCDC_SYN_MODE_VDHDOUT); | ||
819 | + | ||
820 | + isp_reg_writel(syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); | ||
821 | + | ||
822 | + if (!(syncif.bt_r656_en)) { | ||
823 | + isp_reg_and(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_REC656IF, | ||
824 | + ~ISPCCDC_REC656IF_R656ON); | ||
825 | + } | ||
826 | +} | ||
827 | +EXPORT_SYMBOL(ispccdc_config_sync_if); | ||
828 | + | ||
829 | +/** | ||
830 | + * ispccdc_config_black_clamp - Configures the clamp parameters in CCDC. | ||
831 | + * @bclamp: Structure containing the optical black average gain, optical black | ||
832 | + * sample length, sample lines, and the start pixel position of the | ||
833 | + * samples w.r.t the HS pulse. | ||
834 | + * Configures the clamp parameters in CCDC. Either if its being used the | ||
835 | + * optical black clamp, or the digital clamp. If its a digital clamp, then | ||
836 | + * assures to put a valid DC substraction level. | ||
837 | + * | ||
838 | + * Returns always 0 when completed. | ||
839 | + **/ | ||
840 | +int ispccdc_config_black_clamp(struct ispccdc_bclamp bclamp) | ||
841 | +{ | ||
842 | + u32 bclamp_val = 0; | ||
843 | + | ||
844 | + if (ispccdc_obj.obclamp_en) { | ||
845 | + bclamp_val |= bclamp.obgain << ISPCCDC_CLAMP_OBGAIN_SHIFT; | ||
846 | + bclamp_val |= bclamp.oblen << ISPCCDC_CLAMP_OBSLEN_SHIFT; | ||
847 | + bclamp_val |= bclamp.oblines << ISPCCDC_CLAMP_OBSLN_SHIFT; | ||
848 | + bclamp_val |= bclamp.obstpixel << ISPCCDC_CLAMP_OBST_SHIFT; | ||
849 | + isp_reg_writel(bclamp_val, OMAP3_ISP_IOMEM_CCDC, | ||
850 | + ISPCCDC_CLAMP); | ||
851 | + } else { | ||
852 | + if (omap_rev() < OMAP3430_REV_ES2_0) | ||
853 | + if (ispccdc_obj.syncif_ipmod == YUV16 || | ||
854 | + ispccdc_obj.syncif_ipmod == YUV8 || | ||
855 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, | ||
856 | + ISPCCDC_REC656IF) & | ||
857 | + ISPCCDC_REC656IF_R656ON) | ||
858 | + bclamp.dcsubval = 0; | ||
859 | + isp_reg_writel(bclamp.dcsubval, OMAP3_ISP_IOMEM_CCDC, | ||
860 | + ISPCCDC_DCSUB); | ||
861 | + } | ||
862 | + return 0; | ||
863 | +} | ||
864 | +EXPORT_SYMBOL(ispccdc_config_black_clamp); | ||
865 | + | ||
866 | +/** | ||
867 | + * ispccdc_enable_black_clamp - Enables/Disables the optical black clamp. | ||
868 | + * @enable: 0 Disables optical black clamp, 1 Enables optical black clamp. | ||
869 | + * | ||
870 | + * Enables or disables the optical black clamp. When disabled, the digital | ||
871 | + * clamp operates. | ||
872 | + **/ | ||
873 | +void ispccdc_enable_black_clamp(u8 enable) | ||
874 | +{ | ||
875 | + isp_reg_and_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP, | ||
876 | + ~ISPCCDC_CLAMP_CLAMPEN, | ||
877 | + enable ? ISPCCDC_CLAMP_CLAMPEN : 0); | ||
878 | + ispccdc_obj.obclamp_en = enable; | ||
879 | +} | ||
880 | +EXPORT_SYMBOL(ispccdc_enable_black_clamp); | ||
881 | + | ||
882 | +/** | ||
883 | + * ispccdc_config_fpc - Configures the Faulty Pixel Correction parameters. | ||
884 | + * @fpc: Structure containing the number of faulty pixels corrected in the | ||
885 | + * frame, address of the FPC table. | ||
886 | + * | ||
887 | + * Returns 0 if successful, or -EINVAL if FPC Address is not on the 64 byte | ||
888 | + * boundary. | ||
889 | + **/ | ||
890 | +int ispccdc_config_fpc(struct ispccdc_fpc fpc) | ||
891 | +{ | ||
892 | + u32 fpc_val = 0; | ||
893 | + | ||
894 | + fpc_val = isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC); | ||
895 | + | ||
896 | + if ((fpc.fpcaddr & 0xFFFFFFC0) == fpc.fpcaddr) { | ||
897 | + isp_reg_writel(fpc_val & (~ISPCCDC_FPC_FPCEN), | ||
898 | + OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC); | ||
899 | + isp_reg_writel(fpc.fpcaddr, | ||
900 | + OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC_ADDR); | ||
901 | + } else { | ||
902 | + DPRINTK_ISPCCDC("FPC Address should be on 64byte boundary\n"); | ||
903 | + return -EINVAL; | ||
904 | + } | ||
905 | + isp_reg_writel(fpc_val | (fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT), | ||
906 | + OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC); | ||
907 | + return 0; | ||
908 | +} | ||
909 | +EXPORT_SYMBOL(ispccdc_config_fpc); | ||
910 | + | ||
911 | +/** | ||
912 | + * ispccdc_enable_fpc - Enables the Faulty Pixel Correction. | ||
913 | + * @enable: 0 Disables FPC, 1 Enables FPC. | ||
914 | + **/ | ||
915 | +void ispccdc_enable_fpc(u8 enable) | ||
916 | +{ | ||
917 | + isp_reg_and_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC, | ||
918 | + ~ISPCCDC_FPC_FPCEN, | ||
919 | + enable ? ISPCCDC_FPC_FPCEN : 0); | ||
920 | +} | ||
921 | +EXPORT_SYMBOL(ispccdc_enable_fpc); | ||
922 | + | ||
923 | +/** | ||
924 | + * ispccdc_config_black_comp - Configures Black Level Compensation parameters. | ||
925 | + * @blcomp: Structure containing the black level compensation value for RGrGbB | ||
926 | + * pixels. in 2's complement. | ||
927 | + **/ | ||
928 | +void ispccdc_config_black_comp(struct ispccdc_blcomp blcomp) | ||
929 | +{ | ||
930 | + u32 blcomp_val = 0; | ||
931 | + | ||
932 | + blcomp_val |= blcomp.b_mg << ISPCCDC_BLKCMP_B_MG_SHIFT; | ||
933 | + blcomp_val |= blcomp.gb_g << ISPCCDC_BLKCMP_GB_G_SHIFT; | ||
934 | + blcomp_val |= blcomp.gr_cy << ISPCCDC_BLKCMP_GR_CY_SHIFT; | ||
935 | + blcomp_val |= blcomp.r_ye << ISPCCDC_BLKCMP_R_YE_SHIFT; | ||
936 | + | ||
937 | + isp_reg_writel(blcomp_val, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_BLKCMP); | ||
938 | +} | ||
939 | +EXPORT_SYMBOL(ispccdc_config_black_comp); | ||
940 | + | ||
941 | +/** | ||
942 | + * ispccdc_config_vp - Configures the Video Port Configuration parameters. | ||
943 | + * @vpcfg: Structure containing the Video Port input frequency, and the 10 bit | ||
944 | + * format. | ||
945 | + **/ | ||
946 | +void ispccdc_config_vp(struct ispccdc_vp vpcfg) | ||
947 | +{ | ||
948 | + u32 fmtcfg_vp = isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG); | ||
949 | + | ||
950 | + fmtcfg_vp &= ISPCCDC_FMTCFG_VPIN_MASK & ISPCCDC_FMTCF_VPIF_FRQ_MASK; | ||
951 | + | ||
952 | + switch (vpcfg.bitshift_sel) { | ||
953 | + case BIT9_0: | ||
954 | + fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_9_0; | ||
955 | + break; | ||
956 | + case BIT10_1: | ||
957 | + fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_10_1; | ||
958 | + break; | ||
959 | + case BIT11_2: | ||
960 | + fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_11_2; | ||
961 | + break; | ||
962 | + case BIT12_3: | ||
963 | + fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_12_3; | ||
964 | + break; | ||
965 | + }; | ||
966 | + switch (vpcfg.freq_sel) { | ||
967 | + case PIXCLKBY2: | ||
968 | + fmtcfg_vp |= ISPCCDC_FMTCF_VPIF_FRQ_BY2; | ||
969 | + break; | ||
970 | + case PIXCLKBY3_5: | ||
971 | + fmtcfg_vp |= ISPCCDC_FMTCF_VPIF_FRQ_BY3; | ||
972 | + break; | ||
973 | + case PIXCLKBY4_5: | ||
974 | + fmtcfg_vp |= ISPCCDC_FMTCF_VPIF_FRQ_BY4; | ||
975 | + break; | ||
976 | + case PIXCLKBY5_5: | ||
977 | + fmtcfg_vp |= ISPCCDC_FMTCF_VPIF_FRQ_BY5; | ||
978 | + break; | ||
979 | + case PIXCLKBY6_5: | ||
980 | + fmtcfg_vp |= ISPCCDC_FMTCF_VPIF_FRQ_BY6; | ||
981 | + break; | ||
982 | + }; | ||
983 | + isp_reg_writel(fmtcfg_vp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG); | ||
984 | +} | ||
985 | +EXPORT_SYMBOL(ispccdc_config_vp); | ||
986 | + | ||
987 | +/** | ||
988 | + * ispccdc_enable_vp - Enables the Video Port. | ||
989 | + * @enable: 0 Disables VP, 1 Enables VP | ||
990 | + **/ | ||
991 | +void ispccdc_enable_vp(u8 enable) | ||
992 | +{ | ||
993 | + isp_reg_and_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG, | ||
994 | + ~ISPCCDC_FMTCFG_VPEN, | ||
995 | + enable ? ISPCCDC_FMTCFG_VPEN : 0); | ||
996 | +} | ||
997 | +EXPORT_SYMBOL(ispccdc_enable_vp); | ||
998 | + | ||
999 | +/** | ||
1000 | + * ispccdc_config_reformatter - Configures the Reformatter. | ||
1001 | + * @refmt: Structure containing the memory address to format and the bit fields | ||
1002 | + * for the reformatter registers. | ||
1003 | + * | ||
1004 | + * Configures the Reformatter register values if line alternating is disabled. | ||
1005 | + * Else, just enabling line alternating is enough. | ||
1006 | + **/ | ||
1007 | +void ispccdc_config_reformatter(struct ispccdc_refmt refmt) | ||
1008 | +{ | ||
1009 | + u32 fmtcfg_val = 0; | ||
1010 | + | ||
1011 | + fmtcfg_val = isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG); | ||
1012 | + | ||
1013 | + if (refmt.lnalt) | ||
1014 | + fmtcfg_val |= ISPCCDC_FMTCFG_LNALT; | ||
1015 | + else { | ||
1016 | + fmtcfg_val &= ~ISPCCDC_FMTCFG_LNALT; | ||
1017 | + fmtcfg_val &= 0xFFFFF003; | ||
1018 | + fmtcfg_val |= refmt.lnum << ISPCCDC_FMTCFG_LNUM_SHIFT; | ||
1019 | + fmtcfg_val |= refmt.plen_even << | ||
1020 | + ISPCCDC_FMTCFG_PLEN_EVEN_SHIFT; | ||
1021 | + fmtcfg_val |= refmt.plen_odd << ISPCCDC_FMTCFG_PLEN_ODD_SHIFT; | ||
1022 | + | ||
1023 | + isp_reg_writel(refmt.prgeven0, OMAP3_ISP_IOMEM_CCDC, | ||
1024 | + ISPCCDC_PRGEVEN0); | ||
1025 | + isp_reg_writel(refmt.prgeven1, OMAP3_ISP_IOMEM_CCDC, | ||
1026 | + ISPCCDC_PRGEVEN1); | ||
1027 | + isp_reg_writel(refmt.prgodd0, OMAP3_ISP_IOMEM_CCDC, | ||
1028 | + ISPCCDC_PRGODD0); | ||
1029 | + isp_reg_writel(refmt.prgodd1, OMAP3_ISP_IOMEM_CCDC, | ||
1030 | + ISPCCDC_PRGODD1); | ||
1031 | + isp_reg_writel(refmt.fmtaddr0, OMAP3_ISP_IOMEM_CCDC, | ||
1032 | + ISPCCDC_FMT_ADDR0); | ||
1033 | + isp_reg_writel(refmt.fmtaddr1, OMAP3_ISP_IOMEM_CCDC, | ||
1034 | + ISPCCDC_FMT_ADDR1); | ||
1035 | + isp_reg_writel(refmt.fmtaddr2, OMAP3_ISP_IOMEM_CCDC, | ||
1036 | + ISPCCDC_FMT_ADDR2); | ||
1037 | + isp_reg_writel(refmt.fmtaddr3, OMAP3_ISP_IOMEM_CCDC, | ||
1038 | + ISPCCDC_FMT_ADDR3); | ||
1039 | + isp_reg_writel(refmt.fmtaddr4, OMAP3_ISP_IOMEM_CCDC, | ||
1040 | + ISPCCDC_FMT_ADDR4); | ||
1041 | + isp_reg_writel(refmt.fmtaddr5, OMAP3_ISP_IOMEM_CCDC, | ||
1042 | + ISPCCDC_FMT_ADDR5); | ||
1043 | + isp_reg_writel(refmt.fmtaddr6, OMAP3_ISP_IOMEM_CCDC, | ||
1044 | + ISPCCDC_FMT_ADDR6); | ||
1045 | + isp_reg_writel(refmt.fmtaddr7, OMAP3_ISP_IOMEM_CCDC, | ||
1046 | + ISPCCDC_FMT_ADDR7); | ||
1047 | + } | ||
1048 | + isp_reg_writel(fmtcfg_val, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG); | ||
1049 | +} | ||
1050 | +EXPORT_SYMBOL(ispccdc_config_reformatter); | ||
1051 | + | ||
1052 | +/** | ||
1053 | + * ispccdc_enable_reformatter - Enables the Reformatter. | ||
1054 | + * @enable: 0 Disables Reformatter, 1- Enables Data Reformatter | ||
1055 | + **/ | ||
1056 | +void ispccdc_enable_reformatter(u8 enable) | ||
1057 | +{ | ||
1058 | + isp_reg_and_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG, | ||
1059 | + ~ISPCCDC_FMTCFG_FMTEN, | ||
1060 | + enable ? ISPCCDC_FMTCFG_FMTEN : 0); | ||
1061 | + ispccdc_obj.refmt_en = enable; | ||
1062 | +} | ||
1063 | +EXPORT_SYMBOL(ispccdc_enable_reformatter); | ||
1064 | + | ||
1065 | +/** | ||
1066 | + * ispccdc_config_culling - Configures the culling parameters. | ||
1067 | + * @cull: Structure containing the vertical culling pattern, and horizontal | ||
1068 | + * culling pattern for odd and even lines. | ||
1069 | + **/ | ||
1070 | +void ispccdc_config_culling(struct ispccdc_culling cull) | ||
1071 | +{ | ||
1072 | + u32 culling_val = 0; | ||
1073 | + | ||
1074 | + culling_val |= cull.v_pattern << ISPCCDC_CULLING_CULV_SHIFT; | ||
1075 | + culling_val |= cull.h_even << ISPCCDC_CULLING_CULHEVN_SHIFT; | ||
1076 | + culling_val |= cull.h_odd << ISPCCDC_CULLING_CULHODD_SHIFT; | ||
1077 | + | ||
1078 | + isp_reg_writel(culling_val, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CULLING); | ||
1079 | +} | ||
1080 | +EXPORT_SYMBOL(ispccdc_config_culling); | ||
1081 | + | ||
1082 | +/** | ||
1083 | + * ispccdc_enable_lpf - Enables the Low-Pass Filter (LPF). | ||
1084 | + * @enable: 0 Disables LPF, 1 Enables LPF | ||
1085 | + **/ | ||
1086 | +void ispccdc_enable_lpf(u8 enable) | ||
1087 | +{ | ||
1088 | + isp_reg_and_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE, | ||
1089 | + ~ISPCCDC_SYN_MODE_LPF, | ||
1090 | + enable ? ISPCCDC_SYN_MODE_LPF : 0); | ||
1091 | +} | ||
1092 | +EXPORT_SYMBOL(ispccdc_enable_lpf); | ||
1093 | + | ||
1094 | +/** | ||
1095 | + * ispccdc_config_alaw - Configures the input width for A-law. | ||
1096 | + * @ipwidth: Input width for A-law | ||
1097 | + **/ | ||
1098 | +void ispccdc_config_alaw(enum alaw_ipwidth ipwidth) | ||
1099 | +{ | ||
1100 | + isp_reg_writel(ipwidth << ISPCCDC_ALAW_GWDI_SHIFT, | ||
1101 | + OMAP3_ISP_IOMEM_CCDC, ISPCCDC_ALAW); | ||
1102 | +} | ||
1103 | +EXPORT_SYMBOL(ispccdc_config_alaw); | ||
1104 | + | ||
1105 | +/** | ||
1106 | + * ispccdc_enable_alaw - Enables the A-law compression. | ||
1107 | + * @enable: 0 - Disables A-law, 1 - Enables A-law | ||
1108 | + **/ | ||
1109 | +void ispccdc_enable_alaw(u8 enable) | ||
1110 | +{ | ||
1111 | + isp_reg_and_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_ALAW, | ||
1112 | + ~ISPCCDC_ALAW_CCDTBL, | ||
1113 | + enable ? ISPCCDC_ALAW_CCDTBL : 0); | ||
1114 | +} | ||
1115 | +EXPORT_SYMBOL(ispccdc_enable_alaw); | ||
1116 | + | ||
1117 | +/** | ||
1118 | + * ispccdc_config_imgattr - Configures the sensor image specific attributes. | ||
1119 | + * @colptn: Color pattern of the sensor. | ||
1120 | + **/ | ||
1121 | +void ispccdc_config_imgattr(u32 colptn) | ||
1122 | +{ | ||
1123 | + isp_reg_writel(colptn, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_COLPTN); | ||
1124 | +} | ||
1125 | +EXPORT_SYMBOL(ispccdc_config_imgattr); | ||
1126 | + | ||
1127 | +void ispccdc_config_shadow_registers(void) | ||
1128 | +{ | ||
1129 | + if (ispccdc_obj.lsc_enable) { | ||
1130 | + ispccdc_enable_lsc(1); | ||
1131 | + ispccdc_obj.lsc_enable = 0; | ||
1132 | + } | ||
1133 | +} | ||
1134 | + | ||
1135 | +/** | ||
1136 | + * ispccdc_try_size - Checks if requested Input/output dimensions are valid | ||
1137 | + * @input_w: input width for the CCDC in number of pixels per line | ||
1138 | + * @input_h: input height for the CCDC in number of lines | ||
1139 | + * @output_w: output width from the CCDC in number of pixels per line | ||
1140 | + * @output_h: output height for the CCDC in number of lines | ||
1141 | + * | ||
1142 | + * Calculates the number of pixels cropped if the reformater is disabled, | ||
1143 | + * Fills up the output width and height variables in the isp_ccdc structure. | ||
1144 | + * | ||
1145 | + * Returns 0 if successful, or -EINVAL if the input width is less than 2 pixels | ||
1146 | + **/ | ||
1147 | +int ispccdc_try_size(u32 input_w, u32 input_h, u32 *output_w, u32 *output_h) | ||
1148 | +{ | ||
1149 | + if (input_w < 32 || input_h < 32) { | ||
1150 | + DPRINTK_ISPCCDC("ISP_ERR: CCDC cannot handle input width less" | ||
1151 | + " than 32 pixels or height less than 32\n"); | ||
1152 | + return -EINVAL; | ||
1153 | + } | ||
1154 | + | ||
1155 | + if (ispccdc_obj.crop_w) | ||
1156 | + *output_w = ispccdc_obj.crop_w; | ||
1157 | + else | ||
1158 | + *output_w = input_w; | ||
1159 | + | ||
1160 | + if (ispccdc_obj.crop_h) | ||
1161 | + *output_h = ispccdc_obj.crop_h; | ||
1162 | + else | ||
1163 | + *output_h = input_h; | ||
1164 | + | ||
1165 | + if (!ispccdc_obj.refmt_en | ||
1166 | + && ispccdc_obj.ccdc_outfmt != CCDC_OTHERS_MEM | ||
1167 | + && ispccdc_obj.ccdc_outfmt != CCDC_OTHERS_VP_MEM) | ||
1168 | + *output_h -= 1; | ||
1169 | + | ||
1170 | + if (ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_MEM | ||
1171 | + || ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_VP_MEM) { | ||
1172 | + if (*output_w % 16) { | ||
1173 | + *output_w -= (*output_w % 16); | ||
1174 | + *output_w += 16; | ||
1175 | + } | ||
1176 | + } | ||
1177 | + | ||
1178 | + ispccdc_obj.ccdcout_w = *output_w; | ||
1179 | + ispccdc_obj.ccdcout_h = *output_h; | ||
1180 | + ispccdc_obj.ccdcin_w = input_w; | ||
1181 | + ispccdc_obj.ccdcin_h = input_h; | ||
1182 | + | ||
1183 | + DPRINTK_ISPCCDC("try size: ccdcin_w=%u,ccdcin_h=%u,ccdcout_w=%u," | ||
1184 | + " ccdcout_h=%u\n", | ||
1185 | + ispccdc_obj.ccdcin_w, | ||
1186 | + ispccdc_obj.ccdcin_h, | ||
1187 | + ispccdc_obj.ccdcout_w, | ||
1188 | + ispccdc_obj.ccdcout_h); | ||
1189 | + | ||
1190 | + return 0; | ||
1191 | +} | ||
1192 | +EXPORT_SYMBOL(ispccdc_try_size); | ||
1193 | + | ||
1194 | +/** | ||
1195 | + * ispccdc_config_size - Configure the dimensions of the CCDC input/output | ||
1196 | + * @input_w: input width for the CCDC in number of pixels per line | ||
1197 | + * @input_h: input height for the CCDC in number of lines | ||
1198 | + * @output_w: output width from the CCDC in number of pixels per line | ||
1199 | + * @output_h: output height for the CCDC in number of lines | ||
1200 | + * | ||
1201 | + * Configures the appropriate values stored in the isp_ccdc structure to | ||
1202 | + * HORZ/VERT_INFO registers and the VP_OUT depending on whether the image | ||
1203 | + * is stored in memory or given to the another module in the ISP pipeline. | ||
1204 | + * | ||
1205 | + * Returns 0 if successful, or -EINVAL if try_size was not called before to | ||
1206 | + * validate the requested dimensions. | ||
1207 | + **/ | ||
1208 | +int ispccdc_config_size(u32 input_w, u32 input_h, u32 output_w, u32 output_h) | ||
1209 | +{ | ||
1210 | + DPRINTK_ISPCCDC("config size: input_w=%u, input_h=%u, output_w=%u," | ||
1211 | + " output_h=%u\n", | ||
1212 | + input_w, input_h, | ||
1213 | + output_w, output_h); | ||
1214 | + if (output_w != ispccdc_obj.ccdcout_w | ||
1215 | + || output_h != ispccdc_obj.ccdcout_h) { | ||
1216 | + DPRINTK_ISPCCDC("ISP_ERR : ispccdc_try_size should" | ||
1217 | + " be called before config size\n"); | ||
1218 | + return -EINVAL; | ||
1219 | + } | ||
1220 | + | ||
1221 | + if (ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_VP) { | ||
1222 | + isp_reg_writel((ispccdc_obj.ccdcin_woffset << | ||
1223 | + ISPCCDC_FMT_HORZ_FMTSPH_SHIFT) | | ||
1224 | + (ispccdc_obj.ccdcin_w << | ||
1225 | + ISPCCDC_FMT_HORZ_FMTLNH_SHIFT), | ||
1226 | + OMAP3_ISP_IOMEM_CCDC, | ||
1227 | + ISPCCDC_FMT_HORZ); | ||
1228 | + isp_reg_writel((ispccdc_obj.ccdcin_hoffset << | ||
1229 | + ISPCCDC_FMT_VERT_FMTSLV_SHIFT) | | ||
1230 | + (ispccdc_obj.ccdcin_h << | ||
1231 | + ISPCCDC_FMT_VERT_FMTLNV_SHIFT), | ||
1232 | + OMAP3_ISP_IOMEM_CCDC, | ||
1233 | + ISPCCDC_FMT_VERT); | ||
1234 | + isp_reg_writel((ispccdc_obj.ccdcout_w << | ||
1235 | + ISPCCDC_VP_OUT_HORZ_NUM_SHIFT) | | ||
1236 | + (ispccdc_obj.ccdcout_h - 1) << | ||
1237 | + ISPCCDC_VP_OUT_VERT_NUM_SHIFT, | ||
1238 | + OMAP3_ISP_IOMEM_CCDC, | ||
1239 | + ISPCCDC_VP_OUT); | ||
1240 | + isp_reg_writel((((ispccdc_obj.ccdcout_h - 25) & | ||
1241 | + ISPCCDC_VDINT_0_MASK) << | ||
1242 | + ISPCCDC_VDINT_0_SHIFT) | | ||
1243 | + ((50 & ISPCCDC_VDINT_1_MASK) << | ||
1244 | + ISPCCDC_VDINT_1_SHIFT), | ||
1245 | + OMAP3_ISP_IOMEM_CCDC, | ||
1246 | + ISPCCDC_VDINT); | ||
1247 | + | ||
1248 | + } else if (ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_MEM) { | ||
1249 | + isp_reg_writel(0, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT); | ||
1250 | + if (ispccdc_obj.ccdc_inpfmt == CCDC_RAW) { | ||
1251 | + isp_reg_writel(0 << ISPCCDC_HORZ_INFO_SPH_SHIFT | ||
1252 | + | ((ispccdc_obj.ccdcout_w - 1) | ||
1253 | + << ISPCCDC_HORZ_INFO_NPH_SHIFT), | ||
1254 | + OMAP3_ISP_IOMEM_CCDC, | ||
1255 | + ISPCCDC_HORZ_INFO); | ||
1256 | + } else { | ||
1257 | + isp_reg_writel(0 << ISPCCDC_HORZ_INFO_SPH_SHIFT | ||
1258 | + | ((ispccdc_obj.ccdcout_w - 1) | ||
1259 | + << ISPCCDC_HORZ_INFO_NPH_SHIFT), | ||
1260 | + OMAP3_ISP_IOMEM_CCDC, | ||
1261 | + ISPCCDC_HORZ_INFO); | ||
1262 | + } | ||
1263 | + isp_reg_writel(0 << ISPCCDC_VERT_START_SLV0_SHIFT, | ||
1264 | + OMAP3_ISP_IOMEM_CCDC, | ||
1265 | + ISPCCDC_VERT_START); | ||
1266 | + isp_reg_writel((ispccdc_obj.ccdcout_h - 1) << | ||
1267 | + ISPCCDC_VERT_LINES_NLV_SHIFT, | ||
1268 | + OMAP3_ISP_IOMEM_CCDC, | ||
1269 | + ISPCCDC_VERT_LINES); | ||
1270 | + | ||
1271 | + ispccdc_config_outlineoffset(ispccdc_obj.ccdcout_w * 2, 0, 0); | ||
1272 | + isp_reg_writel((((ispccdc_obj.ccdcout_h - 2) & | ||
1273 | + ISPCCDC_VDINT_0_MASK) << | ||
1274 | + ISPCCDC_VDINT_0_SHIFT) | | ||
1275 | + ((100 & ISPCCDC_VDINT_1_MASK) << | ||
1276 | + ISPCCDC_VDINT_1_SHIFT), | ||
1277 | + OMAP3_ISP_IOMEM_CCDC, | ||
1278 | + ISPCCDC_VDINT); | ||
1279 | + } else if (ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_VP_MEM) { | ||
1280 | + isp_reg_writel((0 << ISPCCDC_FMT_HORZ_FMTSPH_SHIFT) | | ||
1281 | + (ispccdc_obj.ccdcin_w << | ||
1282 | + ISPCCDC_FMT_HORZ_FMTLNH_SHIFT), | ||
1283 | + OMAP3_ISP_IOMEM_CCDC, | ||
1284 | + ISPCCDC_FMT_HORZ); | ||
1285 | + isp_reg_writel((0 << ISPCCDC_FMT_VERT_FMTSLV_SHIFT) | | ||
1286 | + ((ispccdc_obj.ccdcin_h) << | ||
1287 | + ISPCCDC_FMT_VERT_FMTLNV_SHIFT), | ||
1288 | + OMAP3_ISP_IOMEM_CCDC, | ||
1289 | + ISPCCDC_FMT_VERT); | ||
1290 | + isp_reg_writel((ispccdc_obj.ccdcout_w | ||
1291 | + << ISPCCDC_VP_OUT_HORZ_NUM_SHIFT) | | ||
1292 | + ((ispccdc_obj.ccdcout_h - 1) << | ||
1293 | + ISPCCDC_VP_OUT_VERT_NUM_SHIFT), | ||
1294 | + OMAP3_ISP_IOMEM_CCDC, | ||
1295 | + ISPCCDC_VP_OUT); | ||
1296 | + isp_reg_writel(0 << ISPCCDC_HORZ_INFO_SPH_SHIFT | | ||
1297 | + ((ispccdc_obj.ccdcout_w - 1) << | ||
1298 | + ISPCCDC_HORZ_INFO_NPH_SHIFT), | ||
1299 | + OMAP3_ISP_IOMEM_CCDC, | ||
1300 | + ISPCCDC_HORZ_INFO); | ||
1301 | + isp_reg_writel(0 << ISPCCDC_VERT_START_SLV0_SHIFT, | ||
1302 | + OMAP3_ISP_IOMEM_CCDC, | ||
1303 | + ISPCCDC_VERT_START); | ||
1304 | + isp_reg_writel((ispccdc_obj.ccdcout_h - 1) << | ||
1305 | + ISPCCDC_VERT_LINES_NLV_SHIFT, | ||
1306 | + OMAP3_ISP_IOMEM_CCDC, | ||
1307 | + ISPCCDC_VERT_LINES); | ||
1308 | + ispccdc_config_outlineoffset(ispccdc_obj.ccdcout_w * 2, 0, 0); | ||
1309 | + isp_reg_writel((((ispccdc_obj.ccdcout_h - 2) & | ||
1310 | + ISPCCDC_VDINT_0_MASK) << | ||
1311 | + ISPCCDC_VDINT_0_SHIFT) | | ||
1312 | + ((100 & ISPCCDC_VDINT_1_MASK) << | ||
1313 | + ISPCCDC_VDINT_1_SHIFT), | ||
1314 | + OMAP3_ISP_IOMEM_CCDC, | ||
1315 | + ISPCCDC_VDINT); | ||
1316 | + } | ||
1317 | + | ||
1318 | + if (is_isplsc_activated()) { | ||
1319 | + if (ispccdc_obj.ccdc_inpfmt == CCDC_RAW) { | ||
1320 | + ispccdc_config_lsc(&lsc_config); | ||
1321 | + ispccdc_load_lsc(lsc_gain_table, lsc_config.size); | ||
1322 | + } | ||
1323 | + } | ||
1324 | + | ||
1325 | + return 0; | ||
1326 | +} | ||
1327 | +EXPORT_SYMBOL(ispccdc_config_size); | ||
1328 | + | ||
1329 | +/** | ||
1330 | + * ispccdc_config_outlineoffset - Configures the output line offset | ||
1331 | + * @offset: Must be twice the Output width and aligned on 32 byte boundary | ||
1332 | + * @oddeven: Specifies the odd/even line pattern to be chosen to store the | ||
1333 | + * output. | ||
1334 | + * @numlines: Set the value 0-3 for +1-4lines, 4-7 for -1-4lines. | ||
1335 | + * | ||
1336 | + * - Configures the output line offset when stored in memory | ||
1337 | + * - Sets the odd/even line pattern to store the output | ||
1338 | + * (EVENEVEN (1), ODDEVEN (2), EVENODD (3), ODDODD (4)) | ||
1339 | + * - Configures the number of even and odd line fields in case of rearranging | ||
1340 | + * the lines. | ||
1341 | + * | ||
1342 | + * Returns 0 if successful, or -EINVAL if the offset is not in 32 byte | ||
1343 | + * boundary. | ||
1344 | + **/ | ||
1345 | +int ispccdc_config_outlineoffset(u32 offset, u8 oddeven, u8 numlines) | ||
1346 | +{ | ||
1347 | + if ((offset & ISP_32B_BOUNDARY_OFFSET) == offset) { | ||
1348 | + isp_reg_writel((offset & 0xFFFF), OMAP3_ISP_IOMEM_CCDC, | ||
1349 | + ISPCCDC_HSIZE_OFF); | ||
1350 | + } else { | ||
1351 | + DPRINTK_ISPCCDC("ISP_ERR : Offset should be in 32 byte" | ||
1352 | + " boundary\n"); | ||
1353 | + return -EINVAL; | ||
1354 | + } | ||
1355 | + | ||
1356 | + isp_reg_and(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, | ||
1357 | + ~ISPCCDC_SDOFST_FINV); | ||
1358 | + | ||
1359 | + isp_reg_and(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, | ||
1360 | + ~ISPCCDC_SDOFST_FOFST_4L); | ||
1361 | + | ||
1362 | + switch (oddeven) { | ||
1363 | + case EVENEVEN: | ||
1364 | + isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, | ||
1365 | + (numlines & 0x7) << ISPCCDC_SDOFST_LOFST0_SHIFT); | ||
1366 | + break; | ||
1367 | + case ODDEVEN: | ||
1368 | + isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, | ||
1369 | + (numlines & 0x7) << ISPCCDC_SDOFST_LOFST1_SHIFT); | ||
1370 | + break; | ||
1371 | + case EVENODD: | ||
1372 | + isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, | ||
1373 | + (numlines & 0x7) << ISPCCDC_SDOFST_LOFST2_SHIFT); | ||
1374 | + break; | ||
1375 | + case ODDODD: | ||
1376 | + isp_reg_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST, | ||
1377 | + (numlines & 0x7) << ISPCCDC_SDOFST_LOFST3_SHIFT); | ||
1378 | + break; | ||
1379 | + default: | ||
1380 | + break; | ||
1381 | + } | ||
1382 | + return 0; | ||
1383 | +} | ||
1384 | +EXPORT_SYMBOL(ispccdc_config_outlineoffset); | ||
1385 | + | ||
1386 | +/** | ||
1387 | + * ispccdc_set_outaddr - Sets the memory address where the output will be saved | ||
1388 | + * @addr: 32-bit memory address aligned on 32 byte boundary. | ||
1389 | + * | ||
1390 | + * Sets the memory address where the output will be saved. | ||
1391 | + * | ||
1392 | + * Returns 0 if successful, or -EINVAL if the address is not in the 32 byte | ||
1393 | + * boundary. | ||
1394 | + **/ | ||
1395 | +int ispccdc_set_outaddr(u32 addr) | ||
1396 | +{ | ||
1397 | + if ((addr & ISP_32B_BOUNDARY_BUF) == addr) { | ||
1398 | + isp_reg_writel(addr, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR); | ||
1399 | + return 0; | ||
1400 | + } else { | ||
1401 | + DPRINTK_ISPCCDC("ISP_ERR : Address should be in 32 byte" | ||
1402 | + " boundary\n"); | ||
1403 | + return -EINVAL; | ||
1404 | + } | ||
1405 | + | ||
1406 | +} | ||
1407 | +EXPORT_SYMBOL(ispccdc_set_outaddr); | ||
1408 | + | ||
1409 | +void __ispccdc_enable(u8 enable) | ||
1410 | +{ | ||
1411 | + if (enable) { | ||
1412 | + if (ispccdc_obj.lsc_enable | ||
1413 | + && ispccdc_obj.ccdc_inpfmt == CCDC_RAW) | ||
1414 | + ispccdc_enable_lsc(1); | ||
1415 | + | ||
1416 | + } else { | ||
1417 | + ispccdc_obj.lsc_enable = ispccdc_obj.lsc_state; | ||
1418 | + } | ||
1419 | + | ||
1420 | + isp_reg_and_or(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR, ~ISPCCDC_PCR_EN, | ||
1421 | + enable ? ISPCCDC_PCR_EN : 0); | ||
1422 | +} | ||
1423 | + | ||
1424 | +/** | ||
1425 | + * ispccdc_enable - Enables the CCDC module. | ||
1426 | + * @enable: 0 Disables CCDC, 1 Enables CCDC | ||
1427 | + * | ||
1428 | + * Client should configure all the sub modules in CCDC before this. | ||
1429 | + **/ | ||
1430 | +void ispccdc_enable(u8 enable) | ||
1431 | +{ | ||
1432 | + __ispccdc_enable(enable); | ||
1433 | + ispccdc_obj.pm_state = enable; | ||
1434 | +} | ||
1435 | +EXPORT_SYMBOL(ispccdc_enable); | ||
1436 | + | ||
1437 | +/** | ||
1438 | + * ispccdc_suspend - Suspend the CCDC module. | ||
1439 | + **/ | ||
1440 | +void ispccdc_suspend(void) | ||
1441 | +{ | ||
1442 | + if (ispccdc_obj.pm_state) { | ||
1443 | + if (ispccdc_obj.lsc_state) | ||
1444 | + __ispccdc_enable_lsc(0); | ||
1445 | + else if (ispccdc_obj.lsc_enable) { | ||
1446 | + ispccdc_obj.lsc_state = 1; | ||
1447 | + ispccdc_obj.lsc_enable = 0; | ||
1448 | + } | ||
1449 | + __ispccdc_enable(0); | ||
1450 | + } | ||
1451 | +} | ||
1452 | +EXPORT_SYMBOL(ispccdc_suspend); | ||
1453 | + | ||
1454 | +/** | ||
1455 | + * ispccdc_resume - Resume the CCDC module. | ||
1456 | + **/ | ||
1457 | +void ispccdc_resume(void) | ||
1458 | +{ | ||
1459 | + if (ispccdc_obj.pm_state) { | ||
1460 | + if (ispccdc_obj.lsc_state) | ||
1461 | + __ispccdc_enable_lsc(1); | ||
1462 | + __ispccdc_enable(1); | ||
1463 | + } | ||
1464 | +} | ||
1465 | +EXPORT_SYMBOL(ispccdc_resume); | ||
1466 | + | ||
1467 | +/* | ||
1468 | + * Returns zero if the CCDC is idle and the image has been written to | ||
1469 | + * memory, too. | ||
1470 | + */ | ||
1471 | +int ispccdc_sbl_busy(void) | ||
1472 | +{ | ||
1473 | + return ispccdc_busy() | ||
1474 | + | (isp_reg_readl(OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_0) & | ||
1475 | + ISPSBL_CCDC_WR_0_DATA_READY) | ||
1476 | + | (isp_reg_readl(OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_1) & | ||
1477 | + ISPSBL_CCDC_WR_0_DATA_READY) | ||
1478 | + | (isp_reg_readl(OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_2) & | ||
1479 | + ISPSBL_CCDC_WR_0_DATA_READY) | ||
1480 | + | (isp_reg_readl(OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_3) & | ||
1481 | + ISPSBL_CCDC_WR_0_DATA_READY); | ||
1482 | +} | ||
1483 | +EXPORT_SYMBOL(ispccdc_sbl_busy); | ||
1484 | + | ||
1485 | +/** | ||
1486 | + * ispccdc_busy - Gets busy state of the CCDC. | ||
1487 | + **/ | ||
1488 | +int ispccdc_busy(void) | ||
1489 | +{ | ||
1490 | + return isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR) & | ||
1491 | + ISPCCDC_PCR_BUSY; | ||
1492 | +} | ||
1493 | +EXPORT_SYMBOL(ispccdc_busy); | ||
1494 | + | ||
1495 | +/** | ||
1496 | + * ispccdc_save_context - Saves the values of the CCDC module registers | ||
1497 | + **/ | ||
1498 | +void ispccdc_save_context(void) | ||
1499 | +{ | ||
1500 | + DPRINTK_ISPCCDC("Saving context\n"); | ||
1501 | + isp_save_context(ispccdc_reg_list); | ||
1502 | +} | ||
1503 | +EXPORT_SYMBOL(ispccdc_save_context); | ||
1504 | + | ||
1505 | +/** | ||
1506 | + * ispccdc_restore_context - Restores the values of the CCDC module registers | ||
1507 | + **/ | ||
1508 | +void ispccdc_restore_context(void) | ||
1509 | +{ | ||
1510 | + DPRINTK_ISPCCDC("Restoring context\n"); | ||
1511 | + isp_restore_context(ispccdc_reg_list); | ||
1512 | +} | ||
1513 | +EXPORT_SYMBOL(ispccdc_restore_context); | ||
1514 | + | ||
1515 | +/** | ||
1516 | + * ispccdc_print_status - Prints the values of the CCDC Module registers | ||
1517 | + * | ||
1518 | + * Also prints other debug information stored in the CCDC module. | ||
1519 | + **/ | ||
1520 | +void ispccdc_print_status(void) | ||
1521 | +{ | ||
1522 | + if (!is_ispccdc_debug_enabled()) | ||
1523 | + return; | ||
1524 | + | ||
1525 | + DPRINTK_ISPCCDC("Module in use =%d\n", ispccdc_obj.ccdc_inuse); | ||
1526 | + DPRINTK_ISPCCDC("Accepted CCDC Input (width = %d,Height = %d)\n", | ||
1527 | + ispccdc_obj.ccdcin_w, | ||
1528 | + ispccdc_obj.ccdcin_h); | ||
1529 | + DPRINTK_ISPCCDC("Accepted CCDC Output (width = %d,Height = %d)\n", | ||
1530 | + ispccdc_obj.ccdcout_w, | ||
1531 | + ispccdc_obj.ccdcout_h); | ||
1532 | + DPRINTK_ISPCCDC("###CCDC PCR=0x%x\n", | ||
1533 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR)); | ||
1534 | + DPRINTK_ISPCCDC("ISP_CTRL =0x%x\n", | ||
1535 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL)); | ||
1536 | + switch (ispccdc_obj.ccdc_inpfmt) { | ||
1537 | + case CCDC_RAW: | ||
1538 | + DPRINTK_ISPCCDC("ccdc input format is CCDC_RAW\n"); | ||
1539 | + break; | ||
1540 | + case CCDC_YUV_SYNC: | ||
1541 | + DPRINTK_ISPCCDC("ccdc input format is CCDC_YUV_SYNC\n"); | ||
1542 | + break; | ||
1543 | + case CCDC_YUV_BT: | ||
1544 | + DPRINTK_ISPCCDC("ccdc input format is CCDC_YUV_BT\n"); | ||
1545 | + break; | ||
1546 | + } | ||
1547 | + | ||
1548 | + switch (ispccdc_obj.ccdc_outfmt) { | ||
1549 | + case CCDC_OTHERS_VP: | ||
1550 | + DPRINTK_ISPCCDC("ccdc output format is CCDC_OTHERS_VP\n"); | ||
1551 | + break; | ||
1552 | + case CCDC_OTHERS_MEM: | ||
1553 | + DPRINTK_ISPCCDC("ccdc output format is CCDC_OTHERS_MEM\n"); | ||
1554 | + break; | ||
1555 | + case CCDC_YUV_RSZ: | ||
1556 | + DPRINTK_ISPCCDC("ccdc output format is CCDC_YUV_RSZ\n"); | ||
1557 | + break; | ||
1558 | + } | ||
1559 | + | ||
1560 | + DPRINTK_ISPCCDC("###ISP_CTRL in ccdc =0x%x\n", | ||
1561 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL)); | ||
1562 | + DPRINTK_ISPCCDC("###ISP_IRQ0ENABLE in ccdc =0x%x\n", | ||
1563 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE)); | ||
1564 | + DPRINTK_ISPCCDC("###ISP_IRQ0STATUS in ccdc =0x%x\n", | ||
1565 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS)); | ||
1566 | + DPRINTK_ISPCCDC("###CCDC SYN_MODE=0x%x\n", | ||
1567 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE)); | ||
1568 | + DPRINTK_ISPCCDC("###CCDC HORZ_INFO=0x%x\n", | ||
1569 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO)); | ||
1570 | + DPRINTK_ISPCCDC("###CCDC VERT_START=0x%x\n", | ||
1571 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, | ||
1572 | + ISPCCDC_VERT_START)); | ||
1573 | + DPRINTK_ISPCCDC("###CCDC VERT_LINES=0x%x\n", | ||
1574 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, | ||
1575 | + ISPCCDC_VERT_LINES)); | ||
1576 | + DPRINTK_ISPCCDC("###CCDC CULLING=0x%x\n", | ||
1577 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CULLING)); | ||
1578 | + DPRINTK_ISPCCDC("###CCDC HSIZE_OFF=0x%x\n", | ||
1579 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF)); | ||
1580 | + DPRINTK_ISPCCDC("###CCDC SDOFST=0x%x\n", | ||
1581 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST)); | ||
1582 | + DPRINTK_ISPCCDC("###CCDC SDR_ADDR=0x%x\n", | ||
1583 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR)); | ||
1584 | + DPRINTK_ISPCCDC("###CCDC CLAMP=0x%x\n", | ||
1585 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP)); | ||
1586 | + DPRINTK_ISPCCDC("###CCDC COLPTN=0x%x\n", | ||
1587 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_COLPTN)); | ||
1588 | + DPRINTK_ISPCCDC("###CCDC CFG=0x%x\n", | ||
1589 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG)); | ||
1590 | + DPRINTK_ISPCCDC("###CCDC VP_OUT=0x%x\n", | ||
1591 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT)); | ||
1592 | + DPRINTK_ISPCCDC("###CCDC_SDR_ADDR= 0x%x\n", | ||
1593 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR)); | ||
1594 | + DPRINTK_ISPCCDC("###CCDC FMTCFG=0x%x\n", | ||
1595 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG)); | ||
1596 | + DPRINTK_ISPCCDC("###CCDC FMT_HORZ=0x%x\n", | ||
1597 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_HORZ)); | ||
1598 | + DPRINTK_ISPCCDC("###CCDC FMT_VERT=0x%x\n", | ||
1599 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_VERT)); | ||
1600 | + DPRINTK_ISPCCDC("###CCDC LSC_CONFIG=0x%x\n", | ||
1601 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, | ||
1602 | + ISPCCDC_LSC_CONFIG)); | ||
1603 | + DPRINTK_ISPCCDC("###CCDC LSC_INIT=0x%x\n", | ||
1604 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, | ||
1605 | + ISPCCDC_LSC_INITIAL)); | ||
1606 | + DPRINTK_ISPCCDC("###CCDC LSC_TABLE BASE=0x%x\n", | ||
1607 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, | ||
1608 | + ISPCCDC_LSC_TABLE_BASE)); | ||
1609 | + DPRINTK_ISPCCDC("###CCDC LSC TABLE OFFSET=0x%x\n", | ||
1610 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, | ||
1611 | + ISPCCDC_LSC_TABLE_OFFSET)); | ||
1612 | +} | ||
1613 | +EXPORT_SYMBOL(ispccdc_print_status); | ||
1614 | + | ||
1615 | +/** | ||
1616 | + * isp_ccdc_init - CCDC module initialization. | ||
1617 | + * | ||
1618 | + * Always returns 0 | ||
1619 | + **/ | ||
1620 | +int __init isp_ccdc_init(void) | ||
1621 | +{ | ||
1622 | + ispccdc_obj.ccdc_inuse = 0; | ||
1623 | + ispccdc_config_crop(0, 0, 0, 0); | ||
1624 | + mutex_init(&ispccdc_obj.mutexlock); | ||
1625 | + | ||
1626 | + if (is_isplsc_activated()) { | ||
1627 | + lsc_gain_table_tmp = kmalloc(LSC_TABLE_INIT_SIZE, GFP_KERNEL | | ||
1628 | + GFP_DMA); | ||
1629 | + memset(lsc_gain_table_tmp, 0x40, LSC_TABLE_INIT_SIZE); | ||
1630 | + lsc_config.initial_x = 0; | ||
1631 | + lsc_config.initial_y = 0; | ||
1632 | + lsc_config.gain_mode_n = 0x6; | ||
1633 | + lsc_config.gain_mode_m = 0x6; | ||
1634 | + lsc_config.gain_format = 0x4; | ||
1635 | + lsc_config.offset = 0x60; | ||
1636 | + lsc_config.size = LSC_TABLE_INIT_SIZE; | ||
1637 | + ispccdc_obj.lsc_enable = 1; | ||
1638 | + } | ||
1639 | + | ||
1640 | + return 0; | ||
1641 | +} | ||
1642 | + | ||
1643 | +/** | ||
1644 | + * isp_ccdc_cleanup - CCDC module cleanup. | ||
1645 | + **/ | ||
1646 | +void isp_ccdc_cleanup(void) | ||
1647 | +{ | ||
1648 | + if (is_isplsc_activated()) { | ||
1649 | + ispccdc_free_lsc(); | ||
1650 | + kfree(lsc_gain_table_tmp); | ||
1651 | + } | ||
1652 | + | ||
1653 | + if (fpc_table_add_m != 0) { | ||
1654 | + ispmmu_kunmap(fpc_table_add_m); | ||
1655 | + kfree(fpc_table_add); | ||
1656 | + } | ||
1657 | +} | ||
1658 | diff --git a/drivers/media/video/isp/ispccdc.h b/drivers/media/video/isp/ispccdc.h | ||
1659 | new file mode 100644 | ||
1660 | index 0000000..4ef40a6 | ||
1661 | --- /dev/null | ||
1662 | +++ b/drivers/media/video/isp/ispccdc.h | ||
1663 | @@ -0,0 +1,209 @@ | ||
1664 | +/* | ||
1665 | + * ispccdc.h | ||
1666 | + * | ||
1667 | + * Driver header file for CCDC module in TI's OMAP3 Camera ISP | ||
1668 | + * | ||
1669 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
1670 | + * | ||
1671 | + * Contributors: | ||
1672 | + * Senthilvadivu Guruswamy <svadivu@ti.com> | ||
1673 | + * Pallavi Kulkarni <p-kulkarni@ti.com> | ||
1674 | + * Sergio Aguirre <saaguirre@ti.com> | ||
1675 | + * | ||
1676 | + * This package is free software; you can redistribute it and/or modify | ||
1677 | + * it under the terms of the GNU General Public License version 2 as | ||
1678 | + * published by the Free Software Foundation. | ||
1679 | + * | ||
1680 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
1681 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
1682 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
1683 | + */ | ||
1684 | + | ||
1685 | +#ifndef OMAP_ISP_CCDC_H | ||
1686 | +#define OMAP_ISP_CCDC_H | ||
1687 | + | ||
1688 | +#include <mach/isp_user.h> | ||
1689 | + | ||
1690 | +#define is_isplsc_activated() 1 | ||
1691 | + | ||
1692 | +/* Enumeration constants for CCDC input output format */ | ||
1693 | +enum ccdc_input { | ||
1694 | + CCDC_RAW, | ||
1695 | + CCDC_YUV_SYNC, | ||
1696 | + CCDC_YUV_BT, | ||
1697 | + CCDC_OTHERS | ||
1698 | +}; | ||
1699 | + | ||
1700 | +enum ccdc_output { | ||
1701 | + CCDC_YUV_RSZ, | ||
1702 | + CCDC_YUV_MEM_RSZ, | ||
1703 | + CCDC_OTHERS_VP, | ||
1704 | + CCDC_OTHERS_MEM, | ||
1705 | + CCDC_OTHERS_VP_MEM | ||
1706 | +}; | ||
1707 | + | ||
1708 | +/* Enumeration constants for the sync interface parameters */ | ||
1709 | +enum inpmode { | ||
1710 | + RAW, | ||
1711 | + YUV16, | ||
1712 | + YUV8 | ||
1713 | +}; | ||
1714 | +enum datasize { | ||
1715 | + DAT8, | ||
1716 | + DAT10, | ||
1717 | + DAT11, | ||
1718 | + DAT12 | ||
1719 | +}; | ||
1720 | + | ||
1721 | + | ||
1722 | +/** | ||
1723 | + * struct ispccdc_syncif - Structure for Sync Interface between sensor and CCDC | ||
1724 | + * @ccdc_mastermode: Master mode. 1 - Master, 0 - Slave. | ||
1725 | + * @fldstat: Field state. 0 - Odd Field, 1 - Even Field. | ||
1726 | + * @ipmod: Input mode. | ||
1727 | + * @datsz: Data size. | ||
1728 | + * @fldmode: 0 - Progressive, 1 - Interlaced. | ||
1729 | + * @datapol: 0 - Positive, 1 - Negative. | ||
1730 | + * @fldpol: 0 - Positive, 1 - Negative. | ||
1731 | + * @hdpol: 0 - Positive, 1 - Negative. | ||
1732 | + * @vdpol: 0 - Positive, 1 - Negative. | ||
1733 | + * @fldout: 0 - Input, 1 - Output. | ||
1734 | + * @hs_width: Width of the Horizontal Sync pulse, used for HS/VS Output. | ||
1735 | + * @vs_width: Width of the Vertical Sync pulse, used for HS/VS Output. | ||
1736 | + * @ppln: Number of pixels per line, used for HS/VS Output. | ||
1737 | + * @hlprf: Number of half lines per frame, used for HS/VS Output. | ||
1738 | + * @bt_r656_en: 1 - Enable ITU-R BT656 mode, 0 - Sync mode. | ||
1739 | + */ | ||
1740 | +struct ispccdc_syncif { | ||
1741 | + u8 ccdc_mastermode; | ||
1742 | + u8 fldstat; | ||
1743 | + enum inpmode ipmod; | ||
1744 | + enum datasize datsz; | ||
1745 | + u8 fldmode; | ||
1746 | + u8 datapol; | ||
1747 | + u8 fldpol; | ||
1748 | + u8 hdpol; | ||
1749 | + u8 vdpol; | ||
1750 | + u8 fldout; | ||
1751 | + u8 hs_width; | ||
1752 | + u8 vs_width; | ||
1753 | + u8 ppln; | ||
1754 | + u8 hlprf; | ||
1755 | + u8 bt_r656_en; | ||
1756 | +}; | ||
1757 | + | ||
1758 | +/** | ||
1759 | + * ispccdc_refmt - Structure for Reformatter parameters | ||
1760 | + * @lnalt: Line alternating mode enable. 0 - Enable, 1 - Disable. | ||
1761 | + * @lnum: Number of output lines from 1 input line. 1 to 4 lines. | ||
1762 | + * @plen_even: Number of program entries in even line minus 1. | ||
1763 | + * @plen_odd: Number of program entries in odd line minus 1. | ||
1764 | + * @prgeven0: Program entries 0-7 for even lines register | ||
1765 | + * @prgeven1: Program entries 8-15 for even lines register | ||
1766 | + * @prgodd0: Program entries 0-7 for odd lines register | ||
1767 | + * @prgodd1: Program entries 8-15 for odd lines register | ||
1768 | + * @fmtaddr0: Output line in which the original pixel is to be placed | ||
1769 | + * @fmtaddr1: Output line in which the original pixel is to be placed | ||
1770 | + * @fmtaddr2: Output line in which the original pixel is to be placed | ||
1771 | + * @fmtaddr3: Output line in which the original pixel is to be placed | ||
1772 | + * @fmtaddr4: Output line in which the original pixel is to be placed | ||
1773 | + * @fmtaddr5: Output line in which the original pixel is to be placed | ||
1774 | + * @fmtaddr6: Output line in which the original pixel is to be placed | ||
1775 | + * @fmtaddr7: Output line in which the original pixel is to be placed | ||
1776 | + */ | ||
1777 | +struct ispccdc_refmt { | ||
1778 | + u8 lnalt; | ||
1779 | + u8 lnum; | ||
1780 | + u8 plen_even; | ||
1781 | + u8 plen_odd; | ||
1782 | + u32 prgeven0; | ||
1783 | + u32 prgeven1; | ||
1784 | + u32 prgodd0; | ||
1785 | + u32 prgodd1; | ||
1786 | + u32 fmtaddr0; | ||
1787 | + u32 fmtaddr1; | ||
1788 | + u32 fmtaddr2; | ||
1789 | + u32 fmtaddr3; | ||
1790 | + u32 fmtaddr4; | ||
1791 | + u32 fmtaddr5; | ||
1792 | + u32 fmtaddr6; | ||
1793 | + u32 fmtaddr7; | ||
1794 | +}; | ||
1795 | + | ||
1796 | +int ispccdc_request(void); | ||
1797 | + | ||
1798 | +int ispccdc_free(void); | ||
1799 | + | ||
1800 | +int ispccdc_config_datapath(enum ccdc_input input, enum ccdc_output output); | ||
1801 | + | ||
1802 | +void ispccdc_config_crop(u32 left, u32 top, u32 height, u32 width); | ||
1803 | + | ||
1804 | +void ispccdc_config_sync_if(struct ispccdc_syncif syncif); | ||
1805 | + | ||
1806 | +int ispccdc_config_black_clamp(struct ispccdc_bclamp bclamp); | ||
1807 | + | ||
1808 | +void ispccdc_enable_black_clamp(u8 enable); | ||
1809 | + | ||
1810 | +int ispccdc_config_fpc(struct ispccdc_fpc fpc); | ||
1811 | + | ||
1812 | +void ispccdc_enable_fpc(u8 enable); | ||
1813 | + | ||
1814 | +void ispccdc_config_black_comp(struct ispccdc_blcomp blcomp); | ||
1815 | + | ||
1816 | +void ispccdc_config_vp(struct ispccdc_vp vp); | ||
1817 | + | ||
1818 | +void ispccdc_enable_vp(u8 enable); | ||
1819 | + | ||
1820 | +void ispccdc_config_reformatter(struct ispccdc_refmt refmt); | ||
1821 | + | ||
1822 | +void ispccdc_enable_reformatter(u8 enable); | ||
1823 | + | ||
1824 | +void ispccdc_config_culling(struct ispccdc_culling culling); | ||
1825 | + | ||
1826 | +void ispccdc_enable_lpf(u8 enable); | ||
1827 | + | ||
1828 | +void ispccdc_config_alaw(enum alaw_ipwidth ipwidth); | ||
1829 | + | ||
1830 | +void ispccdc_enable_alaw(u8 enable); | ||
1831 | + | ||
1832 | +int ispccdc_load_lsc(u8 *table_addr, u32 table_size); | ||
1833 | + | ||
1834 | +void ispccdc_config_lsc(struct ispccdc_lsc_config *lsc_cfg); | ||
1835 | + | ||
1836 | +void ispccdc_enable_lsc(u8 enable); | ||
1837 | + | ||
1838 | +void ispccdc_lsc_error_handler(void); | ||
1839 | + | ||
1840 | +void ispccdc_config_imgattr(u32 colptn); | ||
1841 | + | ||
1842 | +void ispccdc_config_shadow_registers(void); | ||
1843 | + | ||
1844 | +int ispccdc_try_size(u32 input_w, u32 input_h, u32 *output_w, u32 *output_h); | ||
1845 | + | ||
1846 | +int ispccdc_config_size(u32 input_w, u32 input_h, u32 output_w, u32 output_h); | ||
1847 | + | ||
1848 | +int ispccdc_config_outlineoffset(u32 offset, u8 oddeven, u8 numlines); | ||
1849 | + | ||
1850 | +int ispccdc_set_outaddr(u32 addr); | ||
1851 | + | ||
1852 | +void ispccdc_enable(u8 enable); | ||
1853 | + | ||
1854 | +void ispccdc_suspend(void); | ||
1855 | + | ||
1856 | +void ispccdc_resume(void); | ||
1857 | + | ||
1858 | +int ispccdc_sbl_busy(void); | ||
1859 | + | ||
1860 | +int ispccdc_busy(void); | ||
1861 | + | ||
1862 | +void ispccdc_save_context(void); | ||
1863 | + | ||
1864 | +void ispccdc_restore_context(void); | ||
1865 | + | ||
1866 | +void ispccdc_print_status(void); | ||
1867 | + | ||
1868 | +int omap34xx_isp_ccdc_config(void *userspace_add); | ||
1869 | + | ||
1870 | +void ispccdc_set_wenlog(u32 wenlog); | ||
1871 | + | ||
1872 | +#endif /* OMAP_ISP_CCDC_H */ | ||
1873 | -- | ||
1874 | 1.5.6.5 | ||
1875 | |||
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0005-omap3isp-Add-ISP-backend-PRV-and-RSZ.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0005-omap3isp-Add-ISP-backend-PRV-and-RSZ.patch new file mode 100644 index 0000000000..c549eadc88 --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0005-omap3isp-Add-ISP-backend-PRV-and-RSZ.patch | |||
@@ -0,0 +1,3413 @@ | |||
1 | From 926b51afea146826c8076e5fb305eaa0332399b4 Mon Sep 17 00:00:00 2001 | ||
2 | From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
3 | Date: Tue, 10 Mar 2009 10:49:02 +0200 | ||
4 | Subject: [PATCH] omap3isp: Add ISP backend (PRV and RSZ) | ||
5 | |||
6 | Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
7 | --- | ||
8 | drivers/media/video/isp/isppreview.c | 1929 ++++++++++++++++++++++++++++++++++ | ||
9 | drivers/media/video/isp/isppreview.h | 354 +++++++ | ||
10 | drivers/media/video/isp/ispresizer.c | 928 ++++++++++++++++ | ||
11 | drivers/media/video/isp/ispresizer.h | 158 +++ | ||
12 | 4 files changed, 3369 insertions(+), 0 deletions(-) | ||
13 | create mode 100644 drivers/media/video/isp/isppreview.c | ||
14 | create mode 100644 drivers/media/video/isp/isppreview.h | ||
15 | create mode 100644 drivers/media/video/isp/ispresizer.c | ||
16 | create mode 100644 drivers/media/video/isp/ispresizer.h | ||
17 | |||
18 | diff --git a/drivers/media/video/isp/isppreview.c b/drivers/media/video/isp/isppreview.c | ||
19 | new file mode 100644 | ||
20 | index 0000000..17f1abc | ||
21 | --- /dev/null | ||
22 | +++ b/drivers/media/video/isp/isppreview.c | ||
23 | @@ -0,0 +1,1929 @@ | ||
24 | +/* | ||
25 | + * isppreview.c | ||
26 | + * | ||
27 | + * Driver Library for Preview module in TI's OMAP3 Camera ISP | ||
28 | + * | ||
29 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
30 | + * | ||
31 | + * Contributors: | ||
32 | + * Senthilvadivu Guruswamy <svadivu@ti.com> | ||
33 | + * Pallavi Kulkarni <p-kulkarni@ti.com> | ||
34 | + * Sergio Aguirre <saaguirre@ti.com> | ||
35 | + * | ||
36 | + * This package is free software; you can redistribute it and/or modify | ||
37 | + * it under the terms of the GNU General Public License version 2 as | ||
38 | + * published by the Free Software Foundation. | ||
39 | + * | ||
40 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
41 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
42 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
43 | + */ | ||
44 | + | ||
45 | +#include <linux/mutex.h> | ||
46 | +#include <linux/module.h> | ||
47 | +#include <linux/uaccess.h> | ||
48 | + | ||
49 | +#include "isp.h" | ||
50 | +#include "ispreg.h" | ||
51 | +#include "isppreview.h" | ||
52 | + | ||
53 | +static struct ispprev_nf prev_nf_t; | ||
54 | +static struct prev_params *params; | ||
55 | +static int rg_update, gg_update, bg_update, nf_enable, nf_update; | ||
56 | + | ||
57 | +/* Structure for saving/restoring preview module registers */ | ||
58 | +static struct isp_reg ispprev_reg_list[] = { | ||
59 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO, 0x0000}, | ||
60 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_VERT_INFO, 0x0000}, | ||
61 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_RSDR_ADDR, 0x0000}, | ||
62 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_RADR_OFFSET, 0x0000}, | ||
63 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_DSDR_ADDR, 0x0000}, | ||
64 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_DRKF_OFFSET, 0x0000}, | ||
65 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_WSDR_ADDR, 0x0000}, | ||
66 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_WADD_OFFSET, 0x0000}, | ||
67 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE, 0x0000}, | ||
68 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_HMED, 0x0000}, | ||
69 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_NF, 0x0000}, | ||
70 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_WB_DGAIN, 0x0000}, | ||
71 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_WBGAIN, 0x0000}, | ||
72 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_WBSEL, 0x0000}, | ||
73 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_CFA, 0x0000}, | ||
74 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_BLKADJOFF, 0x0000}, | ||
75 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT1, 0x0000}, | ||
76 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT2, 0x0000}, | ||
77 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT3, 0x0000}, | ||
78 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT4, 0x0000}, | ||
79 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT5, 0x0000}, | ||
80 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF1, 0x0000}, | ||
81 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF2, 0x0000}, | ||
82 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC0, 0x0000}, | ||
83 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC1, 0x0000}, | ||
84 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC2, 0x0000}, | ||
85 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC_OFFSET, 0x0000}, | ||
86 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT, 0x0000}, | ||
87 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_CSUP, 0x0000}, | ||
88 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC, 0x0000}, | ||
89 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR0, 0x0000}, | ||
90 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR1, 0x0000}, | ||
91 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR2, 0x0000}, | ||
92 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR3, 0x0000}, | ||
93 | + {OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, 0x0000}, | ||
94 | + {0, ISP_TOK_TERM, 0x0000} | ||
95 | +}; | ||
96 | + | ||
97 | + | ||
98 | +/* Default values in Office Flourescent Light for RGBtoRGB Blending */ | ||
99 | +static struct ispprev_rgbtorgb flr_rgb2rgb = { | ||
100 | + { /* RGB-RGB Matrix */ | ||
101 | + {0x01E2, 0x0F30, 0x0FEE}, | ||
102 | + {0x0F9B, 0x01AC, 0x0FB9}, | ||
103 | + {0x0FE0, 0x0EC0, 0x0260} | ||
104 | + }, /* RGB Offset */ | ||
105 | + {0x0000, 0x0000, 0x0000} | ||
106 | +}; | ||
107 | + | ||
108 | +/* Default values in Office Flourescent Light for RGB to YUV Conversion*/ | ||
109 | +static struct ispprev_csc flr_prev_csc[] = { | ||
110 | + { | ||
111 | + { /* CSC Coef Matrix */ | ||
112 | + {66, 129, 25}, | ||
113 | + {-38, -75, 112}, | ||
114 | + {112, -94 , -18} | ||
115 | + }, /* CSC Offset */ | ||
116 | + {0x0, 0x0, 0x0} | ||
117 | + }, | ||
118 | + { | ||
119 | + { /* CSC Coef Matrix BW */ | ||
120 | + {66, 129, 25}, | ||
121 | + {0, 0, 0}, | ||
122 | + {0, 0, 0} | ||
123 | + }, /* CSC Offset */ | ||
124 | + {0x0, 0x0, 0x0} | ||
125 | + }, | ||
126 | + { | ||
127 | + { /* CSC Coef Matrix Sepia */ | ||
128 | + {19, 38, 7}, | ||
129 | + {0, 0, 0}, | ||
130 | + {0, 0, 0} | ||
131 | + }, /* CSC Offset */ | ||
132 | + {0x0, 0xE7, 0x14} | ||
133 | + } | ||
134 | +}; | ||
135 | + | ||
136 | + | ||
137 | +/* Default values in Office Flourescent Light for CFA Gradient*/ | ||
138 | +#define FLR_CFA_GRADTHRS_HORZ 0x28 | ||
139 | +#define FLR_CFA_GRADTHRS_VERT 0x28 | ||
140 | + | ||
141 | +/* Default values in Office Flourescent Light for Chroma Suppression*/ | ||
142 | +#define FLR_CSUP_GAIN 0x0D | ||
143 | +#define FLR_CSUP_THRES 0xEB | ||
144 | + | ||
145 | +/* Default values in Office Flourescent Light for Noise Filter*/ | ||
146 | +#define FLR_NF_STRGTH 0x03 | ||
147 | + | ||
148 | +/* Default values in Office Flourescent Light for White Balance*/ | ||
149 | +#define FLR_WBAL_DGAIN 0x100 | ||
150 | +#define FLR_WBAL_COEF0 0x20 | ||
151 | +#define FLR_WBAL_COEF1 0x29 | ||
152 | +#define FLR_WBAL_COEF2 0x2d | ||
153 | +#define FLR_WBAL_COEF3 0x20 | ||
154 | + | ||
155 | +#define FLR_WBAL_COEF0_ES1 0x20 | ||
156 | +#define FLR_WBAL_COEF1_ES1 0x23 | ||
157 | +#define FLR_WBAL_COEF2_ES1 0x39 | ||
158 | +#define FLR_WBAL_COEF3_ES1 0x20 | ||
159 | + | ||
160 | +/* Default values in Office Flourescent Light for Black Adjustment*/ | ||
161 | +#define FLR_BLKADJ_BLUE 0x0 | ||
162 | +#define FLR_BLKADJ_GREEN 0x0 | ||
163 | +#define FLR_BLKADJ_RED 0x0 | ||
164 | + | ||
165 | +static int update_color_matrix; | ||
166 | + | ||
167 | +/** | ||
168 | + * struct isp_prev - Structure for storing ISP Preview module information | ||
169 | + * @prev_inuse: Flag to determine if CCDC has been reserved or not (0 or 1). | ||
170 | + * @prevout_w: Preview output width. | ||
171 | + * @prevout_h: Preview output height. | ||
172 | + * @previn_w: Preview input width. | ||
173 | + * @previn_h: Preview input height. | ||
174 | + * @prev_inpfmt: Preview input format. | ||
175 | + * @prev_outfmt: Preview output format. | ||
176 | + * @hmed_en: Horizontal median filter enable. | ||
177 | + * @nf_en: Noise filter enable. | ||
178 | + * @dcor_en: Defect correction enable. | ||
179 | + * @cfa_en: Color Filter Array (CFA) interpolation enable. | ||
180 | + * @csup_en: Chrominance suppression enable. | ||
181 | + * @yenh_en: Luma enhancement enable. | ||
182 | + * @fmtavg: Number of horizontal pixels to average in input formatter. The | ||
183 | + * input width should be a multiple of this number. | ||
184 | + * @brightness: Brightness in preview module. | ||
185 | + * @contrast: Contrast in preview module. | ||
186 | + * @color: Color effect in preview module. | ||
187 | + * @cfafmt: Color Filter Array (CFA) Format. | ||
188 | + * @ispprev_mutex: Mutex for isp preview. | ||
189 | + * | ||
190 | + * This structure is used to store the OMAP ISP Preview module Information. | ||
191 | + */ | ||
192 | +static struct isp_prev { | ||
193 | + int pm_state; | ||
194 | + u8 prev_inuse; | ||
195 | + u32 prevout_w; | ||
196 | + u32 prevout_h; | ||
197 | + u32 previn_w; | ||
198 | + u32 previn_h; | ||
199 | + enum preview_input prev_inpfmt; | ||
200 | + enum preview_output prev_outfmt; | ||
201 | + u8 hmed_en; | ||
202 | + u8 nf_en; | ||
203 | + u8 dcor_en; | ||
204 | + u8 cfa_en; | ||
205 | + u8 csup_en; | ||
206 | + u8 yenh_en; | ||
207 | + u8 fmtavg; | ||
208 | + u8 brightness; | ||
209 | + u8 contrast; | ||
210 | + enum v4l2_colorfx color; | ||
211 | + enum cfa_fmt cfafmt; | ||
212 | + struct mutex ispprev_mutex; /* For checking/modifying prev_inuse */ | ||
213 | + u32 sph; | ||
214 | + u32 slv; | ||
215 | +} ispprev_obj; | ||
216 | + | ||
217 | +/* Saved parameters */ | ||
218 | +static struct prev_params *prev_config_params; | ||
219 | + | ||
220 | +/* | ||
221 | + * Coeficient Tables for the submodules in Preview. | ||
222 | + * Array is initialised with the values from.the tables text file. | ||
223 | + */ | ||
224 | + | ||
225 | +/* | ||
226 | + * CFA Filter Coefficient Table | ||
227 | + * | ||
228 | + */ | ||
229 | +static u32 cfa_coef_table[] = { | ||
230 | +#include "cfa_coef_table.h" | ||
231 | +}; | ||
232 | + | ||
233 | +/* | ||
234 | + * Gamma Correction Table - Red | ||
235 | + */ | ||
236 | +static u32 redgamma_table[] = { | ||
237 | +#include "redgamma_table.h" | ||
238 | +}; | ||
239 | + | ||
240 | +/* | ||
241 | + * Gamma Correction Table - Green | ||
242 | + */ | ||
243 | +static u32 greengamma_table[] = { | ||
244 | +#include "greengamma_table.h" | ||
245 | +}; | ||
246 | + | ||
247 | +/* | ||
248 | + * Gamma Correction Table - Blue | ||
249 | + */ | ||
250 | +static u32 bluegamma_table[] = { | ||
251 | +#include "bluegamma_table.h" | ||
252 | +}; | ||
253 | + | ||
254 | +/* | ||
255 | + * Noise Filter Threshold table | ||
256 | + */ | ||
257 | +static u32 noise_filter_table[] = { | ||
258 | +#include "noise_filter_table.h" | ||
259 | +}; | ||
260 | + | ||
261 | +/* | ||
262 | + * Luminance Enhancement Table | ||
263 | + */ | ||
264 | +static u32 luma_enhance_table[] = { | ||
265 | +#include "luma_enhance_table.h" | ||
266 | +}; | ||
267 | + | ||
268 | +/** | ||
269 | + * omap34xx_isp_preview_config - Abstraction layer Preview configuration. | ||
270 | + * @userspace_add: Pointer from Userspace to structure with flags and data to | ||
271 | + * update. | ||
272 | + **/ | ||
273 | +int omap34xx_isp_preview_config(void *userspace_add) | ||
274 | +{ | ||
275 | + struct ispprev_hmed prev_hmed_t; | ||
276 | + struct ispprev_cfa prev_cfa_t; | ||
277 | + struct ispprev_csup csup_t; | ||
278 | + struct ispprev_wbal prev_wbal_t; | ||
279 | + struct ispprev_blkadj prev_blkadj_t; | ||
280 | + struct ispprev_rgbtorgb rgb2rgb_t; | ||
281 | + struct ispprev_csc prev_csc_t; | ||
282 | + struct ispprev_yclimit yclimit_t; | ||
283 | + struct ispprev_dcor prev_dcor_t; | ||
284 | + struct ispprv_update_config *preview_struct; | ||
285 | + struct isptables_update isp_table_update; | ||
286 | + int yen_t[ISPPRV_YENH_TBL_SIZE]; | ||
287 | + | ||
288 | + if (userspace_add == NULL) | ||
289 | + return -EINVAL; | ||
290 | + | ||
291 | + preview_struct = userspace_add; | ||
292 | + | ||
293 | + if (ISP_ABS_PREV_LUMAENH & preview_struct->flag) { | ||
294 | + if (ISP_ABS_PREV_LUMAENH & preview_struct->update) { | ||
295 | + if (copy_from_user(yen_t, preview_struct->yen, | ||
296 | + sizeof(yen_t))) | ||
297 | + goto err_copy_from_user; | ||
298 | + isppreview_config_luma_enhancement(yen_t); | ||
299 | + } | ||
300 | + params->features |= PREV_LUMA_ENHANCE; | ||
301 | + } else if (ISP_ABS_PREV_LUMAENH & preview_struct->update) | ||
302 | + params->features &= ~PREV_LUMA_ENHANCE; | ||
303 | + | ||
304 | + if (ISP_ABS_PREV_INVALAW & preview_struct->flag) { | ||
305 | + isppreview_enable_invalaw(1); | ||
306 | + params->features |= PREV_INVERSE_ALAW; | ||
307 | + } else { | ||
308 | + isppreview_enable_invalaw(0); | ||
309 | + params->features &= ~PREV_INVERSE_ALAW; | ||
310 | + } | ||
311 | + | ||
312 | + if (ISP_ABS_PREV_HRZ_MED & preview_struct->flag) { | ||
313 | + if (ISP_ABS_PREV_HRZ_MED & preview_struct->update) { | ||
314 | + if (copy_from_user(&prev_hmed_t, | ||
315 | + (struct ispprev_hmed *) | ||
316 | + preview_struct->prev_hmed, | ||
317 | + sizeof(struct ispprev_hmed))) | ||
318 | + goto err_copy_from_user; | ||
319 | + isppreview_config_hmed(prev_hmed_t); | ||
320 | + } | ||
321 | + isppreview_enable_hmed(1); | ||
322 | + params->features |= PREV_HORZ_MEDIAN_FILTER; | ||
323 | + } else if (ISP_ABS_PREV_HRZ_MED & preview_struct->update) { | ||
324 | + isppreview_enable_hmed(0); | ||
325 | + params->features &= ~PREV_HORZ_MEDIAN_FILTER; | ||
326 | + } | ||
327 | + | ||
328 | + if (ISP_ABS_PREV_CFA & preview_struct->flag) { | ||
329 | + if (ISP_ABS_PREV_CFA & preview_struct->update) { | ||
330 | + if (copy_from_user(&prev_cfa_t, | ||
331 | + (struct ispprev_cfa *) | ||
332 | + preview_struct->prev_cfa, | ||
333 | + sizeof(struct ispprev_cfa))) | ||
334 | + goto err_copy_from_user; | ||
335 | + | ||
336 | + isppreview_config_cfa(prev_cfa_t); | ||
337 | + } | ||
338 | + isppreview_enable_cfa(1); | ||
339 | + params->features |= PREV_CFA; | ||
340 | + } else if (ISP_ABS_PREV_CFA & preview_struct->update) { | ||
341 | + isppreview_enable_cfa(0); | ||
342 | + params->features &= ~PREV_CFA; | ||
343 | + } | ||
344 | + | ||
345 | + if (ISP_ABS_PREV_CHROMA_SUPP & preview_struct->flag) { | ||
346 | + if (ISP_ABS_PREV_CHROMA_SUPP & preview_struct->update) { | ||
347 | + if (copy_from_user(&csup_t, | ||
348 | + (struct ispprev_csup *) | ||
349 | + preview_struct->csup, | ||
350 | + sizeof(struct ispprev_csup))) | ||
351 | + goto err_copy_from_user; | ||
352 | + isppreview_config_chroma_suppression(csup_t); | ||
353 | + } | ||
354 | + isppreview_enable_chroma_suppression(1); | ||
355 | + params->features |= PREV_CHROMA_SUPPRESS; | ||
356 | + } else if (ISP_ABS_PREV_CHROMA_SUPP & preview_struct->update) { | ||
357 | + isppreview_enable_chroma_suppression(0); | ||
358 | + params->features &= ~PREV_CHROMA_SUPPRESS; | ||
359 | + } | ||
360 | + | ||
361 | + if (ISP_ABS_PREV_WB & preview_struct->update) { | ||
362 | + if (copy_from_user(&prev_wbal_t, (struct ispprev_wbal *) | ||
363 | + preview_struct->prev_wbal, | ||
364 | + sizeof(struct ispprev_wbal))) | ||
365 | + goto err_copy_from_user; | ||
366 | + isppreview_config_whitebalance(prev_wbal_t); | ||
367 | + } | ||
368 | + | ||
369 | + if (ISP_ABS_PREV_BLKADJ & preview_struct->update) { | ||
370 | + if (copy_from_user(&prev_blkadj_t, (struct ispprev_blkadjl *) | ||
371 | + preview_struct->prev_blkadj, | ||
372 | + sizeof(struct ispprev_blkadj))) | ||
373 | + goto err_copy_from_user; | ||
374 | + isppreview_config_blkadj(prev_blkadj_t); | ||
375 | + } | ||
376 | + | ||
377 | + if (ISP_ABS_PREV_RGB2RGB & preview_struct->update) { | ||
378 | + if (copy_from_user(&rgb2rgb_t, (struct ispprev_rgbtorgb *) | ||
379 | + preview_struct->rgb2rgb, | ||
380 | + sizeof(struct ispprev_rgbtorgb))) | ||
381 | + goto err_copy_from_user; | ||
382 | + isppreview_config_rgb_blending(rgb2rgb_t); | ||
383 | + } | ||
384 | + | ||
385 | + if (ISP_ABS_PREV_COLOR_CONV & preview_struct->update) { | ||
386 | + if (copy_from_user(&prev_csc_t, (struct ispprev_csc *) | ||
387 | + preview_struct->prev_csc, | ||
388 | + sizeof(struct ispprev_csc))) | ||
389 | + goto err_copy_from_user; | ||
390 | + isppreview_config_rgb_to_ycbcr(prev_csc_t); | ||
391 | + } | ||
392 | + | ||
393 | + if (ISP_ABS_PREV_YC_LIMIT & preview_struct->update) { | ||
394 | + if (copy_from_user(&yclimit_t, (struct ispprev_yclimit *) | ||
395 | + preview_struct->yclimit, | ||
396 | + sizeof(struct ispprev_yclimit))) | ||
397 | + goto err_copy_from_user; | ||
398 | + isppreview_config_yc_range(yclimit_t); | ||
399 | + } | ||
400 | + | ||
401 | + if (ISP_ABS_PREV_DEFECT_COR & preview_struct->flag) { | ||
402 | + if (ISP_ABS_PREV_DEFECT_COR & preview_struct->update) { | ||
403 | + if (copy_from_user(&prev_dcor_t, | ||
404 | + (struct ispprev_dcor *) | ||
405 | + preview_struct->prev_dcor, | ||
406 | + sizeof(struct ispprev_dcor))) | ||
407 | + goto err_copy_from_user; | ||
408 | + isppreview_config_dcor(prev_dcor_t); | ||
409 | + } | ||
410 | + isppreview_enable_dcor(1); | ||
411 | + params->features |= PREV_DEFECT_COR; | ||
412 | + } else if (ISP_ABS_PREV_DEFECT_COR & preview_struct->update) { | ||
413 | + isppreview_enable_dcor(0); | ||
414 | + params->features &= ~PREV_DEFECT_COR; | ||
415 | + } | ||
416 | + | ||
417 | + if (ISP_ABS_PREV_GAMMABYPASS & preview_struct->flag) { | ||
418 | + isppreview_enable_gammabypass(1); | ||
419 | + params->features |= PREV_GAMMA_BYPASS; | ||
420 | + } else { | ||
421 | + isppreview_enable_gammabypass(0); | ||
422 | + params->features &= ~PREV_GAMMA_BYPASS; | ||
423 | + } | ||
424 | + | ||
425 | + isp_table_update.update = preview_struct->update; | ||
426 | + isp_table_update.flag = preview_struct->flag; | ||
427 | + isp_table_update.prev_nf = preview_struct->prev_nf; | ||
428 | + isp_table_update.red_gamma = preview_struct->red_gamma; | ||
429 | + isp_table_update.green_gamma = preview_struct->green_gamma; | ||
430 | + isp_table_update.blue_gamma = preview_struct->blue_gamma; | ||
431 | + | ||
432 | + if (omap34xx_isp_tables_update(&isp_table_update)) | ||
433 | + goto err_copy_from_user; | ||
434 | + | ||
435 | + return 0; | ||
436 | + | ||
437 | +err_copy_from_user: | ||
438 | + printk(KERN_ERR "Preview Config: Copy From User Error\n"); | ||
439 | + return -EFAULT; | ||
440 | +} | ||
441 | +EXPORT_SYMBOL_GPL(omap34xx_isp_preview_config); | ||
442 | + | ||
443 | +/** | ||
444 | + * omap34xx_isp_tables_update - Abstraction layer Tables update. | ||
445 | + * @isptables_struct: Pointer from Userspace to structure with flags and table | ||
446 | + * data to update. | ||
447 | + **/ | ||
448 | +int omap34xx_isp_tables_update(struct isptables_update *isptables_struct) | ||
449 | +{ | ||
450 | + | ||
451 | + if (ISP_ABS_TBL_NF & isptables_struct->flag) { | ||
452 | + nf_enable = 1; | ||
453 | + params->features |= PREV_NOISE_FILTER; | ||
454 | + if (ISP_ABS_TBL_NF & isptables_struct->update) { | ||
455 | + if (copy_from_user(&prev_nf_t, (struct ispprev_nf *) | ||
456 | + isptables_struct->prev_nf, | ||
457 | + sizeof(struct ispprev_nf))) | ||
458 | + goto err_copy_from_user; | ||
459 | + | ||
460 | + nf_update = 1; | ||
461 | + } else | ||
462 | + nf_update = 0; | ||
463 | + } else { | ||
464 | + nf_enable = 0; | ||
465 | + params->features &= ~PREV_NOISE_FILTER; | ||
466 | + if (ISP_ABS_TBL_NF & isptables_struct->update) | ||
467 | + nf_update = 1; | ||
468 | + else | ||
469 | + nf_update = 0; | ||
470 | + } | ||
471 | + | ||
472 | + if (ISP_ABS_TBL_REDGAMMA & isptables_struct->update) { | ||
473 | + if (copy_from_user(redgamma_table, isptables_struct->red_gamma, | ||
474 | + sizeof(redgamma_table))) { | ||
475 | + goto err_copy_from_user; | ||
476 | + } | ||
477 | + rg_update = 1; | ||
478 | + } else | ||
479 | + rg_update = 0; | ||
480 | + | ||
481 | + if (ISP_ABS_TBL_GREENGAMMA & isptables_struct->update) { | ||
482 | + if (copy_from_user(greengamma_table, | ||
483 | + isptables_struct->green_gamma, | ||
484 | + sizeof(greengamma_table))) | ||
485 | + goto err_copy_from_user; | ||
486 | + gg_update = 1; | ||
487 | + } else | ||
488 | + gg_update = 0; | ||
489 | + | ||
490 | + if (ISP_ABS_TBL_BLUEGAMMA & isptables_struct->update) { | ||
491 | + if (copy_from_user(bluegamma_table, | ||
492 | + isptables_struct->blue_gamma, | ||
493 | + sizeof(bluegamma_table))) { | ||
494 | + goto err_copy_from_user; | ||
495 | + } | ||
496 | + bg_update = 1; | ||
497 | + } else | ||
498 | + bg_update = 0; | ||
499 | + | ||
500 | + return 0; | ||
501 | + | ||
502 | +err_copy_from_user: | ||
503 | + printk(KERN_ERR "Preview Tables:Copy From User Error\n"); | ||
504 | + return -EFAULT; | ||
505 | +} | ||
506 | + | ||
507 | +/** | ||
508 | + * isppreview_config_shadow_registers - Program shadow registers for preview. | ||
509 | + * | ||
510 | + * Allows user to program shadow registers associated with preview module. | ||
511 | + **/ | ||
512 | +void isppreview_config_shadow_registers() | ||
513 | +{ | ||
514 | + u8 current_brightness_contrast; | ||
515 | + int ctr, prv_disabled; | ||
516 | + | ||
517 | + isppreview_query_brightness(¤t_brightness_contrast); | ||
518 | + if (current_brightness_contrast != | ||
519 | + (ispprev_obj.brightness * ISPPRV_BRIGHT_UNITS)) { | ||
520 | + DPRINTK_ISPPREV(" Changing Brightness level to %d\n", | ||
521 | + ispprev_obj.brightness); | ||
522 | + isppreview_config_brightness(ispprev_obj.brightness * | ||
523 | + ISPPRV_BRIGHT_UNITS); | ||
524 | + } | ||
525 | + | ||
526 | + isppreview_query_contrast(¤t_brightness_contrast); | ||
527 | + if (current_brightness_contrast != | ||
528 | + (ispprev_obj.contrast * ISPPRV_CONTRAST_UNITS)) { | ||
529 | + DPRINTK_ISPPREV(" Changing Contrast level to %d\n", | ||
530 | + ispprev_obj.contrast); | ||
531 | + isppreview_config_contrast(ispprev_obj.contrast * | ||
532 | + ISPPRV_CONTRAST_UNITS); | ||
533 | + } | ||
534 | + if (update_color_matrix) { | ||
535 | + isppreview_config_rgb_to_ycbcr(flr_prev_csc[ispprev_obj.color]); | ||
536 | + update_color_matrix = 0; | ||
537 | + } | ||
538 | + if (gg_update || rg_update || bg_update || nf_update) { | ||
539 | + isppreview_enable(0); | ||
540 | + prv_disabled = 1; | ||
541 | + } | ||
542 | + | ||
543 | + if (gg_update) { | ||
544 | + isp_reg_writel(ISPPRV_TBL_ADDR_GREEN_G_START, | ||
545 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR); | ||
546 | + | ||
547 | + for (ctr = 0; ctr < ISP_GAMMA_TABLE_SIZE; ctr++) { | ||
548 | + isp_reg_writel(greengamma_table[ctr], | ||
549 | + OMAP3_ISP_IOMEM_PREV, | ||
550 | + ISPPRV_SET_TBL_DATA); | ||
551 | + } | ||
552 | + gg_update = 0; | ||
553 | + } | ||
554 | + | ||
555 | + if (rg_update) { | ||
556 | + isp_reg_writel(ISPPRV_TBL_ADDR_RED_G_START, | ||
557 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR); | ||
558 | + | ||
559 | + for (ctr = 0; ctr < ISP_GAMMA_TABLE_SIZE; ctr++) { | ||
560 | + isp_reg_writel(redgamma_table[ctr], | ||
561 | + OMAP3_ISP_IOMEM_PREV, | ||
562 | + ISPPRV_SET_TBL_DATA); | ||
563 | + } | ||
564 | + rg_update = 0; | ||
565 | + } | ||
566 | + | ||
567 | + if (bg_update) { | ||
568 | + isp_reg_writel(ISPPRV_TBL_ADDR_BLUE_G_START, | ||
569 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR); | ||
570 | + | ||
571 | + for (ctr = 0; ctr < ISP_GAMMA_TABLE_SIZE; ctr++) { | ||
572 | + isp_reg_writel(bluegamma_table[ctr], | ||
573 | + OMAP3_ISP_IOMEM_PREV, | ||
574 | + ISPPRV_SET_TBL_DATA); | ||
575 | + } | ||
576 | + bg_update = 0; | ||
577 | + } | ||
578 | + | ||
579 | + if (nf_update && nf_enable) { | ||
580 | + isp_reg_writel(0xC00, | ||
581 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR); | ||
582 | + isp_reg_writel(prev_nf_t.spread, | ||
583 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_NF); | ||
584 | + for (ctr = 0; ctr < ISPPRV_NF_TBL_SIZE; ctr++) { | ||
585 | + isp_reg_writel(prev_nf_t.table[ctr], | ||
586 | + OMAP3_ISP_IOMEM_PREV, | ||
587 | + ISPPRV_SET_TBL_DATA); | ||
588 | + } | ||
589 | + isppreview_enable_noisefilter(1); | ||
590 | + nf_update = 0; | ||
591 | + } | ||
592 | + | ||
593 | + if (~nf_update && nf_enable) | ||
594 | + isppreview_enable_noisefilter(1); | ||
595 | + | ||
596 | + if (nf_update && ~nf_enable) | ||
597 | + isppreview_enable_noisefilter(0); | ||
598 | + | ||
599 | + if (prv_disabled) { | ||
600 | + isppreview_enable(1); | ||
601 | + prv_disabled = 0; | ||
602 | + } | ||
603 | +} | ||
604 | +EXPORT_SYMBOL_GPL(isppreview_config_shadow_registers); | ||
605 | + | ||
606 | +/** | ||
607 | + * isppreview_request - Reserves the preview module. | ||
608 | + * | ||
609 | + * Returns 0 if successful, or -EBUSY if the module was already reserved. | ||
610 | + **/ | ||
611 | +int isppreview_request() | ||
612 | +{ | ||
613 | + mutex_lock(&ispprev_obj.ispprev_mutex); | ||
614 | + if (ispprev_obj.prev_inuse) { | ||
615 | + mutex_unlock(&ispprev_obj.ispprev_mutex); | ||
616 | + printk(KERN_ERR "ISP_ERR : Preview Module Busy\n"); | ||
617 | + return -EBUSY; | ||
618 | + } | ||
619 | + ispprev_obj.prev_inuse = 1; | ||
620 | + mutex_unlock(&ispprev_obj.ispprev_mutex); | ||
621 | + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, ISPCTRL_PREV_RAM_EN | | ||
622 | + ISPCTRL_PREV_CLK_EN | | ||
623 | + ISPCTRL_SBL_WR1_RAM_EN); | ||
624 | + return 0; | ||
625 | +} | ||
626 | +EXPORT_SYMBOL_GPL(isppreview_request); | ||
627 | + | ||
628 | +/** | ||
629 | + * isppreview_free - Frees the preview module. | ||
630 | + * | ||
631 | + * Returns 0 if successful, or -EINVAL if the module was already freed. | ||
632 | + **/ | ||
633 | +int isppreview_free() | ||
634 | +{ | ||
635 | + mutex_lock(&ispprev_obj.ispprev_mutex); | ||
636 | + if (ispprev_obj.prev_inuse) { | ||
637 | + ispprev_obj.prev_inuse = 0; | ||
638 | + mutex_unlock(&ispprev_obj.ispprev_mutex); | ||
639 | + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, | ||
640 | + ~(ISPCTRL_PREV_CLK_EN | | ||
641 | + ISPCTRL_PREV_RAM_EN | | ||
642 | + ISPCTRL_SBL_WR1_RAM_EN)); | ||
643 | + return 0; | ||
644 | + } else { | ||
645 | + mutex_unlock(&ispprev_obj.ispprev_mutex); | ||
646 | + DPRINTK_ISPPREV("ISP_ERR : Preview Module already freed\n"); | ||
647 | + return -EINVAL; | ||
648 | + } | ||
649 | + | ||
650 | +} | ||
651 | +EXPORT_SYMBOL_GPL(isppreview_free); | ||
652 | + | ||
653 | +/** isppreview_config_datapath - Specifies input and output modules for Preview | ||
654 | + * @input: Indicates the module that gives the image to preview. | ||
655 | + * @output: Indicates the module to which the preview outputs to. | ||
656 | + * | ||
657 | + * Configures the default configuration for the CCDC to work with. | ||
658 | + * | ||
659 | + * The valid values for the input are PRV_RAW_CCDC (0), PRV_RAW_MEM (1), | ||
660 | + * PRV_RGBBAYERCFA (2), PRV_COMPCFA (3), PRV_CCDC_DRKF (4), PRV_OTHERS (5). | ||
661 | + * | ||
662 | + * The valid values for the output are PREVIEW_RSZ (0), PREVIEW_MEM (1). | ||
663 | + * | ||
664 | + * Returns 0 if successful, or -EINVAL if wrong input or output values are | ||
665 | + * specified. | ||
666 | + **/ | ||
667 | +int isppreview_config_datapath(enum preview_input input, | ||
668 | + enum preview_output output) | ||
669 | +{ | ||
670 | + u32 pcr = 0; | ||
671 | + u8 enable = 0; | ||
672 | + struct prev_params *params = prev_config_params; | ||
673 | + struct ispprev_yclimit yclimit; | ||
674 | + | ||
675 | + pcr = isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR); | ||
676 | + | ||
677 | + switch (input) { | ||
678 | + case PRV_RAW_CCDC: | ||
679 | + pcr &= ~ISPPRV_PCR_SOURCE; | ||
680 | + pcr &= ~ISPPRV_PCR_ONESHOT; | ||
681 | + ispprev_obj.prev_inpfmt = PRV_RAW_CCDC; | ||
682 | + break; | ||
683 | + case PRV_RAW_MEM: | ||
684 | + pcr |= ISPPRV_PCR_SOURCE; | ||
685 | + pcr |= ISPPRV_PCR_ONESHOT; | ||
686 | + ispprev_obj.prev_inpfmt = PRV_RAW_MEM; | ||
687 | + break; | ||
688 | + case PRV_CCDC_DRKF: | ||
689 | + pcr |= ISPPRV_PCR_DRKFCAP; | ||
690 | + pcr |= ISPPRV_PCR_ONESHOT; | ||
691 | + ispprev_obj.prev_inpfmt = PRV_CCDC_DRKF; | ||
692 | + break; | ||
693 | + case PRV_COMPCFA: | ||
694 | + ispprev_obj.prev_inpfmt = PRV_COMPCFA; | ||
695 | + break; | ||
696 | + case PRV_OTHERS: | ||
697 | + ispprev_obj.prev_inpfmt = PRV_OTHERS; | ||
698 | + break; | ||
699 | + case PRV_RGBBAYERCFA: | ||
700 | + ispprev_obj.prev_inpfmt = PRV_RGBBAYERCFA; | ||
701 | + break; | ||
702 | + default: | ||
703 | + printk(KERN_ERR "ISP_ERR : Wrong Input\n"); | ||
704 | + return -EINVAL; | ||
705 | + }; | ||
706 | + | ||
707 | + switch (output) { | ||
708 | + case PREVIEW_RSZ: | ||
709 | + pcr |= ISPPRV_PCR_RSZPORT; | ||
710 | + pcr &= ~ISPPRV_PCR_SDRPORT; | ||
711 | + break; | ||
712 | + case PREVIEW_MEM: | ||
713 | + pcr &= ~ISPPRV_PCR_RSZPORT; | ||
714 | + pcr |= ISPPRV_PCR_SDRPORT; | ||
715 | + break; | ||
716 | + default: | ||
717 | + printk(KERN_ERR "ISP_ERR : Wrong Output\n"); | ||
718 | + return -EINVAL; | ||
719 | + } | ||
720 | + ispprev_obj.prev_outfmt = output; | ||
721 | + | ||
722 | + isp_reg_writel(pcr, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR); | ||
723 | + | ||
724 | + isppreview_config_ycpos(params->pix_fmt); | ||
725 | + | ||
726 | + if (params->cfa.cfa_table != NULL) | ||
727 | + isppreview_config_cfa(params->cfa); | ||
728 | + if (params->csup.hypf_en == 1) | ||
729 | + isppreview_config_chroma_suppression(params->csup); | ||
730 | + if (params->ytable != NULL) | ||
731 | + isppreview_config_luma_enhancement(params->ytable); | ||
732 | + | ||
733 | + if (params->gtable.redtable != NULL) | ||
734 | + isppreview_config_gammacorrn(params->gtable); | ||
735 | + | ||
736 | + enable = (params->features & PREV_CFA) ? 1 : 0; | ||
737 | + isppreview_enable_cfa(enable); | ||
738 | + | ||
739 | + enable = (params->features & PREV_CHROMA_SUPPRESS) ? 1 : 0; | ||
740 | + isppreview_enable_chroma_suppression(enable); | ||
741 | + | ||
742 | + enable = (params->features & PREV_LUMA_ENHANCE) ? 1 : 0; | ||
743 | + isppreview_enable_luma_enhancement(enable); | ||
744 | + | ||
745 | + enable = (params->features & PREV_NOISE_FILTER) ? 1 : 0; | ||
746 | + if (enable) | ||
747 | + isppreview_config_noisefilter(params->nf); | ||
748 | + isppreview_enable_noisefilter(enable); | ||
749 | + | ||
750 | + enable = (params->features & PREV_DEFECT_COR) ? 1 : 0; | ||
751 | + if (enable) | ||
752 | + isppreview_config_dcor(params->dcor); | ||
753 | + isppreview_enable_dcor(enable); | ||
754 | + | ||
755 | + enable = (params->features & PREV_GAMMA_BYPASS) ? 1 : 0; | ||
756 | + isppreview_enable_gammabypass(enable); | ||
757 | + | ||
758 | + isppreview_config_whitebalance(params->wbal); | ||
759 | + isppreview_config_blkadj(params->blk_adj); | ||
760 | + isppreview_config_rgb_blending(params->rgb2rgb); | ||
761 | + isppreview_config_rgb_to_ycbcr(params->rgb2ycbcr); | ||
762 | + | ||
763 | + isppreview_config_contrast(params->contrast * ISPPRV_CONTRAST_UNITS); | ||
764 | + isppreview_config_brightness(params->brightness * ISPPRV_BRIGHT_UNITS); | ||
765 | + | ||
766 | + yclimit.minC = ISPPRV_YC_MIN; | ||
767 | + yclimit.maxC = ISPPRV_YC_MAX; | ||
768 | + yclimit.minY = ISPPRV_YC_MIN; | ||
769 | + yclimit.maxY = ISPPRV_YC_MAX; | ||
770 | + isppreview_config_yc_range(yclimit); | ||
771 | + | ||
772 | + return 0; | ||
773 | +} | ||
774 | +EXPORT_SYMBOL_GPL(isppreview_config_datapath); | ||
775 | + | ||
776 | +/** | ||
777 | + * isppreview_set_skip - Set the number of rows/columns that should be skipped. | ||
778 | + * h - Start Pixel Horizontal. | ||
779 | + * v - Start Line Vertical. | ||
780 | + **/ | ||
781 | +void isppreview_set_skip(u32 h, u32 v) | ||
782 | +{ | ||
783 | + ispprev_obj.sph = h; | ||
784 | + ispprev_obj.slv = v; | ||
785 | +} | ||
786 | +EXPORT_SYMBOL_GPL(isppreview_set_skip); | ||
787 | + | ||
788 | +/** | ||
789 | + * isppreview_config_ycpos - Configure byte layout of YUV image. | ||
790 | + * @mode: Indicates the required byte layout. | ||
791 | + **/ | ||
792 | +void isppreview_config_ycpos(enum preview_ycpos_mode mode) | ||
793 | +{ | ||
794 | + u32 pcr = isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR); | ||
795 | + pcr &= ~ISPPRV_PCR_YCPOS_CrYCbY; | ||
796 | + pcr |= (mode << ISPPRV_PCR_YCPOS_SHIFT); | ||
797 | + isp_reg_writel(pcr, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR); | ||
798 | +} | ||
799 | +EXPORT_SYMBOL_GPL(isppreview_config_ycpos); | ||
800 | + | ||
801 | +/** | ||
802 | + * isppreview_config_averager - Enable / disable / configure averager | ||
803 | + * @average: Average value to be configured. | ||
804 | + **/ | ||
805 | +void isppreview_config_averager(u8 average) | ||
806 | +{ | ||
807 | + int reg = 0; | ||
808 | + | ||
809 | + reg = AVE_ODD_PIXEL_DIST | AVE_EVEN_PIXEL_DIST | average; | ||
810 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE); | ||
811 | +} | ||
812 | +EXPORT_SYMBOL_GPL(isppreview_config_averager); | ||
813 | + | ||
814 | +/** | ||
815 | + * isppreview_enable_invalaw - Enable/Disable Inverse A-Law module in Preview. | ||
816 | + * @enable: 1 - Reverse the A-Law done in CCDC. | ||
817 | + **/ | ||
818 | +void isppreview_enable_invalaw(u8 enable) | ||
819 | +{ | ||
820 | + u32 pcr_val = 0; | ||
821 | + pcr_val = isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR); | ||
822 | + | ||
823 | + if (enable) { | ||
824 | + isp_reg_writel(pcr_val | ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW, | ||
825 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR); | ||
826 | + } else { | ||
827 | + isp_reg_writel(pcr_val & | ||
828 | + ~(ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW), | ||
829 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR); | ||
830 | + } | ||
831 | +} | ||
832 | +EXPORT_SYMBOL_GPL(isppreview_enable_invalaw); | ||
833 | + | ||
834 | +/** | ||
835 | + * isppreview_enable_drkframe - Enable/Disable of the darkframe subtract. | ||
836 | + * @enable: 1 - Acquires memory bandwidth since the pixels in each frame is | ||
837 | + * subtracted with the pixels in the current frame. | ||
838 | + * | ||
839 | + * The proccess is applied for each captured frame. | ||
840 | + **/ | ||
841 | +void isppreview_enable_drkframe(u8 enable) | ||
842 | +{ | ||
843 | + if (enable) | ||
844 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ISPPRV_PCR_DRKFEN); | ||
845 | + else { | ||
846 | + isp_reg_and(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
847 | + ~ISPPRV_PCR_DRKFEN); | ||
848 | + } | ||
849 | +} | ||
850 | +EXPORT_SYMBOL_GPL(isppreview_enable_drkframe); | ||
851 | + | ||
852 | +/** | ||
853 | + * isppreview_enable_shadcomp - Enables/Disables the shading compensation. | ||
854 | + * @enable: 1 - Enables the shading compensation. | ||
855 | + * | ||
856 | + * If dark frame subtract won't be used, then enable this shading | ||
857 | + * compensation. | ||
858 | + **/ | ||
859 | +void isppreview_enable_shadcomp(u8 enable) | ||
860 | +{ | ||
861 | + | ||
862 | + if (enable) { | ||
863 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
864 | + ISPPRV_PCR_SCOMP_EN); | ||
865 | + isppreview_enable_drkframe(1); | ||
866 | + } else { | ||
867 | + isp_reg_and(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
868 | + ~ISPPRV_PCR_SCOMP_EN); | ||
869 | + } | ||
870 | +} | ||
871 | +EXPORT_SYMBOL_GPL(isppreview_enable_shadcomp); | ||
872 | + | ||
873 | +/** | ||
874 | + * isppreview_config_drkf_shadcomp - Configures shift value in shading comp. | ||
875 | + * @scomp_shtval: 3bit value of shift used in shading compensation. | ||
876 | + **/ | ||
877 | +void isppreview_config_drkf_shadcomp(u8 scomp_shtval) | ||
878 | +{ | ||
879 | + u32 pcr_val = isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR); | ||
880 | + | ||
881 | + pcr_val &= ISPPRV_PCR_SCOMP_SFT_MASK; | ||
882 | + isp_reg_writel(pcr_val | (scomp_shtval << ISPPRV_PCR_SCOMP_SFT_SHIFT), | ||
883 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR); | ||
884 | +} | ||
885 | +EXPORT_SYMBOL_GPL(isppreview_config_drkf_shadcomp); | ||
886 | + | ||
887 | +/** | ||
888 | + * isppreview_enable_hmed - Enables/Disables of the Horizontal Median Filter. | ||
889 | + * @enable: 1 - Enables Horizontal Median Filter. | ||
890 | + **/ | ||
891 | +void isppreview_enable_hmed(u8 enable) | ||
892 | +{ | ||
893 | + if (enable) | ||
894 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ISPPRV_PCR_HMEDEN); | ||
895 | + else { | ||
896 | + isp_reg_and(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
897 | + ~ISPPRV_PCR_HMEDEN); | ||
898 | + } | ||
899 | + ispprev_obj.hmed_en = enable ? 1 : 0; | ||
900 | +} | ||
901 | +EXPORT_SYMBOL_GPL(isppreview_enable_hmed); | ||
902 | + | ||
903 | +/** | ||
904 | + * isppreview_config_hmed - Configures the Horizontal Median Filter. | ||
905 | + * @prev_hmed: Structure containing the odd and even distance between the | ||
906 | + * pixels in the image along with the filter threshold. | ||
907 | + **/ | ||
908 | +void isppreview_config_hmed(struct ispprev_hmed prev_hmed) | ||
909 | +{ | ||
910 | + | ||
911 | + u32 odddist = 0; | ||
912 | + u32 evendist = 0; | ||
913 | + | ||
914 | + if (prev_hmed.odddist == 1) | ||
915 | + odddist = ~ISPPRV_HMED_ODDDIST; | ||
916 | + else | ||
917 | + odddist = ISPPRV_HMED_ODDDIST; | ||
918 | + | ||
919 | + if (prev_hmed.evendist == 1) | ||
920 | + evendist = ~ISPPRV_HMED_EVENDIST; | ||
921 | + else | ||
922 | + evendist = ISPPRV_HMED_EVENDIST; | ||
923 | + | ||
924 | + isp_reg_writel(odddist | evendist | (prev_hmed.thres << | ||
925 | + ISPPRV_HMED_THRESHOLD_SHIFT), | ||
926 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_HMED); | ||
927 | + | ||
928 | +} | ||
929 | +EXPORT_SYMBOL_GPL(isppreview_config_hmed); | ||
930 | + | ||
931 | +/** | ||
932 | + * isppreview_config_noisefilter - Configures the Noise Filter. | ||
933 | + * @prev_nf: Structure containing the noisefilter table, strength to be used | ||
934 | + * for the noise filter and the defect correction enable flag. | ||
935 | + **/ | ||
936 | +void isppreview_config_noisefilter(struct ispprev_nf prev_nf) | ||
937 | +{ | ||
938 | + int i = 0; | ||
939 | + | ||
940 | + isp_reg_writel(prev_nf.spread, OMAP3_ISP_IOMEM_PREV, ISPPRV_NF); | ||
941 | + isp_reg_writel(ISPPRV_NF_TABLE_ADDR, OMAP3_ISP_IOMEM_PREV, | ||
942 | + ISPPRV_SET_TBL_ADDR); | ||
943 | + for (i = 0; i < ISPPRV_NF_TBL_SIZE; i++) { | ||
944 | + isp_reg_writel(prev_nf.table[i], OMAP3_ISP_IOMEM_PREV, | ||
945 | + ISPPRV_SET_TBL_DATA); | ||
946 | + } | ||
947 | +} | ||
948 | +EXPORT_SYMBOL_GPL(isppreview_config_noisefilter); | ||
949 | + | ||
950 | +/** | ||
951 | + * isppreview_config_dcor - Configures the defect correction | ||
952 | + * @prev_nf: Structure containing the defect correction structure | ||
953 | + **/ | ||
954 | +void isppreview_config_dcor(struct ispprev_dcor prev_dcor) | ||
955 | +{ | ||
956 | + if (prev_dcor.couplet_mode_en) { | ||
957 | + isp_reg_writel(prev_dcor.detect_correct[0], | ||
958 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR0); | ||
959 | + isp_reg_writel(prev_dcor.detect_correct[1], | ||
960 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR1); | ||
961 | + isp_reg_writel(prev_dcor.detect_correct[2], | ||
962 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR2); | ||
963 | + isp_reg_writel(prev_dcor.detect_correct[3], | ||
964 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR3); | ||
965 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ISPPRV_PCR_DCCOUP); | ||
966 | + } else { | ||
967 | + isp_reg_and(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
968 | + ~ISPPRV_PCR_DCCOUP); | ||
969 | + } | ||
970 | +} | ||
971 | +EXPORT_SYMBOL_GPL(isppreview_config_dcor); | ||
972 | + | ||
973 | +/** | ||
974 | + * isppreview_config_cfa - Configures the CFA Interpolation parameters. | ||
975 | + * @prev_cfa: Structure containing the CFA interpolation table, CFA format | ||
976 | + * in the image, vertical and horizontal gradient threshold. | ||
977 | + **/ | ||
978 | +void isppreview_config_cfa(struct ispprev_cfa prev_cfa) | ||
979 | +{ | ||
980 | + int i = 0; | ||
981 | + | ||
982 | + ispprev_obj.cfafmt = prev_cfa.cfafmt; | ||
983 | + | ||
984 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
985 | + (prev_cfa.cfafmt << ISPPRV_PCR_CFAFMT_SHIFT)); | ||
986 | + | ||
987 | + isp_reg_writel( | ||
988 | + (prev_cfa.cfa_gradthrs_vert << ISPPRV_CFA_GRADTH_VER_SHIFT) | | ||
989 | + (prev_cfa.cfa_gradthrs_horz << ISPPRV_CFA_GRADTH_HOR_SHIFT), | ||
990 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_CFA); | ||
991 | + | ||
992 | + isp_reg_writel(ISPPRV_CFA_TABLE_ADDR, OMAP3_ISP_IOMEM_PREV, | ||
993 | + ISPPRV_SET_TBL_ADDR); | ||
994 | + | ||
995 | + for (i = 0; i < ISPPRV_CFA_TBL_SIZE; i++) { | ||
996 | + isp_reg_writel(prev_cfa.cfa_table[i], | ||
997 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA); | ||
998 | + } | ||
999 | +} | ||
1000 | +EXPORT_SYMBOL_GPL(isppreview_config_cfa); | ||
1001 | + | ||
1002 | +/** | ||
1003 | + * isppreview_config_gammacorrn - Configures the Gamma Correction table values | ||
1004 | + * @gtable: Structure containing the table for red, blue, green gamma table. | ||
1005 | + **/ | ||
1006 | +void isppreview_config_gammacorrn(struct ispprev_gtable gtable) | ||
1007 | +{ | ||
1008 | + int i = 0; | ||
1009 | + | ||
1010 | + isp_reg_writel(ISPPRV_REDGAMMA_TABLE_ADDR, | ||
1011 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR); | ||
1012 | + for (i = 0; i < ISPPRV_GAMMA_TBL_SIZE; i++) { | ||
1013 | + isp_reg_writel(gtable.redtable[i], | ||
1014 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA); | ||
1015 | + } | ||
1016 | + | ||
1017 | + isp_reg_writel(ISPPRV_GREENGAMMA_TABLE_ADDR, | ||
1018 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR); | ||
1019 | + for (i = 0; i < ISPPRV_GAMMA_TBL_SIZE; i++) { | ||
1020 | + isp_reg_writel(gtable.greentable[i], | ||
1021 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA); | ||
1022 | + } | ||
1023 | + | ||
1024 | + isp_reg_writel(ISPPRV_BLUEGAMMA_TABLE_ADDR, | ||
1025 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR); | ||
1026 | + for (i = 0; i < ISPPRV_GAMMA_TBL_SIZE; i++) { | ||
1027 | + isp_reg_writel(gtable.bluetable[i], | ||
1028 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA); | ||
1029 | + } | ||
1030 | +} | ||
1031 | +EXPORT_SYMBOL_GPL(isppreview_config_gammacorrn); | ||
1032 | + | ||
1033 | +/** | ||
1034 | + * isppreview_config_luma_enhancement - Sets the Luminance Enhancement table. | ||
1035 | + * @ytable: Structure containing the table for Luminance Enhancement table. | ||
1036 | + **/ | ||
1037 | +void isppreview_config_luma_enhancement(u32 *ytable) | ||
1038 | +{ | ||
1039 | + int i = 0; | ||
1040 | + | ||
1041 | + isp_reg_writel(ISPPRV_YENH_TABLE_ADDR, | ||
1042 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR); | ||
1043 | + for (i = 0; i < ISPPRV_YENH_TBL_SIZE; i++) { | ||
1044 | + isp_reg_writel(ytable[i], | ||
1045 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA); | ||
1046 | + } | ||
1047 | +} | ||
1048 | +EXPORT_SYMBOL_GPL(isppreview_config_luma_enhancement); | ||
1049 | + | ||
1050 | +/** | ||
1051 | + * isppreview_config_chroma_suppression - Configures the Chroma Suppression. | ||
1052 | + * @csup: Structure containing the threshold value for suppression | ||
1053 | + * and the hypass filter enable flag. | ||
1054 | + **/ | ||
1055 | +void isppreview_config_chroma_suppression(struct ispprev_csup csup) | ||
1056 | +{ | ||
1057 | + isp_reg_writel(csup.gain | (csup.thres << ISPPRV_CSUP_THRES_SHIFT) | | ||
1058 | + (csup.hypf_en << ISPPRV_CSUP_HPYF_SHIFT), | ||
1059 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_CSUP); | ||
1060 | +} | ||
1061 | +EXPORT_SYMBOL_GPL(isppreview_config_chroma_suppression); | ||
1062 | + | ||
1063 | +/** | ||
1064 | + * isppreview_enable_noisefilter - Enables/Disables the Noise Filter. | ||
1065 | + * @enable: 1 - Enables the Noise Filter. | ||
1066 | + **/ | ||
1067 | +void isppreview_enable_noisefilter(u8 enable) | ||
1068 | +{ | ||
1069 | + if (enable) | ||
1070 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ISPPRV_PCR_NFEN); | ||
1071 | + else | ||
1072 | + isp_reg_and(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ~ISPPRV_PCR_NFEN); | ||
1073 | + ispprev_obj.nf_en = enable ? 1 : 0; | ||
1074 | +} | ||
1075 | +EXPORT_SYMBOL_GPL(isppreview_enable_noisefilter); | ||
1076 | + | ||
1077 | +/** | ||
1078 | + * isppreview_enable_dcor - Enables/Disables the defect correction. | ||
1079 | + * @enable: 1 - Enables the defect correction. | ||
1080 | + **/ | ||
1081 | +void isppreview_enable_dcor(u8 enable) | ||
1082 | +{ | ||
1083 | + if (enable) | ||
1084 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ISPPRV_PCR_DCOREN); | ||
1085 | + else { | ||
1086 | + isp_reg_and(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
1087 | + ~ISPPRV_PCR_DCOREN); | ||
1088 | + } | ||
1089 | + ispprev_obj.dcor_en = enable ? 1 : 0; | ||
1090 | +} | ||
1091 | +EXPORT_SYMBOL_GPL(isppreview_enable_dcor); | ||
1092 | + | ||
1093 | +/** | ||
1094 | + * isppreview_enable_cfa - Enable/Disable the CFA Interpolation. | ||
1095 | + * @enable: 1 - Enables the CFA. | ||
1096 | + **/ | ||
1097 | +void isppreview_enable_cfa(u8 enable) | ||
1098 | +{ | ||
1099 | + if (enable) | ||
1100 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ISPPRV_PCR_CFAEN); | ||
1101 | + else { | ||
1102 | + isp_reg_and(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
1103 | + ~ISPPRV_PCR_CFAEN); | ||
1104 | + } | ||
1105 | + ispprev_obj.cfa_en = enable ? 1 : 0; | ||
1106 | +} | ||
1107 | +EXPORT_SYMBOL_GPL(isppreview_enable_cfa); | ||
1108 | + | ||
1109 | +/** | ||
1110 | + * isppreview_enable_gammabypass - Enables/Disables the GammaByPass | ||
1111 | + * @enable: 1 - Bypasses Gamma - 10bit input is cropped to 8MSB. | ||
1112 | + * 0 - Goes through Gamma Correction. input and output is 10bit. | ||
1113 | + **/ | ||
1114 | +void isppreview_enable_gammabypass(u8 enable) | ||
1115 | +{ | ||
1116 | + if (enable) { | ||
1117 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
1118 | + ISPPRV_PCR_GAMMA_BYPASS); | ||
1119 | + } else { | ||
1120 | + isp_reg_and(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
1121 | + ~ISPPRV_PCR_GAMMA_BYPASS); | ||
1122 | + } | ||
1123 | +} | ||
1124 | +EXPORT_SYMBOL_GPL(isppreview_enable_gammabypass); | ||
1125 | + | ||
1126 | +/** | ||
1127 | + * isppreview_enable_luma_enhancement - Enables/Disables Luminance Enhancement | ||
1128 | + * @enable: 1 - Enable the Luminance Enhancement. | ||
1129 | + **/ | ||
1130 | +void isppreview_enable_luma_enhancement(u8 enable) | ||
1131 | +{ | ||
1132 | + if (enable) { | ||
1133 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
1134 | + ISPPRV_PCR_YNENHEN); | ||
1135 | + } else { | ||
1136 | + isp_reg_and(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
1137 | + ~ISPPRV_PCR_YNENHEN); | ||
1138 | + } | ||
1139 | + ispprev_obj.yenh_en = enable ? 1 : 0; | ||
1140 | +} | ||
1141 | +EXPORT_SYMBOL_GPL(isppreview_enable_luma_enhancement); | ||
1142 | + | ||
1143 | +/** | ||
1144 | + * isppreview_enable_chroma_suppression - Enables/Disables Chrominance Suppr. | ||
1145 | + * @enable: 1 - Enable the Chrominance Suppression. | ||
1146 | + **/ | ||
1147 | +void isppreview_enable_chroma_suppression(u8 enable) | ||
1148 | +{ | ||
1149 | + if (enable) | ||
1150 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ISPPRV_PCR_SUPEN); | ||
1151 | + else { | ||
1152 | + isp_reg_and(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
1153 | + ~ISPPRV_PCR_SUPEN); | ||
1154 | + } | ||
1155 | + ispprev_obj.csup_en = enable ? 1 : 0; | ||
1156 | +} | ||
1157 | +EXPORT_SYMBOL_GPL(isppreview_enable_chroma_suppression); | ||
1158 | + | ||
1159 | +/** | ||
1160 | + * isppreview_config_whitebalance - Configures the White Balance parameters. | ||
1161 | + * @prev_wbal: Structure containing the digital gain and white balance | ||
1162 | + * coefficient. | ||
1163 | + * | ||
1164 | + * Coefficient matrix always with default values. | ||
1165 | + **/ | ||
1166 | +void isppreview_config_whitebalance(struct ispprev_wbal prev_wbal) | ||
1167 | +{ | ||
1168 | + u32 val; | ||
1169 | + | ||
1170 | + isp_reg_writel(prev_wbal.dgain, OMAP3_ISP_IOMEM_PREV, ISPPRV_WB_DGAIN); | ||
1171 | + | ||
1172 | + val = prev_wbal.coef0 << ISPPRV_WBGAIN_COEF0_SHIFT; | ||
1173 | + val |= prev_wbal.coef1 << ISPPRV_WBGAIN_COEF1_SHIFT; | ||
1174 | + val |= prev_wbal.coef2 << ISPPRV_WBGAIN_COEF2_SHIFT; | ||
1175 | + val |= prev_wbal.coef3 << ISPPRV_WBGAIN_COEF3_SHIFT; | ||
1176 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_WBGAIN); | ||
1177 | + | ||
1178 | + isp_reg_writel(ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N0_0_SHIFT | | ||
1179 | + ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N0_1_SHIFT | | ||
1180 | + ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N0_2_SHIFT | | ||
1181 | + ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N0_3_SHIFT | | ||
1182 | + ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N1_0_SHIFT | | ||
1183 | + ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N1_1_SHIFT | | ||
1184 | + ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N1_2_SHIFT | | ||
1185 | + ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N1_3_SHIFT | | ||
1186 | + ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N2_0_SHIFT | | ||
1187 | + ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N2_1_SHIFT | | ||
1188 | + ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N2_2_SHIFT | | ||
1189 | + ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N2_3_SHIFT | | ||
1190 | + ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N3_0_SHIFT | | ||
1191 | + ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N3_1_SHIFT | | ||
1192 | + ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N3_2_SHIFT | | ||
1193 | + ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N3_3_SHIFT, | ||
1194 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_WBSEL); | ||
1195 | +} | ||
1196 | +EXPORT_SYMBOL_GPL(isppreview_config_whitebalance); | ||
1197 | + | ||
1198 | +/** | ||
1199 | + * isppreview_config_whitebalance2 - Configures the White Balance parameters. | ||
1200 | + * @prev_wbal: Structure containing the digital gain and white balance | ||
1201 | + * coefficient. | ||
1202 | + * | ||
1203 | + * Coefficient matrix can be changed. | ||
1204 | + **/ | ||
1205 | +void isppreview_config_whitebalance2(struct prev_white_balance prev_wbal) | ||
1206 | +{ | ||
1207 | + isp_reg_writel(prev_wbal.wb_dgain, | ||
1208 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_WB_DGAIN); | ||
1209 | + isp_reg_writel(prev_wbal.wb_gain[0] | | ||
1210 | + prev_wbal.wb_gain[1] << ISPPRV_WBGAIN_COEF1_SHIFT | | ||
1211 | + prev_wbal.wb_gain[2] << ISPPRV_WBGAIN_COEF2_SHIFT | | ||
1212 | + prev_wbal.wb_gain[3] << ISPPRV_WBGAIN_COEF3_SHIFT, | ||
1213 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_WBGAIN); | ||
1214 | + | ||
1215 | + isp_reg_writel( | ||
1216 | + prev_wbal.wb_coefmatrix[0][0] << ISPPRV_WBSEL_N0_0_SHIFT | | ||
1217 | + prev_wbal.wb_coefmatrix[0][1] << ISPPRV_WBSEL_N0_1_SHIFT | | ||
1218 | + prev_wbal.wb_coefmatrix[0][2] << ISPPRV_WBSEL_N0_2_SHIFT | | ||
1219 | + prev_wbal.wb_coefmatrix[0][3] << ISPPRV_WBSEL_N0_3_SHIFT | | ||
1220 | + prev_wbal.wb_coefmatrix[1][0] << ISPPRV_WBSEL_N1_0_SHIFT | | ||
1221 | + prev_wbal.wb_coefmatrix[1][1] << ISPPRV_WBSEL_N1_1_SHIFT | | ||
1222 | + prev_wbal.wb_coefmatrix[1][2] << ISPPRV_WBSEL_N1_2_SHIFT | | ||
1223 | + prev_wbal.wb_coefmatrix[1][3] << ISPPRV_WBSEL_N1_3_SHIFT | | ||
1224 | + prev_wbal.wb_coefmatrix[2][0] << ISPPRV_WBSEL_N2_0_SHIFT | | ||
1225 | + prev_wbal.wb_coefmatrix[2][1] << ISPPRV_WBSEL_N2_1_SHIFT | | ||
1226 | + prev_wbal.wb_coefmatrix[2][2] << ISPPRV_WBSEL_N2_2_SHIFT | | ||
1227 | + prev_wbal.wb_coefmatrix[2][3] << ISPPRV_WBSEL_N2_3_SHIFT | | ||
1228 | + prev_wbal.wb_coefmatrix[3][0] << ISPPRV_WBSEL_N3_0_SHIFT | | ||
1229 | + prev_wbal.wb_coefmatrix[3][1] << ISPPRV_WBSEL_N3_1_SHIFT | | ||
1230 | + prev_wbal.wb_coefmatrix[3][2] << ISPPRV_WBSEL_N3_2_SHIFT | | ||
1231 | + prev_wbal.wb_coefmatrix[3][3] << ISPPRV_WBSEL_N3_3_SHIFT, | ||
1232 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_WBSEL); | ||
1233 | +} | ||
1234 | +EXPORT_SYMBOL_GPL(isppreview_config_whitebalance2); | ||
1235 | + | ||
1236 | +/** | ||
1237 | + * isppreview_config_blkadj - Configures the Black Adjustment parameters. | ||
1238 | + * @prev_blkadj: Structure containing the black adjustment towards red, green, | ||
1239 | + * blue. | ||
1240 | + **/ | ||
1241 | +void isppreview_config_blkadj(struct ispprev_blkadj prev_blkadj) | ||
1242 | +{ | ||
1243 | + isp_reg_writel(prev_blkadj.blue | | ||
1244 | + (prev_blkadj.green << ISPPRV_BLKADJOFF_G_SHIFT) | | ||
1245 | + (prev_blkadj.red << ISPPRV_BLKADJOFF_R_SHIFT), | ||
1246 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_BLKADJOFF); | ||
1247 | +} | ||
1248 | +EXPORT_SYMBOL_GPL(isppreview_config_blkadj); | ||
1249 | + | ||
1250 | +/** | ||
1251 | + * isppreview_config_rgb_blending - Configures the RGB-RGB Blending matrix. | ||
1252 | + * @rgb2rgb: Structure containing the rgb to rgb blending matrix and the rgb | ||
1253 | + * offset. | ||
1254 | + **/ | ||
1255 | +void isppreview_config_rgb_blending(struct ispprev_rgbtorgb rgb2rgb) | ||
1256 | +{ | ||
1257 | + u32 val = 0; | ||
1258 | + | ||
1259 | + val = (rgb2rgb.matrix[0][0] & 0xfff) << ISPPRV_RGB_MAT1_MTX_RR_SHIFT; | ||
1260 | + val |= (rgb2rgb.matrix[0][1] & 0xfff) << ISPPRV_RGB_MAT1_MTX_GR_SHIFT; | ||
1261 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT1); | ||
1262 | + | ||
1263 | + val = (rgb2rgb.matrix[0][2] & 0xfff) << ISPPRV_RGB_MAT2_MTX_BR_SHIFT; | ||
1264 | + val |= (rgb2rgb.matrix[1][0] & 0xfff) << ISPPRV_RGB_MAT2_MTX_RG_SHIFT; | ||
1265 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT2); | ||
1266 | + | ||
1267 | + val = (rgb2rgb.matrix[1][1] & 0xfff) << ISPPRV_RGB_MAT3_MTX_GG_SHIFT; | ||
1268 | + val |= (rgb2rgb.matrix[1][2] & 0xfff) << ISPPRV_RGB_MAT3_MTX_BG_SHIFT; | ||
1269 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT3); | ||
1270 | + | ||
1271 | + val = (rgb2rgb.matrix[2][0] & 0xfff) << ISPPRV_RGB_MAT4_MTX_RB_SHIFT; | ||
1272 | + val |= (rgb2rgb.matrix[2][1] & 0xfff) << ISPPRV_RGB_MAT4_MTX_GB_SHIFT; | ||
1273 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT4); | ||
1274 | + | ||
1275 | + val = (rgb2rgb.matrix[2][2] & 0xfff) << ISPPRV_RGB_MAT5_MTX_BB_SHIFT; | ||
1276 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT5); | ||
1277 | + | ||
1278 | + val = (rgb2rgb.offset[0] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT; | ||
1279 | + val |= (rgb2rgb.offset[1] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT; | ||
1280 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF1); | ||
1281 | + | ||
1282 | + val = (rgb2rgb.offset[2] & 0x3ff) << ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT; | ||
1283 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF2); | ||
1284 | +} | ||
1285 | +EXPORT_SYMBOL_GPL(isppreview_config_rgb_blending); | ||
1286 | + | ||
1287 | +/** | ||
1288 | + * Configures the RGB-YCbYCr conversion matrix | ||
1289 | + * @prev_csc: Structure containing the RGB to YCbYCr matrix and the | ||
1290 | + * YCbCr offset. | ||
1291 | + **/ | ||
1292 | +void isppreview_config_rgb_to_ycbcr(struct ispprev_csc prev_csc) | ||
1293 | +{ | ||
1294 | + u32 val = 0; | ||
1295 | + | ||
1296 | + val = (prev_csc.matrix[0][0] & 0x3ff) << ISPPRV_CSC0_RY_SHIFT; | ||
1297 | + val |= (prev_csc.matrix[0][1] & 0x3ff) << ISPPRV_CSC0_GY_SHIFT; | ||
1298 | + val |= (prev_csc.matrix[0][2] & 0x3ff) << ISPPRV_CSC0_BY_SHIFT; | ||
1299 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC0); | ||
1300 | + | ||
1301 | + val = (prev_csc.matrix[1][0] & 0x3ff) << ISPPRV_CSC1_RCB_SHIFT; | ||
1302 | + val |= (prev_csc.matrix[1][1] & 0x3ff) << ISPPRV_CSC1_GCB_SHIFT; | ||
1303 | + val |= (prev_csc.matrix[1][2] & 0x3ff) << ISPPRV_CSC1_BCB_SHIFT; | ||
1304 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC1); | ||
1305 | + | ||
1306 | + val = (prev_csc.matrix[2][0] & 0x3ff) << ISPPRV_CSC2_RCR_SHIFT; | ||
1307 | + val |= (prev_csc.matrix[2][1] & 0x3ff) << ISPPRV_CSC2_GCR_SHIFT; | ||
1308 | + val |= (prev_csc.matrix[2][2] & 0x3ff) << ISPPRV_CSC2_BCR_SHIFT; | ||
1309 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC2); | ||
1310 | + | ||
1311 | + val = (prev_csc.offset[0] & 0xff) << ISPPRV_CSC_OFFSET_CR_SHIFT; | ||
1312 | + val |= (prev_csc.offset[1] & 0xff) << ISPPRV_CSC_OFFSET_CB_SHIFT; | ||
1313 | + val |= (prev_csc.offset[2] & 0xff) << ISPPRV_CSC_OFFSET_Y_SHIFT; | ||
1314 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC_OFFSET); | ||
1315 | +} | ||
1316 | +EXPORT_SYMBOL_GPL(isppreview_config_rgb_to_ycbcr); | ||
1317 | + | ||
1318 | +/** | ||
1319 | + * isppreview_query_contrast - Query the contrast. | ||
1320 | + * @contrast: Pointer to hold the current programmed contrast value. | ||
1321 | + **/ | ||
1322 | +void isppreview_query_contrast(u8 *contrast) | ||
1323 | +{ | ||
1324 | + u32 brt_cnt_val = 0; | ||
1325 | + | ||
1326 | + brt_cnt_val = isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT); | ||
1327 | + *contrast = (brt_cnt_val >> ISPPRV_CNT_BRT_CNT_SHIFT) & 0xff; | ||
1328 | + DPRINTK_ISPPREV(" Current brt cnt value in hw is %x\n", brt_cnt_val); | ||
1329 | +} | ||
1330 | +EXPORT_SYMBOL_GPL(isppreview_query_contrast); | ||
1331 | + | ||
1332 | +/** | ||
1333 | + * isppreview_update_contrast - Updates the contrast. | ||
1334 | + * @contrast: Pointer to hold the current programmed contrast value. | ||
1335 | + * | ||
1336 | + * Value should be programmed before enabling the module. | ||
1337 | + **/ | ||
1338 | +void isppreview_update_contrast(u8 *contrast) | ||
1339 | +{ | ||
1340 | + ispprev_obj.contrast = *contrast; | ||
1341 | +} | ||
1342 | +EXPORT_SYMBOL_GPL(isppreview_update_contrast); | ||
1343 | + | ||
1344 | +/** | ||
1345 | + * isppreview_config_contrast - Configures the Contrast. | ||
1346 | + * @contrast: 8 bit value in U8Q4 format. | ||
1347 | + * | ||
1348 | + * Value should be programmed before enabling the module. | ||
1349 | + **/ | ||
1350 | +void isppreview_config_contrast(u8 contrast) | ||
1351 | +{ | ||
1352 | + u32 brt_cnt_val = 0; | ||
1353 | + | ||
1354 | + brt_cnt_val = isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT); | ||
1355 | + brt_cnt_val &= ~(0xff << ISPPRV_CNT_BRT_CNT_SHIFT); | ||
1356 | + contrast &= 0xff; | ||
1357 | + isp_reg_writel(brt_cnt_val | contrast << ISPPRV_CNT_BRT_CNT_SHIFT, | ||
1358 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT); | ||
1359 | +} | ||
1360 | +EXPORT_SYMBOL_GPL(isppreview_config_contrast); | ||
1361 | + | ||
1362 | +/** | ||
1363 | + * isppreview_get_contrast_range - Gets the range contrast value. | ||
1364 | + * @min_contrast: Pointer to hold the minimum Contrast value. | ||
1365 | + * @max_contrast: Pointer to hold the maximum Contrast value. | ||
1366 | + **/ | ||
1367 | +void isppreview_get_contrast_range(u8 *min_contrast, u8 *max_contrast) | ||
1368 | +{ | ||
1369 | + *min_contrast = ISPPRV_CONTRAST_MIN; | ||
1370 | + *max_contrast = ISPPRV_CONTRAST_MAX; | ||
1371 | +} | ||
1372 | +EXPORT_SYMBOL_GPL(isppreview_get_contrast_range); | ||
1373 | + | ||
1374 | +/** | ||
1375 | + * isppreview_update_brightness - Updates the brightness in preview module. | ||
1376 | + * @brightness: Pointer to hold the current programmed brightness value. | ||
1377 | + * | ||
1378 | + **/ | ||
1379 | +void isppreview_update_brightness(u8 *brightness) | ||
1380 | +{ | ||
1381 | + ispprev_obj.brightness = *brightness; | ||
1382 | +} | ||
1383 | +EXPORT_SYMBOL_GPL(isppreview_update_brightness); | ||
1384 | + | ||
1385 | +/** | ||
1386 | + * isppreview_config_brightness - Configures the brightness. | ||
1387 | + * @contrast: 8bitvalue in U8Q0 format. | ||
1388 | + **/ | ||
1389 | +void isppreview_config_brightness(u8 brightness) | ||
1390 | +{ | ||
1391 | + u32 brt_cnt_val = 0; | ||
1392 | + | ||
1393 | + DPRINTK_ISPPREV("\tConfiguring brightness in ISP: %d\n", brightness); | ||
1394 | + brt_cnt_val = isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT); | ||
1395 | + brt_cnt_val &= ~(0xff << ISPPRV_CNT_BRT_BRT_SHIFT); | ||
1396 | + brightness &= 0xff; | ||
1397 | + isp_reg_writel(brt_cnt_val | brightness << ISPPRV_CNT_BRT_BRT_SHIFT, | ||
1398 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT); | ||
1399 | +} | ||
1400 | +EXPORT_SYMBOL_GPL(isppreview_config_brightness); | ||
1401 | + | ||
1402 | +/** | ||
1403 | + * isppreview_query_brightness - Query the brightness. | ||
1404 | + * @brightness: Pointer to hold the current programmed brightness value. | ||
1405 | + **/ | ||
1406 | +void isppreview_query_brightness(u8 *brightness) | ||
1407 | +{ | ||
1408 | + *brightness = isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT); | ||
1409 | +} | ||
1410 | +EXPORT_SYMBOL_GPL(isppreview_query_brightness); | ||
1411 | + | ||
1412 | +/** | ||
1413 | + * isppreview_get_brightness_range - Gets the range brightness value | ||
1414 | + * @min_brightness: Pointer to hold the minimum brightness value | ||
1415 | + * @max_brightness: Pointer to hold the maximum brightness value | ||
1416 | + **/ | ||
1417 | +void isppreview_get_brightness_range(u8 *min_brightness, u8 *max_brightness) | ||
1418 | +{ | ||
1419 | + *min_brightness = ISPPRV_BRIGHT_MIN; | ||
1420 | + *max_brightness = ISPPRV_BRIGHT_MAX; | ||
1421 | +} | ||
1422 | +EXPORT_SYMBOL_GPL(isppreview_get_brightness_range); | ||
1423 | + | ||
1424 | +/** | ||
1425 | + * isppreview_set_color - Sets the color effect. | ||
1426 | + * @mode: Indicates the required color effect. | ||
1427 | + **/ | ||
1428 | +void isppreview_set_color(u8 *mode) | ||
1429 | +{ | ||
1430 | + ispprev_obj.color = *mode; | ||
1431 | + update_color_matrix = 1; | ||
1432 | +} | ||
1433 | +EXPORT_SYMBOL_GPL(isppreview_set_color); | ||
1434 | + | ||
1435 | +/** | ||
1436 | + * isppreview_get_color - Gets the current color effect. | ||
1437 | + * @mode: Indicates the current color effect. | ||
1438 | + **/ | ||
1439 | +void isppreview_get_color(u8 *mode) | ||
1440 | +{ | ||
1441 | + *mode = ispprev_obj.color; | ||
1442 | +} | ||
1443 | +EXPORT_SYMBOL_GPL(isppreview_get_color); | ||
1444 | + | ||
1445 | +/** | ||
1446 | + * isppreview_config_yc_range - Configures the max and min Y and C values. | ||
1447 | + * @yclimit: Structure containing the range of Y and C values. | ||
1448 | + **/ | ||
1449 | +void isppreview_config_yc_range(struct ispprev_yclimit yclimit) | ||
1450 | +{ | ||
1451 | + isp_reg_writel(yclimit.maxC << ISPPRV_SETUP_YC_MAXC_SHIFT | | ||
1452 | + yclimit.maxY << ISPPRV_SETUP_YC_MAXY_SHIFT | | ||
1453 | + yclimit.minC << ISPPRV_SETUP_YC_MINC_SHIFT | | ||
1454 | + yclimit.minY << ISPPRV_SETUP_YC_MINY_SHIFT, | ||
1455 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC); | ||
1456 | +} | ||
1457 | +EXPORT_SYMBOL_GPL(isppreview_config_yc_range); | ||
1458 | + | ||
1459 | +/** | ||
1460 | + * isppreview_try_size - Calculates output dimensions with the modules enabled. | ||
1461 | + * @input_w: input width for the preview in number of pixels per line | ||
1462 | + * @input_h: input height for the preview in number of lines | ||
1463 | + * @output_w: output width from the preview in number of pixels per line | ||
1464 | + * @output_h: output height for the preview in number of lines | ||
1465 | + * | ||
1466 | + * Calculates the number of pixels cropped in the submodules that are enabled, | ||
1467 | + * Fills up the output width height variables in the isp_prev structure. | ||
1468 | + **/ | ||
1469 | +int isppreview_try_size(u32 input_w, u32 input_h, u32 *output_w, u32 *output_h) | ||
1470 | +{ | ||
1471 | + u32 prevout_w = input_w; | ||
1472 | + u32 prevout_h = input_h; | ||
1473 | + u32 div = 0; | ||
1474 | + int max_out; | ||
1475 | + | ||
1476 | + ispprev_obj.previn_w = input_w; | ||
1477 | + ispprev_obj.previn_h = input_h; | ||
1478 | + | ||
1479 | + if (input_w < 32 || input_h < 32) { | ||
1480 | + printk(KERN_ERR "ISP_ERR : preview does not support " | ||
1481 | + "width < 16 or height < 32 \n"); | ||
1482 | + return -EINVAL; | ||
1483 | + } | ||
1484 | + if (omap_rev() == OMAP3430_REV_ES1_0) | ||
1485 | + max_out = ISPPRV_MAXOUTPUT_WIDTH; | ||
1486 | + else | ||
1487 | + max_out = ISPPRV_MAXOUTPUT_WIDTH_ES2; | ||
1488 | + | ||
1489 | + ispprev_obj.fmtavg = 0; | ||
1490 | + | ||
1491 | + if (input_w > max_out) { | ||
1492 | + div = (input_w/max_out); | ||
1493 | + if (div >= 2 && div < 4) { | ||
1494 | + ispprev_obj.fmtavg = 1; | ||
1495 | + prevout_w /= 2; | ||
1496 | + } else if (div >= 4 && div < 8) { | ||
1497 | + ispprev_obj.fmtavg = 2; | ||
1498 | + prevout_w /= 4; | ||
1499 | + } else if (div >= 8) { | ||
1500 | + ispprev_obj.fmtavg = 3; | ||
1501 | + prevout_w /= 8; | ||
1502 | + } | ||
1503 | + } | ||
1504 | + | ||
1505 | + if (ispprev_obj.hmed_en) | ||
1506 | + prevout_w -= 4; | ||
1507 | + if (ispprev_obj.nf_en) { | ||
1508 | + prevout_w -= 4; | ||
1509 | + prevout_h -= 4; | ||
1510 | + } | ||
1511 | + if (ispprev_obj.cfa_en) { | ||
1512 | + switch (ispprev_obj.cfafmt) { | ||
1513 | + case CFAFMT_BAYER: | ||
1514 | + case CFAFMT_SONYVGA: | ||
1515 | + prevout_w -= 4; | ||
1516 | + prevout_h -= 4; | ||
1517 | + break; | ||
1518 | + case CFAFMT_RGBFOVEON: | ||
1519 | + case CFAFMT_RRGGBBFOVEON: | ||
1520 | + case CFAFMT_DNSPL: | ||
1521 | + case CFAFMT_HONEYCOMB: | ||
1522 | + prevout_h -= 2; | ||
1523 | + break; | ||
1524 | + }; | ||
1525 | + } | ||
1526 | + if (ispprev_obj.yenh_en || ispprev_obj.csup_en) | ||
1527 | + prevout_w -= 2; | ||
1528 | + | ||
1529 | + /* Start at the correct row/column by skipping | ||
1530 | + * a Sensor specific amount. | ||
1531 | + */ | ||
1532 | + prevout_w -= ispprev_obj.sph; | ||
1533 | + prevout_h -= ispprev_obj.slv; | ||
1534 | + | ||
1535 | + | ||
1536 | + if (prevout_w % 2) | ||
1537 | + prevout_w -= 1; | ||
1538 | + | ||
1539 | + if (ispprev_obj.prev_outfmt == PREVIEW_MEM) { | ||
1540 | + if (((prevout_w * 2) & ISP_32B_BOUNDARY_OFFSET) != | ||
1541 | + (prevout_w * 2)) { | ||
1542 | + prevout_w = ((prevout_w * 2) & | ||
1543 | + ISP_32B_BOUNDARY_OFFSET) / 2; | ||
1544 | + } | ||
1545 | + } | ||
1546 | + *output_w = prevout_w; | ||
1547 | + ispprev_obj.prevout_w = prevout_w; | ||
1548 | + *output_h = prevout_h; | ||
1549 | + ispprev_obj.prevout_h = prevout_h; | ||
1550 | + return 0; | ||
1551 | +} | ||
1552 | +EXPORT_SYMBOL_GPL(isppreview_try_size); | ||
1553 | + | ||
1554 | +/** | ||
1555 | + * isppreview_config_size - Sets the size of ISP preview output. | ||
1556 | + * @input_w: input width for the preview in number of pixels per line | ||
1557 | + * @input_h: input height for the preview in number of lines | ||
1558 | + * @output_w: output width from the preview in number of pixels per line | ||
1559 | + * @output_h: output height for the preview in number of lines | ||
1560 | + * | ||
1561 | + * Configures the appropriate values stored in the isp_prev structure to | ||
1562 | + * HORZ/VERT_INFO. Configures PRV_AVE if needed for downsampling as calculated | ||
1563 | + * in trysize. | ||
1564 | + **/ | ||
1565 | +int isppreview_config_size(u32 input_w, u32 input_h, u32 output_w, u32 output_h) | ||
1566 | +{ | ||
1567 | + u32 prevsdroff; | ||
1568 | + | ||
1569 | + if ((output_w != ispprev_obj.prevout_w) || | ||
1570 | + (output_h != ispprev_obj.prevout_h)) { | ||
1571 | + printk(KERN_ERR "ISP_ERR : isppreview_try_size should " | ||
1572 | + "be called before config size\n"); | ||
1573 | + return -EINVAL; | ||
1574 | + } | ||
1575 | + | ||
1576 | + isp_reg_writel((ispprev_obj.sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | | ||
1577 | + (ispprev_obj.previn_w - 1), | ||
1578 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO); | ||
1579 | + isp_reg_writel((ispprev_obj.slv << ISPPRV_VERT_INFO_SLV_SHIFT) | | ||
1580 | + (ispprev_obj.previn_h - 2), | ||
1581 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_VERT_INFO); | ||
1582 | + | ||
1583 | + if (ispprev_obj.cfafmt == CFAFMT_BAYER) | ||
1584 | + isp_reg_writel(ISPPRV_AVE_EVENDIST_2 << | ||
1585 | + ISPPRV_AVE_EVENDIST_SHIFT | | ||
1586 | + ISPPRV_AVE_ODDDIST_2 << | ||
1587 | + ISPPRV_AVE_ODDDIST_SHIFT | | ||
1588 | + ispprev_obj.fmtavg, | ||
1589 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE); | ||
1590 | + | ||
1591 | + if (ispprev_obj.prev_outfmt == PREVIEW_MEM) { | ||
1592 | + prevsdroff = ispprev_obj.prevout_w * 2; | ||
1593 | + if ((prevsdroff & ISP_32B_BOUNDARY_OFFSET) != prevsdroff) { | ||
1594 | + DPRINTK_ISPPREV("ISP_WARN: Preview output buffer line" | ||
1595 | + " size is truncated" | ||
1596 | + " to 32byte boundary\n"); | ||
1597 | + prevsdroff &= ISP_32B_BOUNDARY_BUF ; | ||
1598 | + } | ||
1599 | + isppreview_config_outlineoffset(prevsdroff); | ||
1600 | + } | ||
1601 | + return 0; | ||
1602 | +} | ||
1603 | +EXPORT_SYMBOL_GPL(isppreview_config_size); | ||
1604 | + | ||
1605 | +/** | ||
1606 | + * isppreview_config_inlineoffset - Configures the Read address line offset. | ||
1607 | + * @offset: Line Offset for the input image. | ||
1608 | + **/ | ||
1609 | +int isppreview_config_inlineoffset(u32 offset) | ||
1610 | +{ | ||
1611 | + if ((offset & ISP_32B_BOUNDARY_OFFSET) == offset) { | ||
1612 | + isp_reg_writel(offset & 0xffff, | ||
1613 | + OMAP3_ISP_IOMEM_PREV, ISPPRV_RADR_OFFSET); | ||
1614 | + } else { | ||
1615 | + printk(KERN_ERR "ISP_ERR : Offset should be in 32 byte " | ||
1616 | + "boundary\n"); | ||
1617 | + return -EINVAL; | ||
1618 | + } | ||
1619 | + return 0; | ||
1620 | +} | ||
1621 | +EXPORT_SYMBOL_GPL(isppreview_config_inlineoffset); | ||
1622 | + | ||
1623 | +/** | ||
1624 | + * isppreview_set_inaddr - Sets memory address of input frame. | ||
1625 | + * @addr: 32bit memory address aligned on 32byte boundary. | ||
1626 | + * | ||
1627 | + * Configures the memory address from which the input frame is to be read. | ||
1628 | + **/ | ||
1629 | +int isppreview_set_inaddr(u32 addr) | ||
1630 | +{ | ||
1631 | + if ((addr & ISP_32B_BOUNDARY_BUF) == addr) | ||
1632 | + isp_reg_writel(addr, OMAP3_ISP_IOMEM_PREV, ISPPRV_RSDR_ADDR); | ||
1633 | + else { | ||
1634 | + printk(KERN_ERR "ISP_ERR: Address should be in 32 byte " | ||
1635 | + "boundary\n"); | ||
1636 | + return -EINVAL; | ||
1637 | + } | ||
1638 | + return 0; | ||
1639 | +} | ||
1640 | +EXPORT_SYMBOL_GPL(isppreview_set_inaddr); | ||
1641 | + | ||
1642 | +/** | ||
1643 | + * isppreview_config_outlineoffset - Configures the Write address line offset. | ||
1644 | + * @offset: Line Offset for the preview output. | ||
1645 | + **/ | ||
1646 | +int isppreview_config_outlineoffset(u32 offset) | ||
1647 | +{ | ||
1648 | + if ((offset & ISP_32B_BOUNDARY_OFFSET) != offset) { | ||
1649 | + printk(KERN_ERR "ISP_ERR : Offset should be in 32 byte " | ||
1650 | + "boundary\n"); | ||
1651 | + return -EINVAL; | ||
1652 | + } | ||
1653 | + isp_reg_writel(offset & 0xffff, OMAP3_ISP_IOMEM_PREV, | ||
1654 | + ISPPRV_WADD_OFFSET); | ||
1655 | + return 0; | ||
1656 | +} | ||
1657 | +EXPORT_SYMBOL_GPL(isppreview_config_outlineoffset); | ||
1658 | + | ||
1659 | +/** | ||
1660 | + * isppreview_set_outaddr - Sets the memory address to store output frame | ||
1661 | + * @addr: 32bit memory address aligned on 32byte boundary. | ||
1662 | + * | ||
1663 | + * Configures the memory address to which the output frame is written. | ||
1664 | + **/ | ||
1665 | +int isppreview_set_outaddr(u32 addr) | ||
1666 | +{ | ||
1667 | + if ((addr & ISP_32B_BOUNDARY_BUF) != addr) { | ||
1668 | + printk(KERN_ERR "ISP_ERR: Address should be in 32 byte " | ||
1669 | + "boundary\n"); | ||
1670 | + return -EINVAL; | ||
1671 | + } | ||
1672 | + isp_reg_writel(addr, OMAP3_ISP_IOMEM_PREV, ISPPRV_WSDR_ADDR); | ||
1673 | + return 0; | ||
1674 | +} | ||
1675 | +EXPORT_SYMBOL_GPL(isppreview_set_outaddr); | ||
1676 | + | ||
1677 | +/** | ||
1678 | + * isppreview_config_darklineoffset - Sets the Dark frame address line offset. | ||
1679 | + * @offset: Line Offset for the Darkframe. | ||
1680 | + **/ | ||
1681 | +int isppreview_config_darklineoffset(u32 offset) | ||
1682 | +{ | ||
1683 | + if ((offset & ISP_32B_BOUNDARY_OFFSET) != offset) { | ||
1684 | + printk(KERN_ERR "ISP_ERR : Offset should be in 32 byte " | ||
1685 | + "boundary\n"); | ||
1686 | + return -EINVAL; | ||
1687 | + } | ||
1688 | + isp_reg_writel(offset & 0xffff, OMAP3_ISP_IOMEM_PREV, | ||
1689 | + ISPPRV_DRKF_OFFSET); | ||
1690 | + return 0; | ||
1691 | +} | ||
1692 | +EXPORT_SYMBOL_GPL(isppreview_config_darklineoffset); | ||
1693 | + | ||
1694 | +/** | ||
1695 | + * isppreview_set_darkaddr - Sets the memory address to store Dark frame. | ||
1696 | + * @addr: 32bit memory address aligned on 32 bit boundary. | ||
1697 | + **/ | ||
1698 | +int isppreview_set_darkaddr(u32 addr) | ||
1699 | +{ | ||
1700 | + if ((addr & ISP_32B_BOUNDARY_BUF) != addr) { | ||
1701 | + printk(KERN_ERR "ISP_ERR : Address should be in 32 byte " | ||
1702 | + "boundary\n"); | ||
1703 | + return -EINVAL; | ||
1704 | + } | ||
1705 | + isp_reg_writel(addr, OMAP3_ISP_IOMEM_PREV, ISPPRV_DSDR_ADDR); | ||
1706 | + return 0; | ||
1707 | +} | ||
1708 | +EXPORT_SYMBOL_GPL(isppreview_set_darkaddr); | ||
1709 | + | ||
1710 | +void __isppreview_enable(int enable) | ||
1711 | +{ | ||
1712 | + if (enable) | ||
1713 | + isp_reg_or(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ISPPRV_PCR_EN); | ||
1714 | + else | ||
1715 | + isp_reg_and(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ~ISPPRV_PCR_EN); | ||
1716 | +} | ||
1717 | + | ||
1718 | +/** | ||
1719 | + * isppreview_enable - Enables the Preview module. | ||
1720 | + * @enable: 1 - Enables the preview module. | ||
1721 | + * | ||
1722 | + * Client should configure all the sub modules in Preview before this. | ||
1723 | + **/ | ||
1724 | +void isppreview_enable(int enable) | ||
1725 | +{ | ||
1726 | + __isppreview_enable(enable); | ||
1727 | + ispprev_obj.pm_state = enable; | ||
1728 | +} | ||
1729 | +EXPORT_SYMBOL_GPL(isppreview_enable); | ||
1730 | + | ||
1731 | +/** | ||
1732 | + * isppreview_suspend - Suspend Preview module. | ||
1733 | + **/ | ||
1734 | +void isppreview_suspend(void) | ||
1735 | +{ | ||
1736 | + if (ispprev_obj.pm_state) | ||
1737 | + __isppreview_enable(0); | ||
1738 | +} | ||
1739 | +EXPORT_SYMBOL_GPL(isppreview_suspend); | ||
1740 | + | ||
1741 | +/** | ||
1742 | + * isppreview_resume - Resume Preview module. | ||
1743 | + **/ | ||
1744 | +void isppreview_resume(void) | ||
1745 | +{ | ||
1746 | + if (ispprev_obj.pm_state) | ||
1747 | + __isppreview_enable(1); | ||
1748 | +} | ||
1749 | +EXPORT_SYMBOL_GPL(isppreview_resume); | ||
1750 | + | ||
1751 | + | ||
1752 | +/** | ||
1753 | + * isppreview_busy - Gets busy state of preview module. | ||
1754 | + **/ | ||
1755 | +int isppreview_busy(void) | ||
1756 | +{ | ||
1757 | + return isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR) & | ||
1758 | + ISPPRV_PCR_BUSY; | ||
1759 | +} | ||
1760 | +EXPORT_SYMBOL_GPL(isppreview_busy); | ||
1761 | + | ||
1762 | +/** | ||
1763 | + * isppreview_get_config - Gets parameters of preview module. | ||
1764 | + **/ | ||
1765 | +struct prev_params *isppreview_get_config(void) | ||
1766 | +{ | ||
1767 | + return prev_config_params; | ||
1768 | +} | ||
1769 | +EXPORT_SYMBOL_GPL(isppreview_get_config); | ||
1770 | + | ||
1771 | +/** | ||
1772 | + * isppreview_save_context - Saves the values of the preview module registers. | ||
1773 | + **/ | ||
1774 | +void isppreview_save_context(void) | ||
1775 | +{ | ||
1776 | + DPRINTK_ISPPREV("Saving context\n"); | ||
1777 | + isp_save_context(ispprev_reg_list); | ||
1778 | +} | ||
1779 | +EXPORT_SYMBOL_GPL(isppreview_save_context); | ||
1780 | + | ||
1781 | +/** | ||
1782 | + * isppreview_restore_context - Restores the values of preview module registers | ||
1783 | + **/ | ||
1784 | +void isppreview_restore_context(void) | ||
1785 | +{ | ||
1786 | + DPRINTK_ISPPREV("Restoring context\n"); | ||
1787 | + isp_restore_context(ispprev_reg_list); | ||
1788 | +} | ||
1789 | +EXPORT_SYMBOL_GPL(isppreview_restore_context); | ||
1790 | + | ||
1791 | +/** | ||
1792 | + * isppreview_print_status - Prints the values of the Preview Module registers. | ||
1793 | + * | ||
1794 | + * Also prints other debug information stored in the preview moduel. | ||
1795 | + **/ | ||
1796 | +void isppreview_print_status(void) | ||
1797 | +{ | ||
1798 | + DPRINTK_ISPPREV("Module in use =%d\n", ispprev_obj.prev_inuse); | ||
1799 | + DPRINTK_ISPPREV("Preview Input format =%d, Output Format =%d\n", | ||
1800 | + ispprev_obj.prev_inpfmt, | ||
1801 | + ispprev_obj.prev_outfmt); | ||
1802 | + DPRINTK_ISPPREV("Accepted Preview Input (width = %d,Height = %d)\n", | ||
1803 | + ispprev_obj.previn_w, | ||
1804 | + ispprev_obj.previn_h); | ||
1805 | + DPRINTK_ISPPREV("Accepted Preview Output (width = %d,Height = %d)\n", | ||
1806 | + ispprev_obj.prevout_w, | ||
1807 | + ispprev_obj.prevout_h); | ||
1808 | + DPRINTK_ISPPREV("###ISP_CTRL in preview =0x%x\n", | ||
1809 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL)); | ||
1810 | + DPRINTK_ISPPREV("###ISP_IRQ0ENABLE in preview =0x%x\n", | ||
1811 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE)); | ||
1812 | + DPRINTK_ISPPREV("###ISP_IRQ0STATUS in preview =0x%x\n", | ||
1813 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS)); | ||
1814 | + DPRINTK_ISPPREV("###PRV PCR =0x%x\n", | ||
1815 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR)); | ||
1816 | + DPRINTK_ISPPREV("###PRV HORZ_INFO =0x%x\n", | ||
1817 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO)); | ||
1818 | + DPRINTK_ISPPREV("###PRV VERT_INFO =0x%x\n", | ||
1819 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_VERT_INFO)); | ||
1820 | + DPRINTK_ISPPREV("###PRV WSDR_ADDR =0x%x\n", | ||
1821 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_WSDR_ADDR)); | ||
1822 | + DPRINTK_ISPPREV("###PRV WADD_OFFSET =0x%x\n", | ||
1823 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, | ||
1824 | + ISPPRV_WADD_OFFSET)); | ||
1825 | + DPRINTK_ISPPREV("###PRV AVE =0x%x\n", | ||
1826 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE)); | ||
1827 | + DPRINTK_ISPPREV("###PRV HMED =0x%x\n", | ||
1828 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_HMED)); | ||
1829 | + DPRINTK_ISPPREV("###PRV NF =0x%x\n", | ||
1830 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_NF)); | ||
1831 | + DPRINTK_ISPPREV("###PRV WB_DGAIN =0x%x\n", | ||
1832 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_WB_DGAIN)); | ||
1833 | + DPRINTK_ISPPREV("###PRV WBGAIN =0x%x\n", | ||
1834 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_WBGAIN)); | ||
1835 | + DPRINTK_ISPPREV("###PRV WBSEL =0x%x\n", | ||
1836 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_WBSEL)); | ||
1837 | + DPRINTK_ISPPREV("###PRV CFA =0x%x\n", | ||
1838 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_CFA)); | ||
1839 | + DPRINTK_ISPPREV("###PRV BLKADJOFF =0x%x\n", | ||
1840 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_BLKADJOFF)); | ||
1841 | + DPRINTK_ISPPREV("###PRV RGB_MAT1 =0x%x\n", | ||
1842 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT1)); | ||
1843 | + DPRINTK_ISPPREV("###PRV RGB_MAT2 =0x%x\n", | ||
1844 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT2)); | ||
1845 | + DPRINTK_ISPPREV("###PRV RGB_MAT3 =0x%x\n", | ||
1846 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT3)); | ||
1847 | + DPRINTK_ISPPREV("###PRV RGB_MAT4 =0x%x\n", | ||
1848 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT4)); | ||
1849 | + DPRINTK_ISPPREV("###PRV RGB_MAT5 =0x%x\n", | ||
1850 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT5)); | ||
1851 | + DPRINTK_ISPPREV("###PRV RGB_OFF1 =0x%x\n", | ||
1852 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF1)); | ||
1853 | + DPRINTK_ISPPREV("###PRV RGB_OFF2 =0x%x\n", | ||
1854 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF2)); | ||
1855 | + DPRINTK_ISPPREV("###PRV CSC0 =0x%x\n", | ||
1856 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC0)); | ||
1857 | + DPRINTK_ISPPREV("###PRV CSC1 =0x%x\n", | ||
1858 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC1)); | ||
1859 | + DPRINTK_ISPPREV("###PRV CSC2 =0x%x\n", | ||
1860 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC2)); | ||
1861 | + DPRINTK_ISPPREV("###PRV CSC_OFFSET =0x%x\n", | ||
1862 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC_OFFSET)); | ||
1863 | + DPRINTK_ISPPREV("###PRV CNT_BRT =0x%x\n", | ||
1864 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT)); | ||
1865 | + DPRINTK_ISPPREV("###PRV CSUP =0x%x\n", | ||
1866 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_CSUP)); | ||
1867 | + DPRINTK_ISPPREV("###PRV SETUP_YC =0x%x\n", | ||
1868 | + isp_reg_readl(OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC)); | ||
1869 | +} | ||
1870 | +EXPORT_SYMBOL_GPL(isppreview_print_status); | ||
1871 | + | ||
1872 | +/** | ||
1873 | + * isp_preview_init - Module Initialization. | ||
1874 | + **/ | ||
1875 | +int __init isp_preview_init(void) | ||
1876 | +{ | ||
1877 | + int i = 0; | ||
1878 | + | ||
1879 | + prev_config_params = kmalloc(sizeof(*prev_config_params), GFP_KERNEL); | ||
1880 | + if (!prev_config_params) { | ||
1881 | + printk(KERN_ERR "Can't get memory for isp_preview params!\n"); | ||
1882 | + return -ENOMEM; | ||
1883 | + } | ||
1884 | + params = prev_config_params; | ||
1885 | + | ||
1886 | + ispprev_obj.prev_inuse = 0; | ||
1887 | + mutex_init(&ispprev_obj.ispprev_mutex); | ||
1888 | + | ||
1889 | + /* Init values */ | ||
1890 | + ispprev_obj.sph = 2; | ||
1891 | + ispprev_obj.slv = 0; | ||
1892 | + ispprev_obj.color = V4L2_COLORFX_NONE; | ||
1893 | + ispprev_obj.contrast = ISPPRV_CONTRAST_DEF; | ||
1894 | + params->contrast = ISPPRV_CONTRAST_DEF; | ||
1895 | + ispprev_obj.brightness = ISPPRV_BRIGHT_DEF; | ||
1896 | + params->brightness = ISPPRV_BRIGHT_DEF; | ||
1897 | + params->average = NO_AVE; | ||
1898 | + params->lens_shading_shift = 0; | ||
1899 | + params->pix_fmt = YCPOS_YCrYCb; | ||
1900 | + params->cfa.cfafmt = CFAFMT_BAYER; | ||
1901 | + params->cfa.cfa_table = cfa_coef_table; | ||
1902 | + params->cfa.cfa_gradthrs_horz = FLR_CFA_GRADTHRS_HORZ; | ||
1903 | + params->cfa.cfa_gradthrs_vert = FLR_CFA_GRADTHRS_VERT; | ||
1904 | + params->csup.gain = FLR_CSUP_GAIN; | ||
1905 | + params->csup.thres = FLR_CSUP_THRES; | ||
1906 | + params->csup.hypf_en = 0; | ||
1907 | + params->ytable = luma_enhance_table; | ||
1908 | + params->nf.spread = FLR_NF_STRGTH; | ||
1909 | + memcpy(params->nf.table, noise_filter_table, sizeof(params->nf.table)); | ||
1910 | + params->dcor.couplet_mode_en = 1; | ||
1911 | + for (i = 0; i < 4; i++) | ||
1912 | + params->dcor.detect_correct[i] = 0xE; | ||
1913 | + params->gtable.bluetable = bluegamma_table; | ||
1914 | + params->gtable.greentable = greengamma_table; | ||
1915 | + params->gtable.redtable = redgamma_table; | ||
1916 | + params->wbal.dgain = FLR_WBAL_DGAIN; | ||
1917 | + if (omap_rev() > OMAP3430_REV_ES1_0) { | ||
1918 | + params->wbal.coef0 = FLR_WBAL_COEF0_ES1; | ||
1919 | + params->wbal.coef1 = FLR_WBAL_COEF1_ES1; | ||
1920 | + params->wbal.coef2 = FLR_WBAL_COEF2_ES1; | ||
1921 | + params->wbal.coef3 = FLR_WBAL_COEF3_ES1; | ||
1922 | + } else { | ||
1923 | + params->wbal.coef0 = FLR_WBAL_COEF0; | ||
1924 | + params->wbal.coef1 = FLR_WBAL_COEF1; | ||
1925 | + params->wbal.coef2 = FLR_WBAL_COEF2; | ||
1926 | + params->wbal.coef3 = FLR_WBAL_COEF3; | ||
1927 | + } | ||
1928 | + params->blk_adj.red = FLR_BLKADJ_RED; | ||
1929 | + params->blk_adj.green = FLR_BLKADJ_GREEN; | ||
1930 | + params->blk_adj.blue = FLR_BLKADJ_BLUE; | ||
1931 | + params->rgb2rgb = flr_rgb2rgb; | ||
1932 | + params->rgb2ycbcr = flr_prev_csc[ispprev_obj.color]; | ||
1933 | + | ||
1934 | + params->features = PREV_CFA | PREV_DEFECT_COR | PREV_NOISE_FILTER; | ||
1935 | + params->features &= ~(PREV_AVERAGER | PREV_INVERSE_ALAW | | ||
1936 | + PREV_HORZ_MEDIAN_FILTER | | ||
1937 | + PREV_GAMMA_BYPASS | | ||
1938 | + PREV_DARK_FRAME_SUBTRACT | | ||
1939 | + PREV_LENS_SHADING | | ||
1940 | + PREV_DARK_FRAME_CAPTURE | | ||
1941 | + PREV_CHROMA_SUPPRESS | | ||
1942 | + PREV_LUMA_ENHANCE); | ||
1943 | + return 0; | ||
1944 | +} | ||
1945 | + | ||
1946 | +/** | ||
1947 | + * isp_preview_cleanup - Module Cleanup. | ||
1948 | + **/ | ||
1949 | +void isp_preview_cleanup(void) | ||
1950 | +{ | ||
1951 | + kfree(prev_config_params); | ||
1952 | +} | ||
1953 | diff --git a/drivers/media/video/isp/isppreview.h b/drivers/media/video/isp/isppreview.h | ||
1954 | new file mode 100644 | ||
1955 | index 0000000..e88c329 | ||
1956 | --- /dev/null | ||
1957 | +++ b/drivers/media/video/isp/isppreview.h | ||
1958 | @@ -0,0 +1,354 @@ | ||
1959 | +/* | ||
1960 | + * isppreview.h | ||
1961 | + * | ||
1962 | + * Driver header file for Preview module in TI's OMAP3 Camera ISP | ||
1963 | + * | ||
1964 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
1965 | + * | ||
1966 | + * Contributors: | ||
1967 | + * Senthilvadivu Guruswamy <svadivu@ti.com> | ||
1968 | + * Pallavi Kulkarni <p-kulkarni@ti.com> | ||
1969 | + * Sergio Aguirre <saaguirre@ti.com> | ||
1970 | + * | ||
1971 | + * This package is free software; you can redistribute it and/or modify | ||
1972 | + * it under the terms of the GNU General Public License version 2 as | ||
1973 | + * published by the Free Software Foundation. | ||
1974 | + * | ||
1975 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
1976 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
1977 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
1978 | + */ | ||
1979 | + | ||
1980 | +#ifndef OMAP_ISP_PREVIEW_H | ||
1981 | +#define OMAP_ISP_PREVIEW_H | ||
1982 | + | ||
1983 | +#include <mach/isp_user.h> | ||
1984 | +/* Isp query control structure */ | ||
1985 | + | ||
1986 | +#define ISPPRV_BRIGHT_STEP 0x1 | ||
1987 | +#define ISPPRV_BRIGHT_DEF 0x0 | ||
1988 | +#define ISPPRV_BRIGHT_LOW 0x0 | ||
1989 | +#define ISPPRV_BRIGHT_HIGH 0xF | ||
1990 | +#define ISPPRV_BRIGHT_UNITS 0x7 | ||
1991 | + | ||
1992 | +#define ISPPRV_CONTRAST_STEP 0x1 | ||
1993 | +#define ISPPRV_CONTRAST_DEF 0x4 | ||
1994 | +#define ISPPRV_CONTRAST_LOW 0x0 | ||
1995 | +#define ISPPRV_CONTRAST_HIGH 0xF | ||
1996 | +#define ISPPRV_CONTRAST_UNITS 0x4 | ||
1997 | + | ||
1998 | +#define NO_AVE 0x0 | ||
1999 | +#define AVE_2_PIX 0x1 | ||
2000 | +#define AVE_4_PIX 0x2 | ||
2001 | +#define AVE_8_PIX 0x3 | ||
2002 | +#define AVE_ODD_PIXEL_DIST (1 << 4) /* For Bayer Sensors */ | ||
2003 | +#define AVE_EVEN_PIXEL_DIST (1 << 2) | ||
2004 | + | ||
2005 | +#define WB_GAIN_MAX 4 | ||
2006 | + | ||
2007 | +/* Features list */ | ||
2008 | +#define PREV_AVERAGER (1 << 0) | ||
2009 | +#define PREV_INVERSE_ALAW (1 << 1) | ||
2010 | +#define PREV_HORZ_MEDIAN_FILTER (1 << 2) | ||
2011 | +#define PREV_NOISE_FILTER (1 << 3) | ||
2012 | +#define PREV_CFA (1 << 4) | ||
2013 | +#define PREV_GAMMA_BYPASS (1 << 5) | ||
2014 | +#define PREV_LUMA_ENHANCE (1 << 6) | ||
2015 | +#define PREV_CHROMA_SUPPRESS (1 << 7) | ||
2016 | +#define PREV_DARK_FRAME_SUBTRACT (1 << 8) | ||
2017 | +#define PREV_LENS_SHADING (1 << 9) | ||
2018 | +#define PREV_DARK_FRAME_CAPTURE (1 << 10) | ||
2019 | +#define PREV_DEFECT_COR (1 << 11) | ||
2020 | + | ||
2021 | + | ||
2022 | +#define ISP_NF_TABLE_SIZE (1 << 10) | ||
2023 | + | ||
2024 | +#define ISP_GAMMA_TABLE_SIZE (1 << 10) | ||
2025 | + | ||
2026 | +/* Table addresses */ | ||
2027 | +#define ISPPRV_TBL_ADDR_RED_G_START 0x00 | ||
2028 | +#define ISPPRV_TBL_ADDR_BLUE_G_START 0x800 | ||
2029 | +#define ISPPRV_TBL_ADDR_GREEN_G_START 0x400 | ||
2030 | + | ||
2031 | +/* | ||
2032 | + *Enumeration Constants for input and output format | ||
2033 | + */ | ||
2034 | +enum preview_input { | ||
2035 | + PRV_RAW_CCDC, | ||
2036 | + PRV_RAW_MEM, | ||
2037 | + PRV_RGBBAYERCFA, | ||
2038 | + PRV_COMPCFA, | ||
2039 | + PRV_CCDC_DRKF, | ||
2040 | + PRV_OTHERS | ||
2041 | +}; | ||
2042 | +enum preview_output { | ||
2043 | + PREVIEW_RSZ, | ||
2044 | + PREVIEW_MEM | ||
2045 | +}; | ||
2046 | +/* | ||
2047 | + * Configure byte layout of YUV image | ||
2048 | + */ | ||
2049 | +enum preview_ycpos_mode { | ||
2050 | + YCPOS_YCrYCb = 0, | ||
2051 | + YCPOS_YCbYCr = 1, | ||
2052 | + YCPOS_CbYCrY = 2, | ||
2053 | + YCPOS_CrYCbY = 3 | ||
2054 | +}; | ||
2055 | + | ||
2056 | +/** | ||
2057 | + * struct ispprev_gtable - Structure for Gamma Correction. | ||
2058 | + * @redtable: Pointer to the red gamma table. | ||
2059 | + * @greentable: Pointer to the green gamma table. | ||
2060 | + * @bluetable: Pointer to the blue gamma table. | ||
2061 | + */ | ||
2062 | +struct ispprev_gtable { | ||
2063 | + u32 *redtable; | ||
2064 | + u32 *greentable; | ||
2065 | + u32 *bluetable; | ||
2066 | +}; | ||
2067 | + | ||
2068 | +/** | ||
2069 | + * struct prev_white_balance - Structure for White Balance 2. | ||
2070 | + * @wb_dgain: White balance common gain. | ||
2071 | + * @wb_gain: Individual color gains. | ||
2072 | + * @wb_coefmatrix: Coefficient matrix | ||
2073 | + */ | ||
2074 | +struct prev_white_balance { | ||
2075 | + u16 wb_dgain; /* white balance common gain */ | ||
2076 | + u8 wb_gain[WB_GAIN_MAX]; /* individual color gains */ | ||
2077 | + u8 wb_coefmatrix[WB_GAIN_MAX][WB_GAIN_MAX]; | ||
2078 | +}; | ||
2079 | + | ||
2080 | +/** | ||
2081 | + * struct prev_size_params - Structure for size parameters. | ||
2082 | + * @hstart: Starting pixel. | ||
2083 | + * @vstart: Starting line. | ||
2084 | + * @hsize: Width of input image. | ||
2085 | + * @vsize: Height of input image. | ||
2086 | + * @pixsize: Pixel size of the image in terms of bits. | ||
2087 | + * @in_pitch: Line offset of input image. | ||
2088 | + * @out_pitch: Line offset of output image. | ||
2089 | + */ | ||
2090 | +struct prev_size_params { | ||
2091 | + unsigned int hstart; | ||
2092 | + unsigned int vstart; | ||
2093 | + unsigned int hsize; | ||
2094 | + unsigned int vsize; | ||
2095 | + unsigned char pixsize; | ||
2096 | + unsigned short in_pitch; | ||
2097 | + unsigned short out_pitch; | ||
2098 | +}; | ||
2099 | + | ||
2100 | +/** | ||
2101 | + * struct prev_rgb2ycbcr_coeffs - Structure RGB2YCbCr parameters. | ||
2102 | + * @coeff: Color conversion gains in 3x3 matrix. | ||
2103 | + * @offset: Color conversion offsets. | ||
2104 | + */ | ||
2105 | +struct prev_rgb2ycbcr_coeffs { | ||
2106 | + short coeff[RGB_MAX][RGB_MAX]; | ||
2107 | + short offset[RGB_MAX]; | ||
2108 | +}; | ||
2109 | + | ||
2110 | +/** | ||
2111 | + * struct prev_darkfrm_params - Structure for Dark frame suppression. | ||
2112 | + * @addr: Memory start address. | ||
2113 | + * @offset: Line offset. | ||
2114 | + */ | ||
2115 | +struct prev_darkfrm_params { | ||
2116 | + u32 addr; | ||
2117 | + u32 offset; | ||
2118 | + }; | ||
2119 | + | ||
2120 | +/** | ||
2121 | + * struct prev_params - Structure for all configuration | ||
2122 | + * @features: Set of features enabled. | ||
2123 | + * @pix_fmt: Output pixel format. | ||
2124 | + * @cfa: CFA coefficients. | ||
2125 | + * @csup: Chroma suppression coefficients. | ||
2126 | + * @ytable: Pointer to Luma enhancement coefficients. | ||
2127 | + * @nf: Noise filter coefficients. | ||
2128 | + * @dcor: Noise filter coefficients. | ||
2129 | + * @gtable: Gamma coefficients. | ||
2130 | + * @wbal: White Balance parameters. | ||
2131 | + * @blk_adj: Black adjustment parameters. | ||
2132 | + * @rgb2rgb: RGB blending parameters. | ||
2133 | + * @rgb2ycbcr: RGB to ycbcr parameters. | ||
2134 | + * @hmf_params: Horizontal median filter. | ||
2135 | + * @size_params: Size parameters. | ||
2136 | + * @drkf_params: Darkframe parameters. | ||
2137 | + * @lens_shading_shift: | ||
2138 | + * @average: Downsampling rate for averager. | ||
2139 | + * @contrast: Contrast. | ||
2140 | + * @brightness: Brightness. | ||
2141 | + */ | ||
2142 | +struct prev_params { | ||
2143 | + u16 features; | ||
2144 | + enum preview_ycpos_mode pix_fmt; | ||
2145 | + struct ispprev_cfa cfa; | ||
2146 | + struct ispprev_csup csup; | ||
2147 | + u32 *ytable; | ||
2148 | + struct ispprev_nf nf; | ||
2149 | + struct ispprev_dcor dcor; | ||
2150 | + struct ispprev_gtable gtable; | ||
2151 | + struct ispprev_wbal wbal; | ||
2152 | + struct ispprev_blkadj blk_adj; | ||
2153 | + struct ispprev_rgbtorgb rgb2rgb; | ||
2154 | + struct ispprev_csc rgb2ycbcr; | ||
2155 | + struct ispprev_hmed hmf_params; | ||
2156 | + struct prev_size_params size_params; | ||
2157 | + struct prev_darkfrm_params drkf_params; | ||
2158 | + u8 lens_shading_shift; | ||
2159 | + u8 average; | ||
2160 | + u8 contrast; | ||
2161 | + u8 brightness; | ||
2162 | +}; | ||
2163 | + | ||
2164 | +/** | ||
2165 | + * struct isptables_update - Structure for Table Configuration. | ||
2166 | + * @update: Specifies which tables should be updated. | ||
2167 | + * @flag: Specifies which tables should be enabled. | ||
2168 | + * @prev_nf: Pointer to structure for Noise Filter | ||
2169 | + * @lsc: Pointer to LSC gain table. (currently not used) | ||
2170 | + * @red_gamma: Pointer to red gamma correction table. | ||
2171 | + * @green_gamma: Pointer to green gamma correction table. | ||
2172 | + * @blue_gamma: Pointer to blue gamma correction table. | ||
2173 | + */ | ||
2174 | +struct isptables_update { | ||
2175 | + u16 update; | ||
2176 | + u16 flag; | ||
2177 | + struct ispprev_nf *prev_nf; | ||
2178 | + u32 *lsc; | ||
2179 | + u32 *red_gamma; | ||
2180 | + u32 *green_gamma; | ||
2181 | + u32 *blue_gamma; | ||
2182 | +}; | ||
2183 | + | ||
2184 | +void isppreview_config_shadow_registers(void); | ||
2185 | + | ||
2186 | +int isppreview_request(void); | ||
2187 | + | ||
2188 | +int isppreview_free(void); | ||
2189 | + | ||
2190 | +int isppreview_config_datapath(enum preview_input input, | ||
2191 | + enum preview_output output); | ||
2192 | + | ||
2193 | +void isppreview_config_ycpos(enum preview_ycpos_mode mode); | ||
2194 | + | ||
2195 | +void isppreview_config_averager(u8 average); | ||
2196 | + | ||
2197 | +void isppreview_enable_invalaw(u8 enable); | ||
2198 | + | ||
2199 | +void isppreview_enable_drkframe(u8 enable); | ||
2200 | + | ||
2201 | +void isppreview_enable_shadcomp(u8 enable); | ||
2202 | + | ||
2203 | +void isppreview_config_drkf_shadcomp(u8 scomp_shtval); | ||
2204 | + | ||
2205 | +void isppreview_enable_gammabypass(u8 enable); | ||
2206 | + | ||
2207 | +void isppreview_enable_hmed(u8 enable); | ||
2208 | + | ||
2209 | +void isppreview_config_hmed(struct ispprev_hmed); | ||
2210 | + | ||
2211 | +void isppreview_enable_noisefilter(u8 enable); | ||
2212 | + | ||
2213 | +void isppreview_config_noisefilter(struct ispprev_nf prev_nf); | ||
2214 | + | ||
2215 | +void isppreview_enable_dcor(u8 enable); | ||
2216 | + | ||
2217 | +void isppreview_config_dcor(struct ispprev_dcor prev_dcor); | ||
2218 | + | ||
2219 | + | ||
2220 | +void isppreview_config_cfa(struct ispprev_cfa); | ||
2221 | + | ||
2222 | +void isppreview_config_gammacorrn(struct ispprev_gtable); | ||
2223 | + | ||
2224 | +void isppreview_config_chroma_suppression(struct ispprev_csup csup); | ||
2225 | + | ||
2226 | +void isppreview_enable_cfa(u8 enable); | ||
2227 | + | ||
2228 | +void isppreview_config_luma_enhancement(u32 *ytable); | ||
2229 | + | ||
2230 | +void isppreview_enable_luma_enhancement(u8 enable); | ||
2231 | + | ||
2232 | +void isppreview_enable_chroma_suppression(u8 enable); | ||
2233 | + | ||
2234 | +void isppreview_config_whitebalance(struct ispprev_wbal); | ||
2235 | + | ||
2236 | +void isppreview_config_blkadj(struct ispprev_blkadj); | ||
2237 | + | ||
2238 | +void isppreview_config_rgb_blending(struct ispprev_rgbtorgb); | ||
2239 | + | ||
2240 | +void isppreview_config_rgb_to_ycbcr(struct ispprev_csc); | ||
2241 | + | ||
2242 | +void isppreview_update_contrast(u8 *contrast); | ||
2243 | + | ||
2244 | +void isppreview_query_contrast(u8 *contrast); | ||
2245 | + | ||
2246 | +void isppreview_config_contrast(u8 contrast); | ||
2247 | + | ||
2248 | +void isppreview_get_contrast_range(u8 *min_contrast, u8 *max_contrast); | ||
2249 | + | ||
2250 | +void isppreview_update_brightness(u8 *brightness); | ||
2251 | + | ||
2252 | +void isppreview_config_brightness(u8 brightness); | ||
2253 | + | ||
2254 | +void isppreview_get_brightness_range(u8 *min_brightness, u8 *max_brightness); | ||
2255 | + | ||
2256 | +void isppreview_set_color(u8 *mode); | ||
2257 | + | ||
2258 | +void isppreview_get_color(u8 *mode); | ||
2259 | + | ||
2260 | +void isppreview_query_brightness(u8 *brightness); | ||
2261 | + | ||
2262 | +void isppreview_config_yc_range(struct ispprev_yclimit yclimit); | ||
2263 | + | ||
2264 | +int isppreview_try_size(u32 input_w, u32 input_h, u32 *output_w, | ||
2265 | + u32 *output_h); | ||
2266 | + | ||
2267 | +int isppreview_config_size(u32 input_w, u32 input_h, u32 output_w, | ||
2268 | + u32 output_h); | ||
2269 | + | ||
2270 | +int isppreview_config_inlineoffset(u32 offset); | ||
2271 | + | ||
2272 | +int isppreview_set_inaddr(u32 addr); | ||
2273 | + | ||
2274 | +int isppreview_config_outlineoffset(u32 offset); | ||
2275 | + | ||
2276 | +int isppreview_set_outaddr(u32 addr); | ||
2277 | + | ||
2278 | +int isppreview_config_darklineoffset(u32 offset); | ||
2279 | + | ||
2280 | +int isppreview_set_darkaddr(u32 addr); | ||
2281 | + | ||
2282 | +void isppreview_enable(int enable); | ||
2283 | + | ||
2284 | +void isppreview_suspend(void); | ||
2285 | + | ||
2286 | +void isppreview_resume(void); | ||
2287 | + | ||
2288 | +int isppreview_busy(void); | ||
2289 | + | ||
2290 | +struct prev_params *isppreview_get_config(void); | ||
2291 | + | ||
2292 | +void isppreview_print_status(void); | ||
2293 | + | ||
2294 | +#ifndef CONFIG_ARCH_OMAP3410 | ||
2295 | +void isppreview_save_context(void); | ||
2296 | +#else | ||
2297 | +static inline void isppreview_save_context(void) {} | ||
2298 | +#endif | ||
2299 | + | ||
2300 | +#ifndef CONFIG_ARCH_OMAP3410 | ||
2301 | +void isppreview_restore_context(void); | ||
2302 | +#else | ||
2303 | +static inline void isppreview_restore_context(void) {} | ||
2304 | +#endif | ||
2305 | + | ||
2306 | +int omap34xx_isp_preview_config(void *userspace_add); | ||
2307 | + | ||
2308 | +int omap34xx_isp_tables_update(struct isptables_update *isptables_struct); | ||
2309 | + | ||
2310 | +void isppreview_set_skip(u32 h, u32 v); | ||
2311 | + | ||
2312 | +#endif/* OMAP_ISP_PREVIEW_H */ | ||
2313 | diff --git a/drivers/media/video/isp/ispresizer.c b/drivers/media/video/isp/ispresizer.c | ||
2314 | new file mode 100644 | ||
2315 | index 0000000..f78ddb3 | ||
2316 | --- /dev/null | ||
2317 | +++ b/drivers/media/video/isp/ispresizer.c | ||
2318 | @@ -0,0 +1,928 @@ | ||
2319 | +/* | ||
2320 | + * ispresizer.c | ||
2321 | + * | ||
2322 | + * Driver Library for Resizer module in TI's OMAP3 Camera ISP | ||
2323 | + * | ||
2324 | + * Copyright (C)2009 Texas Instruments, Inc. | ||
2325 | + * | ||
2326 | + * Contributors: | ||
2327 | + * Sameer Venkatraman <sameerv@ti.com> | ||
2328 | + * Mohit Jalori | ||
2329 | + * Sergio Aguirre <saaguirre@ti.com> | ||
2330 | + * | ||
2331 | + * This package is free software; you can redistribute it and/or modify | ||
2332 | + * it under the terms of the GNU General Public License version 2 as | ||
2333 | + * published by the Free Software Foundation. | ||
2334 | + * | ||
2335 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
2336 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
2337 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
2338 | + */ | ||
2339 | + | ||
2340 | +#include <linux/module.h> | ||
2341 | + | ||
2342 | +#include "isp.h" | ||
2343 | +#include "ispreg.h" | ||
2344 | +#include "ispresizer.h" | ||
2345 | + | ||
2346 | +/* Default configuration of resizer,filter coefficients,yenh for camera isp */ | ||
2347 | +static struct isprsz_yenh ispreszdefaultyenh = {0, 0, 0, 0}; | ||
2348 | +static struct isprsz_coef ispreszdefcoef = { | ||
2349 | + { | ||
2350 | + 0x0027, 0x00B2, 0x00B2, 0x0027, | ||
2351 | + 0x0027, 0x00B2, 0x0027, 0x00B2, | ||
2352 | + 0x0027, 0x00B2, 0x0027, 0x00B2, | ||
2353 | + 0x0027, 0x00B2, 0x0027, 0x00B2, | ||
2354 | + 0x0027, 0x00B2, 0x0027, 0x00B2, | ||
2355 | + 0x0027, 0x00B2, 0x0027, 0x00B2, | ||
2356 | + 0x0027, 0x00B2, 0x0027, 0x00B2, | ||
2357 | + 0x0027, 0x00B2, 0x0027, 0x00B2, | ||
2358 | + }, | ||
2359 | + { | ||
2360 | + 0x0000, 0x0100, 0x0000, 0x0000, | ||
2361 | + 0x03FA, 0x00F6, 0x0010, 0x0000, | ||
2362 | + 0x03F9, 0x00DB, 0x002C, 0x0000, | ||
2363 | + 0x03FB, 0x00B3, 0x0053, 0x03FF, | ||
2364 | + 0x03FD, 0x0082, 0x0084, 0x03FD, | ||
2365 | + 0x03FF, 0x0053, 0x00B3, 0x03FB, | ||
2366 | + 0x0000, 0x002C, 0x00DB, 0x03F9, | ||
2367 | + 0x0000, 0x0010, 0x00F6, 0x03FA | ||
2368 | + }, | ||
2369 | + { | ||
2370 | + 0x0004, 0x0023, 0x0023, 0x005A, | ||
2371 | + 0x005A, 0x0058, 0x0058, 0x0004, | ||
2372 | + 0x0023, 0x0023, 0x005A, 0x005A, | ||
2373 | + 0x0058, 0x0058, 0x0004, 0x0023, | ||
2374 | + 0x0023, 0x005A, 0x005A, 0x0058, | ||
2375 | + 0x0058, 0x0004, 0x0023, 0x0023, | ||
2376 | + 0x005A, 0x005A, 0x0058, 0x0058 | ||
2377 | + }, | ||
2378 | + { | ||
2379 | + 0x0004, 0x0023, 0x005A, 0x0058, | ||
2380 | + 0x0023, 0x0004, 0x0000, 0x0002, | ||
2381 | + 0x0018, 0x004d, 0x0060, 0x0031, | ||
2382 | + 0x0008, 0x0000, 0x0001, 0x000f, | ||
2383 | + 0x003f, 0x0062, 0x003f, 0x000f, | ||
2384 | + 0x0001, 0x0000, 0x0008, 0x0031, | ||
2385 | + 0x0060, 0x004d, 0x0018, 0x0002 | ||
2386 | + } | ||
2387 | +}; | ||
2388 | + | ||
2389 | +/** | ||
2390 | + * struct isp_res - Structure for the resizer module to store its information. | ||
2391 | + * @res_inuse: Indicates if resizer module has been reserved. 1 - Reserved, | ||
2392 | + * 0 - Freed. | ||
2393 | + * @h_startphase: Horizontal starting phase. | ||
2394 | + * @v_startphase: Vertical starting phase. | ||
2395 | + * @h_resz: Horizontal resizing value. | ||
2396 | + * @v_resz: Vertical resizing value. | ||
2397 | + * @outputwidth: Output Image Width in pixels. | ||
2398 | + * @outputheight: Output Image Height in pixels. | ||
2399 | + * @inputwidth: Input Image Width in pixels. | ||
2400 | + * @inputheight: Input Image Height in pixels. | ||
2401 | + * @algo: Algorithm select. 0 - Disable, 1 - [-1 2 -1]/2 high-pass filter, | ||
2402 | + * 2 - [-1 -2 6 -2 -1]/4 high-pass filter. | ||
2403 | + * @ipht_crop: Vertical start line for cropping. | ||
2404 | + * @ipwd_crop: Horizontal start pixel for cropping. | ||
2405 | + * @cropwidth: Crop Width. | ||
2406 | + * @cropheight: Crop Height. | ||
2407 | + * @resinput: Resizer input. | ||
2408 | + * @coeflist: Register configuration for Resizer. | ||
2409 | + * @ispres_mutex: Mutex for isp resizer. | ||
2410 | + */ | ||
2411 | +static struct isp_res { | ||
2412 | + int pm_state; | ||
2413 | + u8 res_inuse; | ||
2414 | + u8 h_startphase; | ||
2415 | + u8 v_startphase; | ||
2416 | + u16 h_resz; | ||
2417 | + u16 v_resz; | ||
2418 | + u32 outputwidth; | ||
2419 | + u32 outputheight; | ||
2420 | + u32 inputwidth; | ||
2421 | + u32 inputheight; | ||
2422 | + u8 algo; | ||
2423 | + u32 ipht_crop; | ||
2424 | + u32 ipwd_crop; | ||
2425 | + u32 cropwidth; | ||
2426 | + u32 cropheight; | ||
2427 | + dma_addr_t tmp_buf; | ||
2428 | + enum ispresizer_input resinput; | ||
2429 | + struct isprsz_coef coeflist; | ||
2430 | + struct mutex ispres_mutex; /* For checking/modifying res_inuse */ | ||
2431 | +} ispres_obj; | ||
2432 | + | ||
2433 | +/* Structure for saving/restoring resizer module registers */ | ||
2434 | +static struct isp_reg isprsz_reg_list[] = { | ||
2435 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, 0x0000}, | ||
2436 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_OUT_SIZE, 0x0000}, | ||
2437 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_START, 0x0000}, | ||
2438 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_SIZE, 0x0000}, | ||
2439 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INADD, 0x0000}, | ||
2440 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INOFF, 0x0000}, | ||
2441 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTADD, 0x0000}, | ||
2442 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTOFF, 0x0000}, | ||
2443 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT10, 0x0000}, | ||
2444 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT32, 0x0000}, | ||
2445 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT54, 0x0000}, | ||
2446 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT76, 0x0000}, | ||
2447 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT98, 0x0000}, | ||
2448 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT1110, 0x0000}, | ||
2449 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT1312, 0x0000}, | ||
2450 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT1514, 0x0000}, | ||
2451 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT1716, 0x0000}, | ||
2452 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT1918, 0x0000}, | ||
2453 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT2120, 0x0000}, | ||
2454 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT2322, 0x0000}, | ||
2455 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT2524, 0x0000}, | ||
2456 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT2726, 0x0000}, | ||
2457 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT2928, 0x0000}, | ||
2458 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_HFILT3130, 0x0000}, | ||
2459 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT10, 0x0000}, | ||
2460 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT32, 0x0000}, | ||
2461 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT54, 0x0000}, | ||
2462 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT76, 0x0000}, | ||
2463 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT98, 0x0000}, | ||
2464 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT1110, 0x0000}, | ||
2465 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT1312, 0x0000}, | ||
2466 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT1514, 0x0000}, | ||
2467 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT1716, 0x0000}, | ||
2468 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT1918, 0x0000}, | ||
2469 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT2120, 0x0000}, | ||
2470 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT2322, 0x0000}, | ||
2471 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT2524, 0x0000}, | ||
2472 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT2726, 0x0000}, | ||
2473 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT2928, 0x0000}, | ||
2474 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_VFILT3130, 0x0000}, | ||
2475 | + {OMAP3_ISP_IOMEM_RESZ, ISPRSZ_YENH, 0x0000}, | ||
2476 | + {0, ISP_TOK_TERM, 0x0000} | ||
2477 | +}; | ||
2478 | + | ||
2479 | +/** | ||
2480 | + * ispresizer_config_shadow_registers - Configure shadow registers. | ||
2481 | + **/ | ||
2482 | +void ispresizer_config_shadow_registers() | ||
2483 | +{ | ||
2484 | + return; | ||
2485 | +} | ||
2486 | +EXPORT_SYMBOL(ispresizer_config_shadow_registers); | ||
2487 | + | ||
2488 | +/** | ||
2489 | + * ispresizer_trycrop - Validate crop dimensions. | ||
2490 | + * @left: Left distance to start position of crop. | ||
2491 | + * @top: Top distance to start position of crop. | ||
2492 | + * @width: Width of input image. | ||
2493 | + * @height: Height of input image. | ||
2494 | + * @ow: Width of output image. | ||
2495 | + * @oh: Height of output image. | ||
2496 | + **/ | ||
2497 | +void ispresizer_trycrop(u32 left, u32 top, u32 width, u32 height, u32 ow, | ||
2498 | + u32 oh) | ||
2499 | +{ | ||
2500 | + ispres_obj.cropwidth = width + 6; | ||
2501 | + ispres_obj.cropheight = height + 6; | ||
2502 | + ispresizer_try_size(&ispres_obj.cropwidth, &ispres_obj.cropheight, &ow, | ||
2503 | + &oh); | ||
2504 | + ispres_obj.ipht_crop = top; | ||
2505 | + ispres_obj.ipwd_crop = left; | ||
2506 | +} | ||
2507 | +EXPORT_SYMBOL(ispresizer_trycrop); | ||
2508 | + | ||
2509 | +/** | ||
2510 | + * ispresizer_applycrop - Apply crop to input image. | ||
2511 | + **/ | ||
2512 | +void ispresizer_applycrop(void) | ||
2513 | +{ | ||
2514 | + ispresizer_config_size(ispres_obj.cropwidth, ispres_obj.cropheight, | ||
2515 | + ispres_obj.outputwidth, | ||
2516 | + ispres_obj.outputheight); | ||
2517 | + return; | ||
2518 | +} | ||
2519 | +EXPORT_SYMBOL(ispresizer_applycrop); | ||
2520 | + | ||
2521 | +/** | ||
2522 | + * ispresizer_request - Reserves the Resizer module. | ||
2523 | + * | ||
2524 | + * Allows only one user at a time. | ||
2525 | + * | ||
2526 | + * Returns 0 if successful, or -EBUSY if resizer module was already requested. | ||
2527 | + **/ | ||
2528 | +int ispresizer_request() | ||
2529 | +{ | ||
2530 | + mutex_lock(&ispres_obj.ispres_mutex); | ||
2531 | + if (!ispres_obj.res_inuse) { | ||
2532 | + ispres_obj.res_inuse = 1; | ||
2533 | + mutex_unlock(&ispres_obj.ispres_mutex); | ||
2534 | + isp_reg_writel(isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL) | | ||
2535 | + ISPCTRL_SBL_WR0_RAM_EN | | ||
2536 | + ISPCTRL_RSZ_CLK_EN, | ||
2537 | + OMAP3_ISP_IOMEM_MAIN, ISP_CTRL); | ||
2538 | + return 0; | ||
2539 | + } else { | ||
2540 | + mutex_unlock(&ispres_obj.ispres_mutex); | ||
2541 | + printk(KERN_ERR "ISP_ERR : Resizer Module Busy\n"); | ||
2542 | + return -EBUSY; | ||
2543 | + } | ||
2544 | +} | ||
2545 | +EXPORT_SYMBOL(ispresizer_request); | ||
2546 | + | ||
2547 | +/** | ||
2548 | + * ispresizer_free - Makes Resizer module free. | ||
2549 | + * | ||
2550 | + * Returns 0 if successful, or -EINVAL if resizer module was already freed. | ||
2551 | + **/ | ||
2552 | +int ispresizer_free() | ||
2553 | +{ | ||
2554 | + mutex_lock(&ispres_obj.ispres_mutex); | ||
2555 | + if (ispres_obj.res_inuse) { | ||
2556 | + ispres_obj.res_inuse = 0; | ||
2557 | + mutex_unlock(&ispres_obj.ispres_mutex); | ||
2558 | + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, | ||
2559 | + ~(ISPCTRL_RSZ_CLK_EN | ISPCTRL_SBL_WR0_RAM_EN)); | ||
2560 | + return 0; | ||
2561 | + } else { | ||
2562 | + mutex_unlock(&ispres_obj.ispres_mutex); | ||
2563 | + DPRINTK_ISPRESZ("ISP_ERR : Resizer Module already freed\n"); | ||
2564 | + return -EINVAL; | ||
2565 | + } | ||
2566 | +} | ||
2567 | +EXPORT_SYMBOL(ispresizer_free); | ||
2568 | + | ||
2569 | +/** | ||
2570 | + * ispresizer_config_datapath - Specifies which input to use in resizer module | ||
2571 | + * @input: Indicates the module that gives the image to resizer. | ||
2572 | + * | ||
2573 | + * Sets up the default resizer configuration according to the arguments. | ||
2574 | + * | ||
2575 | + * Returns 0 if successful, or -EINVAL if an unsupported input was requested. | ||
2576 | + **/ | ||
2577 | +int ispresizer_config_datapath(enum ispresizer_input input) | ||
2578 | +{ | ||
2579 | + u32 cnt = 0; | ||
2580 | + DPRINTK_ISPRESZ("ispresizer_config_datapath()+\n"); | ||
2581 | + ispres_obj.resinput = input; | ||
2582 | + switch (input) { | ||
2583 | + case RSZ_OTFLY_YUV: | ||
2584 | + cnt &= ~ISPRSZ_CNT_INPTYP; | ||
2585 | + cnt &= ~ISPRSZ_CNT_INPSRC; | ||
2586 | + ispresizer_set_inaddr(0); | ||
2587 | + ispresizer_config_inlineoffset(0); | ||
2588 | + break; | ||
2589 | + case RSZ_MEM_YUV: | ||
2590 | + cnt |= ISPRSZ_CNT_INPSRC; | ||
2591 | + cnt &= ~ISPRSZ_CNT_INPTYP; | ||
2592 | + break; | ||
2593 | + case RSZ_MEM_COL8: | ||
2594 | + cnt |= ISPRSZ_CNT_INPSRC; | ||
2595 | + cnt |= ISPRSZ_CNT_INPTYP; | ||
2596 | + break; | ||
2597 | + default: | ||
2598 | + printk(KERN_ERR "ISP_ERR : Wrong Input\n"); | ||
2599 | + return -EINVAL; | ||
2600 | + } | ||
2601 | + isp_reg_or(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, cnt); | ||
2602 | + ispresizer_config_ycpos(0); | ||
2603 | + ispresizer_config_filter_coef(&ispreszdefcoef); | ||
2604 | + ispresizer_enable_cbilin(0); | ||
2605 | + ispresizer_config_luma_enhance(&ispreszdefaultyenh); | ||
2606 | + DPRINTK_ISPRESZ("ispresizer_config_datapath()-\n"); | ||
2607 | + return 0; | ||
2608 | +} | ||
2609 | +EXPORT_SYMBOL(ispresizer_config_datapath); | ||
2610 | + | ||
2611 | +/** | ||
2612 | + * ispresizer_try_size - Validates input and output images size. | ||
2613 | + * @input_w: input width for the resizer in number of pixels per line | ||
2614 | + * @input_h: input height for the resizer in number of lines | ||
2615 | + * @output_w: output width from the resizer in number of pixels per line | ||
2616 | + * resizer when writing to memory needs this to be multiple of 16. | ||
2617 | + * @output_h: output height for the resizer in number of lines, must be even. | ||
2618 | + * | ||
2619 | + * Calculates the horizontal and vertical resize ratio, number of pixels to | ||
2620 | + * be cropped in the resizer module and checks the validity of various | ||
2621 | + * parameters. Formula used for calculation is:- | ||
2622 | + * | ||
2623 | + * 8-phase 4-tap mode :- | ||
2624 | + * inputwidth = (32 * sph + (ow - 1) * hrsz + 16) >> 8 + 7 | ||
2625 | + * inputheight = (32 * spv + (oh - 1) * vrsz + 16) >> 8 + 4 | ||
2626 | + * endpahse for width = ((32 * sph + (ow - 1) * hrsz + 16) >> 5) % 8 | ||
2627 | + * endphase for height = ((32 * sph + (oh - 1) * hrsz + 16) >> 5) % 8 | ||
2628 | + * | ||
2629 | + * 4-phase 7-tap mode :- | ||
2630 | + * inputwidth = (64 * sph + (ow - 1) * hrsz + 32) >> 8 + 7 | ||
2631 | + * inputheight = (64 * spv + (oh - 1) * vrsz + 32) >> 8 + 7 | ||
2632 | + * endpahse for width = ((64 * sph + (ow - 1) * hrsz + 32) >> 6) % 4 | ||
2633 | + * endphase for height = ((64 * sph + (oh - 1) * hrsz + 32) >> 6) % 4 | ||
2634 | + * | ||
2635 | + * Where: | ||
2636 | + * sph = Start phase horizontal | ||
2637 | + * spv = Start phase vertical | ||
2638 | + * ow = Output width | ||
2639 | + * oh = Output height | ||
2640 | + * hrsz = Horizontal resize value | ||
2641 | + * vrsz = Vertical resize value | ||
2642 | + * | ||
2643 | + * Fills up the output/input widht/height, horizontal/vertical resize ratio, | ||
2644 | + * horizontal/vertical crop variables in the isp_res structure. | ||
2645 | + **/ | ||
2646 | +int ispresizer_try_size(u32 *input_width, u32 *input_height, u32 *output_w, | ||
2647 | + u32 *output_h) | ||
2648 | +{ | ||
2649 | + u32 rsz, rsz_7, rsz_4; | ||
2650 | + u32 sph; | ||
2651 | + u32 input_w, input_h; | ||
2652 | + int max_in_otf, max_out_7tap; | ||
2653 | + | ||
2654 | + input_w = *input_width; | ||
2655 | + input_h = *input_height; | ||
2656 | + | ||
2657 | + if (input_w < 32 || input_h < 32) { | ||
2658 | + DPRINTK_ISPCCDC("ISP_ERR: RESIZER cannot handle input width" | ||
2659 | + " less than 32 pixels or height less than" | ||
2660 | + " 32\n"); | ||
2661 | + return -EINVAL; | ||
2662 | + } | ||
2663 | + input_w -= 6; | ||
2664 | + input_h -= 6; | ||
2665 | + | ||
2666 | + if (input_h > MAX_IN_HEIGHT) | ||
2667 | + return -EINVAL; | ||
2668 | + | ||
2669 | + if (*output_w < 16) | ||
2670 | + *output_w = 16; | ||
2671 | + | ||
2672 | + if (*output_h < 2) | ||
2673 | + *output_h = 2; | ||
2674 | + | ||
2675 | + if (omap_rev() == OMAP3430_REV_ES1_0) { | ||
2676 | + max_in_otf = MAX_IN_WIDTH_ONTHEFLY_MODE; | ||
2677 | + max_out_7tap = MAX_7TAP_VRSZ_OUTWIDTH; | ||
2678 | + } else { | ||
2679 | + max_in_otf = MAX_IN_WIDTH_ONTHEFLY_MODE_ES2; | ||
2680 | + max_out_7tap = MAX_7TAP_VRSZ_OUTWIDTH_ES2; | ||
2681 | + } | ||
2682 | + | ||
2683 | + if (ispres_obj.resinput == RSZ_OTFLY_YUV) { | ||
2684 | + if (input_w > max_in_otf) | ||
2685 | + return -EINVAL; | ||
2686 | + } else { | ||
2687 | + if (input_w > MAX_IN_WIDTH_MEMORY_MODE) | ||
2688 | + return -EINVAL; | ||
2689 | + } | ||
2690 | + | ||
2691 | + *output_h &= 0xfffffffe; | ||
2692 | + sph = DEFAULTSTPHASE; | ||
2693 | + | ||
2694 | + rsz_7 = ((input_h - 7) * 256) / (*output_h - 1); | ||
2695 | + rsz_4 = ((input_h - 4) * 256) / (*output_h - 1); | ||
2696 | + | ||
2697 | + rsz = (input_h * 256) / *output_h; | ||
2698 | + | ||
2699 | + if (rsz <= MID_RESIZE_VALUE) { | ||
2700 | + rsz = rsz_4; | ||
2701 | + if (rsz < MINIMUM_RESIZE_VALUE) { | ||
2702 | + rsz = MINIMUM_RESIZE_VALUE; | ||
2703 | + *output_h = (((input_h - 4) * 256) / rsz) + 1; | ||
2704 | + printk(KERN_INFO "%s: using output_h %d instead\n", | ||
2705 | + __func__, *output_h); | ||
2706 | + } | ||
2707 | + } else { | ||
2708 | + rsz = rsz_7; | ||
2709 | + if (*output_w > max_out_7tap) | ||
2710 | + *output_w = max_out_7tap; | ||
2711 | + if (rsz > MAXIMUM_RESIZE_VALUE) { | ||
2712 | + rsz = MAXIMUM_RESIZE_VALUE; | ||
2713 | + *output_h = (((input_h - 7) * 256) / rsz) + 1; | ||
2714 | + printk(KERN_INFO "%s: using output_h %d instead\n", | ||
2715 | + __func__, *output_h); | ||
2716 | + } | ||
2717 | + } | ||
2718 | + | ||
2719 | + if (rsz > MID_RESIZE_VALUE) { | ||
2720 | + input_h = | ||
2721 | + (((64 * sph) + ((*output_h - 1) * rsz) + 32) / 256) + 7; | ||
2722 | + } else { | ||
2723 | + input_h = | ||
2724 | + (((32 * sph) + ((*output_h - 1) * rsz) + 16) / 256) + 4; | ||
2725 | + } | ||
2726 | + | ||
2727 | + ispres_obj.outputheight = *output_h; | ||
2728 | + ispres_obj.v_resz = rsz; | ||
2729 | + ispres_obj.inputheight = input_h; | ||
2730 | + ispres_obj.ipht_crop = DEFAULTSTPIXEL; | ||
2731 | + ispres_obj.v_startphase = sph; | ||
2732 | + | ||
2733 | + *output_w &= 0xfffffff0; | ||
2734 | + sph = DEFAULTSTPHASE; | ||
2735 | + | ||
2736 | + rsz_7 = ((input_w - 7) * 256) / (*output_w - 1); | ||
2737 | + rsz_4 = ((input_w - 4) * 256) / (*output_w - 1); | ||
2738 | + | ||
2739 | + rsz = (input_w * 256) / *output_w; | ||
2740 | + if (rsz > MID_RESIZE_VALUE) { | ||
2741 | + rsz = rsz_7; | ||
2742 | + if (rsz > MAXIMUM_RESIZE_VALUE) { | ||
2743 | + rsz = MAXIMUM_RESIZE_VALUE; | ||
2744 | + *output_w = (((input_w - 7) * 256) / rsz) + 1; | ||
2745 | + *output_w = (*output_w + 0xf) & 0xfffffff0; | ||
2746 | + printk(KERN_INFO "%s: using output_w %d instead\n", | ||
2747 | + __func__, *output_w); | ||
2748 | + } | ||
2749 | + } else { | ||
2750 | + rsz = rsz_4; | ||
2751 | + if (rsz < MINIMUM_RESIZE_VALUE) { | ||
2752 | + rsz = MINIMUM_RESIZE_VALUE; | ||
2753 | + *output_w = (((input_w - 4) * 256) / rsz) + 1; | ||
2754 | + *output_w = (*output_w + 0xf) & 0xfffffff0; | ||
2755 | + printk(KERN_INFO "%s: using output_w %d instead\n", | ||
2756 | + __func__, *output_w); | ||
2757 | + } | ||
2758 | + } | ||
2759 | + | ||
2760 | + /* Recalculate input based on TRM equations */ | ||
2761 | + if (rsz > MID_RESIZE_VALUE) { | ||
2762 | + input_w = | ||
2763 | + (((64 * sph) + ((*output_w - 1) * rsz) + 32) / 256) + 7; | ||
2764 | + } else { | ||
2765 | + input_w = | ||
2766 | + (((32 * sph) + ((*output_w - 1) * rsz) + 16) / 256) + 7; | ||
2767 | + } | ||
2768 | + | ||
2769 | + ispres_obj.outputwidth = *output_w; | ||
2770 | + ispres_obj.h_resz = rsz; | ||
2771 | + ispres_obj.inputwidth = input_w; | ||
2772 | + ispres_obj.ipwd_crop = DEFAULTSTPIXEL; | ||
2773 | + ispres_obj.h_startphase = sph; | ||
2774 | + | ||
2775 | + *input_height = input_h; | ||
2776 | + *input_width = input_w; | ||
2777 | + return 0; | ||
2778 | +} | ||
2779 | +EXPORT_SYMBOL(ispresizer_try_size); | ||
2780 | + | ||
2781 | +/** | ||
2782 | + * ispresizer_config_size - Configures input and output image size. | ||
2783 | + * @input_w: input width for the resizer in number of pixels per line. | ||
2784 | + * @input_h: input height for the resizer in number of lines. | ||
2785 | + * @output_w: output width from the resizer in number of pixels per line. | ||
2786 | + * @output_h: output height for the resizer in number of lines. | ||
2787 | + * | ||
2788 | + * Configures the appropriate values stored in the isp_res structure in the | ||
2789 | + * resizer registers. | ||
2790 | + * | ||
2791 | + * Returns 0 if successful, or -EINVAL if passed values haven't been verified | ||
2792 | + * with ispresizer_try_size() previously. | ||
2793 | + **/ | ||
2794 | +int ispresizer_config_size(u32 input_w, u32 input_h, u32 output_w, | ||
2795 | + u32 output_h) | ||
2796 | +{ | ||
2797 | + int i, j; | ||
2798 | + u32 res; | ||
2799 | + DPRINTK_ISPRESZ("ispresizer_config_size()+, input_w = %d,input_h =" | ||
2800 | + " %d, output_w = %d, output_h" | ||
2801 | + " = %d,hresz = %d,vresz = %d," | ||
2802 | + " hcrop = %d, vcrop = %d," | ||
2803 | + " hstph = %d, vstph = %d\n", | ||
2804 | + ispres_obj.inputwidth, | ||
2805 | + ispres_obj.inputheight, | ||
2806 | + ispres_obj.outputwidth, | ||
2807 | + ispres_obj.outputheight, | ||
2808 | + ispres_obj.h_resz, | ||
2809 | + ispres_obj.v_resz, | ||
2810 | + ispres_obj.ipwd_crop, | ||
2811 | + ispres_obj.ipht_crop, | ||
2812 | + ispres_obj.h_startphase, | ||
2813 | + ispres_obj.v_startphase); | ||
2814 | + if ((output_w != ispres_obj.outputwidth) | ||
2815 | + || (output_h != ispres_obj.outputheight)) { | ||
2816 | + printk(KERN_ERR "Output parameters passed do not match the" | ||
2817 | + " values calculated by the" | ||
2818 | + " trysize passed w %d, h %d" | ||
2819 | + " \n", output_w , output_h); | ||
2820 | + return -EINVAL; | ||
2821 | + } | ||
2822 | + | ||
2823 | + /* Set Resizer input address and offset adderss */ | ||
2824 | + ispresizer_config_inlineoffset(isp_reg_readl(OMAP3_ISP_IOMEM_PREV, | ||
2825 | + ISPPRV_WADD_OFFSET)); | ||
2826 | + | ||
2827 | + res = isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) & | ||
2828 | + ~(ISPRSZ_CNT_HSTPH_MASK | ISPRSZ_CNT_VSTPH_MASK); | ||
2829 | + isp_reg_writel(res | | ||
2830 | + (ispres_obj.h_startphase << ISPRSZ_CNT_HSTPH_SHIFT) | | ||
2831 | + (ispres_obj.v_startphase << ISPRSZ_CNT_VSTPH_SHIFT), | ||
2832 | + OMAP3_ISP_IOMEM_RESZ, | ||
2833 | + ISPRSZ_CNT); | ||
2834 | + /* Set start address for cropping */ | ||
2835 | + isp_reg_writel(ispres_obj.tmp_buf + 2 * | ||
2836 | + (ispres_obj.ipht_crop * ispres_obj.inputwidth + | ||
2837 | + (ispres_obj.ipwd_crop & ~15)), | ||
2838 | + OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INADD); | ||
2839 | + | ||
2840 | + isp_reg_writel( | ||
2841 | + ((ispres_obj.ipwd_crop & 15) << ISPRSZ_IN_START_HORZ_ST_SHIFT) | | ||
2842 | + (0x00 << ISPRSZ_IN_START_VERT_ST_SHIFT), | ||
2843 | + OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_START); | ||
2844 | + | ||
2845 | + isp_reg_writel((0x00 << ISPRSZ_IN_START_HORZ_ST_SHIFT) | | ||
2846 | + (0x00 << ISPRSZ_IN_START_VERT_ST_SHIFT), | ||
2847 | + OMAP3_ISP_IOMEM_RESZ, | ||
2848 | + ISPRSZ_IN_START); | ||
2849 | + | ||
2850 | + isp_reg_writel((ispres_obj.inputwidth << ISPRSZ_IN_SIZE_HORZ_SHIFT) | | ||
2851 | + (ispres_obj.inputheight << | ||
2852 | + ISPRSZ_IN_SIZE_VERT_SHIFT), | ||
2853 | + OMAP3_ISP_IOMEM_RESZ, | ||
2854 | + ISPRSZ_IN_SIZE); | ||
2855 | + if (!ispres_obj.algo) { | ||
2856 | + isp_reg_writel((output_w << ISPRSZ_OUT_SIZE_HORZ_SHIFT) | | ||
2857 | + (output_h << ISPRSZ_OUT_SIZE_VERT_SHIFT), | ||
2858 | + OMAP3_ISP_IOMEM_RESZ, | ||
2859 | + ISPRSZ_OUT_SIZE); | ||
2860 | + } else { | ||
2861 | + isp_reg_writel(((output_w - 4) << ISPRSZ_OUT_SIZE_HORZ_SHIFT) | | ||
2862 | + (output_h << ISPRSZ_OUT_SIZE_VERT_SHIFT), | ||
2863 | + OMAP3_ISP_IOMEM_RESZ, | ||
2864 | + ISPRSZ_OUT_SIZE); | ||
2865 | + } | ||
2866 | + | ||
2867 | + res = isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) & | ||
2868 | + ~(ISPRSZ_CNT_HRSZ_MASK | ISPRSZ_CNT_VRSZ_MASK); | ||
2869 | + isp_reg_writel(res | | ||
2870 | + ((ispres_obj.h_resz - 1) << ISPRSZ_CNT_HRSZ_SHIFT) | | ||
2871 | + ((ispres_obj.v_resz - 1) << ISPRSZ_CNT_VRSZ_SHIFT), | ||
2872 | + OMAP3_ISP_IOMEM_RESZ, | ||
2873 | + ISPRSZ_CNT); | ||
2874 | + if (ispres_obj.h_resz <= MID_RESIZE_VALUE) { | ||
2875 | + j = 0; | ||
2876 | + for (i = 0; i < 16; i++) { | ||
2877 | + isp_reg_writel( | ||
2878 | + (ispres_obj.coeflist.h_filter_coef_4tap[j] | ||
2879 | + << ISPRSZ_HFILT10_COEF0_SHIFT) | | ||
2880 | + (ispres_obj.coeflist.h_filter_coef_4tap[j + 1] | ||
2881 | + << ISPRSZ_HFILT10_COEF1_SHIFT), | ||
2882 | + OMAP3_ISP_IOMEM_RESZ, | ||
2883 | + ISPRSZ_HFILT10 + (i * 0x04)); | ||
2884 | + j += 2; | ||
2885 | + } | ||
2886 | + } else { | ||
2887 | + j = 0; | ||
2888 | + for (i = 0; i < 16; i++) { | ||
2889 | + if ((i + 1) % 4 == 0) { | ||
2890 | + isp_reg_writel((ispres_obj.coeflist. | ||
2891 | + h_filter_coef_7tap[j] << | ||
2892 | + ISPRSZ_HFILT10_COEF0_SHIFT), | ||
2893 | + OMAP3_ISP_IOMEM_RESZ, | ||
2894 | + ISPRSZ_HFILT10 + (i * 0x04)); | ||
2895 | + j += 1; | ||
2896 | + } else { | ||
2897 | + isp_reg_writel((ispres_obj.coeflist. | ||
2898 | + h_filter_coef_7tap[j] << | ||
2899 | + ISPRSZ_HFILT10_COEF0_SHIFT) | | ||
2900 | + (ispres_obj.coeflist. | ||
2901 | + h_filter_coef_7tap[j+1] << | ||
2902 | + ISPRSZ_HFILT10_COEF1_SHIFT), | ||
2903 | + OMAP3_ISP_IOMEM_RESZ, | ||
2904 | + ISPRSZ_HFILT10 + (i * 0x04)); | ||
2905 | + j += 2; | ||
2906 | + } | ||
2907 | + } | ||
2908 | + } | ||
2909 | + if (ispres_obj.v_resz <= MID_RESIZE_VALUE) { | ||
2910 | + j = 0; | ||
2911 | + for (i = 0; i < 16; i++) { | ||
2912 | + isp_reg_writel((ispres_obj.coeflist. | ||
2913 | + v_filter_coef_4tap[j] << | ||
2914 | + ISPRSZ_VFILT10_COEF0_SHIFT) | | ||
2915 | + (ispres_obj.coeflist. | ||
2916 | + v_filter_coef_4tap[j + 1] << | ||
2917 | + ISPRSZ_VFILT10_COEF1_SHIFT), | ||
2918 | + OMAP3_ISP_IOMEM_RESZ, | ||
2919 | + ISPRSZ_VFILT10 + (i * 0x04)); | ||
2920 | + j += 2; | ||
2921 | + } | ||
2922 | + } else { | ||
2923 | + j = 0; | ||
2924 | + for (i = 0; i < 16; i++) { | ||
2925 | + if ((i + 1) % 4 == 0) { | ||
2926 | + isp_reg_writel((ispres_obj.coeflist. | ||
2927 | + v_filter_coef_7tap[j] << | ||
2928 | + ISPRSZ_VFILT10_COEF0_SHIFT), | ||
2929 | + OMAP3_ISP_IOMEM_RESZ, | ||
2930 | + ISPRSZ_VFILT10 + (i * 0x04)); | ||
2931 | + j += 1; | ||
2932 | + } else { | ||
2933 | + isp_reg_writel((ispres_obj.coeflist. | ||
2934 | + v_filter_coef_7tap[j] << | ||
2935 | + ISPRSZ_VFILT10_COEF0_SHIFT) | | ||
2936 | + (ispres_obj.coeflist. | ||
2937 | + v_filter_coef_7tap[j+1] << | ||
2938 | + ISPRSZ_VFILT10_COEF1_SHIFT), | ||
2939 | + OMAP3_ISP_IOMEM_RESZ, | ||
2940 | + ISPRSZ_VFILT10 + (i * 0x04)); | ||
2941 | + j += 2; | ||
2942 | + } | ||
2943 | + } | ||
2944 | + } | ||
2945 | + | ||
2946 | + ispresizer_config_outlineoffset(output_w*2); | ||
2947 | + DPRINTK_ISPRESZ("ispresizer_config_size()-\n"); | ||
2948 | + return 0; | ||
2949 | +} | ||
2950 | +EXPORT_SYMBOL(ispresizer_config_size); | ||
2951 | + | ||
2952 | +void __ispresizer_enable(int enable) | ||
2953 | +{ | ||
2954 | + int val; | ||
2955 | + DPRINTK_ISPRESZ("+ispresizer_enable()+\n"); | ||
2956 | + if (enable) { | ||
2957 | + val = (isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) & 0x2) | | ||
2958 | + ISPRSZ_PCR_ENABLE; | ||
2959 | + } else { | ||
2960 | + val = isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) & | ||
2961 | + ~ISPRSZ_PCR_ENABLE; | ||
2962 | + } | ||
2963 | + isp_reg_writel(val, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR); | ||
2964 | + DPRINTK_ISPRESZ("+ispresizer_enable()-\n"); | ||
2965 | +} | ||
2966 | + | ||
2967 | +/** | ||
2968 | + * ispresizer_enable - Enables the resizer module. | ||
2969 | + * @enable: 1 - Enable, 0 - Disable | ||
2970 | + * | ||
2971 | + * Client should configure all the sub modules in resizer before this. | ||
2972 | + **/ | ||
2973 | +void ispresizer_enable(int enable) | ||
2974 | +{ | ||
2975 | + __ispresizer_enable(enable); | ||
2976 | + ispres_obj.pm_state = enable; | ||
2977 | +} | ||
2978 | +EXPORT_SYMBOL(ispresizer_enable); | ||
2979 | + | ||
2980 | +/** | ||
2981 | + * ispresizer_suspend - Suspend resizer module. | ||
2982 | + **/ | ||
2983 | +void ispresizer_suspend(void) | ||
2984 | +{ | ||
2985 | + if (ispres_obj.pm_state) | ||
2986 | + __ispresizer_enable(0); | ||
2987 | +} | ||
2988 | +EXPORT_SYMBOL(ispresizer_suspend); | ||
2989 | + | ||
2990 | +/** | ||
2991 | + * ispresizer_resume - Resume resizer module. | ||
2992 | + **/ | ||
2993 | +void ispresizer_resume(void) | ||
2994 | +{ | ||
2995 | + if (ispres_obj.pm_state) | ||
2996 | + __ispresizer_enable(1); | ||
2997 | +} | ||
2998 | +EXPORT_SYMBOL(ispresizer_resume); | ||
2999 | + | ||
3000 | +/** | ||
3001 | + * ispresizer_busy - Checks if ISP resizer is busy. | ||
3002 | + * | ||
3003 | + * Returns busy field from ISPRSZ_PCR register. | ||
3004 | + **/ | ||
3005 | +int ispresizer_busy(void) | ||
3006 | +{ | ||
3007 | + return isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) & | ||
3008 | + ISPPRV_PCR_BUSY; | ||
3009 | +} | ||
3010 | +EXPORT_SYMBOL(ispresizer_busy); | ||
3011 | + | ||
3012 | +/** | ||
3013 | + * ispresizer_config_startphase - Sets the horizontal and vertical start phase. | ||
3014 | + * @hstartphase: horizontal start phase (0 - 7). | ||
3015 | + * @vstartphase: vertical startphase (0 - 7). | ||
3016 | + * | ||
3017 | + * This API just updates the isp_res struct. Actual register write happens in | ||
3018 | + * ispresizer_config_size. | ||
3019 | + **/ | ||
3020 | +void ispresizer_config_startphase(u8 hstartphase, u8 vstartphase) | ||
3021 | +{ | ||
3022 | + DPRINTK_ISPRESZ("ispresizer_config_startphase()+\n"); | ||
3023 | + ispres_obj.h_startphase = hstartphase; | ||
3024 | + ispres_obj.v_startphase = vstartphase; | ||
3025 | + DPRINTK_ISPRESZ("ispresizer_config_startphase()-\n"); | ||
3026 | +} | ||
3027 | +EXPORT_SYMBOL(ispresizer_config_startphase); | ||
3028 | + | ||
3029 | +/** | ||
3030 | + * ispresizer_config_ycpos - Specifies if output should be in YC or CY format. | ||
3031 | + * @yc: 0 - YC format, 1 - CY format | ||
3032 | + **/ | ||
3033 | +void ispresizer_config_ycpos(u8 yc) | ||
3034 | +{ | ||
3035 | + DPRINTK_ISPRESZ("ispresizer_config_ycpos()+\n"); | ||
3036 | + isp_reg_and_or(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ~ISPRSZ_CNT_YCPOS, | ||
3037 | + (yc ? ISPRSZ_CNT_YCPOS : 0)); | ||
3038 | + DPRINTK_ISPRESZ("ispresizer_config_ycpos()-\n"); | ||
3039 | +} | ||
3040 | +EXPORT_SYMBOL(ispresizer_config_ycpos); | ||
3041 | + | ||
3042 | +/** | ||
3043 | + * Sets the chrominance algorithm | ||
3044 | + * @cbilin: 0 - chrominance uses same processing as luminance, | ||
3045 | + * 1 - bilinear interpolation processing | ||
3046 | + **/ | ||
3047 | +void ispresizer_enable_cbilin(u8 enable) | ||
3048 | +{ | ||
3049 | + DPRINTK_ISPRESZ("ispresizer_enable_cbilin()+\n"); | ||
3050 | + isp_reg_and_or(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT, ~ISPRSZ_CNT_CBILIN, | ||
3051 | + (enable ? ISPRSZ_CNT_CBILIN : 0)); | ||
3052 | + DPRINTK_ISPRESZ("ispresizer_enable_cbilin()-\n"); | ||
3053 | +} | ||
3054 | +EXPORT_SYMBOL(ispresizer_enable_cbilin); | ||
3055 | + | ||
3056 | +/** | ||
3057 | + * ispresizer_config_luma_enhance - Configures luminance enhancer parameters. | ||
3058 | + * @yenh: Pointer to structure containing desired values for core, slope, gain | ||
3059 | + * and algo parameters. | ||
3060 | + **/ | ||
3061 | +void ispresizer_config_luma_enhance(struct isprsz_yenh *yenh) | ||
3062 | +{ | ||
3063 | + DPRINTK_ISPRESZ("ispresizer_config_luma_enhance()+\n"); | ||
3064 | + ispres_obj.algo = yenh->algo; | ||
3065 | + isp_reg_writel((yenh->algo << ISPRSZ_YENH_ALGO_SHIFT) | | ||
3066 | + (yenh->gain << ISPRSZ_YENH_GAIN_SHIFT) | | ||
3067 | + (yenh->slope << ISPRSZ_YENH_SLOP_SHIFT) | | ||
3068 | + (yenh->coreoffset << ISPRSZ_YENH_CORE_SHIFT), | ||
3069 | + OMAP3_ISP_IOMEM_RESZ, | ||
3070 | + ISPRSZ_YENH); | ||
3071 | + DPRINTK_ISPRESZ("ispresizer_config_luma_enhance()-\n"); | ||
3072 | +} | ||
3073 | +EXPORT_SYMBOL(ispresizer_config_luma_enhance); | ||
3074 | + | ||
3075 | +/** | ||
3076 | + * ispresizer_config_filter_coef - Sets filter coefficients for 4 & 7-tap mode. | ||
3077 | + * This API just updates the isp_res struct.Actual register write happens in | ||
3078 | + * ispresizer_config_size. | ||
3079 | + * @coef: Structure containing horizontal and vertical filter coefficients for | ||
3080 | + * both 4-tap and 7-tap mode. | ||
3081 | + **/ | ||
3082 | +void ispresizer_config_filter_coef(struct isprsz_coef *coef) | ||
3083 | +{ | ||
3084 | + int i; | ||
3085 | + DPRINTK_ISPRESZ("ispresizer_config_filter_coef()+\n"); | ||
3086 | + for (i = 0; i < 32; i++) { | ||
3087 | + ispres_obj.coeflist.h_filter_coef_4tap[i] = | ||
3088 | + coef->h_filter_coef_4tap[i]; | ||
3089 | + ispres_obj.coeflist.v_filter_coef_4tap[i] = | ||
3090 | + coef->v_filter_coef_4tap[i]; | ||
3091 | + } | ||
3092 | + for (i = 0; i < 28; i++) { | ||
3093 | + ispres_obj.coeflist.h_filter_coef_7tap[i] = | ||
3094 | + coef->h_filter_coef_7tap[i]; | ||
3095 | + ispres_obj.coeflist.v_filter_coef_7tap[i] = | ||
3096 | + coef->v_filter_coef_7tap[i]; | ||
3097 | + } | ||
3098 | + DPRINTK_ISPRESZ("ispresizer_config_filter_coef()-\n"); | ||
3099 | +} | ||
3100 | +EXPORT_SYMBOL(ispresizer_config_filter_coef); | ||
3101 | + | ||
3102 | +/** | ||
3103 | + * ispresizer_config_inlineoffset - Configures the read address line offset. | ||
3104 | + * @offset: Line Offset for the input image. | ||
3105 | + * | ||
3106 | + * Returns 0 if successful, or -EINVAL if offset is not 32 bits aligned. | ||
3107 | + **/ | ||
3108 | +int ispresizer_config_inlineoffset(u32 offset) | ||
3109 | +{ | ||
3110 | + DPRINTK_ISPRESZ("ispresizer_config_inlineoffset()+\n"); | ||
3111 | + if (offset % 32) | ||
3112 | + return -EINVAL; | ||
3113 | + isp_reg_writel(offset << ISPRSZ_SDR_INOFF_OFFSET_SHIFT, | ||
3114 | + OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INOFF); | ||
3115 | + DPRINTK_ISPRESZ("ispresizer_config_inlineoffset()-\n"); | ||
3116 | + return 0; | ||
3117 | +} | ||
3118 | +EXPORT_SYMBOL(ispresizer_config_inlineoffset); | ||
3119 | + | ||
3120 | +/** | ||
3121 | + * ispresizer_set_inaddr - Sets the memory address of the input frame. | ||
3122 | + * @addr: 32bit memory address aligned on 32byte boundary. | ||
3123 | + * | ||
3124 | + * Returns 0 if successful, or -EINVAL if address is not 32 bits aligned. | ||
3125 | + **/ | ||
3126 | +int ispresizer_set_inaddr(u32 addr) | ||
3127 | +{ | ||
3128 | + DPRINTK_ISPRESZ("ispresizer_set_inaddr()+\n"); | ||
3129 | + if (addr % 32) | ||
3130 | + return -EINVAL; | ||
3131 | + isp_reg_writel(addr << ISPRSZ_SDR_INADD_ADDR_SHIFT, | ||
3132 | + OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INADD); | ||
3133 | + ispres_obj.tmp_buf = addr; | ||
3134 | + DPRINTK_ISPRESZ("ispresizer_set_inaddr()-\n"); | ||
3135 | + return 0; | ||
3136 | +} | ||
3137 | +EXPORT_SYMBOL(ispresizer_set_inaddr); | ||
3138 | + | ||
3139 | +/** | ||
3140 | + * ispresizer_config_outlineoffset - Configures the write address line offset. | ||
3141 | + * @offset: Line offset for the preview output. | ||
3142 | + * | ||
3143 | + * Returns 0 if successful, or -EINVAL if address is not 32 bits aligned. | ||
3144 | + **/ | ||
3145 | +int ispresizer_config_outlineoffset(u32 offset) | ||
3146 | +{ | ||
3147 | + DPRINTK_ISPRESZ("ispresizer_config_outlineoffset()+\n"); | ||
3148 | + if (offset % 32) | ||
3149 | + return -EINVAL; | ||
3150 | + isp_reg_writel(offset << ISPRSZ_SDR_OUTOFF_OFFSET_SHIFT, | ||
3151 | + OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTOFF); | ||
3152 | + DPRINTK_ISPRESZ("ispresizer_config_outlineoffset()-\n"); | ||
3153 | + return 0; | ||
3154 | +} | ||
3155 | +EXPORT_SYMBOL(ispresizer_config_outlineoffset); | ||
3156 | + | ||
3157 | +/** | ||
3158 | + * Configures the memory address to which the output frame is written. | ||
3159 | + * @addr: 32bit memory address aligned on 32byte boundary. | ||
3160 | + **/ | ||
3161 | +int ispresizer_set_outaddr(u32 addr) | ||
3162 | +{ | ||
3163 | + DPRINTK_ISPRESZ("ispresizer_set_outaddr()+\n"); | ||
3164 | + if (addr % 32) | ||
3165 | + return -EINVAL; | ||
3166 | + isp_reg_writel(addr << ISPRSZ_SDR_OUTADD_ADDR_SHIFT, | ||
3167 | + OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTADD); | ||
3168 | + DPRINTK_ISPRESZ("ispresizer_set_outaddr()-\n"); | ||
3169 | + return 0; | ||
3170 | +} | ||
3171 | +EXPORT_SYMBOL(ispresizer_set_outaddr); | ||
3172 | + | ||
3173 | +/** | ||
3174 | + * ispresizer_save_context - Saves the values of the resizer module registers. | ||
3175 | + **/ | ||
3176 | +void ispresizer_save_context(void) | ||
3177 | +{ | ||
3178 | + DPRINTK_ISPRESZ("Saving context\n"); | ||
3179 | + isp_save_context(isprsz_reg_list); | ||
3180 | +} | ||
3181 | +EXPORT_SYMBOL(ispresizer_save_context); | ||
3182 | + | ||
3183 | +/** | ||
3184 | + * ispresizer_restore_context - Restores resizer module register values. | ||
3185 | + **/ | ||
3186 | +void ispresizer_restore_context(void) | ||
3187 | +{ | ||
3188 | + DPRINTK_ISPRESZ("Restoring context\n"); | ||
3189 | + isp_restore_context(isprsz_reg_list); | ||
3190 | +} | ||
3191 | +EXPORT_SYMBOL(ispresizer_restore_context); | ||
3192 | + | ||
3193 | +/** | ||
3194 | + * ispresizer_print_status - Prints the values of the resizer module registers. | ||
3195 | + **/ | ||
3196 | +void ispresizer_print_status() | ||
3197 | +{ | ||
3198 | + if (!is_ispresz_debug_enabled()) | ||
3199 | + return; | ||
3200 | + DPRINTK_ISPRESZ("###ISP_CTRL inresizer =0x%x\n", | ||
3201 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL)); | ||
3202 | + DPRINTK_ISPRESZ("###ISP_IRQ0ENABLE in resizer =0x%x\n", | ||
3203 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE)); | ||
3204 | + DPRINTK_ISPRESZ("###ISP_IRQ0STATUS in resizer =0x%x\n", | ||
3205 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS)); | ||
3206 | + DPRINTK_ISPRESZ("###RSZ PCR =0x%x\n", | ||
3207 | + isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR)); | ||
3208 | + DPRINTK_ISPRESZ("###RSZ CNT =0x%x\n", | ||
3209 | + isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT)); | ||
3210 | + DPRINTK_ISPRESZ("###RSZ OUT SIZE =0x%x\n", | ||
3211 | + isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_OUT_SIZE)); | ||
3212 | + DPRINTK_ISPRESZ("###RSZ IN START =0x%x\n", | ||
3213 | + isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_START)); | ||
3214 | + DPRINTK_ISPRESZ("###RSZ IN SIZE =0x%x\n", | ||
3215 | + isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_SIZE)); | ||
3216 | + DPRINTK_ISPRESZ("###RSZ SDR INADD =0x%x\n", | ||
3217 | + isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INADD)); | ||
3218 | + DPRINTK_ISPRESZ("###RSZ SDR INOFF =0x%x\n", | ||
3219 | + isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INOFF)); | ||
3220 | + DPRINTK_ISPRESZ("###RSZ SDR OUTADD =0x%x\n", | ||
3221 | + isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTADD)); | ||
3222 | + DPRINTK_ISPRESZ("###RSZ SDR OTOFF =0x%x\n", | ||
3223 | + isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTOFF)); | ||
3224 | + DPRINTK_ISPRESZ("###RSZ YENH =0x%x\n", | ||
3225 | + isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_YENH)); | ||
3226 | +} | ||
3227 | +EXPORT_SYMBOL(ispresizer_print_status); | ||
3228 | + | ||
3229 | +/** | ||
3230 | + * isp_resizer_init - Module Initialisation. | ||
3231 | + * | ||
3232 | + * Always returns 0. | ||
3233 | + **/ | ||
3234 | +int __init isp_resizer_init(void) | ||
3235 | +{ | ||
3236 | + mutex_init(&ispres_obj.ispres_mutex); | ||
3237 | + ispres_obj.pm_state = 0; | ||
3238 | + return 0; | ||
3239 | +} | ||
3240 | + | ||
3241 | +/** | ||
3242 | + * isp_resizer_cleanup - Module Cleanup. | ||
3243 | + **/ | ||
3244 | +void isp_resizer_cleanup(void) | ||
3245 | +{ | ||
3246 | +} | ||
3247 | diff --git a/drivers/media/video/isp/ispresizer.h b/drivers/media/video/isp/ispresizer.h | ||
3248 | new file mode 100644 | ||
3249 | index 0000000..4e92225 | ||
3250 | --- /dev/null | ||
3251 | +++ b/drivers/media/video/isp/ispresizer.h | ||
3252 | @@ -0,0 +1,158 @@ | ||
3253 | +/* | ||
3254 | + * ispresizer.h | ||
3255 | + * | ||
3256 | + * Driver header file for Resizer module in TI's OMAP3 Camera ISP | ||
3257 | + * | ||
3258 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
3259 | + * | ||
3260 | + * Contributors: | ||
3261 | + * Sameer Venkatraman <sameerv@ti.com> | ||
3262 | + * Mohit Jalori | ||
3263 | + * Sergio Aguirre <saaguirre@ti.com> | ||
3264 | + * | ||
3265 | + * This package is free software; you can redistribute it and/or modify | ||
3266 | + * it under the terms of the GNU General Public License version 2 as | ||
3267 | + * published by the Free Software Foundation. | ||
3268 | + * | ||
3269 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
3270 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
3271 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
3272 | + */ | ||
3273 | + | ||
3274 | +#ifndef OMAP_ISP_RESIZER_H | ||
3275 | +#define OMAP_ISP_RESIZER_H | ||
3276 | + | ||
3277 | +/* | ||
3278 | + * Resizer Constants | ||
3279 | + */ | ||
3280 | +#define MAX_IN_WIDTH_MEMORY_MODE 4095 | ||
3281 | + | ||
3282 | +#define MAX_IN_WIDTH_ONTHEFLY_MODE 1280 | ||
3283 | +#define MAX_IN_WIDTH_ONTHEFLY_MODE_ES2 4095 | ||
3284 | +#define MAX_IN_HEIGHT 4095 | ||
3285 | +#define MINIMUM_RESIZE_VALUE 64 | ||
3286 | +#define MAXIMUM_RESIZE_VALUE 1024 | ||
3287 | +#define MID_RESIZE_VALUE 512 | ||
3288 | + | ||
3289 | +#define MAX_7TAP_HRSZ_OUTWIDTH 1280 | ||
3290 | +#define MAX_7TAP_VRSZ_OUTWIDTH 640 | ||
3291 | + | ||
3292 | +#define MAX_7TAP_HRSZ_OUTWIDTH_ES2 3300 | ||
3293 | +#define MAX_7TAP_VRSZ_OUTWIDTH_ES2 1650 | ||
3294 | + | ||
3295 | +#define DEFAULTSTPIXEL 0 | ||
3296 | +#define DEFAULTSTPHASE 1 | ||
3297 | +#define DEFAULTHSTPIXEL4TAPMODE 3 | ||
3298 | +#define FOURPHASE 4 | ||
3299 | +#define EIGHTPHASE 8 | ||
3300 | +#define RESIZECONSTANT 256 | ||
3301 | +#define SHIFTER4TAPMODE 0 | ||
3302 | +#define SHIFTER7TAPMODE 1 | ||
3303 | +#define DEFAULTOFFSET 7 | ||
3304 | +#define OFFSETVERT4TAPMODE 4 | ||
3305 | +#define OPWDALIGNCONSTANT 0xfffffff0 | ||
3306 | + | ||
3307 | +/* | ||
3308 | + * The client is supposed to call resizer API in the following sequence: | ||
3309 | + * - request() | ||
3310 | + * - config_datatpath() | ||
3311 | + * - optionally config/enable sub modules | ||
3312 | + * - try/config size | ||
3313 | + * - setup callback | ||
3314 | + * - setup in/out memory offsets and ptrs | ||
3315 | + * - enable() | ||
3316 | + * ... | ||
3317 | + * - disable() | ||
3318 | + * - free() | ||
3319 | + */ | ||
3320 | + | ||
3321 | +enum ispresizer_input { | ||
3322 | + RSZ_OTFLY_YUV, | ||
3323 | + RSZ_MEM_YUV, | ||
3324 | + RSZ_MEM_COL8 | ||
3325 | +}; | ||
3326 | + | ||
3327 | +/** | ||
3328 | + * struct isprsz_coef - Structure for resizer filter coeffcients. | ||
3329 | + * @h_filter_coef_4tap: Horizontal filter coefficients for 8-phase/4-tap | ||
3330 | + * mode (.5x-4x) | ||
3331 | + * @v_filter_coef_4tap: Vertical filter coefficients for 8-phase/4-tap | ||
3332 | + * mode (.5x-4x) | ||
3333 | + * @h_filter_coef_7tap: Horizontal filter coefficients for 4-phase/7-tap | ||
3334 | + * mode (.25x-.5x) | ||
3335 | + * @v_filter_coef_7tap: Vertical filter coefficients for 4-phase/7-tap | ||
3336 | + * mode (.25x-.5x) | ||
3337 | + */ | ||
3338 | +struct isprsz_coef { | ||
3339 | + u16 h_filter_coef_4tap[32]; | ||
3340 | + u16 v_filter_coef_4tap[32]; | ||
3341 | + u16 h_filter_coef_7tap[28]; | ||
3342 | + u16 v_filter_coef_7tap[28]; | ||
3343 | +}; | ||
3344 | + | ||
3345 | +/** | ||
3346 | + * struct isprsz_yenh - Structure for resizer luminance enhancer parameters. | ||
3347 | + * @algo: Algorithm select. | ||
3348 | + * @gain: Maximum gain. | ||
3349 | + * @slope: Slope. | ||
3350 | + * @coreoffset: Coring offset. | ||
3351 | + */ | ||
3352 | +struct isprsz_yenh { | ||
3353 | + u8 algo; | ||
3354 | + u8 gain; | ||
3355 | + u8 slope; | ||
3356 | + u8 coreoffset; | ||
3357 | +}; | ||
3358 | + | ||
3359 | +void ispresizer_config_shadow_registers(void); | ||
3360 | + | ||
3361 | +int ispresizer_request(void); | ||
3362 | + | ||
3363 | +int ispresizer_free(void); | ||
3364 | + | ||
3365 | +int ispresizer_config_datapath(enum ispresizer_input input); | ||
3366 | + | ||
3367 | +void ispresizer_enable_cbilin(u8 enable); | ||
3368 | + | ||
3369 | +void ispresizer_config_ycpos(u8 yc); | ||
3370 | + | ||
3371 | +void ispresizer_config_startphase(u8 hstartphase, u8 vstartphase); | ||
3372 | + | ||
3373 | +void ispresizer_config_filter_coef(struct isprsz_coef *coef); | ||
3374 | + | ||
3375 | +void ispresizer_config_luma_enhance(struct isprsz_yenh *yenh); | ||
3376 | + | ||
3377 | +int ispresizer_try_size(u32 *input_w, u32 *input_h, u32 *output_w, | ||
3378 | + u32 *output_h); | ||
3379 | + | ||
3380 | +void ispresizer_applycrop(void); | ||
3381 | + | ||
3382 | +void ispresizer_trycrop(u32 left, u32 top, u32 width, u32 height, u32 ow, | ||
3383 | + u32 oh); | ||
3384 | + | ||
3385 | +int ispresizer_config_size(u32 input_w, u32 input_h, u32 output_w, | ||
3386 | + u32 output_h); | ||
3387 | + | ||
3388 | +int ispresizer_config_inlineoffset(u32 offset); | ||
3389 | + | ||
3390 | +int ispresizer_set_inaddr(u32 addr); | ||
3391 | + | ||
3392 | +int ispresizer_config_outlineoffset(u32 offset); | ||
3393 | + | ||
3394 | +int ispresizer_set_outaddr(u32 addr); | ||
3395 | + | ||
3396 | +void ispresizer_enable(int enable); | ||
3397 | + | ||
3398 | +void ispresizer_suspend(void); | ||
3399 | + | ||
3400 | +void ispresizer_resume(void); | ||
3401 | + | ||
3402 | +int ispresizer_busy(void); | ||
3403 | + | ||
3404 | +void ispresizer_save_context(void); | ||
3405 | + | ||
3406 | +void ispresizer_restore_context(void); | ||
3407 | + | ||
3408 | +void ispresizer_print_status(void); | ||
3409 | + | ||
3410 | +#endif /* OMAP_ISP_RESIZER_H */ | ||
3411 | -- | ||
3412 | 1.5.6.5 | ||
3413 | |||
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0006-omap3isp-Add-statistics-collection-modules-H3A-and.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0006-omap3isp-Add-statistics-collection-modules-H3A-and.patch new file mode 100644 index 0000000000..876ce780f0 --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0006-omap3isp-Add-statistics-collection-modules-H3A-and.patch | |||
@@ -0,0 +1,2741 @@ | |||
1 | From 9a39eab5ed1b70711c3b10de95cd90749293ef7a Mon Sep 17 00:00:00 2001 | ||
2 | From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
3 | Date: Tue, 10 Mar 2009 10:49:02 +0200 | ||
4 | Subject: [PATCH] omap3isp: Add statistics collection modules (H3A and HIST) | ||
5 | |||
6 | Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
7 | --- | ||
8 | drivers/media/video/isp/isp_af.c | 784 +++++++++++++++++++++++++++++++ | ||
9 | drivers/media/video/isp/isp_af.h | 125 +++++ | ||
10 | drivers/media/video/isp/isph3a.c | 932 +++++++++++++++++++++++++++++++++++++ | ||
11 | drivers/media/video/isp/isph3a.h | 127 +++++ | ||
12 | drivers/media/video/isp/isphist.c | 608 ++++++++++++++++++++++++ | ||
13 | drivers/media/video/isp/isphist.h | 105 +++++ | ||
14 | 6 files changed, 2681 insertions(+), 0 deletions(-) | ||
15 | create mode 100644 drivers/media/video/isp/isp_af.c | ||
16 | create mode 100644 drivers/media/video/isp/isp_af.h | ||
17 | create mode 100644 drivers/media/video/isp/isph3a.c | ||
18 | create mode 100644 drivers/media/video/isp/isph3a.h | ||
19 | create mode 100644 drivers/media/video/isp/isphist.c | ||
20 | create mode 100644 drivers/media/video/isp/isphist.h | ||
21 | |||
22 | diff --git a/drivers/media/video/isp/isp_af.c b/drivers/media/video/isp/isp_af.c | ||
23 | new file mode 100644 | ||
24 | index 0000000..a607b97 | ||
25 | --- /dev/null | ||
26 | +++ b/drivers/media/video/isp/isp_af.c | ||
27 | @@ -0,0 +1,784 @@ | ||
28 | +/* | ||
29 | + * isp_af.c | ||
30 | + * | ||
31 | + * AF module for TI's OMAP3 Camera ISP | ||
32 | + * | ||
33 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
34 | + * | ||
35 | + * Contributors: | ||
36 | + * Sergio Aguirre <saaguirre@ti.com> | ||
37 | + * Troy Laramy | ||
38 | + * | ||
39 | + * This package is free software; you can redistribute it and/or modify | ||
40 | + * it under the terms of the GNU General Public License version 2 as | ||
41 | + * published by the Free Software Foundation. | ||
42 | + * | ||
43 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
44 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
45 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
46 | + */ | ||
47 | + | ||
48 | +/* Linux specific include files */ | ||
49 | +#include <asm/cacheflush.h> | ||
50 | + | ||
51 | +#include <linux/uaccess.h> | ||
52 | +#include <linux/dma-mapping.h> | ||
53 | +#include <asm/atomic.h> | ||
54 | + | ||
55 | +#include "isp.h" | ||
56 | +#include "ispreg.h" | ||
57 | +#include "isph3a.h" | ||
58 | +#include "isp_af.h" | ||
59 | +#include "ispmmu.h" | ||
60 | + | ||
61 | +/** | ||
62 | + * struct isp_af_buffer - AF frame stats buffer. | ||
63 | + * @virt_addr: Virtual address to mmap the buffer. | ||
64 | + * @phy_addr: Physical address of the buffer. | ||
65 | + * @addr_align: Virtual Address 32 bytes aligned. | ||
66 | + * @ispmmu_addr: Address of the buffer mapped by the ISPMMU. | ||
67 | + * @mmap_addr: Mapped memory area of buffer. For userspace access. | ||
68 | + * @locked: 1 - Buffer locked from write. 0 - Buffer can be overwritten. | ||
69 | + * @frame_num: Frame number from which the statistics are taken. | ||
70 | + * @lens_position: Lens position currently set in the DW9710 Coil motor driver. | ||
71 | + * @next: Pointer to link next buffer. | ||
72 | + */ | ||
73 | +struct isp_af_buffer { | ||
74 | + unsigned long virt_addr; | ||
75 | + unsigned long phy_addr; | ||
76 | + unsigned long addr_align; | ||
77 | + unsigned long ispmmu_addr; | ||
78 | + unsigned long mmap_addr; | ||
79 | + | ||
80 | + u8 locked; | ||
81 | + u16 frame_num; | ||
82 | + u32 config_counter; | ||
83 | + struct isp_af_xtrastats xtrastats; | ||
84 | + struct isp_af_buffer *next; | ||
85 | +}; | ||
86 | + | ||
87 | +/** | ||
88 | + * struct isp_af_status - AF status. | ||
89 | + * @initialized: 1 - Buffers initialized. | ||
90 | + * @update: 1 - Update registers. | ||
91 | + * @stats_req: 1 - Future stats requested. | ||
92 | + * @stats_done: 1 - Stats ready for user. | ||
93 | + * @frame_req: Number of frame requested for statistics. | ||
94 | + * @af_buff: Array of statistics buffers to access. | ||
95 | + * @stats_buf_size: Statistics buffer size. | ||
96 | + * @curr_cfg_buf_size: Current user configured stats buff size. | ||
97 | + * @min_buf_size: Minimum statisitics buffer size. | ||
98 | + * @frame_count: Frame Count. | ||
99 | + * @stats_wait: Wait primitive for locking/unlocking the stats request. | ||
100 | + * @buffer_lock: Spinlock for statistics buffers access. | ||
101 | + */ | ||
102 | +static struct isp_af_status { | ||
103 | + u8 initialized; | ||
104 | + u8 update; | ||
105 | + u8 stats_req; | ||
106 | + u8 stats_done; | ||
107 | + u16 frame_req; | ||
108 | + | ||
109 | + struct isp_af_buffer af_buff[H3A_MAX_BUFF]; | ||
110 | + unsigned int stats_buf_size; | ||
111 | + unsigned int min_buf_size; | ||
112 | + unsigned int curr_cfg_buf_size; | ||
113 | + | ||
114 | + int pm_state; | ||
115 | + u32 frame_count; | ||
116 | + wait_queue_head_t stats_wait; | ||
117 | + atomic_t config_counter; | ||
118 | + spinlock_t buffer_lock; /* For stats buffers read/write sync */ | ||
119 | +} afstat; | ||
120 | + | ||
121 | +struct af_device *af_dev_configptr; | ||
122 | +static struct isp_af_buffer *active_buff; | ||
123 | +static int af_major = -1; | ||
124 | +static int camnotify; | ||
125 | + | ||
126 | +/** | ||
127 | + * isp_af_setxtrastats - Receives extra statistics from prior frames. | ||
128 | + * @xtrastats: Pointer to structure containing extra statistics fields like | ||
129 | + * field count and timestamp of frame. | ||
130 | + * | ||
131 | + * Called from update_vbq in camera driver | ||
132 | + **/ | ||
133 | +void isp_af_setxtrastats(struct isp_af_xtrastats *xtrastats, u8 updateflag) | ||
134 | +{ | ||
135 | + int i, past_i; | ||
136 | + | ||
137 | + if (active_buff == NULL) | ||
138 | + return; | ||
139 | + | ||
140 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
141 | + if (afstat.af_buff[i].frame_num == active_buff->frame_num) | ||
142 | + break; | ||
143 | + } | ||
144 | + | ||
145 | + if (i == H3A_MAX_BUFF) | ||
146 | + return; | ||
147 | + | ||
148 | + if (i == 0) { | ||
149 | + if (afstat.af_buff[H3A_MAX_BUFF - 1].locked == 0) | ||
150 | + past_i = H3A_MAX_BUFF - 1; | ||
151 | + else | ||
152 | + past_i = H3A_MAX_BUFF - 2; | ||
153 | + } else if (i == 1) { | ||
154 | + if (afstat.af_buff[0].locked == 0) | ||
155 | + past_i = 0; | ||
156 | + else | ||
157 | + past_i = H3A_MAX_BUFF - 1; | ||
158 | + } else { | ||
159 | + if (afstat.af_buff[i - 1].locked == 0) | ||
160 | + past_i = i - 1; | ||
161 | + else | ||
162 | + past_i = i - 2; | ||
163 | + } | ||
164 | + | ||
165 | + if (updateflag & AF_UPDATEXS_TS) | ||
166 | + afstat.af_buff[past_i].xtrastats.ts = xtrastats->ts; | ||
167 | + | ||
168 | + if (updateflag & AF_UPDATEXS_FIELDCOUNT) | ||
169 | + afstat.af_buff[past_i].xtrastats.field_count = | ||
170 | + xtrastats->field_count; | ||
171 | +} | ||
172 | +EXPORT_SYMBOL(isp_af_setxtrastats); | ||
173 | + | ||
174 | +/* | ||
175 | + * Helper function to update buffer cache pages | ||
176 | + */ | ||
177 | +static void isp_af_update_req_buffer(struct isp_af_buffer *buffer) | ||
178 | +{ | ||
179 | + int size = afstat.stats_buf_size; | ||
180 | + | ||
181 | + size = PAGE_ALIGN(size); | ||
182 | + /* Update the kernel pages of the requested buffer */ | ||
183 | + dmac_inv_range((void *)buffer->addr_align, (void *)buffer->addr_align + | ||
184 | + size); | ||
185 | +} | ||
186 | + | ||
187 | +#define IS_OUT_OF_BOUNDS(value, min, max) \ | ||
188 | + (((value) < (min)) || ((value) > (max))) | ||
189 | + | ||
190 | +/* Function to check paxel parameters */ | ||
191 | +int isp_af_check_paxel(void) | ||
192 | +{ | ||
193 | + struct af_paxel *paxel_cfg = &af_dev_configptr->config->paxel_config; | ||
194 | + struct af_iir *iir_cfg = &af_dev_configptr->config->iir_config; | ||
195 | + | ||
196 | + /* Check horizontal Count */ | ||
197 | + if (IS_OUT_OF_BOUNDS(paxel_cfg->hz_cnt, AF_PAXEL_HORIZONTAL_COUNT_MIN, | ||
198 | + AF_PAXEL_HORIZONTAL_COUNT_MAX)) { | ||
199 | + DPRINTK_ISP_AF("Error : Horizontal Count is incorrect"); | ||
200 | + return -AF_ERR_HZ_COUNT; | ||
201 | + } | ||
202 | + | ||
203 | + /*Check Vertical Count */ | ||
204 | + if (IS_OUT_OF_BOUNDS(paxel_cfg->vt_cnt, AF_PAXEL_VERTICAL_COUNT_MIN, | ||
205 | + AF_PAXEL_VERTICAL_COUNT_MAX)) { | ||
206 | + DPRINTK_ISP_AF("Error : Vertical Count is incorrect"); | ||
207 | + return -AF_ERR_VT_COUNT; | ||
208 | + } | ||
209 | + | ||
210 | + /*Check Height */ | ||
211 | + if (IS_OUT_OF_BOUNDS(paxel_cfg->height, AF_PAXEL_HEIGHT_MIN, | ||
212 | + AF_PAXEL_HEIGHT_MAX)) { | ||
213 | + DPRINTK_ISP_AF("Error : Height is incorrect"); | ||
214 | + return -AF_ERR_HEIGHT; | ||
215 | + } | ||
216 | + | ||
217 | + /*Check width */ | ||
218 | + if (IS_OUT_OF_BOUNDS(paxel_cfg->width, AF_PAXEL_WIDTH_MIN, | ||
219 | + AF_PAXEL_WIDTH_MAX)) { | ||
220 | + DPRINTK_ISP_AF("Error : Width is incorrect"); | ||
221 | + return -AF_ERR_WIDTH; | ||
222 | + } | ||
223 | + | ||
224 | + /*Check Line Increment */ | ||
225 | + if (IS_OUT_OF_BOUNDS(paxel_cfg->line_incr, AF_PAXEL_INCREMENT_MIN, | ||
226 | + AF_PAXEL_INCREMENT_MAX)) { | ||
227 | + DPRINTK_ISP_AF("Error : Line Increment is incorrect"); | ||
228 | + return -AF_ERR_INCR; | ||
229 | + } | ||
230 | + | ||
231 | + /*Check Horizontal Start */ | ||
232 | + if ((paxel_cfg->hz_start % 2 != 0) || | ||
233 | + (paxel_cfg->hz_start < (iir_cfg->hz_start_pos + 2)) || | ||
234 | + IS_OUT_OF_BOUNDS(paxel_cfg->hz_start, | ||
235 | + AF_PAXEL_HZSTART_MIN, AF_PAXEL_HZSTART_MAX)) { | ||
236 | + DPRINTK_ISP_AF("Error : Horizontal Start is incorrect"); | ||
237 | + return -AF_ERR_HZ_START; | ||
238 | + } | ||
239 | + | ||
240 | + /*Check Vertical Start */ | ||
241 | + if (IS_OUT_OF_BOUNDS(paxel_cfg->vt_start, AF_PAXEL_VTSTART_MIN, | ||
242 | + AF_PAXEL_VTSTART_MAX)) { | ||
243 | + DPRINTK_ISP_AF("Error : Vertical Start is incorrect"); | ||
244 | + return -AF_ERR_VT_START; | ||
245 | + } | ||
246 | + return 0; | ||
247 | +} | ||
248 | + | ||
249 | +/** | ||
250 | + * isp_af_check_iir - Function to check IIR Coefficient. | ||
251 | + **/ | ||
252 | +int isp_af_check_iir(void) | ||
253 | +{ | ||
254 | + struct af_iir *iir_cfg = &af_dev_configptr->config->iir_config; | ||
255 | + int index; | ||
256 | + | ||
257 | + for (index = 0; index < AF_NUMBER_OF_COEF; index++) { | ||
258 | + if ((iir_cfg->coeff_set0[index]) > AF_COEF_MAX) { | ||
259 | + DPRINTK_ISP_AF("Error : Coefficient for set 0 is " | ||
260 | + "incorrect"); | ||
261 | + return -AF_ERR_IIR_COEF; | ||
262 | + } | ||
263 | + | ||
264 | + if ((iir_cfg->coeff_set1[index]) > AF_COEF_MAX) { | ||
265 | + DPRINTK_ISP_AF("Error : Coefficient for set 1 is " | ||
266 | + "incorrect"); | ||
267 | + return -AF_ERR_IIR_COEF; | ||
268 | + } | ||
269 | + } | ||
270 | + | ||
271 | + if (IS_OUT_OF_BOUNDS(iir_cfg->hz_start_pos, AF_IIRSH_MIN, | ||
272 | + AF_IIRSH_MAX)) { | ||
273 | + DPRINTK_ISP_AF("Error : IIRSH is incorrect"); | ||
274 | + return -AF_ERR_IIRSH; | ||
275 | + } | ||
276 | + | ||
277 | + return 0; | ||
278 | +} | ||
279 | +/** | ||
280 | + * isp_af_unlock_buffers - Helper function to unlock all buffers. | ||
281 | + **/ | ||
282 | +static void isp_af_unlock_buffers(void) | ||
283 | +{ | ||
284 | + int i; | ||
285 | + unsigned long irqflags; | ||
286 | + | ||
287 | + spin_lock_irqsave(&afstat.buffer_lock, irqflags); | ||
288 | + for (i = 0; i < H3A_MAX_BUFF; i++) | ||
289 | + afstat.af_buff[i].locked = 0; | ||
290 | + | ||
291 | + spin_unlock_irqrestore(&afstat.buffer_lock, irqflags); | ||
292 | +} | ||
293 | + | ||
294 | +/* | ||
295 | + * Helper function to link allocated buffers | ||
296 | + */ | ||
297 | +static void isp_af_link_buffers(void) | ||
298 | +{ | ||
299 | + int i; | ||
300 | + | ||
301 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
302 | + if ((i + 1) < H3A_MAX_BUFF) | ||
303 | + afstat.af_buff[i].next = &afstat.af_buff[i + 1]; | ||
304 | + else | ||
305 | + afstat.af_buff[i].next = &afstat.af_buff[0]; | ||
306 | + } | ||
307 | +} | ||
308 | + | ||
309 | +/* Function to perform hardware set up */ | ||
310 | +int isp_af_configure(struct af_configuration *afconfig) | ||
311 | +{ | ||
312 | + int result; | ||
313 | + int buff_size, i; | ||
314 | + unsigned int busyaf; | ||
315 | + struct af_configuration *af_curr_cfg = af_dev_configptr->config; | ||
316 | + | ||
317 | + if (NULL == afconfig) { | ||
318 | + printk(KERN_ERR "Null argument in configuration. \n"); | ||
319 | + return -EINVAL; | ||
320 | + } | ||
321 | + | ||
322 | + memcpy(af_curr_cfg, afconfig, sizeof(struct af_configuration)); | ||
323 | + /* Get the value of PCR register */ | ||
324 | + busyaf = isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); | ||
325 | + | ||
326 | + if ((busyaf & AF_BUSYAF) == AF_BUSYAF) { | ||
327 | + DPRINTK_ISP_AF("AF_register_setup_ERROR : Engine Busy"); | ||
328 | + DPRINTK_ISP_AF("\n Configuration cannot be done "); | ||
329 | + return -AF_ERR_ENGINE_BUSY; | ||
330 | + } | ||
331 | + | ||
332 | + /* Check IIR Coefficient and start Values */ | ||
333 | + result = isp_af_check_iir(); | ||
334 | + if (result < 0) | ||
335 | + return result; | ||
336 | + | ||
337 | + /* Check Paxel Values */ | ||
338 | + result = isp_af_check_paxel(); | ||
339 | + if (result < 0) | ||
340 | + return result; | ||
341 | + | ||
342 | + /* Check HMF Threshold Values */ | ||
343 | + if (af_curr_cfg->hmf_config.threshold > AF_THRESHOLD_MAX) { | ||
344 | + DPRINTK_ISP_AF("Error : HMF Threshold is incorrect"); | ||
345 | + return -AF_ERR_THRESHOLD; | ||
346 | + } | ||
347 | + | ||
348 | + /* Compute buffer size */ | ||
349 | + buff_size = (af_curr_cfg->paxel_config.hz_cnt + 1) * | ||
350 | + (af_curr_cfg->paxel_config.vt_cnt + 1) * AF_PAXEL_SIZE; | ||
351 | + | ||
352 | + afstat.curr_cfg_buf_size = buff_size; | ||
353 | + /* Deallocate the previous buffers */ | ||
354 | + if (afstat.stats_buf_size && buff_size > afstat.stats_buf_size) { | ||
355 | + isp_af_enable(0); | ||
356 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
357 | + ispmmu_kunmap(afstat.af_buff[i].ispmmu_addr); | ||
358 | + dma_free_coherent( | ||
359 | + NULL, afstat.min_buf_size, | ||
360 | + (void *)afstat.af_buff[i].virt_addr, | ||
361 | + (dma_addr_t)afstat.af_buff[i].phy_addr); | ||
362 | + afstat.af_buff[i].virt_addr = 0; | ||
363 | + } | ||
364 | + afstat.stats_buf_size = 0; | ||
365 | + } | ||
366 | + | ||
367 | + if (!afstat.af_buff[0].virt_addr) { | ||
368 | + afstat.stats_buf_size = buff_size; | ||
369 | + afstat.min_buf_size = PAGE_ALIGN(afstat.stats_buf_size); | ||
370 | + | ||
371 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
372 | + afstat.af_buff[i].virt_addr = | ||
373 | + (unsigned long)dma_alloc_coherent( | ||
374 | + NULL, | ||
375 | + afstat.min_buf_size, | ||
376 | + (dma_addr_t *) | ||
377 | + &afstat.af_buff[i].phy_addr, | ||
378 | + GFP_KERNEL | GFP_DMA); | ||
379 | + if (afstat.af_buff[i].virt_addr == 0) { | ||
380 | + printk(KERN_ERR "Can't acquire memory for " | ||
381 | + "buffer[%d]\n", i); | ||
382 | + return -ENOMEM; | ||
383 | + } | ||
384 | + afstat.af_buff[i].addr_align = | ||
385 | + afstat.af_buff[i].virt_addr; | ||
386 | + while ((afstat.af_buff[i].addr_align & 0xFFFFFFC0) != | ||
387 | + afstat.af_buff[i].addr_align) | ||
388 | + afstat.af_buff[i].addr_align++; | ||
389 | + afstat.af_buff[i].ispmmu_addr = | ||
390 | + ispmmu_kmap(afstat.af_buff[i].phy_addr, | ||
391 | + afstat.min_buf_size); | ||
392 | + } | ||
393 | + isp_af_unlock_buffers(); | ||
394 | + isp_af_link_buffers(); | ||
395 | + | ||
396 | + /* First active buffer */ | ||
397 | + if (active_buff == NULL) | ||
398 | + active_buff = &afstat.af_buff[0]; | ||
399 | + isp_af_set_address(active_buff->ispmmu_addr); | ||
400 | + } | ||
401 | + | ||
402 | + result = isp_af_register_setup(af_dev_configptr); | ||
403 | + if (result < 0) | ||
404 | + return result; | ||
405 | + af_dev_configptr->size_paxel = buff_size; | ||
406 | + atomic_inc(&afstat.config_counter); | ||
407 | + afstat.initialized = 1; | ||
408 | + afstat.frame_count = 1; | ||
409 | + active_buff->frame_num = 1; | ||
410 | + /* Set configuration flag to indicate HW setup done */ | ||
411 | + if (af_curr_cfg->af_config) | ||
412 | + isp_af_enable(1); | ||
413 | + else | ||
414 | + isp_af_enable(0); | ||
415 | + | ||
416 | + /* Success */ | ||
417 | + return 0; | ||
418 | +} | ||
419 | +EXPORT_SYMBOL(isp_af_configure); | ||
420 | + | ||
421 | +int isp_af_register_setup(struct af_device *af_dev) | ||
422 | +{ | ||
423 | + unsigned int pcr = 0, pax1 = 0, pax2 = 0, paxstart = 0; | ||
424 | + unsigned int coef = 0; | ||
425 | + unsigned int base_coef_set0 = 0; | ||
426 | + unsigned int base_coef_set1 = 0; | ||
427 | + int index; | ||
428 | + | ||
429 | + /* Configure Hardware Registers */ | ||
430 | + /* Read PCR Register */ | ||
431 | + pcr = isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); | ||
432 | + | ||
433 | + /* Set Accumulator Mode */ | ||
434 | + if (af_dev->config->mode == ACCUMULATOR_PEAK) | ||
435 | + pcr |= FVMODE; | ||
436 | + else | ||
437 | + pcr &= ~FVMODE; | ||
438 | + | ||
439 | + /* Set A-law */ | ||
440 | + if (af_dev->config->alaw_enable == H3A_AF_ALAW_ENABLE) | ||
441 | + pcr |= AF_ALAW_EN; | ||
442 | + else | ||
443 | + pcr &= ~AF_ALAW_EN; | ||
444 | + | ||
445 | + /* Set RGB Position */ | ||
446 | + pcr &= ~RGBPOS; | ||
447 | + pcr |= af_dev->config->rgb_pos << AF_RGBPOS_SHIFT; | ||
448 | + | ||
449 | + /* HMF Configurations */ | ||
450 | + if (af_dev->config->hmf_config.enable == H3A_AF_HMF_ENABLE) { | ||
451 | + pcr &= ~AF_MED_EN; | ||
452 | + /* Enable HMF */ | ||
453 | + pcr |= AF_MED_EN; | ||
454 | + | ||
455 | + /* Set Median Threshold */ | ||
456 | + pcr &= ~MED_TH; | ||
457 | + pcr |= af_dev->config->hmf_config.threshold << AF_MED_TH_SHIFT; | ||
458 | + } else | ||
459 | + pcr &= ~AF_MED_EN; | ||
460 | + | ||
461 | + /* Set PCR Register */ | ||
462 | + isp_reg_writel(pcr, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); | ||
463 | + | ||
464 | + pax1 &= ~PAXW; | ||
465 | + pax1 |= af_dev->config->paxel_config.width << AF_PAXW_SHIFT; | ||
466 | + | ||
467 | + /* Set height in AFPAX1 */ | ||
468 | + pax1 &= ~PAXH; | ||
469 | + pax1 |= af_dev->config->paxel_config.height; | ||
470 | + | ||
471 | + isp_reg_writel(pax1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX1); | ||
472 | + | ||
473 | + /* Configure AFPAX2 Register */ | ||
474 | + /* Set Line Increment in AFPAX2 Register */ | ||
475 | + pax2 &= ~AFINCV; | ||
476 | + pax2 |= af_dev->config->paxel_config.line_incr << AF_LINE_INCR_SHIFT; | ||
477 | + /* Set Vertical Count */ | ||
478 | + pax2 &= ~PAXVC; | ||
479 | + pax2 |= af_dev->config->paxel_config.vt_cnt << AF_VT_COUNT_SHIFT; | ||
480 | + /* Set Horizontal Count */ | ||
481 | + pax2 &= ~PAXHC; | ||
482 | + pax2 |= af_dev->config->paxel_config.hz_cnt; | ||
483 | + isp_reg_writel(pax2, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX2); | ||
484 | + | ||
485 | + /* Configure PAXSTART Register */ | ||
486 | + /*Configure Horizontal Start */ | ||
487 | + paxstart &= ~PAXSH; | ||
488 | + paxstart |= af_dev->config->paxel_config.hz_start << AF_HZ_START_SHIFT; | ||
489 | + /* Configure Vertical Start */ | ||
490 | + paxstart &= ~PAXSV; | ||
491 | + paxstart |= af_dev->config->paxel_config.vt_start; | ||
492 | + isp_reg_writel(paxstart, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAXSTART); | ||
493 | + | ||
494 | + /*SetIIRSH Register */ | ||
495 | + isp_reg_writel(af_dev->config->iir_config.hz_start_pos, | ||
496 | + OMAP3_ISP_IOMEM_H3A, ISPH3A_AFIIRSH); | ||
497 | + | ||
498 | + /*Set IIR Filter0 Coefficients */ | ||
499 | + base_coef_set0 = ISPH3A_AFCOEF010; | ||
500 | + for (index = 0; index <= 8; index += 2) { | ||
501 | + coef &= ~COEF_MASK0; | ||
502 | + coef |= af_dev->config->iir_config.coeff_set0[index]; | ||
503 | + coef &= ~COEF_MASK1; | ||
504 | + coef |= af_dev->config->iir_config.coeff_set0[index + 1] << | ||
505 | + AF_COEF_SHIFT; | ||
506 | + isp_reg_writel(coef, OMAP3_ISP_IOMEM_H3A, base_coef_set0); | ||
507 | + base_coef_set0 = base_coef_set0 + AFCOEF_OFFSET; | ||
508 | + } | ||
509 | + | ||
510 | + /* set AFCOEF0010 Register */ | ||
511 | + isp_reg_writel(af_dev->config->iir_config.coeff_set0[10], | ||
512 | + OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF010); | ||
513 | + | ||
514 | + /*Set IIR Filter1 Coefficients */ | ||
515 | + | ||
516 | + base_coef_set1 = ISPH3A_AFCOEF110; | ||
517 | + for (index = 0; index <= 8; index += 2) { | ||
518 | + coef &= ~COEF_MASK0; | ||
519 | + coef |= af_dev->config->iir_config.coeff_set1[index]; | ||
520 | + coef &= ~COEF_MASK1; | ||
521 | + coef |= af_dev->config->iir_config.coeff_set1[index + 1] << | ||
522 | + AF_COEF_SHIFT; | ||
523 | + isp_reg_writel(coef, OMAP3_ISP_IOMEM_H3A, base_coef_set1); | ||
524 | + | ||
525 | + base_coef_set1 = base_coef_set1 + AFCOEF_OFFSET; | ||
526 | + } | ||
527 | + isp_reg_writel(af_dev->config->iir_config.coeff_set1[10], | ||
528 | + OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF1010); | ||
529 | + | ||
530 | + return 0; | ||
531 | +} | ||
532 | + | ||
533 | +/* Function to set address */ | ||
534 | +void isp_af_set_address(unsigned long address) | ||
535 | +{ | ||
536 | + isp_reg_writel(address, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFBUFST); | ||
537 | +} | ||
538 | + | ||
539 | +static int isp_af_stats_available(struct isp_af_data *afdata) | ||
540 | +{ | ||
541 | + int i, ret; | ||
542 | + unsigned long irqflags; | ||
543 | + | ||
544 | + spin_lock_irqsave(&afstat.buffer_lock, irqflags); | ||
545 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
546 | + DPRINTK_ISP_AF("Checking Stats buff[%d] (%d) for %d\n", | ||
547 | + i, afstat.af_buff[i].frame_num, | ||
548 | + afdata->frame_number); | ||
549 | + if (afdata->frame_number == afstat.af_buff[i].frame_num | ||
550 | + && afstat.af_buff[i].frame_num != active_buff->frame_num) { | ||
551 | + afstat.af_buff[i].locked = 1; | ||
552 | + spin_unlock_irqrestore(&afstat.buffer_lock, irqflags); | ||
553 | + isp_af_update_req_buffer(&afstat.af_buff[i]); | ||
554 | + afstat.af_buff[i].frame_num = 0; | ||
555 | + ret = copy_to_user((void *)afdata->af_statistics_buf, | ||
556 | + (void *)afstat.af_buff[i].virt_addr, | ||
557 | + afstat.curr_cfg_buf_size); | ||
558 | + if (ret) { | ||
559 | + printk(KERN_ERR "Failed copy_to_user for " | ||
560 | + "H3A stats buff, %d\n", ret); | ||
561 | + } | ||
562 | + afdata->xtrastats.ts = afstat.af_buff[i].xtrastats.ts; | ||
563 | + afdata->xtrastats.field_count = | ||
564 | + afstat.af_buff[i].xtrastats.field_count; | ||
565 | + return 0; | ||
566 | + } | ||
567 | + } | ||
568 | + spin_unlock_irqrestore(&afstat.buffer_lock, irqflags); | ||
569 | + /* Stats unavailable */ | ||
570 | + | ||
571 | + return -1; | ||
572 | +} | ||
573 | + | ||
574 | +void isp_af_notify(int notify) | ||
575 | +{ | ||
576 | + camnotify = notify; | ||
577 | + if (camnotify && afstat.initialized) { | ||
578 | + printk(KERN_DEBUG "Warning Camera Off \n"); | ||
579 | + afstat.stats_req = 0; | ||
580 | + afstat.stats_done = 1; | ||
581 | + wake_up_interruptible(&afstat.stats_wait); | ||
582 | + } | ||
583 | +} | ||
584 | +EXPORT_SYMBOL(isp_af_notify); | ||
585 | +/* | ||
586 | + * This API allows the user to update White Balance gains, as well as | ||
587 | + * exposure time and analog gain. It is also used to request frame | ||
588 | + * statistics. | ||
589 | + */ | ||
590 | +int isp_af_request_statistics(struct isp_af_data *afdata) | ||
591 | +{ | ||
592 | + int ret = 0; | ||
593 | + u16 frame_diff = 0; | ||
594 | + u16 frame_cnt = afstat.frame_count; | ||
595 | + wait_queue_t wqt; | ||
596 | + | ||
597 | + if (!af_dev_configptr->config->af_config) { | ||
598 | + printk(KERN_ERR "AF engine not enabled\n"); | ||
599 | + return -EINVAL; | ||
600 | + } | ||
601 | + | ||
602 | + if (!(afdata->update & REQUEST_STATISTICS)) { | ||
603 | + afdata->af_statistics_buf = NULL; | ||
604 | + goto out; | ||
605 | + } | ||
606 | + | ||
607 | + isp_af_unlock_buffers(); | ||
608 | + /* Stats available? */ | ||
609 | + DPRINTK_ISP_AF("Stats available?\n"); | ||
610 | + ret = isp_af_stats_available(afdata); | ||
611 | + if (!ret) | ||
612 | + goto out; | ||
613 | + | ||
614 | + /* Stats in near future? */ | ||
615 | + DPRINTK_ISP_AF("Stats in near future?\n"); | ||
616 | + if (afdata->frame_number > frame_cnt) | ||
617 | + frame_diff = afdata->frame_number - frame_cnt; | ||
618 | + else if (afdata->frame_number < frame_cnt) { | ||
619 | + if (frame_cnt > MAX_FRAME_COUNT - MAX_FUTURE_FRAMES | ||
620 | + && afdata->frame_number < MAX_FRAME_COUNT) { | ||
621 | + frame_diff = afdata->frame_number + MAX_FRAME_COUNT - | ||
622 | + frame_cnt; | ||
623 | + } else { | ||
624 | + /* Frame unavailable */ | ||
625 | + frame_diff = MAX_FUTURE_FRAMES + 1; | ||
626 | + } | ||
627 | + } | ||
628 | + | ||
629 | + if (frame_diff > MAX_FUTURE_FRAMES) { | ||
630 | + printk(KERN_ERR "Invalid frame requested, returning current" | ||
631 | + " frame stats\n"); | ||
632 | + afdata->frame_number = frame_cnt; | ||
633 | + } | ||
634 | + if (!camnotify) { | ||
635 | + /* Block until frame in near future completes */ | ||
636 | + afstat.frame_req = afdata->frame_number; | ||
637 | + afstat.stats_req = 1; | ||
638 | + afstat.stats_done = 0; | ||
639 | + init_waitqueue_entry(&wqt, current); | ||
640 | + ret = wait_event_interruptible(afstat.stats_wait, | ||
641 | + afstat.stats_done == 1); | ||
642 | + if (ret < 0) { | ||
643 | + afdata->af_statistics_buf = NULL; | ||
644 | + return ret; | ||
645 | + } | ||
646 | + DPRINTK_ISP_AF("ISP AF request status interrupt raised\n"); | ||
647 | + | ||
648 | + /* Stats now available */ | ||
649 | + ret = isp_af_stats_available(afdata); | ||
650 | + if (ret) { | ||
651 | + printk(KERN_ERR "After waiting for stats, stats not" | ||
652 | + " available!!\n"); | ||
653 | + afdata->af_statistics_buf = NULL; | ||
654 | + } | ||
655 | + } | ||
656 | + | ||
657 | +out: | ||
658 | + afdata->curr_frame = afstat.frame_count; | ||
659 | + | ||
660 | + return 0; | ||
661 | +} | ||
662 | +EXPORT_SYMBOL(isp_af_request_statistics); | ||
663 | + | ||
664 | +/* This function will handle the H3A interrupt. */ | ||
665 | +static void isp_af_isr(unsigned long status, isp_vbq_callback_ptr arg1, | ||
666 | + void *arg2) | ||
667 | +{ | ||
668 | + u16 frame_align; | ||
669 | + | ||
670 | + if ((H3A_AF_DONE & status) != H3A_AF_DONE) | ||
671 | + return; | ||
672 | + | ||
673 | + /* timestamp stats buffer */ | ||
674 | + do_gettimeofday(&active_buff->xtrastats.ts); | ||
675 | + active_buff->config_counter = atomic_read(&afstat.config_counter); | ||
676 | + | ||
677 | + /* Exchange buffers */ | ||
678 | + active_buff = active_buff->next; | ||
679 | + if (active_buff->locked == 1) | ||
680 | + active_buff = active_buff->next; | ||
681 | + isp_af_set_address(active_buff->ispmmu_addr); | ||
682 | + | ||
683 | + /* Update frame counter */ | ||
684 | + afstat.frame_count++; | ||
685 | + frame_align = afstat.frame_count; | ||
686 | + if (afstat.frame_count > MAX_FRAME_COUNT) { | ||
687 | + afstat.frame_count = 1; | ||
688 | + frame_align++; | ||
689 | + } | ||
690 | + active_buff->frame_num = afstat.frame_count; | ||
691 | + | ||
692 | + /* Future Stats requested? */ | ||
693 | + if (afstat.stats_req) { | ||
694 | + /* Is the frame we want already done? */ | ||
695 | + if (frame_align >= afstat.frame_req + 1) { | ||
696 | + afstat.stats_req = 0; | ||
697 | + afstat.stats_done = 1; | ||
698 | + wake_up_interruptible(&afstat.stats_wait); | ||
699 | + } | ||
700 | + } | ||
701 | +} | ||
702 | + | ||
703 | +int __isp_af_enable(int enable) | ||
704 | +{ | ||
705 | + unsigned int pcr; | ||
706 | + | ||
707 | + pcr = isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); | ||
708 | + | ||
709 | + /* Set AF_EN bit in PCR Register */ | ||
710 | + if (enable) { | ||
711 | + if (isp_set_callback(CBK_H3A_AF_DONE, isp_af_isr, | ||
712 | + (void *)NULL, (void *)NULL)) { | ||
713 | + printk(KERN_ERR "No callback for AF\n"); | ||
714 | + return -EINVAL; | ||
715 | + } | ||
716 | + | ||
717 | + pcr |= AF_EN; | ||
718 | + } else { | ||
719 | + isp_unset_callback(CBK_H3A_AF_DONE); | ||
720 | + pcr &= ~AF_EN; | ||
721 | + } | ||
722 | + isp_reg_writel(pcr, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); | ||
723 | + return 0; | ||
724 | +} | ||
725 | + | ||
726 | +/* Function to Enable/Disable AF Engine */ | ||
727 | +int isp_af_enable(int enable) | ||
728 | +{ | ||
729 | + int rval; | ||
730 | + | ||
731 | + rval = __isp_af_enable(enable); | ||
732 | + | ||
733 | + if (!rval) | ||
734 | + afstat.pm_state = enable; | ||
735 | + | ||
736 | + return rval; | ||
737 | +} | ||
738 | + | ||
739 | +/* Function to Suspend AF Engine */ | ||
740 | +void isp_af_suspend(void) | ||
741 | +{ | ||
742 | + if (afstat.pm_state) | ||
743 | + __isp_af_enable(0); | ||
744 | +} | ||
745 | + | ||
746 | +/* Function to Resume AF Engine */ | ||
747 | +void isp_af_resume(void) | ||
748 | +{ | ||
749 | + if (afstat.pm_state) | ||
750 | + __isp_af_enable(1); | ||
751 | +} | ||
752 | + | ||
753 | +int isp_af_busy(void) | ||
754 | +{ | ||
755 | + return isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR) | ||
756 | + & ISPH3A_PCR_BUSYAF; | ||
757 | +} | ||
758 | + | ||
759 | +/* Function to register the AF character device driver. */ | ||
760 | +int __init isp_af_init(void) | ||
761 | +{ | ||
762 | + /*allocate memory for device structure and initialize it with 0 */ | ||
763 | + af_dev_configptr = kzalloc(sizeof(struct af_device), GFP_KERNEL); | ||
764 | + if (!af_dev_configptr) | ||
765 | + goto err_nomem1; | ||
766 | + | ||
767 | + active_buff = NULL; | ||
768 | + | ||
769 | + af_dev_configptr->config = (struct af_configuration *) | ||
770 | + kzalloc(sizeof(struct af_configuration), GFP_KERNEL); | ||
771 | + | ||
772 | + if (af_dev_configptr->config == NULL) | ||
773 | + goto err_nomem2; | ||
774 | + | ||
775 | + memset(&afstat, 0, sizeof(afstat)); | ||
776 | + | ||
777 | + init_waitqueue_head(&afstat.stats_wait); | ||
778 | + spin_lock_init(&afstat.buffer_lock); | ||
779 | + | ||
780 | + return 0; | ||
781 | + | ||
782 | +err_nomem2: | ||
783 | + kfree(af_dev_configptr); | ||
784 | +err_nomem1: | ||
785 | + printk(KERN_ERR "Error: kmalloc fail"); | ||
786 | + return -ENOMEM; | ||
787 | +} | ||
788 | + | ||
789 | +void isp_af_exit(void) | ||
790 | +{ | ||
791 | + int i; | ||
792 | + | ||
793 | + /* Free buffers */ | ||
794 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
795 | + if (!afstat.af_buff[i].phy_addr) | ||
796 | + continue; | ||
797 | + | ||
798 | + ispmmu_kunmap(afstat.af_buff[i].ispmmu_addr); | ||
799 | + | ||
800 | + dma_free_coherent(NULL, | ||
801 | + afstat.min_buf_size, | ||
802 | + (void *)afstat.af_buff[i].virt_addr, | ||
803 | + (dma_addr_t)afstat.af_buff[i].phy_addr); | ||
804 | + } | ||
805 | + kfree(af_dev_configptr->config); | ||
806 | + kfree(af_dev_configptr); | ||
807 | + | ||
808 | + memset(&afstat, 0, sizeof(afstat)); | ||
809 | + | ||
810 | + af_major = -1; | ||
811 | +} | ||
812 | diff --git a/drivers/media/video/isp/isp_af.h b/drivers/media/video/isp/isp_af.h | ||
813 | new file mode 100644 | ||
814 | index 0000000..ee2b89f | ||
815 | --- /dev/null | ||
816 | +++ b/drivers/media/video/isp/isp_af.h | ||
817 | @@ -0,0 +1,125 @@ | ||
818 | +/* | ||
819 | + * isp_af.h | ||
820 | + * | ||
821 | + * Include file for AF module in TI's OMAP3 Camera ISP | ||
822 | + * | ||
823 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
824 | + * | ||
825 | + * Contributors: | ||
826 | + * Sergio Aguirre <saaguirre@ti.com> | ||
827 | + * Troy Laramy | ||
828 | + * | ||
829 | + * This package is free software; you can redistribute it and/or modify | ||
830 | + * it under the terms of the GNU General Public License version 2 as | ||
831 | + * published by the Free Software Foundation. | ||
832 | + * | ||
833 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
834 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
835 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
836 | + */ | ||
837 | + | ||
838 | +/* Device Constants */ | ||
839 | +#ifndef OMAP_ISP_AF_H | ||
840 | +#define OMAP_ISP_AF_H | ||
841 | + | ||
842 | +#include <mach/isp_user.h> | ||
843 | + | ||
844 | +#define AF_MAJOR_NUMBER 0 | ||
845 | +#define ISPAF_NAME "OMAPISP_AF" | ||
846 | +#define AF_NR_DEVS 1 | ||
847 | +#define AF_TIMEOUT ((300 * HZ) / 1000) | ||
848 | + | ||
849 | + | ||
850 | + | ||
851 | +/* Print Macros */ | ||
852 | +/*list of error code */ | ||
853 | +#define AF_ERR_HZ_COUNT 800 /* Invalid Horizontal Count */ | ||
854 | +#define AF_ERR_VT_COUNT 801 /* Invalid Vertical Count */ | ||
855 | +#define AF_ERR_HEIGHT 802 /* Invalid Height */ | ||
856 | +#define AF_ERR_WIDTH 803 /* Invalid width */ | ||
857 | +#define AF_ERR_INCR 804 /* Invalid Increment */ | ||
858 | +#define AF_ERR_HZ_START 805 /* Invalid horizontal Start */ | ||
859 | +#define AF_ERR_VT_START 806 /* Invalud vertical Start */ | ||
860 | +#define AF_ERR_IIRSH 807 /* Invalid IIRSH value */ | ||
861 | +#define AF_ERR_IIR_COEF 808 /* Invalid Coefficient */ | ||
862 | +#define AF_ERR_SETUP 809 /* Setup not done */ | ||
863 | +#define AF_ERR_THRESHOLD 810 /* Invalid Threshold */ | ||
864 | +#define AF_ERR_ENGINE_BUSY 811 /* Engine is busy */ | ||
865 | + | ||
866 | +#define AFPID 0x0 /* Peripheral Revision | ||
867 | + * and Class Information | ||
868 | + */ | ||
869 | + | ||
870 | +#define AFCOEF_OFFSET 0x00000004 /* COEFFICIENT BASE | ||
871 | + * ADDRESS | ||
872 | + */ | ||
873 | + | ||
874 | +/* | ||
875 | + * PCR fields | ||
876 | + */ | ||
877 | +#define AF_BUSYAF (1 << 15) | ||
878 | +#define FVMODE (1 << 14) | ||
879 | +#define RGBPOS (0x7 << 11) | ||
880 | +#define MED_TH (0xFF << 3) | ||
881 | +#define AF_MED_EN (1 << 2) | ||
882 | +#define AF_ALAW_EN (1 << 1) | ||
883 | +#define AF_EN (1 << 0) | ||
884 | + | ||
885 | +/* | ||
886 | + * AFPAX1 fields | ||
887 | + */ | ||
888 | +#define PAXW (0x7F << 16) | ||
889 | +#define PAXH 0x7F | ||
890 | + | ||
891 | +/* | ||
892 | + * AFPAX2 fields | ||
893 | + */ | ||
894 | +#define AFINCV (0xF << 13) | ||
895 | +#define PAXVC (0x7F << 6) | ||
896 | +#define PAXHC 0x3F | ||
897 | + | ||
898 | +/* | ||
899 | + * AFPAXSTART fields | ||
900 | + */ | ||
901 | +#define PAXSH (0xFFF<<16) | ||
902 | +#define PAXSV 0xFFF | ||
903 | + | ||
904 | +/* | ||
905 | + * COEFFICIENT MASK | ||
906 | + */ | ||
907 | + | ||
908 | +#define COEF_MASK0 0xFFF | ||
909 | +#define COEF_MASK1 (0xFFF<<16) | ||
910 | + | ||
911 | +/* BIT SHIFTS */ | ||
912 | +#define AF_RGBPOS_SHIFT 11 | ||
913 | +#define AF_MED_TH_SHIFT 3 | ||
914 | +#define AF_PAXW_SHIFT 16 | ||
915 | +#define AF_LINE_INCR_SHIFT 13 | ||
916 | +#define AF_VT_COUNT_SHIFT 6 | ||
917 | +#define AF_HZ_START_SHIFT 16 | ||
918 | +#define AF_COEF_SHIFT 16 | ||
919 | + | ||
920 | +#define AF_UPDATEXS_TS (1 << 0) | ||
921 | +#define AF_UPDATEXS_FIELDCOUNT (1 << 1) | ||
922 | +#define AF_UPDATEXS_LENSPOS (1 << 2) | ||
923 | + | ||
924 | +/* Structure for device of AF Engine */ | ||
925 | +struct af_device { | ||
926 | + struct af_configuration *config; /*Device configuration structure */ | ||
927 | + int size_paxel; /*Paxel size in bytes */ | ||
928 | +}; | ||
929 | + | ||
930 | +int isp_af_check_paxel(void); | ||
931 | +int isp_af_check_iir(void); | ||
932 | +int isp_af_register_setup(struct af_device *af_dev); | ||
933 | +int isp_af_enable(int); | ||
934 | +void isp_af_suspend(void); | ||
935 | +void isp_af_resume(void); | ||
936 | +int isp_af_busy(void); | ||
937 | +void isp_af_notify(int notify); | ||
938 | +int isp_af_request_statistics(struct isp_af_data *afdata); | ||
939 | +int isp_af_configure(struct af_configuration *afconfig); | ||
940 | +void isp_af_set_address(unsigned long); | ||
941 | +void isp_af_setxtrastats(struct isp_af_xtrastats *xtrastats, u8 updateflag); | ||
942 | +#endif /* OMAP_ISP_AF_H */ | ||
943 | diff --git a/drivers/media/video/isp/isph3a.c b/drivers/media/video/isp/isph3a.c | ||
944 | new file mode 100644 | ||
945 | index 0000000..7ff1c5b | ||
946 | --- /dev/null | ||
947 | +++ b/drivers/media/video/isp/isph3a.c | ||
948 | @@ -0,0 +1,932 @@ | ||
949 | +/* | ||
950 | + * isph3a.c | ||
951 | + * | ||
952 | + * H3A module for TI's OMAP3 Camera ISP | ||
953 | + * | ||
954 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
955 | + * | ||
956 | + * Contributors: | ||
957 | + * Sergio Aguirre <saaguirre@ti.com> | ||
958 | + * Troy Laramy | ||
959 | + * | ||
960 | + * This package is free software; you can redistribute it and/or modify | ||
961 | + * it under the terms of the GNU General Public License version 2 as | ||
962 | + * published by the Free Software Foundation. | ||
963 | + * | ||
964 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
965 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
966 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
967 | + */ | ||
968 | + | ||
969 | +#include <asm/cacheflush.h> | ||
970 | + | ||
971 | +#include <linux/dma-mapping.h> | ||
972 | +#include <linux/uaccess.h> | ||
973 | + | ||
974 | +#include "isp.h" | ||
975 | +#include "ispreg.h" | ||
976 | +#include "isph3a.h" | ||
977 | +#include "ispmmu.h" | ||
978 | +#include "isppreview.h" | ||
979 | + | ||
980 | +/** | ||
981 | + * struct isph3a_aewb_buffer - AE, AWB frame stats buffer. | ||
982 | + * @virt_addr: Virtual address to mmap the buffer. | ||
983 | + * @phy_addr: Physical address of the buffer. | ||
984 | + * @addr_align: Virtual Address 32 bytes aligned. | ||
985 | + * @ispmmu_addr: Address of the buffer mapped by the ISPMMU. | ||
986 | + * @mmap_addr: Mapped memory area of buffer. For userspace access. | ||
987 | + * @locked: 1 - Buffer locked from write. 0 - Buffer can be overwritten. | ||
988 | + * @frame_num: Frame number from which the statistics are taken. | ||
989 | + * @next: Pointer to link next buffer. | ||
990 | + */ | ||
991 | +struct isph3a_aewb_buffer { | ||
992 | + unsigned long virt_addr; | ||
993 | + unsigned long phy_addr; | ||
994 | + unsigned long addr_align; | ||
995 | + unsigned long ispmmu_addr; | ||
996 | + unsigned long mmap_addr; /* For userspace */ | ||
997 | + struct timeval ts; | ||
998 | + u32 config_counter; | ||
999 | + | ||
1000 | + u8 locked; | ||
1001 | + u16 frame_num; | ||
1002 | + struct isph3a_aewb_buffer *next; | ||
1003 | +}; | ||
1004 | + | ||
1005 | +/** | ||
1006 | + * struct isph3a_aewb_status - AE, AWB status. | ||
1007 | + * @initialized: 1 - Buffers initialized. | ||
1008 | + * @update: 1 - Update registers. | ||
1009 | + * @stats_req: 1 - Future stats requested. | ||
1010 | + * @stats_done: 1 - Stats ready for user. | ||
1011 | + * @frame_req: Number of frame requested for statistics. | ||
1012 | + * @h3a_buff: Array of statistics buffers to access. | ||
1013 | + * @stats_buf_size: Statistics buffer size. | ||
1014 | + * @min_buf_size: Minimum statisitics buffer size. | ||
1015 | + * @win_count: Window Count. | ||
1016 | + * @frame_count: Frame Count. | ||
1017 | + * @stats_wait: Wait primitive for locking/unlocking the stats request. | ||
1018 | + * @buffer_lock: Spinlock for statistics buffers access. | ||
1019 | + */ | ||
1020 | +static struct isph3a_aewb_status { | ||
1021 | + u8 initialized; | ||
1022 | + u8 update; | ||
1023 | + u8 stats_req; | ||
1024 | + u8 stats_done; | ||
1025 | + u16 frame_req; | ||
1026 | + int pm_state; | ||
1027 | + | ||
1028 | + struct isph3a_aewb_buffer h3a_buff[H3A_MAX_BUFF]; | ||
1029 | + unsigned int stats_buf_size; | ||
1030 | + unsigned int min_buf_size; | ||
1031 | + unsigned int curr_cfg_buf_size; | ||
1032 | + | ||
1033 | + atomic_t config_counter; | ||
1034 | + | ||
1035 | + u16 win_count; | ||
1036 | + u32 frame_count; | ||
1037 | + wait_queue_head_t stats_wait; | ||
1038 | + spinlock_t buffer_lock; /* For stats buffers read/write sync */ | ||
1039 | +} aewbstat; | ||
1040 | + | ||
1041 | +/** | ||
1042 | + * struct isph3a_aewb_regs - Current value of AE, AWB configuration registers. | ||
1043 | + * reg_pcr: Peripheral control register. | ||
1044 | + * reg_win1: Control register. | ||
1045 | + * reg_start: Start position register. | ||
1046 | + * reg_blk: Black line register. | ||
1047 | + * reg_subwin: Configuration register. | ||
1048 | + */ | ||
1049 | +static struct isph3a_aewb_regs { | ||
1050 | + u32 reg_pcr; | ||
1051 | + u32 reg_win1; | ||
1052 | + u32 reg_start; | ||
1053 | + u32 reg_blk; | ||
1054 | + u32 reg_subwin; | ||
1055 | +} aewb_regs; | ||
1056 | + | ||
1057 | +static struct isph3a_aewb_config aewb_config_local = { | ||
1058 | + .saturation_limit = 0x3FF, | ||
1059 | + .win_height = 0, | ||
1060 | + .win_width = 0, | ||
1061 | + .ver_win_count = 0, | ||
1062 | + .hor_win_count = 0, | ||
1063 | + .ver_win_start = 0, | ||
1064 | + .hor_win_start = 0, | ||
1065 | + .blk_ver_win_start = 0, | ||
1066 | + .blk_win_height = 0, | ||
1067 | + .subsample_ver_inc = 0, | ||
1068 | + .subsample_hor_inc = 0, | ||
1069 | + .alaw_enable = 0, | ||
1070 | + .aewb_enable = 0, | ||
1071 | +}; | ||
1072 | + | ||
1073 | +/* Structure for saving/restoring h3a module registers */ | ||
1074 | +static struct isp_reg isph3a_reg_list[] = { | ||
1075 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR, 0}, /* Should be the first one */ | ||
1076 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWWIN1, 0}, | ||
1077 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINSTART, 0}, | ||
1078 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINBLK, 0}, | ||
1079 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWSUBWIN, 0}, | ||
1080 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWBUFST, 0}, | ||
1081 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX1, 0}, | ||
1082 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX2, 0}, | ||
1083 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAXSTART, 0}, | ||
1084 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFIIRSH, 0}, | ||
1085 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFBUFST, 0}, | ||
1086 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF010, 0}, | ||
1087 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF032, 0}, | ||
1088 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF054, 0}, | ||
1089 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF076, 0}, | ||
1090 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF098, 0}, | ||
1091 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF0010, 0}, | ||
1092 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF110, 0}, | ||
1093 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF132, 0}, | ||
1094 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF154, 0}, | ||
1095 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF176, 0}, | ||
1096 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF198, 0}, | ||
1097 | + {OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF1010, 0}, | ||
1098 | + {0, ISP_TOK_TERM, 0} | ||
1099 | +}; | ||
1100 | + | ||
1101 | +static struct ispprev_wbal h3awb_update; | ||
1102 | +static struct isph3a_aewb_buffer *active_buff; | ||
1103 | +static struct isph3a_aewb_xtrastats h3a_xtrastats[H3A_MAX_BUFF]; | ||
1104 | +static int camnotify; | ||
1105 | +static int wb_update; | ||
1106 | +static void isph3a_print_status(void); | ||
1107 | + | ||
1108 | +/** | ||
1109 | + * isph3a_aewb_setxtrastats - Receives extra statistics from prior frames. | ||
1110 | + * @xtrastats: Pointer to structure containing extra statistics fields like | ||
1111 | + * field count and timestamp of frame. | ||
1112 | + * | ||
1113 | + * Called from update_vbq in camera driver | ||
1114 | + **/ | ||
1115 | +void isph3a_aewb_setxtrastats(struct isph3a_aewb_xtrastats *xtrastats) | ||
1116 | +{ | ||
1117 | + int i; | ||
1118 | + | ||
1119 | + if (active_buff == NULL) | ||
1120 | + return; | ||
1121 | + | ||
1122 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
1123 | + if (aewbstat.h3a_buff[i].frame_num != active_buff->frame_num) | ||
1124 | + continue; | ||
1125 | + | ||
1126 | + if (i == 0) { | ||
1127 | + if (aewbstat.h3a_buff[H3A_MAX_BUFF - 1].locked == 0) { | ||
1128 | + h3a_xtrastats[H3A_MAX_BUFF - 1] = | ||
1129 | + *xtrastats; | ||
1130 | + } else { | ||
1131 | + h3a_xtrastats[H3A_MAX_BUFF - 2] = | ||
1132 | + *xtrastats; | ||
1133 | + } | ||
1134 | + } else if (i == 1) { | ||
1135 | + if (aewbstat.h3a_buff[0].locked == 0) | ||
1136 | + h3a_xtrastats[0] = *xtrastats; | ||
1137 | + else { | ||
1138 | + h3a_xtrastats[H3A_MAX_BUFF - 1] = | ||
1139 | + *xtrastats; | ||
1140 | + } | ||
1141 | + } else { | ||
1142 | + if (aewbstat.h3a_buff[i - 1].locked == 0) | ||
1143 | + h3a_xtrastats[i - 1] = *xtrastats; | ||
1144 | + else | ||
1145 | + h3a_xtrastats[i - 2] = *xtrastats; | ||
1146 | + } | ||
1147 | + return; | ||
1148 | + } | ||
1149 | +} | ||
1150 | +EXPORT_SYMBOL(isph3a_aewb_setxtrastats); | ||
1151 | + | ||
1152 | +void __isph3a_aewb_enable(u8 enable) | ||
1153 | +{ | ||
1154 | + isp_reg_writel(IRQ0STATUS_H3A_AWB_DONE_IRQ, OMAP3_ISP_IOMEM_MAIN, | ||
1155 | + ISP_IRQ0STATUS); | ||
1156 | + | ||
1157 | + if (enable) { | ||
1158 | + aewb_regs.reg_pcr |= ISPH3A_PCR_AEW_EN; | ||
1159 | + DPRINTK_ISPH3A(" H3A enabled \n"); | ||
1160 | + } else { | ||
1161 | + aewb_regs.reg_pcr &= ~ISPH3A_PCR_AEW_EN; | ||
1162 | + DPRINTK_ISPH3A(" H3A disabled \n"); | ||
1163 | + } | ||
1164 | + isp_reg_and_or(OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR, ~ISPH3A_PCR_AEW_EN, | ||
1165 | + (enable ? ISPH3A_PCR_AEW_EN : 0)); | ||
1166 | + aewb_config_local.aewb_enable = enable; | ||
1167 | +} | ||
1168 | + | ||
1169 | +/** | ||
1170 | + * isph3a_aewb_enable - Enables AE, AWB engine in the H3A module. | ||
1171 | + * @enable: 1 - Enables the AE & AWB engine. | ||
1172 | + * | ||
1173 | + * Client should configure all the AE & AWB registers in H3A before this. | ||
1174 | + **/ | ||
1175 | +void isph3a_aewb_enable(u8 enable) | ||
1176 | +{ | ||
1177 | + __isph3a_aewb_enable(enable); | ||
1178 | + aewbstat.pm_state = enable; | ||
1179 | +} | ||
1180 | + | ||
1181 | +/** | ||
1182 | + * isph3a_aewb_suspend - Suspend AE, AWB engine in the H3A module. | ||
1183 | + **/ | ||
1184 | +void isph3a_aewb_suspend(void) | ||
1185 | +{ | ||
1186 | + if (aewbstat.pm_state) | ||
1187 | + __isph3a_aewb_enable(0); | ||
1188 | +} | ||
1189 | + | ||
1190 | +/** | ||
1191 | + * isph3a_aewb_resume - Resume AE, AWB engine in the H3A module. | ||
1192 | + **/ | ||
1193 | +void isph3a_aewb_resume(void) | ||
1194 | +{ | ||
1195 | + if (aewbstat.pm_state) | ||
1196 | + __isph3a_aewb_enable(1); | ||
1197 | +} | ||
1198 | + | ||
1199 | +int isph3a_aewb_busy(void) | ||
1200 | +{ | ||
1201 | + return isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR) | ||
1202 | + & ISPH3A_PCR_BUSYAEAWB; | ||
1203 | +} | ||
1204 | + | ||
1205 | +/** | ||
1206 | + * isph3a_update_wb - Updates WB parameters. | ||
1207 | + * | ||
1208 | + * Needs to be called when no ISP Preview processing is taking place. | ||
1209 | + **/ | ||
1210 | +void isph3a_update_wb(void) | ||
1211 | +{ | ||
1212 | + if (wb_update) { | ||
1213 | + isppreview_config_whitebalance(h3awb_update); | ||
1214 | + wb_update = 0; | ||
1215 | + } | ||
1216 | + return; | ||
1217 | +} | ||
1218 | +EXPORT_SYMBOL(isph3a_update_wb); | ||
1219 | + | ||
1220 | +/** | ||
1221 | + * isph3a_aewb_update_regs - Helper function to update h3a registers. | ||
1222 | + **/ | ||
1223 | +static void isph3a_aewb_update_regs(void) | ||
1224 | +{ | ||
1225 | + isp_reg_writel(aewb_regs.reg_pcr, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); | ||
1226 | + isp_reg_writel(aewb_regs.reg_win1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWWIN1); | ||
1227 | + isp_reg_writel(aewb_regs.reg_start, OMAP3_ISP_IOMEM_H3A, | ||
1228 | + ISPH3A_AEWINSTART); | ||
1229 | + isp_reg_writel(aewb_regs.reg_blk, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINBLK); | ||
1230 | + isp_reg_writel(aewb_regs.reg_subwin, OMAP3_ISP_IOMEM_H3A, | ||
1231 | + ISPH3A_AEWSUBWIN); | ||
1232 | + | ||
1233 | + aewbstat.update = 0; | ||
1234 | + aewbstat.frame_count = 1; | ||
1235 | +} | ||
1236 | + | ||
1237 | +/** | ||
1238 | + * isph3a_aewb_update_req_buffer - Helper function to update buffer cache pages | ||
1239 | + * @buffer: Pointer to structure | ||
1240 | + **/ | ||
1241 | +static void isph3a_aewb_update_req_buffer(struct isph3a_aewb_buffer *buffer) | ||
1242 | +{ | ||
1243 | + int size = aewbstat.stats_buf_size; | ||
1244 | + | ||
1245 | + size = PAGE_ALIGN(size); | ||
1246 | + dmac_inv_range((void *)buffer->addr_align, | ||
1247 | + (void *)buffer->addr_align + size); | ||
1248 | +} | ||
1249 | + | ||
1250 | +/** | ||
1251 | + * isph3a_aewb_stats_available - Check for stats available of specified frame. | ||
1252 | + * @aewbdata: Pointer to return AE AWB statistics data | ||
1253 | + * | ||
1254 | + * Returns 0 if successful, or -1 if statistics are unavailable. | ||
1255 | + **/ | ||
1256 | +static int isph3a_aewb_stats_available(struct isph3a_aewb_data *aewbdata) | ||
1257 | +{ | ||
1258 | + int i, ret; | ||
1259 | + unsigned long irqflags; | ||
1260 | + | ||
1261 | + spin_lock_irqsave(&aewbstat.buffer_lock, irqflags); | ||
1262 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
1263 | + DPRINTK_ISPH3A("Checking Stats buff[%d] (%d) for %d\n", | ||
1264 | + i, aewbstat.h3a_buff[i].frame_num, | ||
1265 | + aewbdata->frame_number); | ||
1266 | + if ((aewbdata->frame_number != | ||
1267 | + aewbstat.h3a_buff[i].frame_num) || | ||
1268 | + (aewbstat.h3a_buff[i].frame_num == | ||
1269 | + active_buff->frame_num)) | ||
1270 | + continue; | ||
1271 | + aewbstat.h3a_buff[i].locked = 1; | ||
1272 | + spin_unlock_irqrestore(&aewbstat.buffer_lock, irqflags); | ||
1273 | + isph3a_aewb_update_req_buffer(&aewbstat.h3a_buff[i]); | ||
1274 | + aewbstat.h3a_buff[i].frame_num = 0; | ||
1275 | + ret = copy_to_user((void *)aewbdata->h3a_aewb_statistics_buf, | ||
1276 | + (void *)aewbstat.h3a_buff[i].virt_addr, | ||
1277 | + aewbstat.curr_cfg_buf_size); | ||
1278 | + if (ret) { | ||
1279 | + printk(KERN_ERR "Failed copy_to_user for " | ||
1280 | + "H3A stats buff, %d\n", ret); | ||
1281 | + } | ||
1282 | + aewbdata->ts = aewbstat.h3a_buff[i].ts; | ||
1283 | + aewbdata->config_counter = aewbstat.h3a_buff[i].config_counter; | ||
1284 | + aewbdata->field_count = h3a_xtrastats[i].field_count; | ||
1285 | + return 0; | ||
1286 | + } | ||
1287 | + spin_unlock_irqrestore(&aewbstat.buffer_lock, irqflags); | ||
1288 | + | ||
1289 | + return -1; | ||
1290 | +} | ||
1291 | + | ||
1292 | +/** | ||
1293 | + * isph3a_aewb_link_buffers - Helper function to link allocated buffers. | ||
1294 | + **/ | ||
1295 | +static void isph3a_aewb_link_buffers(void) | ||
1296 | +{ | ||
1297 | + int i; | ||
1298 | + | ||
1299 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
1300 | + if ((i + 1) < H3A_MAX_BUFF) { | ||
1301 | + aewbstat.h3a_buff[i].next = &aewbstat.h3a_buff[i + 1]; | ||
1302 | + h3a_xtrastats[i].next = &h3a_xtrastats[i + 1]; | ||
1303 | + } else { | ||
1304 | + aewbstat.h3a_buff[i].next = &aewbstat.h3a_buff[0]; | ||
1305 | + h3a_xtrastats[i].next = &h3a_xtrastats[0]; | ||
1306 | + } | ||
1307 | + } | ||
1308 | +} | ||
1309 | + | ||
1310 | +/** | ||
1311 | + * isph3a_aewb_unlock_buffers - Helper function to unlock all buffers. | ||
1312 | + **/ | ||
1313 | +static void isph3a_aewb_unlock_buffers(void) | ||
1314 | +{ | ||
1315 | + int i; | ||
1316 | + unsigned long irqflags; | ||
1317 | + | ||
1318 | + spin_lock_irqsave(&aewbstat.buffer_lock, irqflags); | ||
1319 | + for (i = 0; i < H3A_MAX_BUFF; i++) | ||
1320 | + aewbstat.h3a_buff[i].locked = 0; | ||
1321 | + | ||
1322 | + spin_unlock_irqrestore(&aewbstat.buffer_lock, irqflags); | ||
1323 | +} | ||
1324 | + | ||
1325 | +/** | ||
1326 | + * isph3a_aewb_isr - Callback from ISP driver for H3A AEWB interrupt. | ||
1327 | + * @status: IRQ0STATUS in case of MMU error, 0 for H3A interrupt. | ||
1328 | + * @arg1: Not used as of now. | ||
1329 | + * @arg2: Not used as of now. | ||
1330 | + */ | ||
1331 | +static void isph3a_aewb_isr(unsigned long status, isp_vbq_callback_ptr arg1, | ||
1332 | + void *arg2) | ||
1333 | +{ | ||
1334 | + u16 frame_align; | ||
1335 | + | ||
1336 | + if ((H3A_AWB_DONE & status) != H3A_AWB_DONE) | ||
1337 | + return; | ||
1338 | + | ||
1339 | + do_gettimeofday(&active_buff->ts); | ||
1340 | + active_buff->config_counter = atomic_read(&aewbstat.config_counter); | ||
1341 | + active_buff = active_buff->next; | ||
1342 | + if (active_buff->locked == 1) | ||
1343 | + active_buff = active_buff->next; | ||
1344 | + isp_reg_writel(active_buff->ispmmu_addr, OMAP3_ISP_IOMEM_H3A, | ||
1345 | + ISPH3A_AEWBUFST); | ||
1346 | + | ||
1347 | + aewbstat.frame_count++; | ||
1348 | + frame_align = aewbstat.frame_count; | ||
1349 | + if (aewbstat.frame_count > MAX_FRAME_COUNT) { | ||
1350 | + aewbstat.frame_count = 1; | ||
1351 | + frame_align++; | ||
1352 | + } | ||
1353 | + active_buff->frame_num = aewbstat.frame_count; | ||
1354 | + | ||
1355 | + if (aewbstat.stats_req) { | ||
1356 | + DPRINTK_ISPH3A("waiting for frame %d\n", aewbstat.frame_req); | ||
1357 | + if (frame_align >= aewbstat.frame_req + 1) { | ||
1358 | + aewbstat.stats_req = 0; | ||
1359 | + aewbstat.stats_done = 1; | ||
1360 | + wake_up_interruptible(&aewbstat.stats_wait); | ||
1361 | + } | ||
1362 | + } | ||
1363 | + | ||
1364 | + if (aewbstat.update) | ||
1365 | + isph3a_aewb_update_regs(); | ||
1366 | +} | ||
1367 | + | ||
1368 | +/** | ||
1369 | + * isph3a_aewb_set_params - Helper function to check & store user given params. | ||
1370 | + * @user_cfg: Pointer to AE and AWB parameters struct. | ||
1371 | + * | ||
1372 | + * As most of them are busy-lock registers, need to wait until AEW_BUSY = 0 to | ||
1373 | + * program them during ISR. | ||
1374 | + * | ||
1375 | + * Returns 0 if successful, or -EINVAL if any of the parameters are invalid. | ||
1376 | + **/ | ||
1377 | +static int isph3a_aewb_set_params(struct isph3a_aewb_config *user_cfg) | ||
1378 | +{ | ||
1379 | + if (unlikely(user_cfg->saturation_limit > MAX_SATURATION_LIM)) { | ||
1380 | + printk(KERN_ERR "Invalid Saturation_limit: %d\n", | ||
1381 | + user_cfg->saturation_limit); | ||
1382 | + return -EINVAL; | ||
1383 | + } | ||
1384 | + if (aewb_config_local.saturation_limit != user_cfg->saturation_limit) { | ||
1385 | + WRITE_SAT_LIM(aewb_regs.reg_pcr, user_cfg->saturation_limit); | ||
1386 | + aewb_config_local.saturation_limit = | ||
1387 | + user_cfg->saturation_limit; | ||
1388 | + aewbstat.update = 1; | ||
1389 | + } | ||
1390 | + | ||
1391 | + if (aewb_config_local.alaw_enable != user_cfg->alaw_enable) { | ||
1392 | + WRITE_ALAW(aewb_regs.reg_pcr, user_cfg->alaw_enable); | ||
1393 | + aewb_config_local.alaw_enable = user_cfg->alaw_enable; | ||
1394 | + aewbstat.update = 1; | ||
1395 | + } | ||
1396 | + | ||
1397 | + if (unlikely(user_cfg->win_height < MIN_WIN_H || | ||
1398 | + user_cfg->win_height > MAX_WIN_H || | ||
1399 | + user_cfg->win_height & 0x01)) { | ||
1400 | + printk(KERN_ERR "Invalid window height: %d\n", | ||
1401 | + user_cfg->win_height); | ||
1402 | + return -EINVAL; | ||
1403 | + } | ||
1404 | + if (aewb_config_local.win_height != user_cfg->win_height) { | ||
1405 | + WRITE_WIN_H(aewb_regs.reg_win1, user_cfg->win_height); | ||
1406 | + aewb_config_local.win_height = user_cfg->win_height; | ||
1407 | + aewbstat.update = 1; | ||
1408 | + } | ||
1409 | + | ||
1410 | + if (unlikely(user_cfg->win_width < MIN_WIN_W || | ||
1411 | + user_cfg->win_width > MAX_WIN_W || | ||
1412 | + user_cfg->win_width & 0x01)) { | ||
1413 | + printk(KERN_ERR "Invalid window width: %d\n", | ||
1414 | + user_cfg->win_width); | ||
1415 | + return -EINVAL; | ||
1416 | + } | ||
1417 | + if (aewb_config_local.win_width != user_cfg->win_width) { | ||
1418 | + WRITE_WIN_W(aewb_regs.reg_win1, user_cfg->win_width); | ||
1419 | + aewb_config_local.win_width = user_cfg->win_width; | ||
1420 | + aewbstat.update = 1; | ||
1421 | + } | ||
1422 | + | ||
1423 | + if (unlikely(user_cfg->ver_win_count < 1 || | ||
1424 | + user_cfg->ver_win_count > MAX_WINVC)) { | ||
1425 | + printk(KERN_ERR "Invalid vertical window count: %d\n", | ||
1426 | + user_cfg->ver_win_count); | ||
1427 | + return -EINVAL; | ||
1428 | + } | ||
1429 | + if (aewb_config_local.ver_win_count != user_cfg->ver_win_count) { | ||
1430 | + WRITE_VER_C(aewb_regs.reg_win1, user_cfg->ver_win_count); | ||
1431 | + aewb_config_local.ver_win_count = user_cfg->ver_win_count; | ||
1432 | + aewbstat.update = 1; | ||
1433 | + } | ||
1434 | + | ||
1435 | + if (unlikely(user_cfg->hor_win_count < 1 || | ||
1436 | + user_cfg->hor_win_count > MAX_WINHC)) { | ||
1437 | + printk(KERN_ERR "Invalid horizontal window count: %d\n", | ||
1438 | + user_cfg->hor_win_count); | ||
1439 | + return -EINVAL; | ||
1440 | + } | ||
1441 | + if (aewb_config_local.hor_win_count != user_cfg->hor_win_count) { | ||
1442 | + WRITE_HOR_C(aewb_regs.reg_win1, user_cfg->hor_win_count); | ||
1443 | + aewb_config_local.hor_win_count = user_cfg->hor_win_count; | ||
1444 | + aewbstat.update = 1; | ||
1445 | + } | ||
1446 | + | ||
1447 | + if (unlikely(user_cfg->ver_win_start > MAX_WINSTART)) { | ||
1448 | + printk(KERN_ERR "Invalid vertical window start: %d\n", | ||
1449 | + user_cfg->ver_win_start); | ||
1450 | + return -EINVAL; | ||
1451 | + } | ||
1452 | + if (aewb_config_local.ver_win_start != user_cfg->ver_win_start) { | ||
1453 | + WRITE_VER_WIN_ST(aewb_regs.reg_start, user_cfg->ver_win_start); | ||
1454 | + aewb_config_local.ver_win_start = user_cfg->ver_win_start; | ||
1455 | + aewbstat.update = 1; | ||
1456 | + } | ||
1457 | + | ||
1458 | + if (unlikely(user_cfg->hor_win_start > MAX_WINSTART)) { | ||
1459 | + printk(KERN_ERR "Invalid horizontal window start: %d\n", | ||
1460 | + user_cfg->hor_win_start); | ||
1461 | + return -EINVAL; | ||
1462 | + } | ||
1463 | + if (aewb_config_local.hor_win_start != user_cfg->hor_win_start) { | ||
1464 | + WRITE_HOR_WIN_ST(aewb_regs.reg_start, user_cfg->hor_win_start); | ||
1465 | + aewb_config_local.hor_win_start = user_cfg->hor_win_start; | ||
1466 | + aewbstat.update = 1; | ||
1467 | + } | ||
1468 | + | ||
1469 | + if (unlikely(user_cfg->blk_ver_win_start > MAX_WINSTART)) { | ||
1470 | + printk(KERN_ERR "Invalid black vertical window start: %d\n", | ||
1471 | + user_cfg->blk_ver_win_start); | ||
1472 | + return -EINVAL; | ||
1473 | + } | ||
1474 | + if (aewb_config_local.blk_ver_win_start != | ||
1475 | + user_cfg->blk_ver_win_start) { | ||
1476 | + WRITE_BLK_VER_WIN_ST(aewb_regs.reg_blk, | ||
1477 | + user_cfg->blk_ver_win_start); | ||
1478 | + aewb_config_local.blk_ver_win_start = | ||
1479 | + user_cfg->blk_ver_win_start; | ||
1480 | + aewbstat.update = 1; | ||
1481 | + } | ||
1482 | + | ||
1483 | + if (unlikely(user_cfg->blk_win_height < MIN_WIN_H || | ||
1484 | + user_cfg->blk_win_height > MAX_WIN_H || | ||
1485 | + user_cfg->blk_win_height & 0x01)) { | ||
1486 | + printk(KERN_ERR "Invalid black window height: %d\n", | ||
1487 | + user_cfg->blk_win_height); | ||
1488 | + return -EINVAL; | ||
1489 | + } | ||
1490 | + if (aewb_config_local.blk_win_height != user_cfg->blk_win_height) { | ||
1491 | + WRITE_BLK_WIN_H(aewb_regs.reg_blk, user_cfg->blk_win_height); | ||
1492 | + aewb_config_local.blk_win_height = user_cfg->blk_win_height; | ||
1493 | + aewbstat.update = 1; | ||
1494 | + } | ||
1495 | + | ||
1496 | + if (unlikely(user_cfg->subsample_ver_inc < MIN_SUB_INC || | ||
1497 | + user_cfg->subsample_ver_inc > MAX_SUB_INC || | ||
1498 | + user_cfg->subsample_ver_inc & 0x01)) { | ||
1499 | + printk(KERN_ERR "Invalid vertical subsample increment: %d\n", | ||
1500 | + user_cfg->subsample_ver_inc); | ||
1501 | + return -EINVAL; | ||
1502 | + } | ||
1503 | + if (aewb_config_local.subsample_ver_inc != | ||
1504 | + user_cfg->subsample_ver_inc) { | ||
1505 | + WRITE_SUB_VER_INC(aewb_regs.reg_subwin, | ||
1506 | + user_cfg->subsample_ver_inc); | ||
1507 | + aewb_config_local.subsample_ver_inc = | ||
1508 | + user_cfg->subsample_ver_inc; | ||
1509 | + aewbstat.update = 1; | ||
1510 | + } | ||
1511 | + | ||
1512 | + if (unlikely(user_cfg->subsample_hor_inc < MIN_SUB_INC || | ||
1513 | + user_cfg->subsample_hor_inc > MAX_SUB_INC || | ||
1514 | + user_cfg->subsample_hor_inc & 0x01)) { | ||
1515 | + printk(KERN_ERR "Invalid horizontal subsample increment: %d\n", | ||
1516 | + user_cfg->subsample_hor_inc); | ||
1517 | + return -EINVAL; | ||
1518 | + } | ||
1519 | + if (aewb_config_local.subsample_hor_inc != | ||
1520 | + user_cfg->subsample_hor_inc) { | ||
1521 | + WRITE_SUB_HOR_INC(aewb_regs.reg_subwin, | ||
1522 | + user_cfg->subsample_hor_inc); | ||
1523 | + aewb_config_local.subsample_hor_inc = | ||
1524 | + user_cfg->subsample_hor_inc; | ||
1525 | + aewbstat.update = 1; | ||
1526 | + } | ||
1527 | + | ||
1528 | + if (!aewbstat.initialized || !aewb_config_local.aewb_enable) { | ||
1529 | + isph3a_aewb_update_regs(); | ||
1530 | + aewbstat.initialized = 1; | ||
1531 | + } | ||
1532 | + return 0; | ||
1533 | +} | ||
1534 | + | ||
1535 | +/** | ||
1536 | + * isph3a_aewb_configure - Configure AEWB regs, enable/disable H3A engine. | ||
1537 | + * @aewbcfg: Pointer to AEWB config structure. | ||
1538 | + * | ||
1539 | + * Returns 0 if successful, -EINVAL if aewbcfg pointer is NULL, -ENOMEM if | ||
1540 | + * was unable to allocate memory for the buffer, of other errors if H3A | ||
1541 | + * callback is not set or the parameters for AEWB are invalid. | ||
1542 | + **/ | ||
1543 | +int isph3a_aewb_configure(struct isph3a_aewb_config *aewbcfg) | ||
1544 | +{ | ||
1545 | + int ret = 0; | ||
1546 | + int i; | ||
1547 | + int win_count = 0; | ||
1548 | + | ||
1549 | + if (NULL == aewbcfg) { | ||
1550 | + printk(KERN_ERR "Null argument in configuration. \n"); | ||
1551 | + return -EINVAL; | ||
1552 | + } | ||
1553 | + | ||
1554 | + if (!aewbstat.initialized) { | ||
1555 | + DPRINTK_ISPH3A("Setting callback for H3A\n"); | ||
1556 | + ret = isp_set_callback(CBK_H3A_AWB_DONE, isph3a_aewb_isr, | ||
1557 | + (void *)NULL, (void *)NULL); | ||
1558 | + if (ret) { | ||
1559 | + printk(KERN_ERR "No callback for H3A\n"); | ||
1560 | + return ret; | ||
1561 | + } | ||
1562 | + } | ||
1563 | + | ||
1564 | + ret = isph3a_aewb_set_params(aewbcfg); | ||
1565 | + if (ret) { | ||
1566 | + printk(KERN_ERR "Invalid parameters! \n"); | ||
1567 | + return ret; | ||
1568 | + } | ||
1569 | + | ||
1570 | + win_count = aewbcfg->ver_win_count * aewbcfg->hor_win_count; | ||
1571 | + win_count += aewbcfg->hor_win_count; | ||
1572 | + ret = win_count / 8; | ||
1573 | + win_count += win_count % 8 ? 1 : 0; | ||
1574 | + win_count += ret; | ||
1575 | + | ||
1576 | + aewbstat.win_count = win_count; | ||
1577 | + aewbstat.curr_cfg_buf_size = win_count * AEWB_PACKET_SIZE; | ||
1578 | + | ||
1579 | + if (aewbstat.stats_buf_size | ||
1580 | + && win_count * AEWB_PACKET_SIZE > aewbstat.stats_buf_size) { | ||
1581 | + DPRINTK_ISPH3A("There was a previous buffer... " | ||
1582 | + "Freeing/unmapping current stat busffs\n"); | ||
1583 | + isph3a_aewb_enable(0); | ||
1584 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
1585 | + ispmmu_kunmap(aewbstat.h3a_buff[i].ispmmu_addr); | ||
1586 | + dma_free_coherent( | ||
1587 | + NULL, | ||
1588 | + aewbstat.min_buf_size, | ||
1589 | + (void *)aewbstat.h3a_buff[i].virt_addr, | ||
1590 | + (dma_addr_t)aewbstat.h3a_buff[i].phy_addr); | ||
1591 | + aewbstat.h3a_buff[i].virt_addr = 0; | ||
1592 | + } | ||
1593 | + aewbstat.stats_buf_size = 0; | ||
1594 | + } | ||
1595 | + | ||
1596 | + if (!aewbstat.h3a_buff[0].virt_addr) { | ||
1597 | + aewbstat.stats_buf_size = win_count * AEWB_PACKET_SIZE; | ||
1598 | + aewbstat.min_buf_size = PAGE_ALIGN(aewbstat.stats_buf_size); | ||
1599 | + | ||
1600 | + DPRINTK_ISPH3A("Allocating/mapping new stat buffs\n"); | ||
1601 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
1602 | + aewbstat.h3a_buff[i].virt_addr = | ||
1603 | + (unsigned long)dma_alloc_coherent( | ||
1604 | + NULL, | ||
1605 | + aewbstat.min_buf_size, | ||
1606 | + (dma_addr_t *) | ||
1607 | + &aewbstat.h3a_buff[i].phy_addr, | ||
1608 | + GFP_KERNEL | GFP_DMA); | ||
1609 | + if (aewbstat.h3a_buff[i].virt_addr == 0) { | ||
1610 | + printk(KERN_ERR "Can't acquire memory for " | ||
1611 | + "buffer[%d]\n", i); | ||
1612 | + return -ENOMEM; | ||
1613 | + } | ||
1614 | + aewbstat.h3a_buff[i].addr_align = | ||
1615 | + aewbstat.h3a_buff[i].virt_addr; | ||
1616 | + while ((aewbstat.h3a_buff[i].addr_align & 0xFFFFFFC0) != | ||
1617 | + aewbstat.h3a_buff[i].addr_align) | ||
1618 | + aewbstat.h3a_buff[i].addr_align++; | ||
1619 | + aewbstat.h3a_buff[i].ispmmu_addr = | ||
1620 | + ispmmu_kmap(aewbstat.h3a_buff[i].phy_addr, | ||
1621 | + aewbstat.min_buf_size); | ||
1622 | + } | ||
1623 | + isph3a_aewb_unlock_buffers(); | ||
1624 | + isph3a_aewb_link_buffers(); | ||
1625 | + | ||
1626 | + if (active_buff == NULL) | ||
1627 | + active_buff = &aewbstat.h3a_buff[0]; | ||
1628 | + | ||
1629 | + isp_reg_writel(active_buff->ispmmu_addr, OMAP3_ISP_IOMEM_H3A, | ||
1630 | + ISPH3A_AEWBUFST); | ||
1631 | + } | ||
1632 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
1633 | + DPRINTK_ISPH3A("buff[%d] addr is:\n virt 0x%lX\n" | ||
1634 | + " aligned 0x%lX\n" | ||
1635 | + " phys 0x%lX\n" | ||
1636 | + " ispmmu 0x%08lX\n" | ||
1637 | + " mmapped 0x%lX\n" | ||
1638 | + " frame_num %d\n", i, | ||
1639 | + aewbstat.h3a_buff[i].virt_addr, | ||
1640 | + aewbstat.h3a_buff[i].addr_align, | ||
1641 | + aewbstat.h3a_buff[i].phy_addr, | ||
1642 | + aewbstat.h3a_buff[i].ispmmu_addr, | ||
1643 | + aewbstat.h3a_buff[i].mmap_addr, | ||
1644 | + aewbstat.h3a_buff[i].frame_num); | ||
1645 | + } | ||
1646 | + | ||
1647 | + active_buff->frame_num = 1; | ||
1648 | + | ||
1649 | + atomic_inc(&aewbstat.config_counter); | ||
1650 | + isph3a_aewb_enable(aewbcfg->aewb_enable); | ||
1651 | + isph3a_print_status(); | ||
1652 | + | ||
1653 | + return 0; | ||
1654 | +} | ||
1655 | +EXPORT_SYMBOL(isph3a_aewb_configure); | ||
1656 | + | ||
1657 | +/** | ||
1658 | + * isph3a_aewb_request_statistics - REquest statistics and update gains in AEWB | ||
1659 | + * @aewbdata: Pointer to return AE AWB statistics data. | ||
1660 | + * | ||
1661 | + * This API allows the user to update White Balance gains, as well as | ||
1662 | + * exposure time and analog gain. It is also used to request frame | ||
1663 | + * statistics. | ||
1664 | + * | ||
1665 | + * Returns 0 if successful, -EINVAL when H3A engine is not enabled, or other | ||
1666 | + * errors when setting gains. | ||
1667 | + **/ | ||
1668 | +int isph3a_aewb_request_statistics(struct isph3a_aewb_data *aewbdata) | ||
1669 | +{ | ||
1670 | + int ret = 0; | ||
1671 | + u16 frame_diff = 0; | ||
1672 | + u16 frame_cnt = aewbstat.frame_count; | ||
1673 | + wait_queue_t wqt; | ||
1674 | + | ||
1675 | + if (!aewb_config_local.aewb_enable) { | ||
1676 | + printk(KERN_ERR "H3A engine not enabled\n"); | ||
1677 | + return -EINVAL; | ||
1678 | + } | ||
1679 | + | ||
1680 | + DPRINTK_ISPH3A("isph3a_aewb_request_statistics: Enter " | ||
1681 | + "(frame req. => %d, current frame => %d," | ||
1682 | + "update => %d)\n", | ||
1683 | + aewbdata->frame_number, frame_cnt, aewbdata->update); | ||
1684 | + DPRINTK_ISPH3A("User data received: \n"); | ||
1685 | + DPRINTK_ISPH3A("Digital gain = 0x%04x\n", aewbdata->dgain); | ||
1686 | + DPRINTK_ISPH3A("WB gain b *= 0x%04x\n", aewbdata->wb_gain_b); | ||
1687 | + DPRINTK_ISPH3A("WB gain r *= 0x%04x\n", aewbdata->wb_gain_r); | ||
1688 | + DPRINTK_ISPH3A("WB gain gb = 0x%04x\n", aewbdata->wb_gain_gb); | ||
1689 | + DPRINTK_ISPH3A("WB gain gr = 0x%04x\n", aewbdata->wb_gain_gr); | ||
1690 | + | ||
1691 | + if (!aewbdata->update) { | ||
1692 | + aewbdata->h3a_aewb_statistics_buf = NULL; | ||
1693 | + goto out; | ||
1694 | + } | ||
1695 | + if (aewbdata->update & SET_DIGITAL_GAIN) | ||
1696 | + h3awb_update.dgain = (u16)aewbdata->dgain; | ||
1697 | + if (aewbdata->update & SET_COLOR_GAINS) { | ||
1698 | + h3awb_update.coef0 = (u8)aewbdata->wb_gain_gr; | ||
1699 | + h3awb_update.coef1 = (u8)aewbdata->wb_gain_r; | ||
1700 | + h3awb_update.coef2 = (u8)aewbdata->wb_gain_b; | ||
1701 | + h3awb_update.coef3 = (u8)aewbdata->wb_gain_gb; | ||
1702 | + } | ||
1703 | + if (aewbdata->update & (SET_COLOR_GAINS | SET_DIGITAL_GAIN)) | ||
1704 | + wb_update = 1; | ||
1705 | + | ||
1706 | + if (!(aewbdata->update & REQUEST_STATISTICS)) { | ||
1707 | + aewbdata->h3a_aewb_statistics_buf = NULL; | ||
1708 | + goto out; | ||
1709 | + } | ||
1710 | + | ||
1711 | + if (aewbdata->frame_number < 1) { | ||
1712 | + printk(KERN_ERR "Illeagal frame number " | ||
1713 | + "requested (%d)\n", | ||
1714 | + aewbdata->frame_number); | ||
1715 | + return -EINVAL; | ||
1716 | + } | ||
1717 | + | ||
1718 | + isph3a_aewb_unlock_buffers(); | ||
1719 | + | ||
1720 | + DPRINTK_ISPH3A("Stats available?\n"); | ||
1721 | + ret = isph3a_aewb_stats_available(aewbdata); | ||
1722 | + if (!ret) | ||
1723 | + goto out; | ||
1724 | + | ||
1725 | + DPRINTK_ISPH3A("Stats in near future?\n"); | ||
1726 | + if (aewbdata->frame_number > frame_cnt) | ||
1727 | + frame_diff = aewbdata->frame_number - frame_cnt; | ||
1728 | + else if (aewbdata->frame_number < frame_cnt) { | ||
1729 | + if ((frame_cnt > (MAX_FRAME_COUNT - MAX_FUTURE_FRAMES)) && | ||
1730 | + (aewbdata->frame_number < MAX_FRAME_COUNT)) { | ||
1731 | + frame_diff = aewbdata->frame_number + MAX_FRAME_COUNT - | ||
1732 | + frame_cnt; | ||
1733 | + } else | ||
1734 | + frame_diff = MAX_FUTURE_FRAMES + 1; | ||
1735 | + } | ||
1736 | + | ||
1737 | + if (frame_diff > MAX_FUTURE_FRAMES) { | ||
1738 | + printk(KERN_ERR "Invalid frame requested, returning current" | ||
1739 | + " frame stats\n"); | ||
1740 | + aewbdata->frame_number = frame_cnt; | ||
1741 | + } | ||
1742 | + if (camnotify) { | ||
1743 | + DPRINTK_ISPH3A("NOT Waiting on stats IRQ for frame %d " | ||
1744 | + "because camnotify set\n", | ||
1745 | + aewbdata->frame_number); | ||
1746 | + aewbdata->h3a_aewb_statistics_buf = NULL; | ||
1747 | + goto out; | ||
1748 | + } | ||
1749 | + DPRINTK_ISPH3A("Waiting on stats IRQ for frame %d\n", | ||
1750 | + aewbdata->frame_number); | ||
1751 | + aewbstat.frame_req = aewbdata->frame_number; | ||
1752 | + aewbstat.stats_req = 1; | ||
1753 | + aewbstat.stats_done = 0; | ||
1754 | + init_waitqueue_entry(&wqt, current); | ||
1755 | + ret = wait_event_interruptible(aewbstat.stats_wait, | ||
1756 | + aewbstat.stats_done == 1); | ||
1757 | + if (ret < 0) { | ||
1758 | + printk(KERN_ERR "isph3a_aewb_request_statistics" | ||
1759 | + " Error on wait event %d\n", ret); | ||
1760 | + aewbdata->h3a_aewb_statistics_buf = NULL; | ||
1761 | + return ret; | ||
1762 | + } | ||
1763 | + | ||
1764 | + DPRINTK_ISPH3A("ISP AEWB request status interrupt raised\n"); | ||
1765 | + ret = isph3a_aewb_stats_available(aewbdata); | ||
1766 | + if (ret) { | ||
1767 | + DPRINTK_ISPH3A("After waiting for stats," | ||
1768 | + " stats not available!!\n"); | ||
1769 | + aewbdata->h3a_aewb_statistics_buf = NULL; | ||
1770 | + } | ||
1771 | +out: | ||
1772 | + DPRINTK_ISPH3A("isph3a_aewb_request_statistics: " | ||
1773 | + "aewbdata->h3a_aewb_statistics_buf => %p\n", | ||
1774 | + aewbdata->h3a_aewb_statistics_buf); | ||
1775 | + aewbdata->curr_frame = aewbstat.frame_count; | ||
1776 | + | ||
1777 | + return 0; | ||
1778 | +} | ||
1779 | +EXPORT_SYMBOL(isph3a_aewb_request_statistics); | ||
1780 | + | ||
1781 | +/** | ||
1782 | + * isph3a_aewb_init - Module Initialisation. | ||
1783 | + * | ||
1784 | + * Always returns 0. | ||
1785 | + **/ | ||
1786 | +int __init isph3a_aewb_init(void) | ||
1787 | +{ | ||
1788 | + memset(&aewbstat, 0, sizeof(aewbstat)); | ||
1789 | + memset(&aewb_regs, 0, sizeof(aewb_regs)); | ||
1790 | + | ||
1791 | + init_waitqueue_head(&aewbstat.stats_wait); | ||
1792 | + spin_lock_init(&aewbstat.buffer_lock); | ||
1793 | + return 0; | ||
1794 | +} | ||
1795 | + | ||
1796 | +/** | ||
1797 | + * isph3a_aewb_cleanup - Module exit. | ||
1798 | + **/ | ||
1799 | +void isph3a_aewb_cleanup(void) | ||
1800 | +{ | ||
1801 | + int i; | ||
1802 | + | ||
1803 | + for (i = 0; i < H3A_MAX_BUFF; i++) { | ||
1804 | + if (!aewbstat.h3a_buff[i].phy_addr) | ||
1805 | + continue; | ||
1806 | + | ||
1807 | + ispmmu_kunmap(aewbstat.h3a_buff[i].ispmmu_addr); | ||
1808 | + dma_free_coherent(NULL, | ||
1809 | + aewbstat.min_buf_size, | ||
1810 | + (void *)aewbstat.h3a_buff[i].virt_addr, | ||
1811 | + (dma_addr_t)aewbstat.h3a_buff[i].phy_addr); | ||
1812 | + } | ||
1813 | + memset(&aewbstat, 0, sizeof(aewbstat)); | ||
1814 | + memset(&aewb_regs, 0, sizeof(aewb_regs)); | ||
1815 | +} | ||
1816 | + | ||
1817 | +/** | ||
1818 | + * isph3a_print_status - Debug print. Values of H3A related registers. | ||
1819 | + **/ | ||
1820 | +static void isph3a_print_status(void) | ||
1821 | +{ | ||
1822 | + DPRINTK_ISPH3A("ISPH3A_PCR = 0x%08x\n", | ||
1823 | + isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR)); | ||
1824 | + DPRINTK_ISPH3A("ISPH3A_AEWWIN1 = 0x%08x\n", | ||
1825 | + isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWWIN1)); | ||
1826 | + DPRINTK_ISPH3A("ISPH3A_AEWINSTART = 0x%08x\n", | ||
1827 | + isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINSTART)); | ||
1828 | + DPRINTK_ISPH3A("ISPH3A_AEWINBLK = 0x%08x\n", | ||
1829 | + isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINBLK)); | ||
1830 | + DPRINTK_ISPH3A("ISPH3A_AEWSUBWIN = 0x%08x\n", | ||
1831 | + isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWSUBWIN)); | ||
1832 | + DPRINTK_ISPH3A("ISPH3A_AEWBUFST = 0x%08x\n", | ||
1833 | + isp_reg_readl(OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWBUFST)); | ||
1834 | + DPRINTK_ISPH3A("stats windows = %d\n", aewbstat.win_count); | ||
1835 | + DPRINTK_ISPH3A("stats buff size = %d\n", aewbstat.stats_buf_size); | ||
1836 | + DPRINTK_ISPH3A("currently configured stats buff size = %d\n", | ||
1837 | + aewbstat.curr_cfg_buf_size); | ||
1838 | +} | ||
1839 | + | ||
1840 | +/** | ||
1841 | + * isph3a_notify - Unblocks user request for statistics when camera is off | ||
1842 | + * @notify: 1 - Camera is turned off | ||
1843 | + * | ||
1844 | + * Used when the user has requested statistics about a future frame, but the | ||
1845 | + * camera is turned off before it happens, and this function unblocks the | ||
1846 | + * request so the user can continue in its program. | ||
1847 | + **/ | ||
1848 | +void isph3a_notify(int notify) | ||
1849 | +{ | ||
1850 | + camnotify = notify; | ||
1851 | + if (camnotify && aewbstat.initialized) { | ||
1852 | + printk(KERN_DEBUG "Warning Camera Off \n"); | ||
1853 | + aewbstat.stats_req = 0; | ||
1854 | + aewbstat.stats_done = 1; | ||
1855 | + wake_up_interruptible(&aewbstat.stats_wait); | ||
1856 | + } | ||
1857 | +} | ||
1858 | +EXPORT_SYMBOL(isph3a_notify); | ||
1859 | + | ||
1860 | +/** | ||
1861 | + * isph3a_save_context - Saves the values of the h3a module registers. | ||
1862 | + **/ | ||
1863 | +void isph3a_save_context(void) | ||
1864 | +{ | ||
1865 | + DPRINTK_ISPH3A(" Saving context\n"); | ||
1866 | + isp_save_context(isph3a_reg_list); | ||
1867 | + /* Avoid enable during restore ctx */ | ||
1868 | + isph3a_reg_list[0].val &= ~ISPH3A_PCR_AEW_EN; | ||
1869 | +} | ||
1870 | +EXPORT_SYMBOL(isph3a_save_context); | ||
1871 | + | ||
1872 | +/** | ||
1873 | + * isph3a_restore_context - Restores the values of the h3a module registers. | ||
1874 | + **/ | ||
1875 | +void isph3a_restore_context(void) | ||
1876 | +{ | ||
1877 | + DPRINTK_ISPH3A(" Restoring context\n"); | ||
1878 | + isp_restore_context(isph3a_reg_list); | ||
1879 | +} | ||
1880 | +EXPORT_SYMBOL(isph3a_restore_context); | ||
1881 | diff --git a/drivers/media/video/isp/isph3a.h b/drivers/media/video/isp/isph3a.h | ||
1882 | new file mode 100644 | ||
1883 | index 0000000..7d4c765 | ||
1884 | --- /dev/null | ||
1885 | +++ b/drivers/media/video/isp/isph3a.h | ||
1886 | @@ -0,0 +1,127 @@ | ||
1887 | +/* | ||
1888 | + * isph3a.h | ||
1889 | + * | ||
1890 | + * Include file for H3A module in TI's OMAP3 Camera ISP | ||
1891 | + * | ||
1892 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
1893 | + * | ||
1894 | + * Contributors: | ||
1895 | + * Sergio Aguirre <saaguirre@ti.com> | ||
1896 | + * Troy Laramy | ||
1897 | + * | ||
1898 | + * This package is free software; you can redistribute it and/or modify | ||
1899 | + * it under the terms of the GNU General Public License version 2 as | ||
1900 | + * published by the Free Software Foundation. | ||
1901 | + * | ||
1902 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
1903 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
1904 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
1905 | + */ | ||
1906 | + | ||
1907 | +#ifndef OMAP_ISP_H3A_H | ||
1908 | +#define OMAP_ISP_H3A_H | ||
1909 | + | ||
1910 | +#include <mach/isp_user.h> | ||
1911 | + | ||
1912 | +#define AEWB_PACKET_SIZE 16 | ||
1913 | +#define H3A_MAX_BUFF 5 | ||
1914 | + | ||
1915 | +/* Flags for changed registers */ | ||
1916 | +#define PCR_CHNG (1 << 0) | ||
1917 | +#define AEWWIN1_CHNG (1 << 1) | ||
1918 | +#define AEWINSTART_CHNG (1 << 2) | ||
1919 | +#define AEWINBLK_CHNG (1 << 3) | ||
1920 | +#define AEWSUBWIN_CHNG (1 << 4) | ||
1921 | +#define PRV_WBDGAIN_CHNG (1 << 5) | ||
1922 | +#define PRV_WBGAIN_CHNG (1 << 6) | ||
1923 | + | ||
1924 | +/* ISPH3A REGISTERS bits */ | ||
1925 | +#define ISPH3A_PCR_AF_EN (1 << 0) | ||
1926 | +#define ISPH3A_PCR_AF_ALAW_EN (1 << 1) | ||
1927 | +#define ISPH3A_PCR_AF_MED_EN (1 << 2) | ||
1928 | +#define ISPH3A_PCR_AF_BUSY (1 << 15) | ||
1929 | +#define ISPH3A_PCR_AEW_EN (1 << 16) | ||
1930 | +#define ISPH3A_PCR_AEW_ALAW_EN (1 << 17) | ||
1931 | +#define ISPH3A_PCR_AEW_BUSY (1 << 18) | ||
1932 | + | ||
1933 | +#define WRITE_SAT_LIM(reg, sat_limit) \ | ||
1934 | + (reg = (reg & (~(ISPH3A_PCR_AEW_AVE2LMT_MASK))) \ | ||
1935 | + | (sat_limit << ISPH3A_PCR_AEW_AVE2LMT_SHIFT)) | ||
1936 | + | ||
1937 | +#define WRITE_ALAW(reg, alaw_en) \ | ||
1938 | + (reg = (reg & (~(ISPH3A_PCR_AEW_ALAW_EN))) \ | ||
1939 | + | ((alaw_en & ISPH3A_PCR_AF_ALAW_EN) \ | ||
1940 | + << ISPH3A_PCR_AEW_ALAW_EN_SHIFT)) | ||
1941 | + | ||
1942 | +#define WRITE_WIN_H(reg, height) \ | ||
1943 | + (reg = (reg & (~(ISPH3A_AEWWIN1_WINH_MASK))) \ | ||
1944 | + | (((height >> 1) - 1) << ISPH3A_AEWWIN1_WINH_SHIFT)) | ||
1945 | + | ||
1946 | +#define WRITE_WIN_W(reg, width) \ | ||
1947 | + (reg = (reg & (~(ISPH3A_AEWWIN1_WINW_MASK))) \ | ||
1948 | + | (((width >> 1) - 1) << ISPH3A_AEWWIN1_WINW_SHIFT)) | ||
1949 | + | ||
1950 | +#define WRITE_VER_C(reg, ver_count) \ | ||
1951 | + (reg = (reg & ~(ISPH3A_AEWWIN1_WINVC_MASK)) \ | ||
1952 | + | ((ver_count - 1) << ISPH3A_AEWWIN1_WINVC_SHIFT)) | ||
1953 | + | ||
1954 | +#define WRITE_HOR_C(reg, hor_count) \ | ||
1955 | + (reg = (reg & ~(ISPH3A_AEWWIN1_WINHC_MASK)) \ | ||
1956 | + | ((hor_count - 1) << ISPH3A_AEWWIN1_WINHC_SHIFT)) | ||
1957 | + | ||
1958 | +#define WRITE_VER_WIN_ST(reg, ver_win_st) \ | ||
1959 | + (reg = (reg & ~(ISPH3A_AEWINSTART_WINSV_MASK)) \ | ||
1960 | + | (ver_win_st << ISPH3A_AEWINSTART_WINSV_SHIFT)) | ||
1961 | + | ||
1962 | +#define WRITE_HOR_WIN_ST(reg, hor_win_st) \ | ||
1963 | + (reg = (reg & ~(ISPH3A_AEWINSTART_WINSH_MASK)) \ | ||
1964 | + | (hor_win_st << ISPH3A_AEWINSTART_WINSH_SHIFT)) | ||
1965 | + | ||
1966 | +#define WRITE_BLK_VER_WIN_ST(reg, blk_win_st) \ | ||
1967 | + (reg = (reg & ~(ISPH3A_AEWINBLK_WINSV_MASK)) \ | ||
1968 | + | (blk_win_st << ISPH3A_AEWINBLK_WINSV_SHIFT)) | ||
1969 | + | ||
1970 | +#define WRITE_BLK_WIN_H(reg, height) \ | ||
1971 | + (reg = (reg & ~(ISPH3A_AEWINBLK_WINH_MASK)) \ | ||
1972 | + | (((height >> 1) - 1) << ISPH3A_AEWINBLK_WINH_SHIFT)) | ||
1973 | + | ||
1974 | +#define WRITE_SUB_VER_INC(reg, sub_ver_inc) \ | ||
1975 | + (reg = (reg & ~(ISPH3A_AEWSUBWIN_AEWINCV_MASK)) \ | ||
1976 | + | (((sub_ver_inc >> 1) - 1) << ISPH3A_AEWSUBWIN_AEWINCV_SHIFT)) | ||
1977 | + | ||
1978 | +#define WRITE_SUB_HOR_INC(reg, sub_hor_inc) \ | ||
1979 | + (reg = (reg & ~(ISPH3A_AEWSUBWIN_AEWINCH_MASK)) \ | ||
1980 | + | (((sub_hor_inc >> 1) - 1) << ISPH3A_AEWSUBWIN_AEWINCH_SHIFT)) | ||
1981 | + | ||
1982 | +/** | ||
1983 | + * struct isph3a_aewb_xtrastats - Structure with extra statistics sent by cam. | ||
1984 | + * @field_count: Sequence number of returned framestats. | ||
1985 | + * @isph3a_aewb_xtrastats: Pointer to next buffer with extra stats. | ||
1986 | + */ | ||
1987 | +struct isph3a_aewb_xtrastats { | ||
1988 | + unsigned long field_count; | ||
1989 | + struct isph3a_aewb_xtrastats *next; | ||
1990 | +}; | ||
1991 | + | ||
1992 | +void isph3a_aewb_setxtrastats(struct isph3a_aewb_xtrastats *xtrastats); | ||
1993 | + | ||
1994 | +int isph3a_aewb_configure(struct isph3a_aewb_config *aewbcfg); | ||
1995 | + | ||
1996 | +int isph3a_aewb_request_statistics(struct isph3a_aewb_data *aewbdata); | ||
1997 | + | ||
1998 | +void isph3a_save_context(void); | ||
1999 | + | ||
2000 | +void isph3a_restore_context(void); | ||
2001 | + | ||
2002 | +void isph3a_aewb_enable(u8 enable); | ||
2003 | + | ||
2004 | +int isph3a_aewb_busy(void); | ||
2005 | + | ||
2006 | +void isph3a_aewb_suspend(void); | ||
2007 | + | ||
2008 | +void isph3a_aewb_resume(void); | ||
2009 | + | ||
2010 | +void isph3a_update_wb(void); | ||
2011 | + | ||
2012 | +void isph3a_notify(int notify); | ||
2013 | +#endif /* OMAP_ISP_H3A_H */ | ||
2014 | diff --git a/drivers/media/video/isp/isphist.c b/drivers/media/video/isp/isphist.c | ||
2015 | new file mode 100644 | ||
2016 | index 0000000..c6f6a77 | ||
2017 | --- /dev/null | ||
2018 | +++ b/drivers/media/video/isp/isphist.c | ||
2019 | @@ -0,0 +1,608 @@ | ||
2020 | +/* | ||
2021 | + * isphist.c | ||
2022 | + * | ||
2023 | + * HISTOGRAM module for TI's OMAP3 Camera ISP | ||
2024 | + * | ||
2025 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
2026 | + * | ||
2027 | + * Contributors: | ||
2028 | + * Sergio Aguirre <saaguirre@ti.com> | ||
2029 | + * Troy Laramy | ||
2030 | + * | ||
2031 | + * This package is free software; you can redistribute it and/or modify | ||
2032 | + * it under the terms of the GNU General Public License version 2 as | ||
2033 | + * published by the Free Software Foundation. | ||
2034 | + * | ||
2035 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
2036 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
2037 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
2038 | + */ | ||
2039 | + | ||
2040 | +#include <asm/cacheflush.h> | ||
2041 | + | ||
2042 | +#include <linux/delay.h> | ||
2043 | +#include <linux/dma-mapping.h> | ||
2044 | +#include <linux/uaccess.h> | ||
2045 | + | ||
2046 | +#include "isp.h" | ||
2047 | +#include "ispreg.h" | ||
2048 | +#include "isphist.h" | ||
2049 | +#include "ispmmu.h" | ||
2050 | + | ||
2051 | +/** | ||
2052 | + * struct isp_hist_status - Histogram status. | ||
2053 | + * @hist_enable: Enables the histogram module. | ||
2054 | + * @initialized: Flag to indicate that the module is correctly initializated. | ||
2055 | + * @frame_cnt: Actual frame count. | ||
2056 | + * @frame_req: Frame requested by user. | ||
2057 | + * @completed: Flag to indicate if a frame request is completed. | ||
2058 | + */ | ||
2059 | +struct isp_hist_status { | ||
2060 | + u8 hist_enable; | ||
2061 | + u8 pm_state; | ||
2062 | + u8 initialized; | ||
2063 | + u8 frame_cnt; | ||
2064 | + u8 frame_req; | ||
2065 | + u8 completed; | ||
2066 | +} histstat; | ||
2067 | + | ||
2068 | +/** | ||
2069 | + * struct isp_hist_buffer - Frame histogram buffer. | ||
2070 | + * @virt_addr: Virtual address to mmap the buffer. | ||
2071 | + * @phy_addr: Physical address of the buffer. | ||
2072 | + * @addr_align: Virtual Address 32 bytes aligned. | ||
2073 | + * @ispmmu_addr: Address of the buffer mapped by the ISPMMU. | ||
2074 | + * @mmap_addr: Mapped memory area of buffer. For userspace access. | ||
2075 | + */ | ||
2076 | +struct isp_hist_buffer { | ||
2077 | + unsigned long virt_addr; | ||
2078 | + unsigned long phy_addr; | ||
2079 | + unsigned long addr_align; | ||
2080 | + unsigned long ispmmu_addr; | ||
2081 | + unsigned long mmap_addr; | ||
2082 | +} hist_buff; | ||
2083 | + | ||
2084 | +/** | ||
2085 | + * struct isp_hist_regs - Current value of Histogram configuration registers. | ||
2086 | + * @reg_pcr: Peripheral control register. | ||
2087 | + * @reg_cnt: Histogram control register. | ||
2088 | + * @reg_wb_gain: Histogram white balance gain register. | ||
2089 | + * @reg_r0_h: Region 0 horizontal register. | ||
2090 | + * @reg_r0_v: Region 0 vertical register. | ||
2091 | + * @reg_r1_h: Region 1 horizontal register. | ||
2092 | + * @reg_r1_v: Region 1 vertical register. | ||
2093 | + * @reg_r2_h: Region 2 horizontal register. | ||
2094 | + * @reg_r2_v: Region 2 vertical register. | ||
2095 | + * @reg_r3_h: Region 3 horizontal register. | ||
2096 | + * @reg_r3_v: Region 3 vertical register. | ||
2097 | + * @reg_hist_addr: Histogram address register. | ||
2098 | + * @reg_hist_data: Histogram data. | ||
2099 | + * @reg_hist_radd: Address register. When input data comes from mem. | ||
2100 | + * @reg_hist_radd_off: Address offset register. When input data comes from mem. | ||
2101 | + * @reg_h_v_info: Image size register. When input data comes from mem. | ||
2102 | + */ | ||
2103 | +static struct isp_hist_regs { | ||
2104 | + u32 reg_pcr; | ||
2105 | + u32 reg_cnt; | ||
2106 | + u32 reg_wb_gain; | ||
2107 | + u32 reg_r0_h; | ||
2108 | + u32 reg_r0_v; | ||
2109 | + u32 reg_r1_h; | ||
2110 | + u32 reg_r1_v; | ||
2111 | + u32 reg_r2_h; | ||
2112 | + u32 reg_r2_v; | ||
2113 | + u32 reg_r3_h; | ||
2114 | + u32 reg_r3_v; | ||
2115 | + u32 reg_hist_addr; | ||
2116 | + u32 reg_hist_data; | ||
2117 | + u32 reg_hist_radd; | ||
2118 | + u32 reg_hist_radd_off; | ||
2119 | + u32 reg_h_v_info; | ||
2120 | +} hist_regs; | ||
2121 | + | ||
2122 | +/* Structure for saving/restoring histogram module registers */ | ||
2123 | +struct isp_reg isphist_reg_list[] = { | ||
2124 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, 0}, | ||
2125 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_WB_GAIN, 0}, | ||
2126 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_HORZ, 0}, | ||
2127 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_VERT, 0}, | ||
2128 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_HORZ, 0}, | ||
2129 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_VERT, 0}, | ||
2130 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_HORZ, 0}, | ||
2131 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_VERT, 0}, | ||
2132 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_HORZ, 0}, | ||
2133 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_VERT, 0}, | ||
2134 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR, 0}, | ||
2135 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_RADD, 0}, | ||
2136 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_RADD_OFF, 0}, | ||
2137 | + {OMAP3_ISP_IOMEM_HIST, ISPHIST_H_V_INFO, 0}, | ||
2138 | + {0, ISP_TOK_TERM, 0} | ||
2139 | +}; | ||
2140 | + | ||
2141 | +static void isp_hist_print_status(void); | ||
2142 | + | ||
2143 | +void __isp_hist_enable(u8 enable) | ||
2144 | +{ | ||
2145 | + if (enable) | ||
2146 | + DPRINTK_ISPHIST(" histogram enabled \n"); | ||
2147 | + else | ||
2148 | + DPRINTK_ISPHIST(" histogram disabled \n"); | ||
2149 | + | ||
2150 | + isp_reg_and_or(OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR, ~ISPHIST_PCR_EN, | ||
2151 | + (enable ? ISPHIST_PCR_EN : 0)); | ||
2152 | + histstat.hist_enable = enable; | ||
2153 | +} | ||
2154 | + | ||
2155 | +/** | ||
2156 | + * isp_hist_enable - Enables ISP Histogram submodule operation. | ||
2157 | + * @enable: 1 - Enables the histogram submodule. | ||
2158 | + * | ||
2159 | + * Client should configure all the Histogram registers before calling this | ||
2160 | + * function. | ||
2161 | + **/ | ||
2162 | +void isp_hist_enable(u8 enable) | ||
2163 | +{ | ||
2164 | + __isp_hist_enable(enable); | ||
2165 | + histstat.pm_state = enable; | ||
2166 | +} | ||
2167 | + | ||
2168 | +/** | ||
2169 | + * isp_hist_suspend - Suspend ISP Histogram submodule. | ||
2170 | + **/ | ||
2171 | +void isp_hist_suspend(void) | ||
2172 | +{ | ||
2173 | + if (histstat.pm_state) | ||
2174 | + __isp_hist_enable(0); | ||
2175 | +} | ||
2176 | + | ||
2177 | +/** | ||
2178 | + * isp_hist_resume - Resume ISP Histogram submodule. | ||
2179 | + **/ | ||
2180 | +void isp_hist_resume(void) | ||
2181 | +{ | ||
2182 | + if (histstat.pm_state) | ||
2183 | + __isp_hist_enable(1); | ||
2184 | +} | ||
2185 | + | ||
2186 | +int isp_hist_busy(void) | ||
2187 | +{ | ||
2188 | + return isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR) & | ||
2189 | + ISPHIST_PCR_BUSY; | ||
2190 | +} | ||
2191 | + | ||
2192 | + | ||
2193 | +/** | ||
2194 | + * isp_hist_update_regs - Helper function to update Histogram registers. | ||
2195 | + **/ | ||
2196 | +static void isp_hist_update_regs(void) | ||
2197 | +{ | ||
2198 | + isp_reg_writel(hist_regs.reg_pcr, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR); | ||
2199 | + isp_reg_writel(hist_regs.reg_cnt, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT); | ||
2200 | + isp_reg_writel(hist_regs.reg_wb_gain, OMAP3_ISP_IOMEM_HIST, | ||
2201 | + ISPHIST_WB_GAIN); | ||
2202 | + isp_reg_writel(hist_regs.reg_r0_h, OMAP3_ISP_IOMEM_HIST, | ||
2203 | + ISPHIST_R0_HORZ); | ||
2204 | + isp_reg_writel(hist_regs.reg_r0_v, OMAP3_ISP_IOMEM_HIST, | ||
2205 | + ISPHIST_R0_VERT); | ||
2206 | + isp_reg_writel(hist_regs.reg_r1_h, OMAP3_ISP_IOMEM_HIST, | ||
2207 | + ISPHIST_R1_HORZ); | ||
2208 | + isp_reg_writel(hist_regs.reg_r1_v, OMAP3_ISP_IOMEM_HIST, | ||
2209 | + ISPHIST_R1_VERT); | ||
2210 | + isp_reg_writel(hist_regs.reg_r2_h, OMAP3_ISP_IOMEM_HIST, | ||
2211 | + ISPHIST_R2_HORZ); | ||
2212 | + isp_reg_writel(hist_regs.reg_r2_v, OMAP3_ISP_IOMEM_HIST, | ||
2213 | + ISPHIST_R2_VERT); | ||
2214 | + isp_reg_writel(hist_regs.reg_r3_h, OMAP3_ISP_IOMEM_HIST, | ||
2215 | + ISPHIST_R3_HORZ); | ||
2216 | + isp_reg_writel(hist_regs.reg_r3_v, OMAP3_ISP_IOMEM_HIST, | ||
2217 | + ISPHIST_R3_VERT); | ||
2218 | + isp_reg_writel(hist_regs.reg_hist_addr, OMAP3_ISP_IOMEM_HIST, | ||
2219 | + ISPHIST_ADDR); | ||
2220 | + isp_reg_writel(hist_regs.reg_hist_data, OMAP3_ISP_IOMEM_HIST, | ||
2221 | + ISPHIST_DATA); | ||
2222 | + isp_reg_writel(hist_regs.reg_hist_radd, OMAP3_ISP_IOMEM_HIST, | ||
2223 | + ISPHIST_RADD); | ||
2224 | + isp_reg_writel(hist_regs.reg_hist_radd_off, OMAP3_ISP_IOMEM_HIST, | ||
2225 | + ISPHIST_RADD_OFF); | ||
2226 | + isp_reg_writel(hist_regs.reg_h_v_info, OMAP3_ISP_IOMEM_HIST, | ||
2227 | + ISPHIST_H_V_INFO); | ||
2228 | +} | ||
2229 | + | ||
2230 | +/** | ||
2231 | + * isp_hist_isr - Callback from ISP driver for HIST interrupt. | ||
2232 | + * @status: IRQ0STATUS in case of MMU error, 0 for hist interrupt. | ||
2233 | + * arg1 and arg2 Not used as of now. | ||
2234 | + **/ | ||
2235 | +static void isp_hist_isr(unsigned long status, isp_vbq_callback_ptr arg1, | ||
2236 | + void *arg2) | ||
2237 | +{ | ||
2238 | + isp_hist_enable(0); | ||
2239 | + | ||
2240 | + if (!(status & HIST_DONE)) | ||
2241 | + return; | ||
2242 | + | ||
2243 | + if (!histstat.completed) { | ||
2244 | + if (histstat.frame_req == histstat.frame_cnt) { | ||
2245 | + histstat.frame_cnt = 0; | ||
2246 | + histstat.frame_req = 0; | ||
2247 | + histstat.completed = 1; | ||
2248 | + } else { | ||
2249 | + isp_hist_enable(1); | ||
2250 | + histstat.frame_cnt++; | ||
2251 | + } | ||
2252 | + } | ||
2253 | +} | ||
2254 | + | ||
2255 | +/** | ||
2256 | + * isp_hist_reset_mem - clear Histogram memory before start stats engine. | ||
2257 | + * | ||
2258 | + * Returns 0 after histogram memory was cleared. | ||
2259 | + **/ | ||
2260 | +static int isp_hist_reset_mem(void) | ||
2261 | +{ | ||
2262 | + int i; | ||
2263 | + | ||
2264 | + isp_reg_or(OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLR_EN); | ||
2265 | + | ||
2266 | + for (i = 0; i < HIST_MEM_SIZE; i++) | ||
2267 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA); | ||
2268 | + | ||
2269 | + isp_reg_and(OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ~ISPHIST_CNT_CLR_EN); | ||
2270 | + | ||
2271 | + return 0; | ||
2272 | +} | ||
2273 | + | ||
2274 | +/** | ||
2275 | + * isp_hist_set_params - Helper function to check and store user given params. | ||
2276 | + * @user_cfg: Pointer to user configuration structure. | ||
2277 | + * | ||
2278 | + * Returns 0 on success configuration. | ||
2279 | + **/ | ||
2280 | +static int isp_hist_set_params(struct isp_hist_config *user_cfg) | ||
2281 | +{ | ||
2282 | + | ||
2283 | + int reg_num = 0; | ||
2284 | + int bit_shift = 0; | ||
2285 | + | ||
2286 | + | ||
2287 | + if (isp_hist_busy()) | ||
2288 | + return -EINVAL; | ||
2289 | + | ||
2290 | + if (user_cfg->input_bit_width > MIN_BIT_WIDTH) | ||
2291 | + WRITE_DATA_SIZE(hist_regs.reg_cnt, 0); | ||
2292 | + else | ||
2293 | + WRITE_DATA_SIZE(hist_regs.reg_cnt, 1); | ||
2294 | + | ||
2295 | + WRITE_SOURCE(hist_regs.reg_cnt, user_cfg->hist_source); | ||
2296 | + | ||
2297 | + if (user_cfg->hist_source) { | ||
2298 | + WRITE_HV_INFO(hist_regs.reg_h_v_info, user_cfg->hist_h_v_info); | ||
2299 | + | ||
2300 | + if ((user_cfg->hist_radd & ISP_32B_BOUNDARY_BUF) == | ||
2301 | + user_cfg->hist_radd) { | ||
2302 | + WRITE_RADD(hist_regs.reg_hist_radd, | ||
2303 | + user_cfg->hist_radd); | ||
2304 | + } else { | ||
2305 | + printk(KERN_ERR "Address should be in 32 byte boundary" | ||
2306 | + "\n"); | ||
2307 | + return -EINVAL; | ||
2308 | + } | ||
2309 | + | ||
2310 | + if ((user_cfg->hist_radd_off & ISP_32B_BOUNDARY_OFFSET) == | ||
2311 | + user_cfg->hist_radd_off) { | ||
2312 | + WRITE_RADD_OFF(hist_regs.reg_hist_radd_off, | ||
2313 | + user_cfg->hist_radd_off); | ||
2314 | + } else { | ||
2315 | + printk(KERN_ERR "Offset should be in 32 byte boundary" | ||
2316 | + "\n"); | ||
2317 | + return -EINVAL; | ||
2318 | + } | ||
2319 | + | ||
2320 | + } | ||
2321 | + | ||
2322 | + isp_hist_reset_mem(); | ||
2323 | + DPRINTK_ISPHIST("ISPHIST: Memory Cleared\n"); | ||
2324 | + histstat.frame_req = user_cfg->hist_frames; | ||
2325 | + | ||
2326 | + if (unlikely(user_cfg->wb_gain_R > MAX_WB_GAIN || | ||
2327 | + user_cfg->wb_gain_RG > MAX_WB_GAIN || | ||
2328 | + user_cfg->wb_gain_B > MAX_WB_GAIN || | ||
2329 | + user_cfg->wb_gain_BG > MAX_WB_GAIN)) { | ||
2330 | + printk(KERN_ERR "Invalid WB gain\n"); | ||
2331 | + return -EINVAL; | ||
2332 | + } else { | ||
2333 | + WRITE_WB_R(hist_regs.reg_wb_gain, user_cfg->wb_gain_R); | ||
2334 | + WRITE_WB_RG(hist_regs.reg_wb_gain, user_cfg->wb_gain_RG); | ||
2335 | + WRITE_WB_B(hist_regs.reg_wb_gain, user_cfg->wb_gain_B); | ||
2336 | + WRITE_WB_BG(hist_regs.reg_wb_gain, user_cfg->wb_gain_BG); | ||
2337 | + } | ||
2338 | + | ||
2339 | + /* Regions size and position */ | ||
2340 | + | ||
2341 | + if (user_cfg->num_regions > MAX_REGIONS) | ||
2342 | + return -EINVAL; | ||
2343 | + | ||
2344 | + if (likely((user_cfg->reg0_hor & ISPHIST_REGHORIZ_HEND_MASK) - | ||
2345 | + ((user_cfg->reg0_hor & ISPHIST_REGHORIZ_HSTART_MASK) >> | ||
2346 | + ISPHIST_REGHORIZ_HSTART_SHIFT))) { | ||
2347 | + WRITE_REG_HORIZ(hist_regs.reg_r0_h, user_cfg->reg0_hor); | ||
2348 | + reg_num++; | ||
2349 | + } else { | ||
2350 | + printk(KERN_ERR "Invalid Region parameters\n"); | ||
2351 | + return -EINVAL; | ||
2352 | + } | ||
2353 | + | ||
2354 | + if (likely((user_cfg->reg0_ver & ISPHIST_REGVERT_VEND_MASK) - | ||
2355 | + ((user_cfg->reg0_ver & ISPHIST_REGVERT_VSTART_MASK) >> | ||
2356 | + ISPHIST_REGVERT_VSTART_SHIFT))) { | ||
2357 | + WRITE_REG_VERT(hist_regs.reg_r0_v, user_cfg->reg0_ver); | ||
2358 | + } else { | ||
2359 | + printk(KERN_ERR "Invalid Region parameters\n"); | ||
2360 | + return -EINVAL; | ||
2361 | + } | ||
2362 | + | ||
2363 | + if (user_cfg->num_regions >= 1) { | ||
2364 | + if (likely((user_cfg->reg1_hor & ISPHIST_REGHORIZ_HEND_MASK) - | ||
2365 | + ((user_cfg->reg1_hor & | ||
2366 | + ISPHIST_REGHORIZ_HSTART_MASK) >> | ||
2367 | + ISPHIST_REGHORIZ_HSTART_SHIFT))) { | ||
2368 | + WRITE_REG_HORIZ(hist_regs.reg_r1_h, user_cfg->reg1_hor); | ||
2369 | + } else { | ||
2370 | + printk(KERN_ERR "Invalid Region parameters\n"); | ||
2371 | + return -EINVAL; | ||
2372 | + } | ||
2373 | + | ||
2374 | + if (likely((user_cfg->reg1_ver & ISPHIST_REGVERT_VEND_MASK) - | ||
2375 | + ((user_cfg->reg1_ver & | ||
2376 | + ISPHIST_REGVERT_VSTART_MASK) >> | ||
2377 | + ISPHIST_REGVERT_VSTART_SHIFT))) { | ||
2378 | + WRITE_REG_VERT(hist_regs.reg_r1_v, user_cfg->reg1_ver); | ||
2379 | + } else { | ||
2380 | + printk(KERN_ERR "Invalid Region parameters\n"); | ||
2381 | + return -EINVAL; | ||
2382 | + } | ||
2383 | + } | ||
2384 | + | ||
2385 | + if (user_cfg->num_regions >= 2) { | ||
2386 | + if (likely((user_cfg->reg2_hor & ISPHIST_REGHORIZ_HEND_MASK) - | ||
2387 | + ((user_cfg->reg2_hor & | ||
2388 | + ISPHIST_REGHORIZ_HSTART_MASK) >> | ||
2389 | + ISPHIST_REGHORIZ_HSTART_SHIFT))) { | ||
2390 | + WRITE_REG_HORIZ(hist_regs.reg_r2_h, user_cfg->reg2_hor); | ||
2391 | + } else { | ||
2392 | + printk(KERN_ERR "Invalid Region parameters\n"); | ||
2393 | + return -EINVAL; | ||
2394 | + } | ||
2395 | + | ||
2396 | + if (likely((user_cfg->reg2_ver & ISPHIST_REGVERT_VEND_MASK) - | ||
2397 | + ((user_cfg->reg2_ver & | ||
2398 | + ISPHIST_REGVERT_VSTART_MASK) >> | ||
2399 | + ISPHIST_REGVERT_VSTART_SHIFT))) { | ||
2400 | + WRITE_REG_VERT(hist_regs.reg_r2_v, user_cfg->reg2_ver); | ||
2401 | + } else { | ||
2402 | + printk(KERN_ERR "Invalid Region parameters\n"); | ||
2403 | + return -EINVAL; | ||
2404 | + } | ||
2405 | + } | ||
2406 | + | ||
2407 | + if (user_cfg->num_regions >= 3) { | ||
2408 | + if (likely((user_cfg->reg3_hor & ISPHIST_REGHORIZ_HEND_MASK) - | ||
2409 | + ((user_cfg->reg3_hor & | ||
2410 | + ISPHIST_REGHORIZ_HSTART_MASK) >> | ||
2411 | + ISPHIST_REGHORIZ_HSTART_SHIFT))) { | ||
2412 | + WRITE_REG_HORIZ(hist_regs.reg_r3_h, user_cfg->reg3_hor); | ||
2413 | + } else { | ||
2414 | + printk(KERN_ERR "Invalid Region parameters\n"); | ||
2415 | + return -EINVAL; | ||
2416 | + } | ||
2417 | + | ||
2418 | + if (likely((user_cfg->reg3_ver & ISPHIST_REGVERT_VEND_MASK) - | ||
2419 | + ((user_cfg->reg3_ver & | ||
2420 | + ISPHIST_REGVERT_VSTART_MASK) >> | ||
2421 | + ISPHIST_REGVERT_VSTART_SHIFT))) { | ||
2422 | + WRITE_REG_VERT(hist_regs.reg_r3_v, user_cfg->reg3_ver); | ||
2423 | + } else { | ||
2424 | + printk(KERN_ERR "Invalid Region parameters\n"); | ||
2425 | + return -EINVAL; | ||
2426 | + } | ||
2427 | + } | ||
2428 | + reg_num = user_cfg->num_regions; | ||
2429 | + if (unlikely(((user_cfg->hist_bins > BINS_256) && | ||
2430 | + (user_cfg->hist_bins != BINS_32)) || | ||
2431 | + ((user_cfg->hist_bins == BINS_256) && | ||
2432 | + reg_num != 0) || ((user_cfg->hist_bins == | ||
2433 | + BINS_128) && reg_num >= 2))) { | ||
2434 | + printk(KERN_ERR "Invalid Bins Number: %d\n", | ||
2435 | + user_cfg->hist_bins); | ||
2436 | + return -EINVAL; | ||
2437 | + } else { | ||
2438 | + WRITE_NUM_BINS(hist_regs.reg_cnt, user_cfg->hist_bins); | ||
2439 | + } | ||
2440 | + | ||
2441 | + if (user_cfg->input_bit_width > MAX_BIT_WIDTH || | ||
2442 | + user_cfg->input_bit_width < MIN_BIT_WIDTH) { | ||
2443 | + printk(KERN_ERR "Invalid Bit Width: %d\n", | ||
2444 | + user_cfg->input_bit_width); | ||
2445 | + return -EINVAL; | ||
2446 | + } else { | ||
2447 | + switch (user_cfg->hist_bins) { | ||
2448 | + case BINS_256: | ||
2449 | + bit_shift = user_cfg->input_bit_width - 8; | ||
2450 | + break; | ||
2451 | + case BINS_128: | ||
2452 | + bit_shift = user_cfg->input_bit_width - 7; | ||
2453 | + break; | ||
2454 | + case BINS_64: | ||
2455 | + bit_shift = user_cfg->input_bit_width - 6; | ||
2456 | + break; | ||
2457 | + case BINS_32: | ||
2458 | + bit_shift = user_cfg->input_bit_width - 5; | ||
2459 | + break; | ||
2460 | + default: | ||
2461 | + return -EINVAL; | ||
2462 | + } | ||
2463 | + WRITE_BIT_SHIFT(hist_regs.reg_cnt, bit_shift); | ||
2464 | + } | ||
2465 | + | ||
2466 | + isp_hist_update_regs(); | ||
2467 | + histstat.initialized = 1; | ||
2468 | + | ||
2469 | + return 0; | ||
2470 | +} | ||
2471 | + | ||
2472 | +/** | ||
2473 | + * isp_hist_configure - API to configure HIST registers. | ||
2474 | + * @histcfg: Pointer to user configuration structure. | ||
2475 | + * | ||
2476 | + * Returns 0 on success configuration. | ||
2477 | + **/ | ||
2478 | +int isp_hist_configure(struct isp_hist_config *histcfg) | ||
2479 | +{ | ||
2480 | + | ||
2481 | + int ret = 0; | ||
2482 | + | ||
2483 | + if (NULL == histcfg) { | ||
2484 | + printk(KERN_ERR "Null argument in configuration. \n"); | ||
2485 | + return -EINVAL; | ||
2486 | + } | ||
2487 | + | ||
2488 | + if (!histstat.initialized) { | ||
2489 | + DPRINTK_ISPHIST("Setting callback for HISTOGRAM\n"); | ||
2490 | + ret = isp_set_callback(CBK_HIST_DONE, isp_hist_isr, | ||
2491 | + (void *)NULL, (void *)NULL); | ||
2492 | + if (ret) { | ||
2493 | + printk(KERN_ERR "No callback for HIST\n"); | ||
2494 | + return ret; | ||
2495 | + } | ||
2496 | + } | ||
2497 | + | ||
2498 | + ret = isp_hist_set_params(histcfg); | ||
2499 | + if (ret) { | ||
2500 | + printk(KERN_ERR "Invalid parameters! \n"); | ||
2501 | + return ret; | ||
2502 | + } | ||
2503 | + | ||
2504 | + histstat.frame_cnt = 0; | ||
2505 | + histstat.completed = 0; | ||
2506 | + isp_hist_enable(1); | ||
2507 | + isp_hist_print_status(); | ||
2508 | + | ||
2509 | + return 0; | ||
2510 | +} | ||
2511 | +EXPORT_SYMBOL(isp_hist_configure); | ||
2512 | + | ||
2513 | +/** | ||
2514 | + * isp_hist_request_statistics - Request statistics in Histogram. | ||
2515 | + * @histdata: Pointer to data structure. | ||
2516 | + * | ||
2517 | + * This API allows the user to request for histogram statistics. | ||
2518 | + * | ||
2519 | + * Returns 0 on successful request. | ||
2520 | + **/ | ||
2521 | +int isp_hist_request_statistics(struct isp_hist_data *histdata) | ||
2522 | +{ | ||
2523 | + int i, ret; | ||
2524 | + u32 curr; | ||
2525 | + | ||
2526 | + if (isp_hist_busy()) | ||
2527 | + return -EBUSY; | ||
2528 | + | ||
2529 | + if (!histstat.completed && histstat.initialized) | ||
2530 | + return -EINVAL; | ||
2531 | + | ||
2532 | + isp_reg_or(OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLR_EN); | ||
2533 | + | ||
2534 | + for (i = 0; i < HIST_MEM_SIZE; i++) { | ||
2535 | + curr = isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA); | ||
2536 | + ret = put_user(curr, histdata->hist_statistics_buf + i); | ||
2537 | + if (ret) { | ||
2538 | + printk(KERN_ERR "Failed copy_to_user for " | ||
2539 | + "HIST stats buff, %d\n", ret); | ||
2540 | + } | ||
2541 | + } | ||
2542 | + | ||
2543 | + isp_reg_and(OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, | ||
2544 | + ~ISPHIST_CNT_CLR_EN); | ||
2545 | + histstat.completed = 0; | ||
2546 | + return 0; | ||
2547 | +} | ||
2548 | +EXPORT_SYMBOL(isp_hist_request_statistics); | ||
2549 | + | ||
2550 | +/** | ||
2551 | + * isp_hist_init - Module Initialization. | ||
2552 | + * | ||
2553 | + * Returns 0 if successful. | ||
2554 | + **/ | ||
2555 | +int __init isp_hist_init(void) | ||
2556 | +{ | ||
2557 | + memset(&histstat, 0, sizeof(histstat)); | ||
2558 | + memset(&hist_regs, 0, sizeof(hist_regs)); | ||
2559 | + | ||
2560 | + return 0; | ||
2561 | +} | ||
2562 | + | ||
2563 | +/** | ||
2564 | + * isp_hist_cleanup - Module cleanup. | ||
2565 | + **/ | ||
2566 | +void isp_hist_cleanup(void) | ||
2567 | +{ | ||
2568 | + memset(&histstat, 0, sizeof(histstat)); | ||
2569 | + memset(&hist_regs, 0, sizeof(hist_regs)); | ||
2570 | +} | ||
2571 | + | ||
2572 | +/** | ||
2573 | + * isphist_save_context - Saves the values of the histogram module registers. | ||
2574 | + **/ | ||
2575 | +void isphist_save_context(void) | ||
2576 | +{ | ||
2577 | + DPRINTK_ISPHIST(" Saving context\n"); | ||
2578 | + isp_save_context(isphist_reg_list); | ||
2579 | +} | ||
2580 | +EXPORT_SYMBOL(isphist_save_context); | ||
2581 | + | ||
2582 | +/** | ||
2583 | + * isphist_restore_context - Restores the values of the histogram module regs. | ||
2584 | + **/ | ||
2585 | +void isphist_restore_context(void) | ||
2586 | +{ | ||
2587 | + DPRINTK_ISPHIST(" Restoring context\n"); | ||
2588 | + isp_restore_context(isphist_reg_list); | ||
2589 | +} | ||
2590 | +EXPORT_SYMBOL(isphist_restore_context); | ||
2591 | + | ||
2592 | +/** | ||
2593 | + * isp_hist_print_status - Debug print | ||
2594 | + **/ | ||
2595 | +static void isp_hist_print_status(void) | ||
2596 | +{ | ||
2597 | + DPRINTK_ISPHIST("ISPHIST_PCR = 0x%08x\n", | ||
2598 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR)); | ||
2599 | + DPRINTK_ISPHIST("ISPHIST_CNT = 0x%08x\n", | ||
2600 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT)); | ||
2601 | + DPRINTK_ISPHIST("ISPHIST_WB_GAIN = 0x%08x\n", | ||
2602 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_WB_GAIN)); | ||
2603 | + DPRINTK_ISPHIST("ISPHIST_R0_HORZ = 0x%08x\n", | ||
2604 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_HORZ)); | ||
2605 | + DPRINTK_ISPHIST("ISPHIST_R0_VERT = 0x%08x\n", | ||
2606 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_VERT)); | ||
2607 | + DPRINTK_ISPHIST("ISPHIST_R1_HORZ = 0x%08x\n", | ||
2608 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_HORZ)); | ||
2609 | + DPRINTK_ISPHIST("ISPHIST_R1_VERT = 0x%08x\n", | ||
2610 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_VERT)); | ||
2611 | + DPRINTK_ISPHIST("ISPHIST_R2_HORZ = 0x%08x\n", | ||
2612 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_HORZ)); | ||
2613 | + DPRINTK_ISPHIST("ISPHIST_R2_VERT = 0x%08x\n", | ||
2614 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_VERT)); | ||
2615 | + DPRINTK_ISPHIST("ISPHIST_R3_HORZ = 0x%08x\n", | ||
2616 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_HORZ)); | ||
2617 | + DPRINTK_ISPHIST("ISPHIST_R3_VERT = 0x%08x\n", | ||
2618 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_VERT)); | ||
2619 | + DPRINTK_ISPHIST("ISPHIST_ADDR = 0x%08x\n", | ||
2620 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR)); | ||
2621 | + DPRINTK_ISPHIST("ISPHIST_RADD = 0x%08x\n", | ||
2622 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_RADD)); | ||
2623 | + DPRINTK_ISPHIST("ISPHIST_RADD_OFF = 0x%08x\n", | ||
2624 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_RADD_OFF)); | ||
2625 | + DPRINTK_ISPHIST("ISPHIST_H_V_INFO = 0x%08x\n", | ||
2626 | + isp_reg_readl(OMAP3_ISP_IOMEM_HIST, ISPHIST_H_V_INFO)); | ||
2627 | +} | ||
2628 | diff --git a/drivers/media/video/isp/isphist.h b/drivers/media/video/isp/isphist.h | ||
2629 | new file mode 100644 | ||
2630 | index 0000000..6b17c4e | ||
2631 | --- /dev/null | ||
2632 | +++ b/drivers/media/video/isp/isphist.h | ||
2633 | @@ -0,0 +1,105 @@ | ||
2634 | +/* | ||
2635 | + * isphist.h | ||
2636 | + * | ||
2637 | + * Header file for HISTOGRAM module in TI's OMAP3 Camera ISP | ||
2638 | + * | ||
2639 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
2640 | + * | ||
2641 | + * Contributors: | ||
2642 | + * Sergio Aguirre <saaguirre@ti.com> | ||
2643 | + * Troy Laramy | ||
2644 | + * | ||
2645 | + * This package is free software; you can redistribute it and/or modify | ||
2646 | + * it under the terms of the GNU General Public License version 2 as | ||
2647 | + * published by the Free Software Foundation. | ||
2648 | + * | ||
2649 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
2650 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
2651 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
2652 | + */ | ||
2653 | + | ||
2654 | +#ifndef OMAP_ISP_HIST_H | ||
2655 | +#define OMAP_ISP_HIST_H | ||
2656 | + | ||
2657 | +#include <mach/isp_user.h> | ||
2658 | + | ||
2659 | +#define MAX_REGIONS 0x4 | ||
2660 | +#define MAX_WB_GAIN 255 | ||
2661 | +#define MIN_WB_GAIN 0x0 | ||
2662 | +#define MAX_BIT_WIDTH 14 | ||
2663 | +#define MIN_BIT_WIDTH 8 | ||
2664 | + | ||
2665 | +#define ISPHIST_PCR_EN (1 << 0) | ||
2666 | +#define HIST_MEM_SIZE 1024 | ||
2667 | +#define ISPHIST_CNT_CLR_EN (1 << 7) | ||
2668 | + | ||
2669 | +#define WRITE_SOURCE(reg, source) \ | ||
2670 | + (reg = (reg & ~(ISPHIST_CNT_SOURCE_MASK)) \ | ||
2671 | + | (source << ISPHIST_CNT_SOURCE_SHIFT)) | ||
2672 | + | ||
2673 | +#define WRITE_HV_INFO(reg, hv_info) \ | ||
2674 | + (reg = ((reg & ~(ISPHIST_HV_INFO_MASK)) \ | ||
2675 | + | (hv_info & ISPHIST_HV_INFO_MASK))) | ||
2676 | + | ||
2677 | +#define WRITE_RADD(reg, radd) \ | ||
2678 | + (reg = (reg & ~(ISPHIST_RADD_MASK)) \ | ||
2679 | + | (radd << ISPHIST_RADD_SHIFT)) | ||
2680 | + | ||
2681 | +#define WRITE_RADD_OFF(reg, radd_off) \ | ||
2682 | + (reg = (reg & ~(ISPHIST_RADD_OFF_MASK)) \ | ||
2683 | + | (radd_off << ISPHIST_RADD_OFF_SHIFT)) | ||
2684 | + | ||
2685 | +#define WRITE_BIT_SHIFT(reg, bit_shift) \ | ||
2686 | + (reg = (reg & ~(ISPHIST_CNT_SHIFT_MASK)) \ | ||
2687 | + | (bit_shift << ISPHIST_CNT_SHIFT_SHIFT)) | ||
2688 | + | ||
2689 | +#define WRITE_DATA_SIZE(reg, data_size) \ | ||
2690 | + (reg = (reg & ~(ISPHIST_CNT_DATASIZE_MASK)) \ | ||
2691 | + | (data_size << ISPHIST_CNT_DATASIZE_SHIFT)) | ||
2692 | + | ||
2693 | +#define WRITE_NUM_BINS(reg, num_bins) \ | ||
2694 | + (reg = (reg & ~(ISPHIST_CNT_BINS_MASK)) \ | ||
2695 | + | (num_bins << ISPHIST_CNT_BINS_SHIFT)) | ||
2696 | + | ||
2697 | +#define WRITE_WB_R(reg, reg_wb_gain) \ | ||
2698 | + reg = ((reg & ~(ISPHIST_WB_GAIN_WG00_MASK)) \ | ||
2699 | + | (reg_wb_gain << ISPHIST_WB_GAIN_WG00_SHIFT)) | ||
2700 | + | ||
2701 | +#define WRITE_WB_RG(reg, reg_wb_gain) \ | ||
2702 | + (reg = (reg & ~(ISPHIST_WB_GAIN_WG01_MASK)) \ | ||
2703 | + | (reg_wb_gain << ISPHIST_WB_GAIN_WG01_SHIFT)) | ||
2704 | + | ||
2705 | +#define WRITE_WB_B(reg, reg_wb_gain) \ | ||
2706 | + (reg = (reg & ~(ISPHIST_WB_GAIN_WG02_MASK)) \ | ||
2707 | + | (reg_wb_gain << ISPHIST_WB_GAIN_WG02_SHIFT)) | ||
2708 | + | ||
2709 | +#define WRITE_WB_BG(reg, reg_wb_gain) \ | ||
2710 | + (reg = (reg & ~(ISPHIST_WB_GAIN_WG03_MASK)) \ | ||
2711 | + | (reg_wb_gain << ISPHIST_WB_GAIN_WG03_SHIFT)) | ||
2712 | + | ||
2713 | +#define WRITE_REG_HORIZ(reg, reg_n_hor) \ | ||
2714 | + (reg = ((reg & ~ISPHIST_REGHORIZ_MASK) \ | ||
2715 | + | (reg_n_hor & ISPHIST_REGHORIZ_MASK))) | ||
2716 | + | ||
2717 | +#define WRITE_REG_VERT(reg, reg_n_vert) \ | ||
2718 | + (reg = ((reg & ~ISPHIST_REGVERT_MASK) \ | ||
2719 | + | (reg_n_vert & ISPHIST_REGVERT_MASK))) | ||
2720 | + | ||
2721 | + | ||
2722 | +void isp_hist_enable(u8 enable); | ||
2723 | + | ||
2724 | +int isp_hist_busy(void); | ||
2725 | + | ||
2726 | +int isp_hist_configure(struct isp_hist_config *histcfg); | ||
2727 | + | ||
2728 | +int isp_hist_request_statistics(struct isp_hist_data *histdata); | ||
2729 | + | ||
2730 | +void isphist_save_context(void); | ||
2731 | + | ||
2732 | +void isp_hist_suspend(void); | ||
2733 | + | ||
2734 | +void isp_hist_resume(void); | ||
2735 | + | ||
2736 | +void isphist_restore_context(void); | ||
2737 | + | ||
2738 | +#endif /* OMAP_ISP_HIST */ | ||
2739 | -- | ||
2740 | 1.5.6.5 | ||
2741 | |||
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0007-omap3isp-Add-CSI2-interface-support.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0007-omap3isp-Add-CSI2-interface-support.patch new file mode 100644 index 0000000000..842f395388 --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0007-omap3isp-Add-CSI2-interface-support.patch | |||
@@ -0,0 +1,2384 @@ | |||
1 | From 9fbe7b786427d981cac890a7407da09232f5d1e2 Mon Sep 17 00:00:00 2001 | ||
2 | From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
3 | Date: Tue, 10 Mar 2009 10:49:02 +0200 | ||
4 | Subject: [PATCH] omap3isp: Add CSI2 interface support | ||
5 | |||
6 | Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
7 | --- | ||
8 | drivers/media/video/isp/ispcsi2.c | 2124 +++++++++++++++++++++++++++++++++++++ | ||
9 | drivers/media/video/isp/ispcsi2.h | 232 ++++ | ||
10 | 2 files changed, 2356 insertions(+), 0 deletions(-) | ||
11 | create mode 100644 drivers/media/video/isp/ispcsi2.c | ||
12 | create mode 100644 drivers/media/video/isp/ispcsi2.h | ||
13 | |||
14 | diff --git a/drivers/media/video/isp/ispcsi2.c b/drivers/media/video/isp/ispcsi2.c | ||
15 | new file mode 100644 | ||
16 | index 0000000..5141b5a | ||
17 | --- /dev/null | ||
18 | +++ b/drivers/media/video/isp/ispcsi2.c | ||
19 | @@ -0,0 +1,2124 @@ | ||
20 | +/* | ||
21 | + * ispcsi2.c | ||
22 | + * | ||
23 | + * Driver Library for ISP CSI Control module in TI's OMAP3 Camera ISP | ||
24 | + * ISP CSI interface and IRQ related APIs are defined here. | ||
25 | + * | ||
26 | + * Copyright (C) 2009 Texas Instruments. | ||
27 | + * | ||
28 | + * Contributors: | ||
29 | + * Sergio Aguirre <saaguirre@ti.com> | ||
30 | + * Dominic Curran <dcurran@ti.com> | ||
31 | + * | ||
32 | + * This package is free software; you can redistribute it and/or modify | ||
33 | + * it under the terms of the GNU General Public License version 2 as | ||
34 | + * published by the Free Software Foundation. | ||
35 | + * | ||
36 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
37 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
38 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
39 | + */ | ||
40 | + | ||
41 | +#include <linux/delay.h> | ||
42 | +#include <media/v4l2-common.h> | ||
43 | + | ||
44 | +#include "isp.h" | ||
45 | +#include "ispreg.h" | ||
46 | +#include "ispcsi2.h" | ||
47 | + | ||
48 | +static struct isp_csi2_cfg current_csi2_cfg; | ||
49 | +static struct isp_csi2_cfg_update current_csi2_cfg_update; | ||
50 | + | ||
51 | +static bool update_complexio_cfg1; | ||
52 | +static bool update_phy_cfg0; | ||
53 | +static bool update_phy_cfg1; | ||
54 | +static bool update_ctx_ctrl1[8]; | ||
55 | +static bool update_ctx_ctrl2[8]; | ||
56 | +static bool update_ctx_ctrl3[8]; | ||
57 | +static bool update_timing; | ||
58 | +static bool update_ctrl; | ||
59 | +static bool uses_videoport; | ||
60 | + | ||
61 | +/** | ||
62 | + * isp_csi2_complexio_lanes_config - Configuration of CSI2 ComplexIO lanes. | ||
63 | + * @reqcfg: Pointer to structure containing desired lane configuration | ||
64 | + * | ||
65 | + * Validates and saves to internal driver memory the passed configuration. | ||
66 | + * Returns 0 if successful, or -EINVAL if null pointer is passed, invalid | ||
67 | + * lane position or polarity is set, and if 2 lanes try to occupy the same | ||
68 | + * position. To apply this settings, use the isp_csi2_complexio_lanes_update() | ||
69 | + * function just after calling this function. | ||
70 | + **/ | ||
71 | +int isp_csi2_complexio_lanes_config(struct isp_csi2_lanes_cfg *reqcfg) | ||
72 | +{ | ||
73 | + int i; | ||
74 | + bool pos_occupied[5] = {false, false, false, false, false}; | ||
75 | + struct isp_csi2_lanes_cfg *currlanes = ¤t_csi2_cfg.lanes; | ||
76 | + struct isp_csi2_lanes_cfg_update *currlanes_u = | ||
77 | + ¤t_csi2_cfg_update.lanes; | ||
78 | + | ||
79 | + /* Validating parameters sent by driver */ | ||
80 | + if (reqcfg == NULL) { | ||
81 | + printk(KERN_ERR "Invalid Complex IO Configuration sent by" | ||
82 | + " sensor\n"); | ||
83 | + goto err_einval; | ||
84 | + } | ||
85 | + | ||
86 | + /* Data lanes verification */ | ||
87 | + for (i = 0; i < 4; i++) { | ||
88 | + if ((reqcfg->data[i].pol > 1) || (reqcfg->data[i].pos > 5)) { | ||
89 | + printk(KERN_ERR "Invalid CSI-2 Complex IO configuration" | ||
90 | + " parameters for data lane #%d\n", i); | ||
91 | + goto err_einval; | ||
92 | + } | ||
93 | + if (pos_occupied[reqcfg->data[i].pos - 1] && | ||
94 | + reqcfg->data[i].pos > 0) { | ||
95 | + printk(KERN_ERR "Lane #%d already occupied\n", | ||
96 | + reqcfg->data[i].pos); | ||
97 | + goto err_einval; | ||
98 | + } else | ||
99 | + pos_occupied[reqcfg->data[i].pos - 1] = true; | ||
100 | + } | ||
101 | + | ||
102 | + /* Clock lane verification */ | ||
103 | + if ((reqcfg->clk.pol > 1) || (reqcfg->clk.pos > 5) || | ||
104 | + (reqcfg->clk.pos == 0)) { | ||
105 | + printk(KERN_ERR "Invalid CSI-2 Complex IO configuration" | ||
106 | + " parameters for clock lane\n"); | ||
107 | + goto err_einval; | ||
108 | + } | ||
109 | + if (pos_occupied[reqcfg->clk.pos - 1]) { | ||
110 | + printk(KERN_ERR "Lane #%d already occupied", | ||
111 | + reqcfg->clk.pos); | ||
112 | + goto err_einval; | ||
113 | + } else | ||
114 | + pos_occupied[reqcfg->clk.pos - 1] = true; | ||
115 | + | ||
116 | + for (i = 0; i < 4; i++) { | ||
117 | + if (currlanes->data[i].pos != reqcfg->data[i].pos) { | ||
118 | + currlanes->data[i].pos = reqcfg->data[i].pos; | ||
119 | + currlanes_u->data[i] = true; | ||
120 | + update_complexio_cfg1 = true; | ||
121 | + } | ||
122 | + if (currlanes->data[i].pol != reqcfg->data[i].pol) { | ||
123 | + currlanes->data[i].pol = reqcfg->data[i].pol; | ||
124 | + currlanes_u->data[i] = true; | ||
125 | + update_complexio_cfg1 = true; | ||
126 | + } | ||
127 | + } | ||
128 | + | ||
129 | + if (currlanes->clk.pos != reqcfg->clk.pos) { | ||
130 | + currlanes->clk.pos = reqcfg->clk.pos; | ||
131 | + currlanes_u->clk = true; | ||
132 | + update_complexio_cfg1 = true; | ||
133 | + } | ||
134 | + if (currlanes->clk.pol != reqcfg->clk.pol) { | ||
135 | + currlanes->clk.pol = reqcfg->clk.pol; | ||
136 | + currlanes_u->clk = true; | ||
137 | + update_complexio_cfg1 = true; | ||
138 | + } | ||
139 | + return 0; | ||
140 | +err_einval: | ||
141 | + return -EINVAL; | ||
142 | +} | ||
143 | + | ||
144 | +/** | ||
145 | + * isp_csi2_complexio_lanes_update - Applies CSI2 ComplexIO lanes configuration. | ||
146 | + * @force_update: Flag to force rewrite of registers, even if they haven't been | ||
147 | + * updated with the isp_csi2_complexio_lanes_config() function. | ||
148 | + * | ||
149 | + * It only saves settings when they were previously updated using the | ||
150 | + * isp_csi2_complexio_lanes_config() function, unless the force_update flag is | ||
151 | + * set to true. | ||
152 | + * Always returns 0. | ||
153 | + **/ | ||
154 | +int isp_csi2_complexio_lanes_update(bool force_update) | ||
155 | +{ | ||
156 | + struct isp_csi2_lanes_cfg *currlanes = ¤t_csi2_cfg.lanes; | ||
157 | + struct isp_csi2_lanes_cfg_update *currlanes_u = | ||
158 | + ¤t_csi2_cfg_update.lanes; | ||
159 | + u32 reg; | ||
160 | + int i; | ||
161 | + | ||
162 | + if (!update_complexio_cfg1 && !force_update) | ||
163 | + return 0; | ||
164 | + | ||
165 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); | ||
166 | + for (i = 0; i < 4; i++) { | ||
167 | + if (currlanes_u->data[i] || force_update) { | ||
168 | + reg &= ~(ISPCSI2_COMPLEXIO_CFG1_DATA_POL_MASK(i + 1) | | ||
169 | + ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_MASK(i + | ||
170 | + 1)); | ||
171 | + reg |= (currlanes->data[i].pol << | ||
172 | + ISPCSI2_COMPLEXIO_CFG1_DATA_POL_SHIFT(i + 1)); | ||
173 | + reg |= (currlanes->data[i].pos << | ||
174 | + ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(i + | ||
175 | + 1)); | ||
176 | + currlanes_u->data[i] = false; | ||
177 | + } | ||
178 | + } | ||
179 | + | ||
180 | + if (currlanes_u->clk || force_update) { | ||
181 | + reg &= ~(ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_MASK | | ||
182 | + ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_MASK); | ||
183 | + reg |= (currlanes->clk.pol << | ||
184 | + ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_SHIFT); | ||
185 | + reg |= (currlanes->clk.pos << | ||
186 | + ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT); | ||
187 | + currlanes_u->clk = false; | ||
188 | + } | ||
189 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); | ||
190 | + | ||
191 | + update_complexio_cfg1 = false; | ||
192 | + return 0; | ||
193 | +} | ||
194 | + | ||
195 | +/** | ||
196 | + * isp_csi2_complexio_lanes_get - Gets CSI2 ComplexIO lanes configuration. | ||
197 | + * | ||
198 | + * Gets settings from HW registers and fills in the internal driver memory | ||
199 | + * Always returns 0. | ||
200 | + **/ | ||
201 | +int isp_csi2_complexio_lanes_get(void) | ||
202 | +{ | ||
203 | + struct isp_csi2_lanes_cfg *currlanes = ¤t_csi2_cfg.lanes; | ||
204 | + struct isp_csi2_lanes_cfg_update *currlanes_u = | ||
205 | + ¤t_csi2_cfg_update.lanes; | ||
206 | + u32 reg; | ||
207 | + int i; | ||
208 | + | ||
209 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); | ||
210 | + for (i = 0; i < 4; i++) { | ||
211 | + currlanes->data[i].pol = (reg & | ||
212 | + ISPCSI2_COMPLEXIO_CFG1_DATA_POL_MASK(i + 1)) >> | ||
213 | + ISPCSI2_COMPLEXIO_CFG1_DATA_POL_SHIFT(i + 1); | ||
214 | + currlanes->data[i].pos = (reg & | ||
215 | + ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_MASK(i + 1)) >> | ||
216 | + ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(i + 1); | ||
217 | + currlanes_u->data[i] = false; | ||
218 | + } | ||
219 | + currlanes->clk.pol = (reg & ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_MASK) >> | ||
220 | + ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_SHIFT; | ||
221 | + currlanes->clk.pos = (reg & | ||
222 | + ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_MASK) >> | ||
223 | + ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT; | ||
224 | + currlanes_u->clk = false; | ||
225 | + | ||
226 | + update_complexio_cfg1 = false; | ||
227 | + return 0; | ||
228 | +} | ||
229 | + | ||
230 | +/** | ||
231 | + * isp_csi2_complexio_power_status - Gets CSI2 ComplexIO power status. | ||
232 | + * | ||
233 | + * Returns 3 possible valid states: ISP_CSI2_POWER_OFF, ISP_CSI2_POWER_ON, | ||
234 | + * and ISP_CSI2_POWER_ULPW. | ||
235 | + **/ | ||
236 | +static enum isp_csi2_power_cmds isp_csi2_complexio_power_status(void) | ||
237 | +{ | ||
238 | + enum isp_csi2_power_cmds ret; | ||
239 | + u32 reg; | ||
240 | + | ||
241 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1) & | ||
242 | + ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_MASK; | ||
243 | + switch (reg) { | ||
244 | + case ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_OFF: | ||
245 | + ret = ISP_CSI2_POWER_OFF; | ||
246 | + break; | ||
247 | + case ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_ON: | ||
248 | + ret = ISP_CSI2_POWER_ON; | ||
249 | + break; | ||
250 | + case ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_ULPW: | ||
251 | + ret = ISP_CSI2_POWER_ULPW; | ||
252 | + break; | ||
253 | + default: | ||
254 | + return -EINVAL; | ||
255 | + } | ||
256 | + return ret; | ||
257 | +} | ||
258 | + | ||
259 | +/** | ||
260 | + * isp_csi2_complexio_power_autoswitch - Sets CSI2 ComplexIO power autoswitch. | ||
261 | + * @enable: Sets or clears the autoswitch function enable flag. | ||
262 | + * | ||
263 | + * Always returns 0. | ||
264 | + **/ | ||
265 | +int isp_csi2_complexio_power_autoswitch(bool enable) | ||
266 | +{ | ||
267 | + u32 reg; | ||
268 | + | ||
269 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); | ||
270 | + reg &= ~ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_MASK; | ||
271 | + | ||
272 | + if (enable) | ||
273 | + reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_ENABLE; | ||
274 | + else | ||
275 | + reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_DISABLE; | ||
276 | + | ||
277 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); | ||
278 | + return 0; | ||
279 | +} | ||
280 | + | ||
281 | +/** | ||
282 | + * isp_csi2_complexio_power - Sets the desired power command for CSI2 ComplexIO. | ||
283 | + * @power_cmd: Power command to be set. | ||
284 | + * | ||
285 | + * Returns 0 if successful, or -EBUSY if the retry count is exceeded. | ||
286 | + **/ | ||
287 | +int isp_csi2_complexio_power(enum isp_csi2_power_cmds power_cmd) | ||
288 | +{ | ||
289 | + enum isp_csi2_power_cmds current_state; | ||
290 | + u32 reg; | ||
291 | + u8 retry_count; | ||
292 | + | ||
293 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1) & | ||
294 | + ~ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_MASK; | ||
295 | + switch (power_cmd) { | ||
296 | + case ISP_CSI2_POWER_OFF: | ||
297 | + reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_OFF; | ||
298 | + break; | ||
299 | + case ISP_CSI2_POWER_ON: | ||
300 | + reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_ON; | ||
301 | + break; | ||
302 | + case ISP_CSI2_POWER_ULPW: | ||
303 | + reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_ULPW; | ||
304 | + break; | ||
305 | + default: | ||
306 | + printk(KERN_ERR "CSI2: ERROR - Wrong Power command!\n"); | ||
307 | + return -EINVAL; | ||
308 | + } | ||
309 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); | ||
310 | + | ||
311 | + retry_count = 0; | ||
312 | + do { | ||
313 | + udelay(50); | ||
314 | + current_state = isp_csi2_complexio_power_status(); | ||
315 | + | ||
316 | + if (current_state != power_cmd) { | ||
317 | + printk(KERN_DEBUG "CSI2: Complex IO power command not" | ||
318 | + " yet taken."); | ||
319 | + if (++retry_count < 100) { | ||
320 | + printk(KERN_DEBUG " Retrying...\n"); | ||
321 | + udelay(50); | ||
322 | + } else { | ||
323 | + printk(KERN_DEBUG " Retry count exceeded!\n"); | ||
324 | + } | ||
325 | + } | ||
326 | + } while ((current_state != power_cmd) && (retry_count < 100)); | ||
327 | + | ||
328 | + if (retry_count == 100) | ||
329 | + return -EBUSY; | ||
330 | + | ||
331 | + return 0; | ||
332 | +} | ||
333 | + | ||
334 | +/** | ||
335 | + * isp_csi2_ctrl_config_frame_mode - Configure if_en behaviour for CSI2 | ||
336 | + * @frame_mode: Desired action for IF_EN switch off. 0 - disable IF immediately | ||
337 | + * 1 - disable after all Frame end Code is received in all | ||
338 | + * contexts. | ||
339 | + * | ||
340 | + * Validates and saves to internal driver memory the passed configuration. | ||
341 | + * Always returns 0. | ||
342 | + **/ | ||
343 | +int isp_csi2_ctrl_config_frame_mode(enum isp_csi2_frame_mode frame_mode) | ||
344 | +{ | ||
345 | + struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; | ||
346 | + struct isp_csi2_ctrl_cfg_update *currctrl_u = | ||
347 | + ¤t_csi2_cfg_update.ctrl; | ||
348 | + | ||
349 | + if (currctrl->frame_mode != frame_mode) { | ||
350 | + currctrl->frame_mode = frame_mode; | ||
351 | + currctrl_u->frame_mode = true; | ||
352 | + update_ctrl = true; | ||
353 | + } | ||
354 | + return 0; | ||
355 | +} | ||
356 | + | ||
357 | +/** | ||
358 | + * isp_csi2_ctrl_config_vp_clk_enable - Enables/disables CSI2 Videoport clock. | ||
359 | + * @vp_clk_enable: Boolean value to specify the Videoport clock state. | ||
360 | + * | ||
361 | + * Validates and saves to internal driver memory the passed configuration. | ||
362 | + * Always returns 0. | ||
363 | + **/ | ||
364 | +int isp_csi2_ctrl_config_vp_clk_enable(bool vp_clk_enable) | ||
365 | +{ | ||
366 | + struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; | ||
367 | + struct isp_csi2_ctrl_cfg_update *currctrl_u = | ||
368 | + ¤t_csi2_cfg_update.ctrl; | ||
369 | + | ||
370 | + if (currctrl->vp_clk_enable != vp_clk_enable) { | ||
371 | + currctrl->vp_clk_enable = vp_clk_enable; | ||
372 | + currctrl_u->vp_clk_enable = true; | ||
373 | + update_ctrl = true; | ||
374 | + } | ||
375 | + return 0; | ||
376 | +} | ||
377 | + | ||
378 | +/** | ||
379 | + * isp_csi2_ctrl_config_vp_only_enable - Sets CSI2 Videoport clock as exclusive | ||
380 | + * @vp_only_enable: Boolean value to specify if the Videoport clock is | ||
381 | + * exclusive, setting the OCP port as disabled. | ||
382 | + * | ||
383 | + * Validates and saves to internal driver memory the passed configuration. | ||
384 | + * Always returns 0. | ||
385 | + **/ | ||
386 | +int isp_csi2_ctrl_config_vp_only_enable(bool vp_only_enable) | ||
387 | +{ | ||
388 | + struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; | ||
389 | + struct isp_csi2_ctrl_cfg_update *currctrl_u = | ||
390 | + ¤t_csi2_cfg_update.ctrl; | ||
391 | + | ||
392 | + if (currctrl->vp_only_enable != vp_only_enable) { | ||
393 | + currctrl->vp_only_enable = vp_only_enable; | ||
394 | + currctrl_u->vp_only_enable = true; | ||
395 | + update_ctrl = true; | ||
396 | + } | ||
397 | + return 0; | ||
398 | +} | ||
399 | + | ||
400 | +/** | ||
401 | + * isp_csi2_ctrl_config_vp_out_ctrl - Sets CSI2 Videoport clock divider | ||
402 | + * @vp_out_ctrl: Divider value for setting videoport clock frequency based on | ||
403 | + * OCP port frequency, valid dividers are between 1 and 4. | ||
404 | + * | ||
405 | + * Validates and saves to internal driver memory the passed configuration. | ||
406 | + * Returns 0 if successful, or -EINVAL if wrong divider value is passed. | ||
407 | + **/ | ||
408 | +int isp_csi2_ctrl_config_vp_out_ctrl(u8 vp_out_ctrl) | ||
409 | +{ | ||
410 | + struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; | ||
411 | + struct isp_csi2_ctrl_cfg_update *currctrl_u = | ||
412 | + ¤t_csi2_cfg_update.ctrl; | ||
413 | + | ||
414 | + if ((vp_out_ctrl == 0) || (vp_out_ctrl > 4)) { | ||
415 | + printk(KERN_ERR "CSI2: Wrong divisor value. Must be between" | ||
416 | + " 1 and 4"); | ||
417 | + return -EINVAL; | ||
418 | + } | ||
419 | + | ||
420 | + if (currctrl->vp_out_ctrl != vp_out_ctrl) { | ||
421 | + currctrl->vp_out_ctrl = vp_out_ctrl; | ||
422 | + currctrl_u->vp_out_ctrl = true; | ||
423 | + update_ctrl = true; | ||
424 | + } | ||
425 | + return 0; | ||
426 | +} | ||
427 | + | ||
428 | +/** | ||
429 | + * isp_csi2_ctrl_config_debug_enable - Sets CSI2 debug | ||
430 | + * @debug_enable: Boolean for setting debug configuration on CSI2. | ||
431 | + * | ||
432 | + * Always returns 0. | ||
433 | + **/ | ||
434 | +int isp_csi2_ctrl_config_debug_enable(bool debug_enable) | ||
435 | +{ | ||
436 | + struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; | ||
437 | + struct isp_csi2_ctrl_cfg_update *currctrl_u = | ||
438 | + ¤t_csi2_cfg_update.ctrl; | ||
439 | + | ||
440 | + if (currctrl->debug_enable != debug_enable) { | ||
441 | + currctrl->debug_enable = debug_enable; | ||
442 | + currctrl_u->debug_enable = true; | ||
443 | + update_ctrl = true; | ||
444 | + } | ||
445 | + return 0; | ||
446 | +} | ||
447 | + | ||
448 | +/** | ||
449 | + * isp_csi2_ctrl_config_burst_size - Sets CSI2 burst size. | ||
450 | + * @burst_size: Burst size of the memory saving capability of receiver. | ||
451 | + * | ||
452 | + * Returns 0 if successful, or -EINVAL if burst size is wrong. | ||
453 | + **/ | ||
454 | +int isp_csi2_ctrl_config_burst_size(u8 burst_size) | ||
455 | +{ | ||
456 | + struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; | ||
457 | + struct isp_csi2_ctrl_cfg_update *currctrl_u = | ||
458 | + ¤t_csi2_cfg_update.ctrl; | ||
459 | + if (burst_size > 3) { | ||
460 | + printk(KERN_ERR "CSI2: Wrong burst size. Must be between" | ||
461 | + " 0 and 3"); | ||
462 | + return -EINVAL; | ||
463 | + } | ||
464 | + | ||
465 | + if (currctrl->burst_size != burst_size) { | ||
466 | + currctrl->burst_size = burst_size; | ||
467 | + currctrl_u->burst_size = true; | ||
468 | + update_ctrl = true; | ||
469 | + } | ||
470 | + return 0; | ||
471 | +} | ||
472 | + | ||
473 | +/** | ||
474 | + * isp_csi2_ctrl_config_ecc_enable - Enables ECC on CSI2 Receiver | ||
475 | + * @ecc_enable: Boolean to enable/disable the CSI2 receiver ECC handling. | ||
476 | + * | ||
477 | + * Always returns 0. | ||
478 | + **/ | ||
479 | +int isp_csi2_ctrl_config_ecc_enable(bool ecc_enable) | ||
480 | +{ | ||
481 | + struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; | ||
482 | + struct isp_csi2_ctrl_cfg_update *currctrl_u = | ||
483 | + ¤t_csi2_cfg_update.ctrl; | ||
484 | + | ||
485 | + if (currctrl->ecc_enable != ecc_enable) { | ||
486 | + currctrl->ecc_enable = ecc_enable; | ||
487 | + currctrl_u->ecc_enable = true; | ||
488 | + update_ctrl = true; | ||
489 | + } | ||
490 | + return 0; | ||
491 | +} | ||
492 | + | ||
493 | +/** | ||
494 | + * isp_csi2_ctrl_config_ecc_enable - Enables ECC on CSI2 Receiver | ||
495 | + * @ecc_enable: Boolean to enable/disable the CSI2 receiver ECC handling. | ||
496 | + * | ||
497 | + * Always returns 0. | ||
498 | + **/ | ||
499 | +int isp_csi2_ctrl_config_secure_mode(bool secure_mode) | ||
500 | +{ | ||
501 | + struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; | ||
502 | + struct isp_csi2_ctrl_cfg_update *currctrl_u = | ||
503 | + ¤t_csi2_cfg_update.ctrl; | ||
504 | + | ||
505 | + if (currctrl->secure_mode != secure_mode) { | ||
506 | + currctrl->secure_mode = secure_mode; | ||
507 | + currctrl_u->secure_mode = true; | ||
508 | + update_ctrl = true; | ||
509 | + } | ||
510 | + return 0; | ||
511 | +} | ||
512 | + | ||
513 | +/** | ||
514 | + * isp_csi2_ctrl_config_if_enable - Enables CSI2 Receiver interface. | ||
515 | + * @if_enable: Boolean to enable/disable the CSI2 receiver interface. | ||
516 | + * | ||
517 | + * Always returns 0. | ||
518 | + **/ | ||
519 | +int isp_csi2_ctrl_config_if_enable(bool if_enable) | ||
520 | +{ | ||
521 | + struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; | ||
522 | + struct isp_csi2_ctrl_cfg_update *currctrl_u = | ||
523 | + ¤t_csi2_cfg_update.ctrl; | ||
524 | + | ||
525 | + if (currctrl->if_enable != if_enable) { | ||
526 | + currctrl->if_enable = if_enable; | ||
527 | + currctrl_u->if_enable = true; | ||
528 | + update_ctrl = true; | ||
529 | + } | ||
530 | + return 0; | ||
531 | +} | ||
532 | + | ||
533 | +/** | ||
534 | + * isp_csi2_ctrl_update - Applies CSI2 control configuration. | ||
535 | + * @force_update: Flag to force rewrite of registers, even if they haven't been | ||
536 | + * updated with the isp_csi2_ctrl_config_*() functions. | ||
537 | + * | ||
538 | + * It only saves settings when they were previously updated using the | ||
539 | + * isp_csi2_ctrl_config_*() functions, unless the force_update flag is | ||
540 | + * set to true. | ||
541 | + * Always returns 0. | ||
542 | + **/ | ||
543 | +int isp_csi2_ctrl_update(bool force_update) | ||
544 | +{ | ||
545 | + struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; | ||
546 | + struct isp_csi2_ctrl_cfg_update *currctrl_u = | ||
547 | + ¤t_csi2_cfg_update.ctrl; | ||
548 | + u32 reg; | ||
549 | + | ||
550 | + if (update_ctrl || force_update) { | ||
551 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL); | ||
552 | + if (currctrl_u->frame_mode || force_update) { | ||
553 | + reg &= ~ISPCSI2_CTRL_FRAME_MASK; | ||
554 | + if (currctrl->frame_mode) | ||
555 | + reg |= ISPCSI2_CTRL_FRAME_DISABLE_FEC; | ||
556 | + else | ||
557 | + reg |= ISPCSI2_CTRL_FRAME_DISABLE_IMM; | ||
558 | + currctrl_u->frame_mode = false; | ||
559 | + } | ||
560 | + if (currctrl_u->vp_clk_enable || force_update) { | ||
561 | + reg &= ~ISPCSI2_CTRL_VP_CLK_EN_MASK; | ||
562 | + if (currctrl->vp_clk_enable) | ||
563 | + reg |= ISPCSI2_CTRL_VP_CLK_EN_ENABLE; | ||
564 | + else | ||
565 | + reg |= ISPCSI2_CTRL_VP_CLK_EN_DISABLE; | ||
566 | + currctrl_u->vp_clk_enable = false; | ||
567 | + } | ||
568 | + if (currctrl_u->vp_only_enable || force_update) { | ||
569 | + reg &= ~ISPCSI2_CTRL_VP_ONLY_EN_MASK; | ||
570 | + uses_videoport = currctrl->vp_only_enable; | ||
571 | + if (currctrl->vp_only_enable) | ||
572 | + reg |= ISPCSI2_CTRL_VP_ONLY_EN_ENABLE; | ||
573 | + else | ||
574 | + reg |= ISPCSI2_CTRL_VP_ONLY_EN_DISABLE; | ||
575 | + currctrl_u->vp_only_enable = false; | ||
576 | + } | ||
577 | + if (currctrl_u->vp_out_ctrl || force_update) { | ||
578 | + reg &= ~ISPCSI2_CTRL_VP_OUT_CTRL_MASK; | ||
579 | + reg |= (currctrl->vp_out_ctrl - 1) << | ||
580 | + ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT; | ||
581 | + currctrl_u->vp_out_ctrl = false; | ||
582 | + } | ||
583 | + if (currctrl_u->debug_enable || force_update) { | ||
584 | + reg &= ~ISPCSI2_CTRL_DBG_EN_MASK; | ||
585 | + if (currctrl->debug_enable) | ||
586 | + reg |= ISPCSI2_CTRL_DBG_EN_ENABLE; | ||
587 | + else | ||
588 | + reg |= ISPCSI2_CTRL_DBG_EN_DISABLE; | ||
589 | + currctrl_u->debug_enable = false; | ||
590 | + } | ||
591 | + if (currctrl_u->burst_size || force_update) { | ||
592 | + reg &= ~ISPCSI2_CTRL_BURST_SIZE_MASK; | ||
593 | + reg |= currctrl->burst_size << | ||
594 | + ISPCSI2_CTRL_BURST_SIZE_SHIFT; | ||
595 | + currctrl_u->burst_size = false; | ||
596 | + } | ||
597 | + if (currctrl_u->ecc_enable || force_update) { | ||
598 | + reg &= ~ISPCSI2_CTRL_ECC_EN_MASK; | ||
599 | + if (currctrl->ecc_enable) | ||
600 | + reg |= ISPCSI2_CTRL_ECC_EN_ENABLE; | ||
601 | + else | ||
602 | + reg |= ISPCSI2_CTRL_ECC_EN_DISABLE; | ||
603 | + currctrl_u->ecc_enable = false; | ||
604 | + } | ||
605 | + if (currctrl_u->secure_mode || force_update) { | ||
606 | + reg &= ~ISPCSI2_CTRL_SECURE_MASK; | ||
607 | + if (currctrl->secure_mode) | ||
608 | + reg |= ISPCSI2_CTRL_SECURE_ENABLE; | ||
609 | + else | ||
610 | + reg |= ISPCSI2_CTRL_SECURE_DISABLE; | ||
611 | + currctrl_u->secure_mode = false; | ||
612 | + } | ||
613 | + if (currctrl_u->if_enable || force_update) { | ||
614 | + reg &= ~ISPCSI2_CTRL_IF_EN_MASK; | ||
615 | + if (currctrl->if_enable) | ||
616 | + reg |= ISPCSI2_CTRL_IF_EN_ENABLE; | ||
617 | + else | ||
618 | + reg |= ISPCSI2_CTRL_IF_EN_DISABLE; | ||
619 | + currctrl_u->if_enable = false; | ||
620 | + } | ||
621 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL); | ||
622 | + update_ctrl = false; | ||
623 | + } | ||
624 | + return 0; | ||
625 | +} | ||
626 | + | ||
627 | +/** | ||
628 | + * isp_csi2_ctrl_get - Gets CSI2 control configuration | ||
629 | + * | ||
630 | + * Always returns 0. | ||
631 | + **/ | ||
632 | +int isp_csi2_ctrl_get(void) | ||
633 | +{ | ||
634 | + struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; | ||
635 | + struct isp_csi2_ctrl_cfg_update *currctrl_u = | ||
636 | + ¤t_csi2_cfg_update.ctrl; | ||
637 | + u32 reg; | ||
638 | + | ||
639 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL); | ||
640 | + currctrl->frame_mode = (reg & ISPCSI2_CTRL_FRAME_MASK) >> | ||
641 | + ISPCSI2_CTRL_FRAME_SHIFT; | ||
642 | + currctrl_u->frame_mode = false; | ||
643 | + | ||
644 | + if ((reg & ISPCSI2_CTRL_VP_CLK_EN_MASK) == | ||
645 | + ISPCSI2_CTRL_VP_CLK_EN_ENABLE) | ||
646 | + currctrl->vp_clk_enable = true; | ||
647 | + else | ||
648 | + currctrl->vp_clk_enable = false; | ||
649 | + currctrl_u->vp_clk_enable = false; | ||
650 | + | ||
651 | + if ((reg & ISPCSI2_CTRL_VP_ONLY_EN_MASK) == | ||
652 | + ISPCSI2_CTRL_VP_ONLY_EN_ENABLE) | ||
653 | + currctrl->vp_only_enable = true; | ||
654 | + else | ||
655 | + currctrl->vp_only_enable = false; | ||
656 | + uses_videoport = currctrl->vp_only_enable; | ||
657 | + currctrl_u->vp_only_enable = false; | ||
658 | + | ||
659 | + currctrl->vp_out_ctrl = ((reg & ISPCSI2_CTRL_VP_OUT_CTRL_MASK) >> | ||
660 | + ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT) + 1; | ||
661 | + currctrl_u->vp_out_ctrl = false; | ||
662 | + | ||
663 | + if ((reg & ISPCSI2_CTRL_DBG_EN_MASK) == ISPCSI2_CTRL_DBG_EN_ENABLE) | ||
664 | + currctrl->debug_enable = true; | ||
665 | + else | ||
666 | + currctrl->debug_enable = false; | ||
667 | + currctrl_u->debug_enable = false; | ||
668 | + | ||
669 | + currctrl->burst_size = (reg & ISPCSI2_CTRL_BURST_SIZE_MASK) >> | ||
670 | + ISPCSI2_CTRL_BURST_SIZE_SHIFT; | ||
671 | + currctrl_u->burst_size = false; | ||
672 | + | ||
673 | + if ((reg & ISPCSI2_CTRL_ECC_EN_MASK) == ISPCSI2_CTRL_ECC_EN_ENABLE) | ||
674 | + currctrl->ecc_enable = true; | ||
675 | + else | ||
676 | + currctrl->ecc_enable = false; | ||
677 | + currctrl_u->ecc_enable = false; | ||
678 | + | ||
679 | + if ((reg & ISPCSI2_CTRL_SECURE_MASK) == ISPCSI2_CTRL_SECURE_ENABLE) | ||
680 | + currctrl->secure_mode = true; | ||
681 | + else | ||
682 | + currctrl->secure_mode = false; | ||
683 | + currctrl_u->secure_mode = false; | ||
684 | + | ||
685 | + if ((reg & ISPCSI2_CTRL_IF_EN_MASK) == ISPCSI2_CTRL_IF_EN_ENABLE) | ||
686 | + currctrl->if_enable = true; | ||
687 | + else | ||
688 | + currctrl->if_enable = false; | ||
689 | + currctrl_u->if_enable = false; | ||
690 | + | ||
691 | + update_ctrl = false; | ||
692 | + return 0; | ||
693 | +} | ||
694 | + | ||
695 | +/** | ||
696 | + * isp_csi2_ctx_validate - Validates the context number value | ||
697 | + * @ctxnum: Pointer to variable containing context number. | ||
698 | + * | ||
699 | + * If the value is not in range (3 bits), it is being ANDed with 0x7 to force | ||
700 | + * it to be on range. | ||
701 | + **/ | ||
702 | +static void isp_csi2_ctx_validate(u8 *ctxnum) | ||
703 | +{ | ||
704 | + if (*ctxnum > 7) { | ||
705 | + printk(KERN_ERR "Invalid context number. Forcing valid" | ||
706 | + " value...\n"); | ||
707 | + *ctxnum &= ~(0x7); | ||
708 | + } | ||
709 | +} | ||
710 | + | ||
711 | +/** | ||
712 | + * isp_csi2_ctx_config_virtual_id - Maps a virtual ID with a CSI2 Rx context | ||
713 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
714 | + * @virtual_id: CSI2 Virtual ID to associate with specified context number. | ||
715 | + * | ||
716 | + * Returns 0 if successful, or -EINVAL if Virtual ID is not in range (0-3). | ||
717 | + **/ | ||
718 | +int isp_csi2_ctx_config_virtual_id(u8 ctxnum, u8 virtual_id) | ||
719 | +{ | ||
720 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
721 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
722 | + | ||
723 | + isp_csi2_ctx_validate(&ctxnum); | ||
724 | + | ||
725 | + if (virtual_id > 3) { | ||
726 | + printk(KERN_ERR "Wrong requested virtual_id\n"); | ||
727 | + return -EINVAL; | ||
728 | + } | ||
729 | + | ||
730 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
731 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
732 | + | ||
733 | + if (selected_ctx->virtual_id != virtual_id) { | ||
734 | + selected_ctx->virtual_id = virtual_id; | ||
735 | + selected_ctx_u->virtual_id = true; | ||
736 | + update_ctx_ctrl2[ctxnum] = true; | ||
737 | + } | ||
738 | + | ||
739 | + return 0; | ||
740 | +} | ||
741 | + | ||
742 | +/** | ||
743 | + * isp_csi2_ctx_config_frame_count - Sets frame count to be received in CSI2 Rx. | ||
744 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
745 | + * @frame_count: Number of frames to acquire. | ||
746 | + * | ||
747 | + * Always returns 0. | ||
748 | + **/ | ||
749 | +int isp_csi2_ctx_config_frame_count(u8 ctxnum, u8 frame_count) | ||
750 | +{ | ||
751 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
752 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
753 | + | ||
754 | + isp_csi2_ctx_validate(&ctxnum); | ||
755 | + | ||
756 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
757 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
758 | + | ||
759 | + if (selected_ctx->frame_count != frame_count) { | ||
760 | + selected_ctx->frame_count = frame_count; | ||
761 | + selected_ctx_u->frame_count = true; | ||
762 | + update_ctx_ctrl1[ctxnum] = true; | ||
763 | + } | ||
764 | + | ||
765 | + return 0; | ||
766 | +} | ||
767 | + | ||
768 | +/** | ||
769 | + * isp_csi2_ctx_config_format - Maps a pixel format to a specified context. | ||
770 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
771 | + * @pixformat: V4L2 structure for pixel format. | ||
772 | + * | ||
773 | + * Returns 0 if successful, or -EINVAL if the format is not supported by the | ||
774 | + * receiver. | ||
775 | + **/ | ||
776 | +int isp_csi2_ctx_config_format(u8 ctxnum, u32 pixformat) | ||
777 | +{ | ||
778 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
779 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
780 | + struct v4l2_pix_format pix; | ||
781 | + | ||
782 | + isp_csi2_ctx_validate(&ctxnum); | ||
783 | + | ||
784 | + pix.pixelformat = pixformat; | ||
785 | + switch (pix.pixelformat) { | ||
786 | + case V4L2_PIX_FMT_RGB565: | ||
787 | + case V4L2_PIX_FMT_RGB565X: | ||
788 | + case V4L2_PIX_FMT_YUYV: | ||
789 | + case V4L2_PIX_FMT_UYVY: | ||
790 | + case V4L2_PIX_FMT_RGB555: | ||
791 | + case V4L2_PIX_FMT_RGB555X: | ||
792 | + case V4L2_PIX_FMT_SGRBG10: | ||
793 | + break; | ||
794 | + default: | ||
795 | + printk(KERN_ERR "Context config pixel format unsupported\n"); | ||
796 | + return -EINVAL; | ||
797 | + } | ||
798 | + | ||
799 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
800 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
801 | + | ||
802 | + selected_ctx->format = pix; | ||
803 | + selected_ctx_u->format = true; | ||
804 | + update_ctx_ctrl2[ctxnum] = true; | ||
805 | + | ||
806 | + return 0; | ||
807 | +} | ||
808 | + | ||
809 | +/** | ||
810 | + * isp_csi2_ctx_config_alpha - Sets the alpha value for pixel format | ||
811 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
812 | + * @alpha: Alpha value. | ||
813 | + * | ||
814 | + * Returns 0 if successful, or -EINVAL if the alpha value is bigger than 16383. | ||
815 | + **/ | ||
816 | +int isp_csi2_ctx_config_alpha(u8 ctxnum, u16 alpha) | ||
817 | +{ | ||
818 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
819 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
820 | + | ||
821 | + isp_csi2_ctx_validate(&ctxnum); | ||
822 | + | ||
823 | + if (alpha > 0x3FFF) { | ||
824 | + printk(KERN_ERR "Wrong alpha value\n"); | ||
825 | + return -EINVAL; | ||
826 | + } | ||
827 | + | ||
828 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
829 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
830 | + | ||
831 | + if (selected_ctx->alpha != alpha) { | ||
832 | + selected_ctx->alpha = alpha; | ||
833 | + selected_ctx_u->alpha = true; | ||
834 | + update_ctx_ctrl3[ctxnum] = true; | ||
835 | + } | ||
836 | + return 0; | ||
837 | +} | ||
838 | + | ||
839 | +/** | ||
840 | + * isp_csi2_ctx_config_data_offset - Sets the offset between received lines | ||
841 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
842 | + * @data_offset: Offset between first pixel of each 2 contiguous lines. | ||
843 | + * | ||
844 | + * Returns 0 if successful, or -EINVAL if the line offset is bigger than 1023. | ||
845 | + **/ | ||
846 | +int isp_csi2_ctx_config_data_offset(u8 ctxnum, u16 data_offset) | ||
847 | +{ | ||
848 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
849 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
850 | + | ||
851 | + isp_csi2_ctx_validate(&ctxnum); | ||
852 | + | ||
853 | + if (data_offset > 0x3FF) { | ||
854 | + printk(KERN_ERR "Wrong line offset\n"); | ||
855 | + return -EINVAL; | ||
856 | + } | ||
857 | + | ||
858 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
859 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
860 | + | ||
861 | + if (selected_ctx->data_offset != data_offset) { | ||
862 | + selected_ctx->data_offset = data_offset; | ||
863 | + selected_ctx_u->data_offset = true; | ||
864 | + } | ||
865 | + return 0; | ||
866 | +} | ||
867 | + | ||
868 | +/** | ||
869 | + * isp_csi2_ctx_config_ping_addr - Sets Ping address for CSI2 Rx. buffer saving | ||
870 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
871 | + * @ping_addr: 32 bit ISP MMU mapped address. | ||
872 | + * | ||
873 | + * Always returns 0. | ||
874 | + **/ | ||
875 | +int isp_csi2_ctx_config_ping_addr(u8 ctxnum, u32 ping_addr) | ||
876 | +{ | ||
877 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
878 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
879 | + | ||
880 | + isp_csi2_ctx_validate(&ctxnum); | ||
881 | + | ||
882 | + ping_addr &= ~(0x1F); | ||
883 | + | ||
884 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
885 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
886 | + | ||
887 | + if (selected_ctx->ping_addr != ping_addr) { | ||
888 | + selected_ctx->ping_addr = ping_addr; | ||
889 | + selected_ctx_u->ping_addr = true; | ||
890 | + } | ||
891 | + return 0; | ||
892 | +} | ||
893 | + | ||
894 | +/** | ||
895 | + * isp_csi2_ctx_config_pong_addr - Sets Pong address for CSI2 Rx. buffer saving | ||
896 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
897 | + * @pong_addr: 32 bit ISP MMU mapped address. | ||
898 | + * | ||
899 | + * Always returns 0. | ||
900 | + **/ | ||
901 | +int isp_csi2_ctx_config_pong_addr(u8 ctxnum, u32 pong_addr) | ||
902 | +{ | ||
903 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
904 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
905 | + | ||
906 | + isp_csi2_ctx_validate(&ctxnum); | ||
907 | + | ||
908 | + pong_addr &= ~(0x1F); | ||
909 | + | ||
910 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
911 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
912 | + | ||
913 | + if (selected_ctx->pong_addr != pong_addr) { | ||
914 | + selected_ctx->pong_addr = pong_addr; | ||
915 | + selected_ctx_u->pong_addr = true; | ||
916 | + } | ||
917 | + return 0; | ||
918 | +} | ||
919 | + | ||
920 | +/** | ||
921 | + * isp_csi2_ctx_config_eof_enabled - Enables EOF signal assertion | ||
922 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
923 | + * @eof_enabled: Boolean to enable/disable EOF signal assertion on received | ||
924 | + * packets. | ||
925 | + * | ||
926 | + * Always returns 0. | ||
927 | + **/ | ||
928 | +int isp_csi2_ctx_config_eof_enabled(u8 ctxnum, bool eof_enabled) | ||
929 | +{ | ||
930 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
931 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
932 | + | ||
933 | + isp_csi2_ctx_validate(&ctxnum); | ||
934 | + | ||
935 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
936 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
937 | + | ||
938 | + if (selected_ctx->eof_enabled != eof_enabled) { | ||
939 | + selected_ctx->eof_enabled = eof_enabled; | ||
940 | + selected_ctx_u->eof_enabled = true; | ||
941 | + update_ctx_ctrl1[ctxnum] = true; | ||
942 | + } | ||
943 | + return 0; | ||
944 | +} | ||
945 | + | ||
946 | +/** | ||
947 | + * isp_csi2_ctx_config_eol_enabled - Enables EOL signal assertion | ||
948 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
949 | + * @eol_enabled: Boolean to enable/disable EOL signal assertion on received | ||
950 | + * packets. | ||
951 | + * | ||
952 | + * Always returns 0. | ||
953 | + **/ | ||
954 | +int isp_csi2_ctx_config_eol_enabled(u8 ctxnum, bool eol_enabled) | ||
955 | +{ | ||
956 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
957 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
958 | + | ||
959 | + isp_csi2_ctx_validate(&ctxnum); | ||
960 | + | ||
961 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
962 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
963 | + | ||
964 | + if (selected_ctx->eol_enabled != eol_enabled) { | ||
965 | + selected_ctx->eol_enabled = eol_enabled; | ||
966 | + selected_ctx_u->eol_enabled = true; | ||
967 | + update_ctx_ctrl1[ctxnum] = true; | ||
968 | + } | ||
969 | + return 0; | ||
970 | +} | ||
971 | + | ||
972 | +/** | ||
973 | + * isp_csi2_ctx_config_checksum_enabled - Enables Checksum check in rcvd packets | ||
974 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
975 | + * @checksum_enabled: Boolean to enable/disable Checksum check on received | ||
976 | + * packets | ||
977 | + * | ||
978 | + * Always returns 0. | ||
979 | + **/ | ||
980 | +int isp_csi2_ctx_config_checksum_enabled(u8 ctxnum, bool checksum_enabled) | ||
981 | +{ | ||
982 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
983 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
984 | + | ||
985 | + isp_csi2_ctx_validate(&ctxnum); | ||
986 | + | ||
987 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
988 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
989 | + | ||
990 | + if (selected_ctx->checksum_enabled != checksum_enabled) { | ||
991 | + selected_ctx->checksum_enabled = checksum_enabled; | ||
992 | + selected_ctx_u->checksum_enabled = true; | ||
993 | + update_ctx_ctrl1[ctxnum] = true; | ||
994 | + } | ||
995 | + return 0; | ||
996 | +} | ||
997 | + | ||
998 | +/** | ||
999 | + * isp_csi2_ctx_config_enabled - Enables specified CSI2 context | ||
1000 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
1001 | + * @enabled: Boolean to enable/disable specified context. | ||
1002 | + * | ||
1003 | + * Always returns 0. | ||
1004 | + **/ | ||
1005 | +int isp_csi2_ctx_config_enabled(u8 ctxnum, bool enabled) | ||
1006 | +{ | ||
1007 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
1008 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
1009 | + | ||
1010 | + isp_csi2_ctx_validate(&ctxnum); | ||
1011 | + | ||
1012 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
1013 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
1014 | + | ||
1015 | + if (selected_ctx->enabled != enabled) { | ||
1016 | + selected_ctx->enabled = enabled; | ||
1017 | + selected_ctx_u->enabled = true; | ||
1018 | + update_ctx_ctrl1[ctxnum] = true; | ||
1019 | + } | ||
1020 | + return 0; | ||
1021 | +} | ||
1022 | + | ||
1023 | +/** | ||
1024 | + * isp_csi2_ctx_update - Applies CSI2 context configuration. | ||
1025 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
1026 | + * @force_update: Flag to force rewrite of registers, even if they haven't been | ||
1027 | + * updated with the isp_csi2_ctx_config_*() functions. | ||
1028 | + * | ||
1029 | + * It only saves settings when they were previously updated using the | ||
1030 | + * isp_csi2_ctx_config_*() functions, unless the force_update flag is | ||
1031 | + * set to true. | ||
1032 | + * Always returns 0. | ||
1033 | + **/ | ||
1034 | +int isp_csi2_ctx_update(u8 ctxnum, bool force_update) | ||
1035 | +{ | ||
1036 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
1037 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
1038 | + u32 reg; | ||
1039 | + | ||
1040 | + isp_csi2_ctx_validate(&ctxnum); | ||
1041 | + | ||
1042 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
1043 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
1044 | + | ||
1045 | + if (update_ctx_ctrl1[ctxnum] || force_update) { | ||
1046 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1047 | + ISPCSI2_CTX_CTRL1(ctxnum)); | ||
1048 | + if (selected_ctx_u->frame_count || force_update) { | ||
1049 | + reg &= ~(ISPCSI2_CTX_CTRL1_COUNT_MASK); | ||
1050 | + reg |= selected_ctx->frame_count << | ||
1051 | + ISPCSI2_CTX_CTRL1_COUNT_SHIFT; | ||
1052 | + selected_ctx_u->frame_count = false; | ||
1053 | + } | ||
1054 | + if (selected_ctx_u->eof_enabled || force_update) { | ||
1055 | + reg &= ~(ISPCSI2_CTX_CTRL1_EOF_EN_MASK); | ||
1056 | + if (selected_ctx->eof_enabled) | ||
1057 | + reg |= ISPCSI2_CTX_CTRL1_EOF_EN_ENABLE; | ||
1058 | + else | ||
1059 | + reg |= ISPCSI2_CTX_CTRL1_EOF_EN_DISABLE; | ||
1060 | + selected_ctx_u->eof_enabled = false; | ||
1061 | + } | ||
1062 | + if (selected_ctx_u->eol_enabled || force_update) { | ||
1063 | + reg &= ~(ISPCSI2_CTX_CTRL1_EOL_EN_MASK); | ||
1064 | + if (selected_ctx->eol_enabled) | ||
1065 | + reg |= ISPCSI2_CTX_CTRL1_EOL_EN_ENABLE; | ||
1066 | + else | ||
1067 | + reg |= ISPCSI2_CTX_CTRL1_EOL_EN_DISABLE; | ||
1068 | + selected_ctx_u->eol_enabled = false; | ||
1069 | + } | ||
1070 | + if (selected_ctx_u->checksum_enabled || force_update) { | ||
1071 | + reg &= ~(ISPCSI2_CTX_CTRL1_CS_EN_MASK); | ||
1072 | + if (selected_ctx->checksum_enabled) | ||
1073 | + reg |= ISPCSI2_CTX_CTRL1_CS_EN_ENABLE; | ||
1074 | + else | ||
1075 | + reg |= ISPCSI2_CTX_CTRL1_CS_EN_DISABLE; | ||
1076 | + selected_ctx_u->checksum_enabled = false; | ||
1077 | + } | ||
1078 | + if (selected_ctx_u->enabled || force_update) { | ||
1079 | + reg &= ~(ISPCSI2_CTX_CTRL1_CTX_EN_MASK); | ||
1080 | + if (selected_ctx->enabled) | ||
1081 | + reg |= ISPCSI2_CTX_CTRL1_CTX_EN_ENABLE; | ||
1082 | + else | ||
1083 | + reg |= ISPCSI2_CTX_CTRL1_CTX_EN_DISABLE; | ||
1084 | + selected_ctx_u->enabled = false; | ||
1085 | + } | ||
1086 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, | ||
1087 | + ISPCSI2_CTX_CTRL1(ctxnum)); | ||
1088 | + update_ctx_ctrl1[ctxnum] = false; | ||
1089 | + } | ||
1090 | + | ||
1091 | + if (update_ctx_ctrl2[ctxnum] || force_update) { | ||
1092 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1093 | + ISPCSI2_CTX_CTRL2(ctxnum)); | ||
1094 | + if (selected_ctx_u->virtual_id || force_update) { | ||
1095 | + reg &= ~(ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK); | ||
1096 | + reg |= selected_ctx->virtual_id << | ||
1097 | + ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT; | ||
1098 | + selected_ctx_u->virtual_id = false; | ||
1099 | + } | ||
1100 | + | ||
1101 | + if (selected_ctx_u->format || force_update) { | ||
1102 | + struct v4l2_pix_format *pix; | ||
1103 | + u16 new_format = 0; | ||
1104 | + | ||
1105 | + reg &= ~(ISPCSI2_CTX_CTRL2_FORMAT_MASK); | ||
1106 | + pix = &selected_ctx->format; | ||
1107 | + switch (pix->pixelformat) { | ||
1108 | + case V4L2_PIX_FMT_RGB565: | ||
1109 | + case V4L2_PIX_FMT_RGB565X: | ||
1110 | + new_format = 0x22; | ||
1111 | + break; | ||
1112 | + case V4L2_PIX_FMT_YUYV: | ||
1113 | + case V4L2_PIX_FMT_UYVY: | ||
1114 | + if (uses_videoport) | ||
1115 | + new_format = 0x9E; | ||
1116 | + else | ||
1117 | + new_format = 0x1E; | ||
1118 | + break; | ||
1119 | + case V4L2_PIX_FMT_RGB555: | ||
1120 | + case V4L2_PIX_FMT_RGB555X: | ||
1121 | + new_format = 0xA1; | ||
1122 | + break; | ||
1123 | + case V4L2_PIX_FMT_SGRBG10: | ||
1124 | + if (uses_videoport) | ||
1125 | + new_format = 0x12F; | ||
1126 | + else | ||
1127 | + new_format = 0xAB; | ||
1128 | + break; | ||
1129 | + } | ||
1130 | + reg |= (new_format << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT); | ||
1131 | + selected_ctx_u->format = false; | ||
1132 | + } | ||
1133 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, | ||
1134 | + ISPCSI2_CTX_CTRL2(ctxnum)); | ||
1135 | + update_ctx_ctrl2[ctxnum] = false; | ||
1136 | + } | ||
1137 | + | ||
1138 | + if (update_ctx_ctrl3[ctxnum] || force_update) { | ||
1139 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1140 | + ISPCSI2_CTX_CTRL3(ctxnum)); | ||
1141 | + if (selected_ctx_u->alpha || force_update) { | ||
1142 | + reg &= ~(ISPCSI2_CTX_CTRL3_ALPHA_MASK); | ||
1143 | + reg |= (selected_ctx->alpha << | ||
1144 | + ISPCSI2_CTX_CTRL3_ALPHA_SHIFT); | ||
1145 | + selected_ctx_u->alpha = false; | ||
1146 | + } | ||
1147 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, | ||
1148 | + ISPCSI2_CTX_CTRL3(ctxnum)); | ||
1149 | + update_ctx_ctrl3[ctxnum] = false; | ||
1150 | + } | ||
1151 | + | ||
1152 | + if (selected_ctx_u->data_offset) { | ||
1153 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1154 | + ISPCSI2_CTX_DAT_OFST(ctxnum)); | ||
1155 | + reg &= ~ISPCSI2_CTX_DAT_OFST_OFST_MASK; | ||
1156 | + reg |= selected_ctx->data_offset << | ||
1157 | + ISPCSI2_CTX_DAT_OFST_OFST_SHIFT; | ||
1158 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, | ||
1159 | + ISPCSI2_CTX_DAT_OFST(ctxnum)); | ||
1160 | + selected_ctx_u->data_offset = false; | ||
1161 | + } | ||
1162 | + | ||
1163 | + if (selected_ctx_u->ping_addr) { | ||
1164 | + reg = selected_ctx->ping_addr; | ||
1165 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, | ||
1166 | + ISPCSI2_CTX_DAT_PING_ADDR(ctxnum)); | ||
1167 | + selected_ctx_u->ping_addr = false; | ||
1168 | + } | ||
1169 | + | ||
1170 | + if (selected_ctx_u->pong_addr) { | ||
1171 | + reg = selected_ctx->pong_addr; | ||
1172 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, | ||
1173 | + ISPCSI2_CTX_DAT_PONG_ADDR(ctxnum)); | ||
1174 | + selected_ctx_u->pong_addr = false; | ||
1175 | + } | ||
1176 | + return 0; | ||
1177 | +} | ||
1178 | + | ||
1179 | +/** | ||
1180 | + * isp_csi2_ctx_get - Gets specific CSI2 Context configuration | ||
1181 | + * @ctxnum: Context number, valid between 0 and 7 values. | ||
1182 | + * | ||
1183 | + * Always returns 0. | ||
1184 | + **/ | ||
1185 | +int isp_csi2_ctx_get(u8 ctxnum) | ||
1186 | +{ | ||
1187 | + struct isp_csi2_ctx_cfg *selected_ctx; | ||
1188 | + struct isp_csi2_ctx_cfg_update *selected_ctx_u; | ||
1189 | + u32 reg; | ||
1190 | + | ||
1191 | + isp_csi2_ctx_validate(&ctxnum); | ||
1192 | + | ||
1193 | + selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; | ||
1194 | + selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; | ||
1195 | + | ||
1196 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTX_CTRL1(ctxnum)); | ||
1197 | + selected_ctx->frame_count = (reg & ISPCSI2_CTX_CTRL1_COUNT_MASK) >> | ||
1198 | + ISPCSI2_CTX_CTRL1_COUNT_SHIFT; | ||
1199 | + selected_ctx_u->frame_count = false; | ||
1200 | + | ||
1201 | + if ((reg & ISPCSI2_CTX_CTRL1_EOF_EN_MASK) == | ||
1202 | + ISPCSI2_CTX_CTRL1_EOF_EN_ENABLE) | ||
1203 | + selected_ctx->eof_enabled = true; | ||
1204 | + else | ||
1205 | + selected_ctx->eof_enabled = false; | ||
1206 | + selected_ctx_u->eof_enabled = false; | ||
1207 | + | ||
1208 | + if ((reg & ISPCSI2_CTX_CTRL1_EOL_EN_MASK) == | ||
1209 | + ISPCSI2_CTX_CTRL1_EOL_EN_ENABLE) | ||
1210 | + selected_ctx->eol_enabled = true; | ||
1211 | + else | ||
1212 | + selected_ctx->eol_enabled = false; | ||
1213 | + selected_ctx_u->eol_enabled = false; | ||
1214 | + | ||
1215 | + if ((reg & ISPCSI2_CTX_CTRL1_CS_EN_MASK) == | ||
1216 | + ISPCSI2_CTX_CTRL1_CS_EN_ENABLE) | ||
1217 | + selected_ctx->checksum_enabled = true; | ||
1218 | + else | ||
1219 | + selected_ctx->checksum_enabled = false; | ||
1220 | + selected_ctx_u->checksum_enabled = false; | ||
1221 | + | ||
1222 | + if ((reg & ISPCSI2_CTX_CTRL1_CTX_EN_MASK) == | ||
1223 | + ISPCSI2_CTX_CTRL1_CTX_EN_ENABLE) | ||
1224 | + selected_ctx->enabled = true; | ||
1225 | + else | ||
1226 | + selected_ctx->enabled = false; | ||
1227 | + selected_ctx_u->enabled = false; | ||
1228 | + update_ctx_ctrl1[ctxnum] = false; | ||
1229 | + | ||
1230 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTX_CTRL2(ctxnum)); | ||
1231 | + | ||
1232 | + selected_ctx->virtual_id = (reg & ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK) >> | ||
1233 | + ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT; | ||
1234 | + selected_ctx_u->virtual_id = false; | ||
1235 | + | ||
1236 | + switch ((reg & ISPCSI2_CTX_CTRL2_FORMAT_MASK) >> | ||
1237 | + ISPCSI2_CTX_CTRL2_FORMAT_SHIFT) { | ||
1238 | + case 0x22: | ||
1239 | + selected_ctx->format.pixelformat = V4L2_PIX_FMT_RGB565; | ||
1240 | + break; | ||
1241 | + case 0x9E: | ||
1242 | + case 0x1E: | ||
1243 | + selected_ctx->format.pixelformat = V4L2_PIX_FMT_YUYV; | ||
1244 | + break; | ||
1245 | + case 0xA1: | ||
1246 | + selected_ctx->format.pixelformat = V4L2_PIX_FMT_RGB555; | ||
1247 | + break; | ||
1248 | + case 0xAB: | ||
1249 | + case 0x12F: | ||
1250 | + selected_ctx->format.pixelformat = V4L2_PIX_FMT_SGRBG10; | ||
1251 | + break; | ||
1252 | + } | ||
1253 | + selected_ctx_u->format = false; | ||
1254 | + update_ctx_ctrl2[ctxnum] = false; | ||
1255 | + | ||
1256 | + selected_ctx->alpha = (isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1257 | + ISPCSI2_CTX_CTRL3(ctxnum)) & | ||
1258 | + ISPCSI2_CTX_CTRL3_ALPHA_MASK) >> | ||
1259 | + ISPCSI2_CTX_CTRL3_ALPHA_SHIFT; | ||
1260 | + selected_ctx_u->alpha = false; | ||
1261 | + update_ctx_ctrl3[ctxnum] = false; | ||
1262 | + | ||
1263 | + selected_ctx->data_offset = (isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1264 | + ISPCSI2_CTX_DAT_OFST(ctxnum)) & | ||
1265 | + ISPCSI2_CTX_DAT_OFST_OFST_MASK) >> | ||
1266 | + ISPCSI2_CTX_DAT_OFST_OFST_SHIFT; | ||
1267 | + selected_ctx_u->data_offset = false; | ||
1268 | + | ||
1269 | + selected_ctx->ping_addr = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1270 | + ISPCSI2_CTX_DAT_PING_ADDR(ctxnum)); | ||
1271 | + selected_ctx_u->ping_addr = false; | ||
1272 | + | ||
1273 | + selected_ctx->pong_addr = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1274 | + ISPCSI2_CTX_DAT_PONG_ADDR(ctxnum)); | ||
1275 | + selected_ctx_u->pong_addr = false; | ||
1276 | + return 0; | ||
1277 | +} | ||
1278 | + | ||
1279 | +/** | ||
1280 | + * isp_csi2_ctx_update_all - Applies all CSI2 context configuration. | ||
1281 | + * @force_update: Flag to force rewrite of registers, even if they haven't been | ||
1282 | + * updated with the isp_csi2_ctx_config_*() functions. | ||
1283 | + * | ||
1284 | + * It only saves settings when they were previously updated using the | ||
1285 | + * isp_csi2_ctx_config_*() functions, unless the force_update flag is | ||
1286 | + * set to true. | ||
1287 | + * Always returns 0. | ||
1288 | + **/ | ||
1289 | +int isp_csi2_ctx_update_all(bool force_update) | ||
1290 | +{ | ||
1291 | + u8 ctxnum; | ||
1292 | + | ||
1293 | + for (ctxnum = 0; ctxnum < 8; ctxnum++) | ||
1294 | + isp_csi2_ctx_update(ctxnum, force_update); | ||
1295 | + | ||
1296 | + return 0; | ||
1297 | +} | ||
1298 | + | ||
1299 | +/** | ||
1300 | + * isp_csi2_ctx_get_all - Gets all CSI2 Context configurations | ||
1301 | + * | ||
1302 | + * Always returns 0. | ||
1303 | + **/ | ||
1304 | +int isp_csi2_ctx_get_all(void) | ||
1305 | +{ | ||
1306 | + u8 ctxnum; | ||
1307 | + | ||
1308 | + for (ctxnum = 0; ctxnum < 8; ctxnum++) | ||
1309 | + isp_csi2_ctx_get(ctxnum); | ||
1310 | + | ||
1311 | + return 0; | ||
1312 | +} | ||
1313 | + | ||
1314 | +int isp_csi2_phy_config(struct isp_csi2_phy_cfg *desiredphyconfig) | ||
1315 | +{ | ||
1316 | + struct isp_csi2_phy_cfg *currphy = ¤t_csi2_cfg.phy; | ||
1317 | + struct isp_csi2_phy_cfg_update *currphy_u = | ||
1318 | + ¤t_csi2_cfg_update.phy; | ||
1319 | + | ||
1320 | + if ((desiredphyconfig->tclk_term > 0x7f) || | ||
1321 | + (desiredphyconfig->tclk_miss > 0x3)) { | ||
1322 | + printk(KERN_ERR "Invalid PHY configuration sent by the" | ||
1323 | + " driver\n"); | ||
1324 | + return -EINVAL; | ||
1325 | + } | ||
1326 | + | ||
1327 | + if (currphy->ths_term != desiredphyconfig->ths_term) { | ||
1328 | + currphy->ths_term = desiredphyconfig->ths_term; | ||
1329 | + currphy_u->ths_term = true; | ||
1330 | + update_phy_cfg0 = true; | ||
1331 | + } | ||
1332 | + if (currphy->ths_settle != desiredphyconfig->ths_settle) { | ||
1333 | + currphy->ths_settle = desiredphyconfig->ths_settle; | ||
1334 | + currphy_u->ths_settle = true; | ||
1335 | + update_phy_cfg0 = true; | ||
1336 | + } | ||
1337 | + if (currphy->tclk_term != desiredphyconfig->tclk_term) { | ||
1338 | + currphy->tclk_term = desiredphyconfig->tclk_term; | ||
1339 | + currphy_u->tclk_term = true; | ||
1340 | + update_phy_cfg1 = true; | ||
1341 | + } | ||
1342 | + if (currphy->tclk_miss != desiredphyconfig->tclk_miss) { | ||
1343 | + currphy->tclk_miss = desiredphyconfig->tclk_miss; | ||
1344 | + currphy_u->tclk_miss = true; | ||
1345 | + update_phy_cfg1 = true; | ||
1346 | + } | ||
1347 | + if (currphy->tclk_settle != desiredphyconfig->tclk_settle) { | ||
1348 | + currphy->tclk_settle = desiredphyconfig->tclk_settle; | ||
1349 | + currphy_u->tclk_settle = true; | ||
1350 | + update_phy_cfg1 = true; | ||
1351 | + } | ||
1352 | + return 0; | ||
1353 | +} | ||
1354 | + | ||
1355 | +/** | ||
1356 | + * isp_csi2_calc_phy_cfg0 - Calculates D-PHY config based on the MIPIClk speed. | ||
1357 | + * @mipiclk: MIPI clock frequency being used with CSI2 sensor. | ||
1358 | + * @lbound_hs_settle: Lower bound for CSI2 High Speed Settle transition. | ||
1359 | + * @ubound_hs_settle: Upper bound for CSI2 High Speed Settle transition. | ||
1360 | + * | ||
1361 | + * From TRM, we have the same calculation for HS Termination signal. | ||
1362 | + * THS_TERM = ceil( 12.5ns / DDRCLK period ) - 1 | ||
1363 | + * But for Settle, we use the mid value between the two passed boundaries from | ||
1364 | + * sensor: | ||
1365 | + * THS_SETTLE = (Upper bound + Lower bound) / 2 | ||
1366 | + * | ||
1367 | + * Always returns 0. | ||
1368 | + */ | ||
1369 | +int isp_csi2_calc_phy_cfg0(u32 mipiclk, u32 lbound_hs_settle, | ||
1370 | + u32 ubound_hs_settle) | ||
1371 | +{ | ||
1372 | + struct isp_csi2_phy_cfg *currphy = ¤t_csi2_cfg.phy; | ||
1373 | + struct isp_csi2_phy_cfg_update *currphy_u = | ||
1374 | + ¤t_csi2_cfg_update.phy; | ||
1375 | + u32 tmp, ddrclk = mipiclk >> 1; | ||
1376 | + | ||
1377 | + /* Calculate THS_TERM */ | ||
1378 | + tmp = ddrclk / 80000000; | ||
1379 | + if ((ddrclk % 80000000) > 0) | ||
1380 | + tmp++; | ||
1381 | + currphy->ths_term = tmp - 1; | ||
1382 | + currphy_u->ths_term = true; | ||
1383 | + | ||
1384 | + /* Calculate THS_SETTLE */ | ||
1385 | + currphy->ths_settle = (ubound_hs_settle + lbound_hs_settle) / 2; | ||
1386 | + | ||
1387 | + currphy_u->ths_settle = true; | ||
1388 | + isp_csi2_phy_update(true); | ||
1389 | + return 0; | ||
1390 | +} | ||
1391 | +EXPORT_SYMBOL(isp_csi2_calc_phy_cfg0); | ||
1392 | + | ||
1393 | +/** | ||
1394 | + * isp_csi2_phy_update - Applies CSI2 D-PHY configuration. | ||
1395 | + * @force_update: Flag to force rewrite of registers, even if they haven't been | ||
1396 | + * updated with the isp_csi2_phy_config_*() functions. | ||
1397 | + * | ||
1398 | + * It only saves settings when they were previously updated using the | ||
1399 | + * isp_csi2_phy_config_*() functions, unless the force_update flag is | ||
1400 | + * set to true. | ||
1401 | + * Always returns 0. | ||
1402 | + **/ | ||
1403 | +int isp_csi2_phy_update(bool force_update) | ||
1404 | +{ | ||
1405 | + struct isp_csi2_phy_cfg *currphy = ¤t_csi2_cfg.phy; | ||
1406 | + struct isp_csi2_phy_cfg_update *currphy_u = | ||
1407 | + ¤t_csi2_cfg_update.phy; | ||
1408 | + u32 reg; | ||
1409 | + | ||
1410 | + if (update_phy_cfg0 || force_update) { | ||
1411 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG0); | ||
1412 | + if (currphy_u->ths_term || force_update) { | ||
1413 | + reg &= ~ISPCSI2PHY_CFG0_THS_TERM_MASK; | ||
1414 | + reg |= (currphy->ths_term << | ||
1415 | + ISPCSI2PHY_CFG0_THS_TERM_SHIFT); | ||
1416 | + currphy_u->ths_term = false; | ||
1417 | + } | ||
1418 | + if (currphy_u->ths_settle || force_update) { | ||
1419 | + reg &= ~ISPCSI2PHY_CFG0_THS_SETTLE_MASK; | ||
1420 | + reg |= (currphy->ths_settle << | ||
1421 | + ISPCSI2PHY_CFG0_THS_SETTLE_SHIFT); | ||
1422 | + currphy_u->ths_settle = false; | ||
1423 | + } | ||
1424 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG0); | ||
1425 | + update_phy_cfg0 = false; | ||
1426 | + } | ||
1427 | + | ||
1428 | + if (update_phy_cfg1 || force_update) { | ||
1429 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG1); | ||
1430 | + if (currphy_u->tclk_term || force_update) { | ||
1431 | + reg &= ~ISPCSI2PHY_CFG1_TCLK_TERM_MASK; | ||
1432 | + reg |= (currphy->tclk_term << | ||
1433 | + ISPCSI2PHY_CFG1_TCLK_TERM_SHIFT); | ||
1434 | + currphy_u->tclk_term = false; | ||
1435 | + } | ||
1436 | + if (currphy_u->tclk_miss || force_update) { | ||
1437 | + reg &= ~ISPCSI2PHY_CFG1_TCLK_MISS_MASK; | ||
1438 | + reg |= (currphy->tclk_miss << | ||
1439 | + ISPCSI2PHY_CFG1_TCLK_MISS_SHIFT); | ||
1440 | + currphy_u->tclk_miss = false; | ||
1441 | + } | ||
1442 | + if (currphy_u->tclk_settle || force_update) { | ||
1443 | + reg &= ~ISPCSI2PHY_CFG1_TCLK_SETTLE_MASK; | ||
1444 | + reg |= (currphy->tclk_settle << | ||
1445 | + ISPCSI2PHY_CFG1_TCLK_SETTLE_SHIFT); | ||
1446 | + currphy_u->tclk_settle = false; | ||
1447 | + } | ||
1448 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG1); | ||
1449 | + update_phy_cfg1 = false; | ||
1450 | + } | ||
1451 | + return 0; | ||
1452 | +} | ||
1453 | + | ||
1454 | +/** | ||
1455 | + * isp_csi2_phy_get - Gets CSI2 D-PHY configuration | ||
1456 | + * | ||
1457 | + * Gets settings from HW registers and fills in the internal driver memory | ||
1458 | + * Always returns 0. | ||
1459 | + **/ | ||
1460 | +int isp_csi2_phy_get(void) | ||
1461 | +{ | ||
1462 | + struct isp_csi2_phy_cfg *currphy = ¤t_csi2_cfg.phy; | ||
1463 | + struct isp_csi2_phy_cfg_update *currphy_u = | ||
1464 | + ¤t_csi2_cfg_update.phy; | ||
1465 | + u32 reg; | ||
1466 | + | ||
1467 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG0); | ||
1468 | + currphy->ths_term = (reg & ISPCSI2PHY_CFG0_THS_TERM_MASK) >> | ||
1469 | + ISPCSI2PHY_CFG0_THS_TERM_SHIFT; | ||
1470 | + currphy_u->ths_term = false; | ||
1471 | + | ||
1472 | + currphy->ths_settle = (reg & ISPCSI2PHY_CFG0_THS_SETTLE_MASK) >> | ||
1473 | + ISPCSI2PHY_CFG0_THS_SETTLE_SHIFT; | ||
1474 | + currphy_u->ths_settle = false; | ||
1475 | + update_phy_cfg0 = false; | ||
1476 | + | ||
1477 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG1); | ||
1478 | + | ||
1479 | + currphy->tclk_term = (reg & ISPCSI2PHY_CFG1_TCLK_TERM_MASK) >> | ||
1480 | + ISPCSI2PHY_CFG1_TCLK_TERM_SHIFT; | ||
1481 | + currphy_u->tclk_term = false; | ||
1482 | + | ||
1483 | + currphy->tclk_miss = (reg & ISPCSI2PHY_CFG1_TCLK_MISS_MASK) >> | ||
1484 | + ISPCSI2PHY_CFG1_TCLK_MISS_SHIFT; | ||
1485 | + currphy_u->tclk_miss = false; | ||
1486 | + | ||
1487 | + currphy->tclk_settle = (reg & ISPCSI2PHY_CFG1_TCLK_SETTLE_MASK) >> | ||
1488 | + ISPCSI2PHY_CFG1_TCLK_SETTLE_SHIFT; | ||
1489 | + currphy_u->tclk_settle = false; | ||
1490 | + | ||
1491 | + update_phy_cfg1 = false; | ||
1492 | + return 0; | ||
1493 | +} | ||
1494 | + | ||
1495 | +/** | ||
1496 | + * isp_csi2_timings_config_forcerxmode - Sets Force Rx mode on stop state count | ||
1497 | + * @force_rx_mode: Boolean to enable/disable forcing Rx mode in CSI2 receiver | ||
1498 | + * | ||
1499 | + * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected. | ||
1500 | + **/ | ||
1501 | +int isp_csi2_timings_config_forcerxmode(u8 io, bool force_rx_mode) | ||
1502 | +{ | ||
1503 | + struct isp_csi2_timings_cfg *currtimings; | ||
1504 | + struct isp_csi2_timings_cfg_update *currtimings_u; | ||
1505 | + | ||
1506 | + if (io < 1 || io > 2) { | ||
1507 | + printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); | ||
1508 | + return -EINVAL; | ||
1509 | + } | ||
1510 | + | ||
1511 | + currtimings = ¤t_csi2_cfg.timings[io - 1]; | ||
1512 | + currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; | ||
1513 | + if (currtimings->force_rx_mode != force_rx_mode) { | ||
1514 | + currtimings->force_rx_mode = force_rx_mode; | ||
1515 | + currtimings_u->force_rx_mode = true; | ||
1516 | + update_timing = true; | ||
1517 | + } | ||
1518 | + return 0; | ||
1519 | +} | ||
1520 | + | ||
1521 | +/** | ||
1522 | + * isp_csi2_timings_config_stopstate_16x - Sets 16x factor for L3 cycles | ||
1523 | + * @stop_state_16x: Boolean to use or not use the 16x multiplier for stop count | ||
1524 | + * | ||
1525 | + * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected. | ||
1526 | + **/ | ||
1527 | +int isp_csi2_timings_config_stopstate_16x(u8 io, bool stop_state_16x) | ||
1528 | +{ | ||
1529 | + struct isp_csi2_timings_cfg *currtimings; | ||
1530 | + struct isp_csi2_timings_cfg_update *currtimings_u; | ||
1531 | + | ||
1532 | + if (io < 1 || io > 2) { | ||
1533 | + printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); | ||
1534 | + return -EINVAL; | ||
1535 | + } | ||
1536 | + | ||
1537 | + currtimings = ¤t_csi2_cfg.timings[io - 1]; | ||
1538 | + currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; | ||
1539 | + if (currtimings->stop_state_16x != stop_state_16x) { | ||
1540 | + currtimings->stop_state_16x = stop_state_16x; | ||
1541 | + currtimings_u->stop_state_16x = true; | ||
1542 | + update_timing = true; | ||
1543 | + } | ||
1544 | + return 0; | ||
1545 | +} | ||
1546 | + | ||
1547 | +/** | ||
1548 | + * isp_csi2_timings_config_stopstate_4x - Sets 4x factor for L3 cycles | ||
1549 | + * @stop_state_4x: Boolean to use or not use the 4x multiplier for stop count | ||
1550 | + * | ||
1551 | + * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected. | ||
1552 | + **/ | ||
1553 | +int isp_csi2_timings_config_stopstate_4x(u8 io, bool stop_state_4x) | ||
1554 | +{ | ||
1555 | + struct isp_csi2_timings_cfg *currtimings; | ||
1556 | + struct isp_csi2_timings_cfg_update *currtimings_u; | ||
1557 | + | ||
1558 | + if (io < 1 || io > 2) { | ||
1559 | + printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); | ||
1560 | + return -EINVAL; | ||
1561 | + } | ||
1562 | + | ||
1563 | + currtimings = ¤t_csi2_cfg.timings[io - 1]; | ||
1564 | + currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; | ||
1565 | + if (currtimings->stop_state_4x != stop_state_4x) { | ||
1566 | + currtimings->stop_state_4x = stop_state_4x; | ||
1567 | + currtimings_u->stop_state_4x = true; | ||
1568 | + update_timing = true; | ||
1569 | + } | ||
1570 | + return 0; | ||
1571 | +} | ||
1572 | + | ||
1573 | +/** | ||
1574 | + * isp_csi2_timings_config_stopstate_cnt - Sets L3 cycles | ||
1575 | + * @stop_state_counter: Stop state counter value for L3 cycles | ||
1576 | + * | ||
1577 | + * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected. | ||
1578 | + **/ | ||
1579 | +int isp_csi2_timings_config_stopstate_cnt(u8 io, u16 stop_state_counter) | ||
1580 | +{ | ||
1581 | + struct isp_csi2_timings_cfg *currtimings; | ||
1582 | + struct isp_csi2_timings_cfg_update *currtimings_u; | ||
1583 | + | ||
1584 | + if (io < 1 || io > 2) { | ||
1585 | + printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); | ||
1586 | + return -EINVAL; | ||
1587 | + } | ||
1588 | + | ||
1589 | + currtimings = ¤t_csi2_cfg.timings[io - 1]; | ||
1590 | + currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; | ||
1591 | + if (currtimings->stop_state_counter != stop_state_counter) { | ||
1592 | + currtimings->stop_state_counter = (stop_state_counter & 0x1FFF); | ||
1593 | + currtimings_u->stop_state_counter = true; | ||
1594 | + update_timing = true; | ||
1595 | + } | ||
1596 | + return 0; | ||
1597 | +} | ||
1598 | + | ||
1599 | +/** | ||
1600 | + * isp_csi2_timings_update - Applies specified CSI2 timing configuration. | ||
1601 | + * @io: IO number (1 or 2) which specifies which ComplexIO are we updating | ||
1602 | + * @force_update: Flag to force rewrite of registers, even if they haven't been | ||
1603 | + * updated with the isp_csi2_timings_config_*() functions. | ||
1604 | + * | ||
1605 | + * It only saves settings when they were previously updated using the | ||
1606 | + * isp_csi2_timings_config_*() functions, unless the force_update flag is | ||
1607 | + * set to true. | ||
1608 | + * Returns 0 if successful, or -EINVAL if invalid IO number is passed. | ||
1609 | + **/ | ||
1610 | +int isp_csi2_timings_update(u8 io, bool force_update) | ||
1611 | +{ | ||
1612 | + struct isp_csi2_timings_cfg *currtimings; | ||
1613 | + struct isp_csi2_timings_cfg_update *currtimings_u; | ||
1614 | + u32 reg; | ||
1615 | + | ||
1616 | + if (io < 1 || io > 2) { | ||
1617 | + printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); | ||
1618 | + return -EINVAL; | ||
1619 | + } | ||
1620 | + | ||
1621 | + currtimings = ¤t_csi2_cfg.timings[io - 1]; | ||
1622 | + currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; | ||
1623 | + | ||
1624 | + if (update_timing || force_update) { | ||
1625 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING); | ||
1626 | + if (currtimings_u->force_rx_mode || force_update) { | ||
1627 | + reg &= ~ISPCSI2_TIMING_FORCE_RX_MODE_IO_MASK(io); | ||
1628 | + if (currtimings->force_rx_mode) | ||
1629 | + reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO_ENABLE | ||
1630 | + (io); | ||
1631 | + else | ||
1632 | + reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO_DISABLE | ||
1633 | + (io); | ||
1634 | + currtimings_u->force_rx_mode = false; | ||
1635 | + } | ||
1636 | + if (currtimings_u->stop_state_16x || force_update) { | ||
1637 | + reg &= ~ISPCSI2_TIMING_STOP_STATE_X16_IO_MASK(io); | ||
1638 | + if (currtimings->stop_state_16x) | ||
1639 | + reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO_ENABLE | ||
1640 | + (io); | ||
1641 | + else | ||
1642 | + reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO_DISABLE | ||
1643 | + (io); | ||
1644 | + currtimings_u->stop_state_16x = false; | ||
1645 | + } | ||
1646 | + if (currtimings_u->stop_state_4x || force_update) { | ||
1647 | + reg &= ~ISPCSI2_TIMING_STOP_STATE_X4_IO_MASK(io); | ||
1648 | + if (currtimings->stop_state_4x) { | ||
1649 | + reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO_ENABLE | ||
1650 | + (io); | ||
1651 | + } else { | ||
1652 | + reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO_DISABLE | ||
1653 | + (io); | ||
1654 | + } | ||
1655 | + currtimings_u->stop_state_4x = false; | ||
1656 | + } | ||
1657 | + if (currtimings_u->stop_state_counter || force_update) { | ||
1658 | + reg &= ~ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(io); | ||
1659 | + reg |= currtimings->stop_state_counter << | ||
1660 | + ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(io); | ||
1661 | + currtimings_u->stop_state_counter = false; | ||
1662 | + } | ||
1663 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING); | ||
1664 | + update_timing = false; | ||
1665 | + } | ||
1666 | + return 0; | ||
1667 | +} | ||
1668 | + | ||
1669 | +/** | ||
1670 | + * isp_csi2_timings_get - Gets specific CSI2 ComplexIO timing configuration | ||
1671 | + * @io: IO number (1 or 2) which specifies which ComplexIO are we getting | ||
1672 | + * | ||
1673 | + * Gets settings from HW registers and fills in the internal driver memory | ||
1674 | + * Returns 0 if successful, or -EINVAL if invalid IO number is passed. | ||
1675 | + **/ | ||
1676 | +int isp_csi2_timings_get(u8 io) | ||
1677 | +{ | ||
1678 | + struct isp_csi2_timings_cfg *currtimings; | ||
1679 | + struct isp_csi2_timings_cfg_update *currtimings_u; | ||
1680 | + u32 reg; | ||
1681 | + | ||
1682 | + if (io < 1 || io > 2) { | ||
1683 | + printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); | ||
1684 | + return -EINVAL; | ||
1685 | + } | ||
1686 | + | ||
1687 | + currtimings = ¤t_csi2_cfg.timings[io - 1]; | ||
1688 | + currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; | ||
1689 | + | ||
1690 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING); | ||
1691 | + if ((reg & ISPCSI2_TIMING_FORCE_RX_MODE_IO_MASK(io)) == | ||
1692 | + ISPCSI2_TIMING_FORCE_RX_MODE_IO_ENABLE(io)) | ||
1693 | + currtimings->force_rx_mode = true; | ||
1694 | + else | ||
1695 | + currtimings->force_rx_mode = false; | ||
1696 | + currtimings_u->force_rx_mode = false; | ||
1697 | + | ||
1698 | + if ((reg & ISPCSI2_TIMING_STOP_STATE_X16_IO_MASK(io)) == | ||
1699 | + ISPCSI2_TIMING_STOP_STATE_X16_IO_ENABLE(io)) | ||
1700 | + currtimings->stop_state_16x = true; | ||
1701 | + else | ||
1702 | + currtimings->stop_state_16x = false; | ||
1703 | + currtimings_u->stop_state_16x = false; | ||
1704 | + | ||
1705 | + if ((reg & ISPCSI2_TIMING_STOP_STATE_X4_IO_MASK(io)) == | ||
1706 | + ISPCSI2_TIMING_STOP_STATE_X4_IO_ENABLE(io)) | ||
1707 | + currtimings->stop_state_4x = true; | ||
1708 | + else | ||
1709 | + currtimings->stop_state_4x = false; | ||
1710 | + currtimings_u->stop_state_4x = false; | ||
1711 | + | ||
1712 | + currtimings->stop_state_counter = (reg & | ||
1713 | + ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(io)) >> | ||
1714 | + ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(io); | ||
1715 | + currtimings_u->stop_state_counter = false; | ||
1716 | + update_timing = false; | ||
1717 | + return 0; | ||
1718 | +} | ||
1719 | + | ||
1720 | +/** | ||
1721 | + * isp_csi2_timings_update_all - Applies specified CSI2 timing configuration. | ||
1722 | + * @force_update: Flag to force rewrite of registers, even if they haven't been | ||
1723 | + * updated with the isp_csi2_timings_config_*() functions. | ||
1724 | + * | ||
1725 | + * It only saves settings when they were previously updated using the | ||
1726 | + * isp_csi2_timings_config_*() functions, unless the force_update flag is | ||
1727 | + * set to true. | ||
1728 | + * Always returns 0. | ||
1729 | + **/ | ||
1730 | +int isp_csi2_timings_update_all(bool force_update) | ||
1731 | +{ | ||
1732 | + int i; | ||
1733 | + | ||
1734 | + for (i = 1; i < 3; i++) | ||
1735 | + isp_csi2_timings_update(i, force_update); | ||
1736 | + return 0; | ||
1737 | +} | ||
1738 | + | ||
1739 | +/** | ||
1740 | + * isp_csi2_timings_get_all - Gets all CSI2 ComplexIO timing configurations | ||
1741 | + * | ||
1742 | + * Always returns 0. | ||
1743 | + **/ | ||
1744 | +int isp_csi2_timings_get_all(void) | ||
1745 | +{ | ||
1746 | + int i; | ||
1747 | + | ||
1748 | + for (i = 1; i < 3; i++) | ||
1749 | + isp_csi2_timings_get(i); | ||
1750 | + return 0; | ||
1751 | +} | ||
1752 | + | ||
1753 | +/** | ||
1754 | + * isp_csi2_isr - CSI2 interrupt handling. | ||
1755 | + **/ | ||
1756 | +void isp_csi2_isr(void) | ||
1757 | +{ | ||
1758 | + u32 csi2_irqstatus, cpxio1_irqstatus, ctxirqstatus; | ||
1759 | + | ||
1760 | + csi2_irqstatus = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1761 | + ISPCSI2_IRQSTATUS); | ||
1762 | + isp_reg_writel(csi2_irqstatus, OMAP3_ISP_IOMEM_CSI2A, | ||
1763 | + ISPCSI2_IRQSTATUS); | ||
1764 | + | ||
1765 | + if (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ) { | ||
1766 | + cpxio1_irqstatus = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1767 | + ISPCSI2_COMPLEXIO1_IRQSTATUS); | ||
1768 | + isp_reg_writel(cpxio1_irqstatus, OMAP3_ISP_IOMEM_CSI2A, | ||
1769 | + ISPCSI2_COMPLEXIO1_IRQSTATUS); | ||
1770 | + printk(KERN_ERR "CSI2: ComplexIO Error IRQ %x\n", | ||
1771 | + cpxio1_irqstatus); | ||
1772 | + } | ||
1773 | + | ||
1774 | + if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0)) { | ||
1775 | + ctxirqstatus = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1776 | + ISPCSI2_CTX_IRQSTATUS(0)); | ||
1777 | + isp_reg_writel(ctxirqstatus, OMAP3_ISP_IOMEM_CSI2A, | ||
1778 | + ISPCSI2_CTX_IRQSTATUS(0)); | ||
1779 | + } | ||
1780 | + | ||
1781 | + if (csi2_irqstatus & ISPCSI2_IRQSTATUS_OCP_ERR_IRQ) | ||
1782 | + printk(KERN_ERR "CSI2: OCP Transmission Error\n"); | ||
1783 | + | ||
1784 | + if (csi2_irqstatus & ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ) | ||
1785 | + printk(KERN_ERR "CSI2: Short packet receive error\n"); | ||
1786 | + | ||
1787 | + if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ) | ||
1788 | + printk(KERN_DEBUG "CSI2: ECC correction done\n"); | ||
1789 | + | ||
1790 | + if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ) | ||
1791 | + printk(KERN_ERR "CSI2: ECC correction failed\n"); | ||
1792 | + | ||
1793 | + if (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ) | ||
1794 | + printk(KERN_ERR "CSI2: ComplexIO #2 failed\n"); | ||
1795 | + | ||
1796 | + if (csi2_irqstatus & ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ) | ||
1797 | + printk(KERN_ERR "CSI2: FIFO overflow error\n"); | ||
1798 | + | ||
1799 | + return; | ||
1800 | +} | ||
1801 | +EXPORT_SYMBOL(isp_csi2_isr); | ||
1802 | + | ||
1803 | +/** | ||
1804 | + * isp_csi2_irq_complexio1_set - Enables CSI2 ComplexIO IRQs. | ||
1805 | + * @enable: Enable/disable CSI2 ComplexIO #1 interrupts | ||
1806 | + **/ | ||
1807 | +void isp_csi2_irq_complexio1_set(int enable) | ||
1808 | +{ | ||
1809 | + u32 reg; | ||
1810 | + reg = ISPCSI2_COMPLEXIO1_IRQENABLE_STATEALLULPMEXIT | | ||
1811 | + ISPCSI2_COMPLEXIO1_IRQENABLE_STATEALLULPMENTER | | ||
1812 | + ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM5 | | ||
1813 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL5 | | ||
1814 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC5 | | ||
1815 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS5 | | ||
1816 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS5 | | ||
1817 | + ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM4 | | ||
1818 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL4 | | ||
1819 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC4 | | ||
1820 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS4 | | ||
1821 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS4 | | ||
1822 | + ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM3 | | ||
1823 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL3 | | ||
1824 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC3 | | ||
1825 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS3 | | ||
1826 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS3 | | ||
1827 | + ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM2 | | ||
1828 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL2 | | ||
1829 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC2 | | ||
1830 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS2 | | ||
1831 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS2 | | ||
1832 | + ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM1 | | ||
1833 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL1 | | ||
1834 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC1 | | ||
1835 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS1 | | ||
1836 | + ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS1; | ||
1837 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, | ||
1838 | + ISPCSI2_COMPLEXIO1_IRQSTATUS); | ||
1839 | + if (enable) { | ||
1840 | + reg |= isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
1841 | + ISPCSI2_COMPLEXIO1_IRQENABLE); | ||
1842 | + } else | ||
1843 | + reg = 0; | ||
1844 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, | ||
1845 | + ISPCSI2_COMPLEXIO1_IRQENABLE); | ||
1846 | +} | ||
1847 | +EXPORT_SYMBOL(isp_csi2_irq_complexio1_set); | ||
1848 | + | ||
1849 | +/** | ||
1850 | + * isp_csi2_irq_ctx_set - Enables CSI2 Context IRQs. | ||
1851 | + * @enable: Enable/disable CSI2 Context interrupts | ||
1852 | + **/ | ||
1853 | +void isp_csi2_irq_ctx_set(int enable) | ||
1854 | +{ | ||
1855 | + u32 reg; | ||
1856 | + int i; | ||
1857 | + | ||
1858 | + reg = ISPCSI2_CTX_IRQSTATUS_FS_IRQ | ISPCSI2_CTX_IRQSTATUS_FE_IRQ; | ||
1859 | + for (i = 0; i < 8; i++) { | ||
1860 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, | ||
1861 | + ISPCSI2_CTX_IRQSTATUS(i)); | ||
1862 | + if (enable) { | ||
1863 | + isp_reg_or(OMAP3_ISP_IOMEM_CSI2A, | ||
1864 | + ISPCSI2_CTX_IRQENABLE(i), reg); | ||
1865 | + } else { | ||
1866 | + isp_reg_writel(0, OMAP3_ISP_IOMEM_CSI2A, | ||
1867 | + ISPCSI2_CTX_IRQENABLE(i)); | ||
1868 | + } | ||
1869 | + } | ||
1870 | + | ||
1871 | +} | ||
1872 | +EXPORT_SYMBOL(isp_csi2_irq_ctx_set); | ||
1873 | + | ||
1874 | +/** | ||
1875 | + * isp_csi2_irq_status_set - Enables CSI2 Status IRQs. | ||
1876 | + * @enable: Enable/disable CSI2 Status interrupts | ||
1877 | + **/ | ||
1878 | +void isp_csi2_irq_status_set(int enable) | ||
1879 | +{ | ||
1880 | + u32 reg; | ||
1881 | + reg = ISPCSI2_IRQSTATUS_OCP_ERR_IRQ | | ||
1882 | + ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ | | ||
1883 | + ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ | | ||
1884 | + ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ | | ||
1885 | + ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ | | ||
1886 | + ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ | | ||
1887 | + ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ | | ||
1888 | + ISPCSI2_IRQSTATUS_CONTEXT(0); | ||
1889 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_IRQSTATUS); | ||
1890 | + if (enable) | ||
1891 | + reg |= isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_IRQENABLE); | ||
1892 | + else | ||
1893 | + reg = 0; | ||
1894 | + | ||
1895 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_IRQENABLE); | ||
1896 | +} | ||
1897 | +EXPORT_SYMBOL(isp_csi2_irq_status_set); | ||
1898 | + | ||
1899 | +/** | ||
1900 | + * isp_csi2_irq_status_set - Enables main CSI2 IRQ. | ||
1901 | + * @enable: Enable/disable main CSI2 interrupt | ||
1902 | + **/ | ||
1903 | +void isp_csi2_irq_set(int enable) | ||
1904 | +{ | ||
1905 | + isp_reg_writel(IRQ0STATUS_CSIA_IRQ, OMAP3_ISP_IOMEM_MAIN, | ||
1906 | + ISP_IRQ0STATUS); | ||
1907 | + isp_reg_and_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, | ||
1908 | + ~IRQ0ENABLE_CSIA_IRQ, | ||
1909 | + (enable ? IRQ0ENABLE_CSIA_IRQ : 0)); | ||
1910 | +} | ||
1911 | +EXPORT_SYMBOL(isp_csi2_irq_set); | ||
1912 | + | ||
1913 | +/** | ||
1914 | + * isp_csi2_irq_all_set - Enable/disable CSI2 interrupts. | ||
1915 | + * @enable: 0-Disable, 1-Enable. | ||
1916 | + **/ | ||
1917 | +void isp_csi2_irq_all_set(int enable) | ||
1918 | +{ | ||
1919 | + if (enable) { | ||
1920 | + isp_csi2_irq_complexio1_set(enable); | ||
1921 | + isp_csi2_irq_ctx_set(enable); | ||
1922 | + isp_csi2_irq_status_set(enable); | ||
1923 | + isp_csi2_irq_set(enable); | ||
1924 | + } else { | ||
1925 | + isp_csi2_irq_set(enable); | ||
1926 | + isp_csi2_irq_status_set(enable); | ||
1927 | + isp_csi2_irq_ctx_set(enable); | ||
1928 | + isp_csi2_irq_complexio1_set(enable); | ||
1929 | + } | ||
1930 | + return; | ||
1931 | +} | ||
1932 | +EXPORT_SYMBOL(isp_csi2_irq_all_set); | ||
1933 | + | ||
1934 | +/** | ||
1935 | + * isp_csi2_reset - Resets the CSI2 module. | ||
1936 | + * | ||
1937 | + * Returns 0 if successful, or -EBUSY if power command didn't respond. | ||
1938 | + **/ | ||
1939 | +int isp_csi2_reset(void) | ||
1940 | +{ | ||
1941 | + u32 reg; | ||
1942 | + u8 soft_reset_retries = 0; | ||
1943 | + int i; | ||
1944 | + | ||
1945 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG); | ||
1946 | + reg |= ISPCSI2_SYSCONFIG_SOFT_RESET_RESET; | ||
1947 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG); | ||
1948 | + | ||
1949 | + do { | ||
1950 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSSTATUS) & | ||
1951 | + ISPCSI2_SYSSTATUS_RESET_DONE_MASK; | ||
1952 | + if (reg == ISPCSI2_SYSSTATUS_RESET_DONE_DONE) | ||
1953 | + break; | ||
1954 | + soft_reset_retries++; | ||
1955 | + if (soft_reset_retries < 5) | ||
1956 | + udelay(100); | ||
1957 | + } while (soft_reset_retries < 5); | ||
1958 | + | ||
1959 | + if (soft_reset_retries == 5) { | ||
1960 | + printk(KERN_ERR "CSI2: Soft reset try count exceeded!\n"); | ||
1961 | + return -EBUSY; | ||
1962 | + } | ||
1963 | + | ||
1964 | + reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG); | ||
1965 | + reg &= ~ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK; | ||
1966 | + reg |= ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO; | ||
1967 | + reg &= ~ISPCSI2_SYSCONFIG_AUTO_IDLE_MASK; | ||
1968 | + isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG); | ||
1969 | + | ||
1970 | + uses_videoport = false; | ||
1971 | + update_complexio_cfg1 = false; | ||
1972 | + update_phy_cfg0 = false; | ||
1973 | + update_phy_cfg1 = false; | ||
1974 | + for (i = 0; i < 8; i++) { | ||
1975 | + update_ctx_ctrl1[i] = false; | ||
1976 | + update_ctx_ctrl2[i] = false; | ||
1977 | + update_ctx_ctrl3[i] = false; | ||
1978 | + } | ||
1979 | + update_timing = false; | ||
1980 | + update_ctrl = false; | ||
1981 | + | ||
1982 | + isp_csi2_complexio_lanes_get(); | ||
1983 | + isp_csi2_ctrl_get(); | ||
1984 | + isp_csi2_ctx_get_all(); | ||
1985 | + isp_csi2_phy_get(); | ||
1986 | + isp_csi2_timings_get_all(); | ||
1987 | + | ||
1988 | + isp_csi2_complexio_power_autoswitch(true); | ||
1989 | + isp_csi2_complexio_power(ISP_CSI2_POWER_ON); | ||
1990 | + | ||
1991 | + isp_csi2_timings_config_forcerxmode(1, true); | ||
1992 | + isp_csi2_timings_config_stopstate_cnt(1, 0x1FF); | ||
1993 | + isp_csi2_timings_update_all(true); | ||
1994 | + | ||
1995 | + return 0; | ||
1996 | +} | ||
1997 | + | ||
1998 | +/** | ||
1999 | + * isp_csi2_enable - Enables the CSI2 module. | ||
2000 | + * @enable: Enables/disables the CSI2 module. | ||
2001 | + **/ | ||
2002 | +void isp_csi2_enable(int enable) | ||
2003 | +{ | ||
2004 | + if (enable) { | ||
2005 | + isp_csi2_ctx_config_enabled(0, true); | ||
2006 | + isp_csi2_ctx_config_eof_enabled(0, true); | ||
2007 | + isp_csi2_ctx_config_checksum_enabled(0, true); | ||
2008 | + isp_csi2_ctx_update(0, false); | ||
2009 | + | ||
2010 | + isp_csi2_ctrl_config_ecc_enable(true); | ||
2011 | + isp_csi2_ctrl_config_if_enable(true); | ||
2012 | + isp_csi2_ctrl_update(false); | ||
2013 | + } else { | ||
2014 | + isp_csi2_ctx_config_enabled(0, false); | ||
2015 | + isp_csi2_ctx_config_eof_enabled(0, false); | ||
2016 | + isp_csi2_ctx_config_checksum_enabled(0, false); | ||
2017 | + isp_csi2_ctx_update(0, false); | ||
2018 | + | ||
2019 | + isp_csi2_ctrl_config_ecc_enable(false); | ||
2020 | + isp_csi2_ctrl_config_if_enable(false); | ||
2021 | + isp_csi2_ctrl_update(false); | ||
2022 | + } | ||
2023 | +} | ||
2024 | +EXPORT_SYMBOL(isp_csi2_enable); | ||
2025 | + | ||
2026 | +/** | ||
2027 | + * isp_csi2_regdump - Prints CSI2 debug information. | ||
2028 | + **/ | ||
2029 | +void isp_csi2_regdump(void) | ||
2030 | +{ | ||
2031 | + printk(KERN_DEBUG "-------------Register dump-------------\n"); | ||
2032 | + | ||
2033 | + printk(KERN_DEBUG "ISP_CTRL: %x\n", | ||
2034 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL)); | ||
2035 | + printk(KERN_DEBUG "ISP_TCTRL_CTRL: %x\n", | ||
2036 | + isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL)); | ||
2037 | + | ||
2038 | + printk(KERN_DEBUG "ISPCCDC_SDR_ADDR: %x\n", | ||
2039 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR)); | ||
2040 | + printk(KERN_DEBUG "ISPCCDC_SYN_MODE: %x\n", | ||
2041 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE)); | ||
2042 | + printk(KERN_DEBUG "ISPCCDC_CFG: %x\n", | ||
2043 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG)); | ||
2044 | + printk(KERN_DEBUG "ISPCCDC_FMTCFG: %x\n", | ||
2045 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG)); | ||
2046 | + printk(KERN_DEBUG "ISPCCDC_HSIZE_OFF: %x\n", | ||
2047 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF)); | ||
2048 | + printk(KERN_DEBUG "ISPCCDC_HORZ_INFO: %x\n", | ||
2049 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO)); | ||
2050 | + printk(KERN_DEBUG "ISPCCDC_VERT_START: %x\n", | ||
2051 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, | ||
2052 | + ISPCCDC_VERT_START)); | ||
2053 | + printk(KERN_DEBUG "ISPCCDC_VERT_LINES: %x\n", | ||
2054 | + isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, | ||
2055 | + ISPCCDC_VERT_LINES)); | ||
2056 | + | ||
2057 | + printk(KERN_DEBUG "ISPCSI2_COMPLEXIO_CFG1: %x\n", | ||
2058 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2059 | + ISPCSI2_COMPLEXIO_CFG1)); | ||
2060 | + printk(KERN_DEBUG "ISPCSI2_SYSSTATUS: %x\n", | ||
2061 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2062 | + ISPCSI2_SYSSTATUS)); | ||
2063 | + printk(KERN_DEBUG "ISPCSI2_SYSCONFIG: %x\n", | ||
2064 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2065 | + ISPCSI2_SYSCONFIG)); | ||
2066 | + printk(KERN_DEBUG "ISPCSI2_IRQENABLE: %x\n", | ||
2067 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2068 | + ISPCSI2_IRQENABLE)); | ||
2069 | + printk(KERN_DEBUG "ISPCSI2_IRQSTATUS: %x\n", | ||
2070 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2071 | + ISPCSI2_IRQSTATUS)); | ||
2072 | + | ||
2073 | + printk(KERN_DEBUG "ISPCSI2_CTX_IRQENABLE(0): %x\n", | ||
2074 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2075 | + ISPCSI2_CTX_IRQENABLE(0))); | ||
2076 | + printk(KERN_DEBUG "ISPCSI2_CTX_IRQSTATUS(0): %x\n", | ||
2077 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2078 | + ISPCSI2_CTX_IRQSTATUS(0))); | ||
2079 | + printk(KERN_DEBUG "ISPCSI2_TIMING: %x\n", | ||
2080 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING)); | ||
2081 | + printk(KERN_DEBUG "ISPCSI2PHY_CFG0: %x\n", | ||
2082 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, | ||
2083 | + ISPCSI2PHY_CFG0)); | ||
2084 | + printk(KERN_DEBUG "ISPCSI2PHY_CFG1: %x\n", | ||
2085 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, | ||
2086 | + ISPCSI2PHY_CFG1)); | ||
2087 | + printk(KERN_DEBUG "ISPCSI2_CTX_CTRL1(0): %x\n", | ||
2088 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2089 | + ISPCSI2_CTX_CTRL1(0))); | ||
2090 | + printk(KERN_DEBUG "ISPCSI2_CTX_CTRL2(0): %x\n", | ||
2091 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2092 | + ISPCSI2_CTX_CTRL2(0))); | ||
2093 | + printk(KERN_DEBUG "ISPCSI2_CTX_CTRL3(0): %x\n", | ||
2094 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2095 | + ISPCSI2_CTX_CTRL3(0))); | ||
2096 | + printk(KERN_DEBUG "ISPCSI2_CTX_DAT_OFST(0): %x\n", | ||
2097 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2098 | + ISPCSI2_CTX_DAT_OFST(0))); | ||
2099 | + printk(KERN_DEBUG "ISPCSI2_CTX_DAT_PING_ADDR(0): %x\n", | ||
2100 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2101 | + ISPCSI2_CTX_DAT_PING_ADDR(0))); | ||
2102 | + printk(KERN_DEBUG "ISPCSI2_CTX_DAT_PONG_ADDR(0): %x\n", | ||
2103 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, | ||
2104 | + ISPCSI2_CTX_DAT_PONG_ADDR(0))); | ||
2105 | + printk(KERN_DEBUG "ISPCSI2_CTRL: %x\n", | ||
2106 | + isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL)); | ||
2107 | + printk(KERN_DEBUG "---------------------------------------\n"); | ||
2108 | +} | ||
2109 | + | ||
2110 | +/** | ||
2111 | + * isp_csi2_cleanup - Routine for module driver cleanup | ||
2112 | + **/ | ||
2113 | +void isp_csi2_cleanup(void) | ||
2114 | +{ | ||
2115 | + return; | ||
2116 | +} | ||
2117 | + | ||
2118 | +/** | ||
2119 | + * isp_csi2_init - Routine for module driver init | ||
2120 | + **/ | ||
2121 | +int __init isp_csi2_init(void) | ||
2122 | +{ | ||
2123 | + int i; | ||
2124 | + | ||
2125 | + update_complexio_cfg1 = false; | ||
2126 | + update_phy_cfg0 = false; | ||
2127 | + update_phy_cfg1 = false; | ||
2128 | + for (i = 0; i < 8; i++) { | ||
2129 | + update_ctx_ctrl1[i] = false; | ||
2130 | + update_ctx_ctrl2[i] = false; | ||
2131 | + update_ctx_ctrl3[i] = false; | ||
2132 | + } | ||
2133 | + update_timing = false; | ||
2134 | + update_ctrl = false; | ||
2135 | + | ||
2136 | + memset(¤t_csi2_cfg, 0, sizeof(current_csi2_cfg)); | ||
2137 | + memset(¤t_csi2_cfg_update, 0, sizeof(current_csi2_cfg_update)); | ||
2138 | + return 0; | ||
2139 | +} | ||
2140 | + | ||
2141 | +MODULE_AUTHOR("Texas Instruments"); | ||
2142 | +MODULE_DESCRIPTION("ISP CSI2 Receiver Module"); | ||
2143 | +MODULE_LICENSE("GPL"); | ||
2144 | diff --git a/drivers/media/video/isp/ispcsi2.h b/drivers/media/video/isp/ispcsi2.h | ||
2145 | new file mode 100644 | ||
2146 | index 0000000..4582c96 | ||
2147 | --- /dev/null | ||
2148 | +++ b/drivers/media/video/isp/ispcsi2.h | ||
2149 | @@ -0,0 +1,232 @@ | ||
2150 | +/* | ||
2151 | + * ispcsi2.h | ||
2152 | + * | ||
2153 | + * Copyright (C) 2009 Texas Instruments. | ||
2154 | + * | ||
2155 | + * Contributors: | ||
2156 | + * Sergio Aguirre <saaguirre@ti.com> | ||
2157 | + * Dominic Curran <dcurran@ti.com> | ||
2158 | + * | ||
2159 | + * This package is free software; you can redistribute it and/or modify | ||
2160 | + * it under the terms of the GNU General Public License version 2 as | ||
2161 | + * published by the Free Software Foundation. | ||
2162 | + * | ||
2163 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
2164 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
2165 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
2166 | + */ | ||
2167 | + | ||
2168 | +#ifndef OMAP_ISP_CSI2_API_H | ||
2169 | +#define OMAP_ISP_CSI2_API_H | ||
2170 | +#include <linux/videodev2.h> | ||
2171 | + | ||
2172 | +enum isp_csi2_irqevents { | ||
2173 | + OCP_ERR_IRQ = 0x4000, | ||
2174 | + SHORT_PACKET_IRQ = 0x2000, | ||
2175 | + ECC_CORRECTION_IRQ = 0x1000, | ||
2176 | + ECC_NO_CORRECTION_IRQ = 0x800, | ||
2177 | + COMPLEXIO2_ERR_IRQ = 0x400, | ||
2178 | + COMPLEXIO1_ERR_IRQ = 0x200, | ||
2179 | + FIFO_OVF_IRQ = 0x100, | ||
2180 | + CONTEXT7 = 0x80, | ||
2181 | + CONTEXT6 = 0x40, | ||
2182 | + CONTEXT5 = 0x20, | ||
2183 | + CONTEXT4 = 0x10, | ||
2184 | + CONTEXT3 = 0x8, | ||
2185 | + CONTEXT2 = 0x4, | ||
2186 | + CONTEXT1 = 0x2, | ||
2187 | + CONTEXT0 = 0x1, | ||
2188 | +}; | ||
2189 | + | ||
2190 | +enum isp_csi2_ctx_irqevents { | ||
2191 | + CTX_ECC_CORRECTION = 0x100, | ||
2192 | + CTX_LINE_NUMBER = 0x80, | ||
2193 | + CTX_FRAME_NUMBER = 0x40, | ||
2194 | + CTX_CS = 0x20, | ||
2195 | + CTX_LE = 0x8, | ||
2196 | + CTX_LS = 0x4, | ||
2197 | + CTX_FE = 0x2, | ||
2198 | + CTX_FS = 0x1, | ||
2199 | +}; | ||
2200 | + | ||
2201 | +enum isp_csi2_power_cmds { | ||
2202 | + ISP_CSI2_POWER_OFF, | ||
2203 | + ISP_CSI2_POWER_ON, | ||
2204 | + ISP_CSI2_POWER_ULPW, | ||
2205 | +}; | ||
2206 | + | ||
2207 | +enum isp_csi2_frame_mode { | ||
2208 | + ISP_CSI2_FRAME_IMMEDIATE, | ||
2209 | + ISP_CSI2_FRAME_AFTERFEC, | ||
2210 | +}; | ||
2211 | + | ||
2212 | +struct csi2_lanecfg { | ||
2213 | + u8 pos; | ||
2214 | + u8 pol; | ||
2215 | +}; | ||
2216 | + | ||
2217 | +struct isp_csi2_lanes_cfg { | ||
2218 | + struct csi2_lanecfg data[4]; | ||
2219 | + struct csi2_lanecfg clk; | ||
2220 | +}; | ||
2221 | + | ||
2222 | +struct isp_csi2_lanes_cfg_update { | ||
2223 | + bool data[4]; | ||
2224 | + bool clk; | ||
2225 | +}; | ||
2226 | + | ||
2227 | +struct isp_csi2_phy_cfg { | ||
2228 | + u8 ths_term; | ||
2229 | + u8 ths_settle; | ||
2230 | + u8 tclk_term; | ||
2231 | + unsigned tclk_miss:1; | ||
2232 | + u8 tclk_settle; | ||
2233 | +}; | ||
2234 | + | ||
2235 | +struct isp_csi2_phy_cfg_update { | ||
2236 | + bool ths_term; | ||
2237 | + bool ths_settle; | ||
2238 | + bool tclk_term; | ||
2239 | + bool tclk_miss; | ||
2240 | + bool tclk_settle; | ||
2241 | +}; | ||
2242 | + | ||
2243 | +struct isp_csi2_ctx_cfg { | ||
2244 | + u8 virtual_id; | ||
2245 | + u8 frame_count; | ||
2246 | + struct v4l2_pix_format format; | ||
2247 | + u16 alpha; | ||
2248 | + u16 data_offset; | ||
2249 | + u32 ping_addr; | ||
2250 | + u32 pong_addr; | ||
2251 | + bool eof_enabled; | ||
2252 | + bool eol_enabled; | ||
2253 | + bool checksum_enabled; | ||
2254 | + bool enabled; | ||
2255 | +}; | ||
2256 | + | ||
2257 | +struct isp_csi2_ctx_cfg_update { | ||
2258 | + bool virtual_id; | ||
2259 | + bool frame_count; | ||
2260 | + bool format; | ||
2261 | + bool alpha; | ||
2262 | + bool data_offset; | ||
2263 | + bool ping_addr; | ||
2264 | + bool pong_addr; | ||
2265 | + bool eof_enabled; | ||
2266 | + bool eol_enabled; | ||
2267 | + bool checksum_enabled; | ||
2268 | + bool enabled; | ||
2269 | +}; | ||
2270 | + | ||
2271 | +struct isp_csi2_timings_cfg { | ||
2272 | + bool force_rx_mode; | ||
2273 | + bool stop_state_16x; | ||
2274 | + bool stop_state_4x; | ||
2275 | + u16 stop_state_counter; | ||
2276 | +}; | ||
2277 | + | ||
2278 | +struct isp_csi2_timings_cfg_update { | ||
2279 | + bool force_rx_mode; | ||
2280 | + bool stop_state_16x; | ||
2281 | + bool stop_state_4x; | ||
2282 | + bool stop_state_counter; | ||
2283 | +}; | ||
2284 | + | ||
2285 | +struct isp_csi2_ctrl_cfg { | ||
2286 | + bool vp_clk_enable; | ||
2287 | + bool vp_only_enable; | ||
2288 | + u8 vp_out_ctrl; | ||
2289 | + bool debug_enable; | ||
2290 | + u8 burst_size; | ||
2291 | + enum isp_csi2_frame_mode frame_mode; | ||
2292 | + bool ecc_enable; | ||
2293 | + bool secure_mode; | ||
2294 | + bool if_enable; | ||
2295 | +}; | ||
2296 | + | ||
2297 | +struct isp_csi2_ctrl_cfg_update { | ||
2298 | + bool vp_clk_enable; | ||
2299 | + bool vp_only_enable; | ||
2300 | + bool vp_out_ctrl; | ||
2301 | + bool debug_enable; | ||
2302 | + bool burst_size; | ||
2303 | + bool frame_mode; | ||
2304 | + bool ecc_enable; | ||
2305 | + bool secure_mode; | ||
2306 | + bool if_enable; | ||
2307 | +}; | ||
2308 | + | ||
2309 | +struct isp_csi2_cfg { | ||
2310 | + struct isp_csi2_lanes_cfg lanes; | ||
2311 | + struct isp_csi2_phy_cfg phy; | ||
2312 | + struct isp_csi2_ctx_cfg contexts[8]; | ||
2313 | + struct isp_csi2_timings_cfg timings[2]; | ||
2314 | + struct isp_csi2_ctrl_cfg ctrl; | ||
2315 | +}; | ||
2316 | + | ||
2317 | +struct isp_csi2_cfg_update { | ||
2318 | + struct isp_csi2_lanes_cfg_update lanes; | ||
2319 | + struct isp_csi2_phy_cfg_update phy; | ||
2320 | + struct isp_csi2_ctx_cfg_update contexts[8]; | ||
2321 | + struct isp_csi2_timings_cfg_update timings[2]; | ||
2322 | + struct isp_csi2_ctrl_cfg_update ctrl; | ||
2323 | +}; | ||
2324 | + | ||
2325 | +int isp_csi2_complexio_lanes_config(struct isp_csi2_lanes_cfg *reqcfg); | ||
2326 | +int isp_csi2_complexio_lanes_update(bool force_update); | ||
2327 | +int isp_csi2_complexio_lanes_get(void); | ||
2328 | +int isp_csi2_complexio_power_autoswitch(bool enable); | ||
2329 | +int isp_csi2_complexio_power(enum isp_csi2_power_cmds power_cmd); | ||
2330 | +int isp_csi2_ctrl_config_frame_mode(enum isp_csi2_frame_mode frame_mode); | ||
2331 | +int isp_csi2_ctrl_config_vp_clk_enable(bool vp_clk_enable); | ||
2332 | +int isp_csi2_ctrl_config_vp_only_enable(bool vp_only_enable); | ||
2333 | +int isp_csi2_ctrl_config_debug_enable(bool debug_enable); | ||
2334 | +int isp_csi2_ctrl_config_burst_size(u8 burst_size); | ||
2335 | +int isp_csi2_ctrl_config_ecc_enable(bool ecc_enable); | ||
2336 | +int isp_csi2_ctrl_config_secure_mode(bool secure_mode); | ||
2337 | +int isp_csi2_ctrl_config_if_enable(bool if_enable); | ||
2338 | +int isp_csi2_ctrl_config_vp_out_ctrl(u8 vp_out_ctrl); | ||
2339 | +int isp_csi2_ctrl_update(bool force_update); | ||
2340 | +int isp_csi2_ctrl_get(void); | ||
2341 | +int isp_csi2_ctx_config_virtual_id(u8 ctxnum, u8 virtual_id); | ||
2342 | +int isp_csi2_ctx_config_frame_count(u8 ctxnum, u8 frame_count); | ||
2343 | +int isp_csi2_ctx_config_format(u8 ctxnum, u32 pixformat); | ||
2344 | +int isp_csi2_ctx_config_alpha(u8 ctxnum, u16 alpha); | ||
2345 | +int isp_csi2_ctx_config_data_offset(u8 ctxnum, u16 data_offset); | ||
2346 | +int isp_csi2_ctx_config_ping_addr(u8 ctxnum, u32 ping_addr); | ||
2347 | +int isp_csi2_ctx_config_pong_addr(u8 ctxnum, u32 pong_addr); | ||
2348 | +int isp_csi2_ctx_config_eof_enabled(u8 ctxnum, bool eof_enabled); | ||
2349 | +int isp_csi2_ctx_config_eol_enabled(u8 ctxnum, bool eol_enabled); | ||
2350 | +int isp_csi2_ctx_config_checksum_enabled(u8 ctxnum, bool checksum_enabled); | ||
2351 | +int isp_csi2_ctx_config_enabled(u8 ctxnum, bool enabled); | ||
2352 | +int isp_csi2_ctx_update(u8 ctxnum, bool force_update); | ||
2353 | +int isp_csi2_ctx_get(u8 ctxnum); | ||
2354 | +int isp_csi2_ctx_update_all(bool force_update); | ||
2355 | +int isp_csi2_ctx_get_all(void); | ||
2356 | +int isp_csi2_phy_config(struct isp_csi2_phy_cfg *desiredphyconfig); | ||
2357 | +int isp_csi2_calc_phy_cfg0(u32 mipiclk, u32 lbound_hs_settle, | ||
2358 | + u32 ubound_hs_settle); | ||
2359 | +int isp_csi2_phy_update(bool force_update); | ||
2360 | +int isp_csi2_phy_get(void); | ||
2361 | +int isp_csi2_timings_config_forcerxmode(u8 io, bool force_rx_mode); | ||
2362 | +int isp_csi2_timings_config_stopstate_16x(u8 io, bool stop_state_16x); | ||
2363 | +int isp_csi2_timings_config_stopstate_4x(u8 io, bool stop_state_4x); | ||
2364 | +int isp_csi2_timings_config_stopstate_cnt(u8 io, u16 stop_state_counter); | ||
2365 | +int isp_csi2_timings_update(u8 io, bool force_update); | ||
2366 | +int isp_csi2_timings_get(u8 io); | ||
2367 | +int isp_csi2_timings_update_all(bool force_update); | ||
2368 | +int isp_csi2_timings_get_all(void); | ||
2369 | +void isp_csi2_irq_complexio1_set(int enable); | ||
2370 | +void isp_csi2_irq_ctx_set(int enable); | ||
2371 | +void isp_csi2_irq_status_set(int enable); | ||
2372 | +void isp_csi2_irq_set(int enable); | ||
2373 | +void isp_csi2_irq_all_set(int enable); | ||
2374 | + | ||
2375 | +void isp_csi2_isr(void); | ||
2376 | +int isp_csi2_reset(void); | ||
2377 | +void isp_csi2_enable(int enable); | ||
2378 | +void isp_csi2_regdump(void); | ||
2379 | + | ||
2380 | +#endif /* OMAP_ISP_CSI2_H */ | ||
2381 | + | ||
2382 | -- | ||
2383 | 1.5.6.5 | ||
2384 | |||
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0008-omap3isp-Add-ISP-tables.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0008-omap3isp-Add-ISP-tables.patch new file mode 100644 index 0000000000..db023e514d --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0008-omap3isp-Add-ISP-tables.patch | |||
@@ -0,0 +1,4018 @@ | |||
1 | From 5de7cb2cac5f7d76cb025ddc8fb09c99a1007e08 Mon Sep 17 00:00:00 2001 | ||
2 | From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
3 | Date: Tue, 10 Mar 2009 10:49:02 +0200 | ||
4 | Subject: [PATCH] omap3isp: Add ISP tables | ||
5 | |||
6 | * Blue Gamma gain table | ||
7 | * CFA gain table | ||
8 | * Green Gamma gain table | ||
9 | * Luma Enhancement gain table | ||
10 | * Noise filter gain table | ||
11 | * Red Gamma gain table | ||
12 | |||
13 | TODO: | ||
14 | |||
15 | - Get rid of this kind of tables. Either generate them at runtime or | ||
16 | use a user space program to fill defaults. | ||
17 | |||
18 | Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
19 | --- | ||
20 | drivers/media/video/isp/bluegamma_table.h | 1040 ++++++++++++++++++++++++++ | ||
21 | drivers/media/video/isp/cfa_coef_table.h | 603 +++++++++++++++ | ||
22 | drivers/media/video/isp/greengamma_table.h | 1040 ++++++++++++++++++++++++++ | ||
23 | drivers/media/video/isp/luma_enhance_table.h | 144 ++++ | ||
24 | drivers/media/video/isp/noise_filter_table.h | 79 ++ | ||
25 | drivers/media/video/isp/redgamma_table.h | 1040 ++++++++++++++++++++++++++ | ||
26 | 6 files changed, 3946 insertions(+), 0 deletions(-) | ||
27 | create mode 100644 drivers/media/video/isp/bluegamma_table.h | ||
28 | create mode 100644 drivers/media/video/isp/cfa_coef_table.h | ||
29 | create mode 100644 drivers/media/video/isp/greengamma_table.h | ||
30 | create mode 100644 drivers/media/video/isp/luma_enhance_table.h | ||
31 | create mode 100644 drivers/media/video/isp/noise_filter_table.h | ||
32 | create mode 100644 drivers/media/video/isp/redgamma_table.h | ||
33 | |||
34 | diff --git a/drivers/media/video/isp/bluegamma_table.h b/drivers/media/video/isp/bluegamma_table.h | ||
35 | new file mode 100644 | ||
36 | index 0000000..301382a | ||
37 | --- /dev/null | ||
38 | +++ b/drivers/media/video/isp/bluegamma_table.h | ||
39 | @@ -0,0 +1,1040 @@ | ||
40 | +/* | ||
41 | + * bluegamma_table.h | ||
42 | + * | ||
43 | + * Gamma Table values for BLUE for TI's OMAP3 Camera ISP | ||
44 | + * | ||
45 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
46 | + * | ||
47 | + * This package is free software; you can redistribute it and/or modify | ||
48 | + * it under the terms of the GNU General Public License version 2 as | ||
49 | + * published by the Free Software Foundation. | ||
50 | + * | ||
51 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
52 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
53 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
54 | + */ | ||
55 | + | ||
56 | +0, | ||
57 | +0, | ||
58 | +1, | ||
59 | +2, | ||
60 | +3, | ||
61 | +3, | ||
62 | +4, | ||
63 | +5, | ||
64 | +6, | ||
65 | +8, | ||
66 | +10, | ||
67 | +12, | ||
68 | +14, | ||
69 | +16, | ||
70 | +18, | ||
71 | +20, | ||
72 | +22, | ||
73 | +23, | ||
74 | +25, | ||
75 | +26, | ||
76 | +28, | ||
77 | +29, | ||
78 | +31, | ||
79 | +32, | ||
80 | +34, | ||
81 | +35, | ||
82 | +36, | ||
83 | +37, | ||
84 | +39, | ||
85 | +40, | ||
86 | +41, | ||
87 | +42, | ||
88 | +43, | ||
89 | +44, | ||
90 | +45, | ||
91 | +46, | ||
92 | +47, | ||
93 | +48, | ||
94 | +49, | ||
95 | +50, | ||
96 | +51, | ||
97 | +52, | ||
98 | +52, | ||
99 | +53, | ||
100 | +54, | ||
101 | +55, | ||
102 | +56, | ||
103 | +57, | ||
104 | +58, | ||
105 | +59, | ||
106 | +60, | ||
107 | +61, | ||
108 | +62, | ||
109 | +63, | ||
110 | +63, | ||
111 | +64, | ||
112 | +65, | ||
113 | +66, | ||
114 | +66, | ||
115 | +67, | ||
116 | +68, | ||
117 | +69, | ||
118 | +69, | ||
119 | +70, | ||
120 | +71, | ||
121 | +72, | ||
122 | +72, | ||
123 | +73, | ||
124 | +74, | ||
125 | +75, | ||
126 | +75, | ||
127 | +76, | ||
128 | +77, | ||
129 | +78, | ||
130 | +78, | ||
131 | +79, | ||
132 | +80, | ||
133 | +81, | ||
134 | +81, | ||
135 | +82, | ||
136 | +83, | ||
137 | +84, | ||
138 | +84, | ||
139 | +85, | ||
140 | +86, | ||
141 | +87, | ||
142 | +88, | ||
143 | +88, | ||
144 | +89, | ||
145 | +90, | ||
146 | +91, | ||
147 | +91, | ||
148 | +92, | ||
149 | +93, | ||
150 | +94, | ||
151 | +94, | ||
152 | +95, | ||
153 | +96, | ||
154 | +97, | ||
155 | +97, | ||
156 | +98, | ||
157 | +98, | ||
158 | +99, | ||
159 | +99, | ||
160 | +100, | ||
161 | +100, | ||
162 | +101, | ||
163 | +101, | ||
164 | +102, | ||
165 | +103, | ||
166 | +104, | ||
167 | +104, | ||
168 | +105, | ||
169 | +106, | ||
170 | +107, | ||
171 | +108, | ||
172 | +108, | ||
173 | +109, | ||
174 | +110, | ||
175 | +111, | ||
176 | +111, | ||
177 | +112, | ||
178 | +113, | ||
179 | +114, | ||
180 | +114, | ||
181 | +115, | ||
182 | +116, | ||
183 | +117, | ||
184 | +117, | ||
185 | +118, | ||
186 | +119, | ||
187 | +119, | ||
188 | +120, | ||
189 | +120, | ||
190 | +121, | ||
191 | +121, | ||
192 | +122, | ||
193 | +122, | ||
194 | +123, | ||
195 | +123, | ||
196 | +124, | ||
197 | +124, | ||
198 | +125, | ||
199 | +125, | ||
200 | +126, | ||
201 | +126, | ||
202 | +127, | ||
203 | +127, | ||
204 | +128, | ||
205 | +128, | ||
206 | +129, | ||
207 | +129, | ||
208 | +130, | ||
209 | +130, | ||
210 | +131, | ||
211 | +131, | ||
212 | +132, | ||
213 | +132, | ||
214 | +133, | ||
215 | +133, | ||
216 | +134, | ||
217 | +134, | ||
218 | +135, | ||
219 | +135, | ||
220 | +136, | ||
221 | +136, | ||
222 | +137, | ||
223 | +137, | ||
224 | +138, | ||
225 | +138, | ||
226 | +139, | ||
227 | +139, | ||
228 | +140, | ||
229 | +140, | ||
230 | +141, | ||
231 | +141, | ||
232 | +142, | ||
233 | +142, | ||
234 | +143, | ||
235 | +143, | ||
236 | +144, | ||
237 | +144, | ||
238 | +145, | ||
239 | +145, | ||
240 | +146, | ||
241 | +146, | ||
242 | +147, | ||
243 | +147, | ||
244 | +148, | ||
245 | +148, | ||
246 | +149, | ||
247 | +149, | ||
248 | +150, | ||
249 | +150, | ||
250 | +151, | ||
251 | +151, | ||
252 | +152, | ||
253 | +152, | ||
254 | +153, | ||
255 | +153, | ||
256 | +153, | ||
257 | +153, | ||
258 | +154, | ||
259 | +154, | ||
260 | +154, | ||
261 | +154, | ||
262 | +155, | ||
263 | +155, | ||
264 | +156, | ||
265 | +156, | ||
266 | +157, | ||
267 | +157, | ||
268 | +158, | ||
269 | +158, | ||
270 | +158, | ||
271 | +159, | ||
272 | +159, | ||
273 | +159, | ||
274 | +160, | ||
275 | +160, | ||
276 | +160, | ||
277 | +161, | ||
278 | +161, | ||
279 | +162, | ||
280 | +162, | ||
281 | +163, | ||
282 | +163, | ||
283 | +164, | ||
284 | +164, | ||
285 | +164, | ||
286 | +164, | ||
287 | +165, | ||
288 | +165, | ||
289 | +165, | ||
290 | +165, | ||
291 | +166, | ||
292 | +166, | ||
293 | +167, | ||
294 | +167, | ||
295 | +168, | ||
296 | +168, | ||
297 | +169, | ||
298 | +169, | ||
299 | +170, | ||
300 | +170, | ||
301 | +170, | ||
302 | +170, | ||
303 | +171, | ||
304 | +171, | ||
305 | +171, | ||
306 | +171, | ||
307 | +172, | ||
308 | +172, | ||
309 | +173, | ||
310 | +173, | ||
311 | +174, | ||
312 | +174, | ||
313 | +175, | ||
314 | +175, | ||
315 | +176, | ||
316 | +176, | ||
317 | +176, | ||
318 | +176, | ||
319 | +177, | ||
320 | +177, | ||
321 | +177, | ||
322 | +177, | ||
323 | +178, | ||
324 | +178, | ||
325 | +178, | ||
326 | +178, | ||
327 | +179, | ||
328 | +179, | ||
329 | +179, | ||
330 | +179, | ||
331 | +180, | ||
332 | +180, | ||
333 | +180, | ||
334 | +180, | ||
335 | +181, | ||
336 | +181, | ||
337 | +181, | ||
338 | +181, | ||
339 | +182, | ||
340 | +182, | ||
341 | +182, | ||
342 | +182, | ||
343 | +183, | ||
344 | +183, | ||
345 | +183, | ||
346 | +183, | ||
347 | +184, | ||
348 | +184, | ||
349 | +184, | ||
350 | +184, | ||
351 | +185, | ||
352 | +185, | ||
353 | +185, | ||
354 | +185, | ||
355 | +186, | ||
356 | +186, | ||
357 | +186, | ||
358 | +186, | ||
359 | +187, | ||
360 | +187, | ||
361 | +187, | ||
362 | +187, | ||
363 | +188, | ||
364 | +188, | ||
365 | +188, | ||
366 | +188, | ||
367 | +189, | ||
368 | +189, | ||
369 | +189, | ||
370 | +189, | ||
371 | +190, | ||
372 | +190, | ||
373 | +190, | ||
374 | +190, | ||
375 | +191, | ||
376 | +191, | ||
377 | +191, | ||
378 | +191, | ||
379 | +192, | ||
380 | +192, | ||
381 | +192, | ||
382 | +192, | ||
383 | +193, | ||
384 | +193, | ||
385 | +193, | ||
386 | +193, | ||
387 | +194, | ||
388 | +194, | ||
389 | +194, | ||
390 | +194, | ||
391 | +195, | ||
392 | +195, | ||
393 | +195, | ||
394 | +195, | ||
395 | +196, | ||
396 | +196, | ||
397 | +196, | ||
398 | +196, | ||
399 | +197, | ||
400 | +197, | ||
401 | +197, | ||
402 | +197, | ||
403 | +198, | ||
404 | +198, | ||
405 | +198, | ||
406 | +198, | ||
407 | +199, | ||
408 | +199, | ||
409 | +199, | ||
410 | +199, | ||
411 | +200, | ||
412 | +200, | ||
413 | +200, | ||
414 | +200, | ||
415 | +201, | ||
416 | +201, | ||
417 | +201, | ||
418 | +201, | ||
419 | +202, | ||
420 | +202, | ||
421 | +202, | ||
422 | +203, | ||
423 | +203, | ||
424 | +203, | ||
425 | +203, | ||
426 | +204, | ||
427 | +204, | ||
428 | +204, | ||
429 | +204, | ||
430 | +205, | ||
431 | +205, | ||
432 | +205, | ||
433 | +205, | ||
434 | +206, | ||
435 | +206, | ||
436 | +206, | ||
437 | +206, | ||
438 | +207, | ||
439 | +207, | ||
440 | +207, | ||
441 | +207, | ||
442 | +208, | ||
443 | +208, | ||
444 | +208, | ||
445 | +208, | ||
446 | +209, | ||
447 | +209, | ||
448 | +209, | ||
449 | +209, | ||
450 | +210, | ||
451 | +210, | ||
452 | +210, | ||
453 | +210, | ||
454 | +210, | ||
455 | +210, | ||
456 | +210, | ||
457 | +210, | ||
458 | +210, | ||
459 | +210, | ||
460 | +210, | ||
461 | +210, | ||
462 | +211, | ||
463 | +211, | ||
464 | +211, | ||
465 | +211, | ||
466 | +211, | ||
467 | +211, | ||
468 | +211, | ||
469 | +211, | ||
470 | +211, | ||
471 | +211, | ||
472 | +211, | ||
473 | +212, | ||
474 | +212, | ||
475 | +212, | ||
476 | +212, | ||
477 | +213, | ||
478 | +213, | ||
479 | +213, | ||
480 | +213, | ||
481 | +213, | ||
482 | +213, | ||
483 | +213, | ||
484 | +213, | ||
485 | +213, | ||
486 | +213, | ||
487 | +213, | ||
488 | +213, | ||
489 | +214, | ||
490 | +214, | ||
491 | +214, | ||
492 | +214, | ||
493 | +215, | ||
494 | +215, | ||
495 | +215, | ||
496 | +215, | ||
497 | +215, | ||
498 | +215, | ||
499 | +215, | ||
500 | +215, | ||
501 | +215, | ||
502 | +215, | ||
503 | +215, | ||
504 | +216, | ||
505 | +216, | ||
506 | +216, | ||
507 | +216, | ||
508 | +217, | ||
509 | +217, | ||
510 | +217, | ||
511 | +217, | ||
512 | +218, | ||
513 | +218, | ||
514 | +218, | ||
515 | +218, | ||
516 | +219, | ||
517 | +219, | ||
518 | +219, | ||
519 | +219, | ||
520 | +219, | ||
521 | +219, | ||
522 | +219, | ||
523 | +219, | ||
524 | +219, | ||
525 | +219, | ||
526 | +219, | ||
527 | +219, | ||
528 | +220, | ||
529 | +220, | ||
530 | +220, | ||
531 | +220, | ||
532 | +221, | ||
533 | +221, | ||
534 | +221, | ||
535 | +221, | ||
536 | +221, | ||
537 | +221, | ||
538 | +221, | ||
539 | +221, | ||
540 | +221, | ||
541 | +221, | ||
542 | +221, | ||
543 | +222, | ||
544 | +222, | ||
545 | +222, | ||
546 | +222, | ||
547 | +223, | ||
548 | +223, | ||
549 | +223, | ||
550 | +223, | ||
551 | +223, | ||
552 | +223, | ||
553 | +223, | ||
554 | +223, | ||
555 | +223, | ||
556 | +223, | ||
557 | +223, | ||
558 | +223, | ||
559 | +224, | ||
560 | +224, | ||
561 | +224, | ||
562 | +224, | ||
563 | +225, | ||
564 | +225, | ||
565 | +225, | ||
566 | +225, | ||
567 | +225, | ||
568 | +225, | ||
569 | +225, | ||
570 | +225, | ||
571 | +225, | ||
572 | +225, | ||
573 | +225, | ||
574 | +225, | ||
575 | +225, | ||
576 | +225, | ||
577 | +225, | ||
578 | +225, | ||
579 | +225, | ||
580 | +225, | ||
581 | +225, | ||
582 | +226, | ||
583 | +226, | ||
584 | +226, | ||
585 | +226, | ||
586 | +227, | ||
587 | +227, | ||
588 | +227, | ||
589 | +227, | ||
590 | +227, | ||
591 | +227, | ||
592 | +227, | ||
593 | +227, | ||
594 | +227, | ||
595 | +227, | ||
596 | +227, | ||
597 | +227, | ||
598 | +228, | ||
599 | +228, | ||
600 | +228, | ||
601 | +229, | ||
602 | +229, | ||
603 | +229, | ||
604 | +229, | ||
605 | +229, | ||
606 | +229, | ||
607 | +229, | ||
608 | +229, | ||
609 | +229, | ||
610 | +229, | ||
611 | +229, | ||
612 | +229, | ||
613 | +230, | ||
614 | +230, | ||
615 | +230, | ||
616 | +230, | ||
617 | +231, | ||
618 | +231, | ||
619 | +231, | ||
620 | +231, | ||
621 | +231, | ||
622 | +231, | ||
623 | +231, | ||
624 | +231, | ||
625 | +231, | ||
626 | +231, | ||
627 | +231, | ||
628 | +231, | ||
629 | +232, | ||
630 | +232, | ||
631 | +232, | ||
632 | +232, | ||
633 | +232, | ||
634 | +232, | ||
635 | +232, | ||
636 | +232, | ||
637 | +232, | ||
638 | +232, | ||
639 | +232, | ||
640 | +232, | ||
641 | +232, | ||
642 | +232, | ||
643 | +232, | ||
644 | +232, | ||
645 | +232, | ||
646 | +232, | ||
647 | +232, | ||
648 | +233, | ||
649 | +233, | ||
650 | +233, | ||
651 | +233, | ||
652 | +234, | ||
653 | +234, | ||
654 | +234, | ||
655 | +234, | ||
656 | +234, | ||
657 | +234, | ||
658 | +234, | ||
659 | +234, | ||
660 | +234, | ||
661 | +234, | ||
662 | +234, | ||
663 | +235, | ||
664 | +235, | ||
665 | +235, | ||
666 | +235, | ||
667 | +236, | ||
668 | +236, | ||
669 | +236, | ||
670 | +236, | ||
671 | +236, | ||
672 | +236, | ||
673 | +236, | ||
674 | +236, | ||
675 | +236, | ||
676 | +236, | ||
677 | +236, | ||
678 | +236, | ||
679 | +236, | ||
680 | +236, | ||
681 | +236, | ||
682 | +236, | ||
683 | +236, | ||
684 | +236, | ||
685 | +236, | ||
686 | +237, | ||
687 | +237, | ||
688 | +237, | ||
689 | +237, | ||
690 | +238, | ||
691 | +238, | ||
692 | +238, | ||
693 | +238, | ||
694 | +238, | ||
695 | +238, | ||
696 | +238, | ||
697 | +238, | ||
698 | +238, | ||
699 | +238, | ||
700 | +238, | ||
701 | +238, | ||
702 | +238, | ||
703 | +238, | ||
704 | +238, | ||
705 | +238, | ||
706 | +238, | ||
707 | +238, | ||
708 | +238, | ||
709 | +238, | ||
710 | +238, | ||
711 | +238, | ||
712 | +238, | ||
713 | +238, | ||
714 | +238, | ||
715 | +238, | ||
716 | +238, | ||
717 | +239, | ||
718 | +239, | ||
719 | +239, | ||
720 | +239, | ||
721 | +240, | ||
722 | +240, | ||
723 | +240, | ||
724 | +240, | ||
725 | +240, | ||
726 | +240, | ||
727 | +240, | ||
728 | +240, | ||
729 | +240, | ||
730 | +240, | ||
731 | +240, | ||
732 | +240, | ||
733 | +240, | ||
734 | +240, | ||
735 | +240, | ||
736 | +240, | ||
737 | +240, | ||
738 | +240, | ||
739 | +240, | ||
740 | +240, | ||
741 | +240, | ||
742 | +240, | ||
743 | +240, | ||
744 | +240, | ||
745 | +240, | ||
746 | +240, | ||
747 | +240, | ||
748 | +241, | ||
749 | +241, | ||
750 | +241, | ||
751 | +241, | ||
752 | +242, | ||
753 | +242, | ||
754 | +242, | ||
755 | +242, | ||
756 | +242, | ||
757 | +242, | ||
758 | +242, | ||
759 | +242, | ||
760 | +242, | ||
761 | +242, | ||
762 | +242, | ||
763 | +242, | ||
764 | +242, | ||
765 | +242, | ||
766 | +242, | ||
767 | +242, | ||
768 | +242, | ||
769 | +242, | ||
770 | +242, | ||
771 | +242, | ||
772 | +242, | ||
773 | +242, | ||
774 | +242, | ||
775 | +242, | ||
776 | +242, | ||
777 | +242, | ||
778 | +243, | ||
779 | +243, | ||
780 | +243, | ||
781 | +243, | ||
782 | +244, | ||
783 | +244, | ||
784 | +244, | ||
785 | +244, | ||
786 | +244, | ||
787 | +244, | ||
788 | +244, | ||
789 | +244, | ||
790 | +244, | ||
791 | +244, | ||
792 | +244, | ||
793 | +244, | ||
794 | +244, | ||
795 | +244, | ||
796 | +244, | ||
797 | +244, | ||
798 | +244, | ||
799 | +244, | ||
800 | +244, | ||
801 | +244, | ||
802 | +244, | ||
803 | +244, | ||
804 | +244, | ||
805 | +244, | ||
806 | +244, | ||
807 | +244, | ||
808 | +244, | ||
809 | +245, | ||
810 | +245, | ||
811 | +245, | ||
812 | +245, | ||
813 | +246, | ||
814 | +246, | ||
815 | +246, | ||
816 | +246, | ||
817 | +246, | ||
818 | +246, | ||
819 | +246, | ||
820 | +246, | ||
821 | +246, | ||
822 | +246, | ||
823 | +246, | ||
824 | +246, | ||
825 | +246, | ||
826 | +246, | ||
827 | +246, | ||
828 | +246, | ||
829 | +246, | ||
830 | +246, | ||
831 | +246, | ||
832 | +246, | ||
833 | +246, | ||
834 | +246, | ||
835 | +246, | ||
836 | +246, | ||
837 | +246, | ||
838 | +246, | ||
839 | +246, | ||
840 | +246, | ||
841 | +246, | ||
842 | +246, | ||
843 | +246, | ||
844 | +246, | ||
845 | +246, | ||
846 | +246, | ||
847 | +247, | ||
848 | +247, | ||
849 | +247, | ||
850 | +247, | ||
851 | +248, | ||
852 | +248, | ||
853 | +248, | ||
854 | +248, | ||
855 | +248, | ||
856 | +248, | ||
857 | +248, | ||
858 | +248, | ||
859 | +248, | ||
860 | +248, | ||
861 | +248, | ||
862 | +248, | ||
863 | +248, | ||
864 | +248, | ||
865 | +248, | ||
866 | +248, | ||
867 | +248, | ||
868 | +248, | ||
869 | +248, | ||
870 | +248, | ||
871 | +248, | ||
872 | +248, | ||
873 | +248, | ||
874 | +248, | ||
875 | +248, | ||
876 | +248, | ||
877 | +248, | ||
878 | +249, | ||
879 | +249, | ||
880 | +249, | ||
881 | +249, | ||
882 | +250, | ||
883 | +250, | ||
884 | +250, | ||
885 | +250, | ||
886 | +250, | ||
887 | +250, | ||
888 | +250, | ||
889 | +250, | ||
890 | +250, | ||
891 | +250, | ||
892 | +250, | ||
893 | +250, | ||
894 | +250, | ||
895 | +250, | ||
896 | +250, | ||
897 | +250, | ||
898 | +250, | ||
899 | +250, | ||
900 | +250, | ||
901 | +250, | ||
902 | +250, | ||
903 | +250, | ||
904 | +250, | ||
905 | +250, | ||
906 | +250, | ||
907 | +250, | ||
908 | +250, | ||
909 | +250, | ||
910 | +250, | ||
911 | +250, | ||
912 | +250, | ||
913 | +250, | ||
914 | +250, | ||
915 | +250, | ||
916 | +250, | ||
917 | +250, | ||
918 | +250, | ||
919 | +250, | ||
920 | +250, | ||
921 | +250, | ||
922 | +250, | ||
923 | +250, | ||
924 | +251, | ||
925 | +251, | ||
926 | +251, | ||
927 | +251, | ||
928 | +252, | ||
929 | +252, | ||
930 | +252, | ||
931 | +252, | ||
932 | +252, | ||
933 | +252, | ||
934 | +252, | ||
935 | +252, | ||
936 | +252, | ||
937 | +252, | ||
938 | +252, | ||
939 | +252, | ||
940 | +252, | ||
941 | +252, | ||
942 | +252, | ||
943 | +252, | ||
944 | +252, | ||
945 | +252, | ||
946 | +252, | ||
947 | +252, | ||
948 | +252, | ||
949 | +252, | ||
950 | +252, | ||
951 | +252, | ||
952 | +252, | ||
953 | +252, | ||
954 | +252, | ||
955 | +252, | ||
956 | +252, | ||
957 | +252, | ||
958 | +252, | ||
959 | +252, | ||
960 | +252, | ||
961 | +252, | ||
962 | +252, | ||
963 | +252, | ||
964 | +252, | ||
965 | +252, | ||
966 | +252, | ||
967 | +252, | ||
968 | +252, | ||
969 | +252, | ||
970 | +252, | ||
971 | +252, | ||
972 | +252, | ||
973 | +252, | ||
974 | +252, | ||
975 | +252, | ||
976 | +252, | ||
977 | +252, | ||
978 | +252, | ||
979 | +252, | ||
980 | +252, | ||
981 | +252, | ||
982 | +252, | ||
983 | +252, | ||
984 | +252, | ||
985 | +252, | ||
986 | +252, | ||
987 | +252, | ||
988 | +252, | ||
989 | +252, | ||
990 | +252, | ||
991 | +252, | ||
992 | +253, | ||
993 | +253, | ||
994 | +253, | ||
995 | +253, | ||
996 | +253, | ||
997 | +253, | ||
998 | +253, | ||
999 | +253, | ||
1000 | +253, | ||
1001 | +253, | ||
1002 | +253, | ||
1003 | +253, | ||
1004 | +253, | ||
1005 | +253, | ||
1006 | +253, | ||
1007 | +253, | ||
1008 | +253, | ||
1009 | +253, | ||
1010 | +253, | ||
1011 | +253, | ||
1012 | +253, | ||
1013 | +253, | ||
1014 | +253, | ||
1015 | +253, | ||
1016 | +253, | ||
1017 | +253, | ||
1018 | +253, | ||
1019 | +253, | ||
1020 | +253, | ||
1021 | +253, | ||
1022 | +253, | ||
1023 | +253, | ||
1024 | +253, | ||
1025 | +253, | ||
1026 | +253, | ||
1027 | +253, | ||
1028 | +253, | ||
1029 | +253, | ||
1030 | +253, | ||
1031 | +253, | ||
1032 | +253, | ||
1033 | +253, | ||
1034 | +253, | ||
1035 | +253, | ||
1036 | +253, | ||
1037 | +253, | ||
1038 | +253, | ||
1039 | +253, | ||
1040 | +253, | ||
1041 | +253, | ||
1042 | +253, | ||
1043 | +253, | ||
1044 | +253, | ||
1045 | +253, | ||
1046 | +253, | ||
1047 | +253, | ||
1048 | +253, | ||
1049 | +254, | ||
1050 | +254, | ||
1051 | +254, | ||
1052 | +254, | ||
1053 | +255, | ||
1054 | +255, | ||
1055 | +255, | ||
1056 | +255, | ||
1057 | +255, | ||
1058 | +255, | ||
1059 | +255, | ||
1060 | +255, | ||
1061 | +255, | ||
1062 | +255, | ||
1063 | +255, | ||
1064 | +255, | ||
1065 | +255, | ||
1066 | +255, | ||
1067 | +255, | ||
1068 | +255, | ||
1069 | +255, | ||
1070 | +255, | ||
1071 | +255, | ||
1072 | +255, | ||
1073 | +255, | ||
1074 | +255, | ||
1075 | +255, | ||
1076 | +255, | ||
1077 | +255, | ||
1078 | +255, | ||
1079 | +255 | ||
1080 | diff --git a/drivers/media/video/isp/cfa_coef_table.h b/drivers/media/video/isp/cfa_coef_table.h | ||
1081 | new file mode 100644 | ||
1082 | index 0000000..8cafa1f | ||
1083 | --- /dev/null | ||
1084 | +++ b/drivers/media/video/isp/cfa_coef_table.h | ||
1085 | @@ -0,0 +1,603 @@ | ||
1086 | +/* | ||
1087 | + * cfa_coef_table.h | ||
1088 | + * | ||
1089 | + * Copyright (C) 2009 Nokia Corporation | ||
1090 | + * | ||
1091 | + * Contact: Sakari Ailus <sakari.ailus@nokia.com> | ||
1092 | + * Tuukka Toivonen <tuukka.o.toivonen@nokia.com> | ||
1093 | + * | ||
1094 | + * Written by Gjorgji Rosikopulos | ||
1095 | + * | ||
1096 | + * This program is free software; you can redistribute it and/or | ||
1097 | + * modify it under the terms of the GNU General Public License | ||
1098 | + * version 2 as published by the Free Software Foundation. | ||
1099 | + * | ||
1100 | + * This program is distributed in the hope that it will be useful, but | ||
1101 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1102 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
1103 | + * General Public License for more details. | ||
1104 | + * | ||
1105 | + * You should have received a copy of the GNU General Public License | ||
1106 | + * along with this program; if not, write to the Free Software | ||
1107 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
1108 | + * 02110-1301 USA | ||
1109 | + * | ||
1110 | + */ | ||
1111 | + | ||
1112 | +244, | ||
1113 | +0, | ||
1114 | +247, | ||
1115 | +0, | ||
1116 | +12, | ||
1117 | +27, | ||
1118 | +36, | ||
1119 | +247, | ||
1120 | +250, | ||
1121 | +0, | ||
1122 | +27, | ||
1123 | +0, | ||
1124 | +4, | ||
1125 | +250, | ||
1126 | +12, | ||
1127 | +244, | ||
1128 | +248, | ||
1129 | +0, | ||
1130 | +0, | ||
1131 | +0, | ||
1132 | +0, | ||
1133 | +40, | ||
1134 | +0, | ||
1135 | +0, | ||
1136 | +244, | ||
1137 | +12, | ||
1138 | +250, | ||
1139 | +4, | ||
1140 | +0, | ||
1141 | +27, | ||
1142 | +0, | ||
1143 | +250, | ||
1144 | +247, | ||
1145 | +36, | ||
1146 | +27, | ||
1147 | +12, | ||
1148 | +0, | ||
1149 | +247, | ||
1150 | +0, | ||
1151 | +244, | ||
1152 | +0, | ||
1153 | +0, | ||
1154 | +40, | ||
1155 | +0, | ||
1156 | +0, | ||
1157 | +0, | ||
1158 | +0, | ||
1159 | +248, | ||
1160 | +244, | ||
1161 | +0, | ||
1162 | +247, | ||
1163 | +0, | ||
1164 | +12, | ||
1165 | +27, | ||
1166 | +36, | ||
1167 | +247, | ||
1168 | +250, | ||
1169 | +0, | ||
1170 | +27, | ||
1171 | +0, | ||
1172 | +4, | ||
1173 | +250, | ||
1174 | +12, | ||
1175 | +244, | ||
1176 | +248, | ||
1177 | +0, | ||
1178 | +0, | ||
1179 | +0, | ||
1180 | +0, | ||
1181 | +40, | ||
1182 | +0, | ||
1183 | +0, | ||
1184 | +244, | ||
1185 | +12, | ||
1186 | +250, | ||
1187 | +4, | ||
1188 | +0, | ||
1189 | +27, | ||
1190 | +0, | ||
1191 | +250, | ||
1192 | +247, | ||
1193 | +36, | ||
1194 | +27, | ||
1195 | +12, | ||
1196 | +0, | ||
1197 | +247, | ||
1198 | +0, | ||
1199 | +244, | ||
1200 | +0, | ||
1201 | +0, | ||
1202 | +40, | ||
1203 | +0, | ||
1204 | +0, | ||
1205 | +0, | ||
1206 | +0, | ||
1207 | +248, | ||
1208 | +244, | ||
1209 | +0, | ||
1210 | +247, | ||
1211 | +0, | ||
1212 | +12, | ||
1213 | +27, | ||
1214 | +36, | ||
1215 | +247, | ||
1216 | +250, | ||
1217 | +0, | ||
1218 | +27, | ||
1219 | +0, | ||
1220 | +4, | ||
1221 | +250, | ||
1222 | +12, | ||
1223 | +244, | ||
1224 | +248, | ||
1225 | +0, | ||
1226 | +0, | ||
1227 | +0, | ||
1228 | +0, | ||
1229 | +40, | ||
1230 | +0, | ||
1231 | +0, | ||
1232 | +244, | ||
1233 | +12, | ||
1234 | +250, | ||
1235 | +4, | ||
1236 | +0, | ||
1237 | +27, | ||
1238 | +0, | ||
1239 | +250, | ||
1240 | +247, | ||
1241 | +36, | ||
1242 | +27, | ||
1243 | +12, | ||
1244 | +0, | ||
1245 | +247, | ||
1246 | +0, | ||
1247 | +244, | ||
1248 | +0, | ||
1249 | +0, | ||
1250 | +40, | ||
1251 | +0, | ||
1252 | +0, | ||
1253 | +0, | ||
1254 | +0, | ||
1255 | +248, | ||
1256 | +0, | ||
1257 | +247, | ||
1258 | +0, | ||
1259 | +244, | ||
1260 | +247, | ||
1261 | +36, | ||
1262 | +27, | ||
1263 | +12, | ||
1264 | +0, | ||
1265 | +27, | ||
1266 | +0, | ||
1267 | +250, | ||
1268 | +244, | ||
1269 | +12, | ||
1270 | +250, | ||
1271 | +4, | ||
1272 | +0, | ||
1273 | +0, | ||
1274 | +0, | ||
1275 | +248, | ||
1276 | +0, | ||
1277 | +0, | ||
1278 | +40, | ||
1279 | +0, | ||
1280 | +4, | ||
1281 | +250, | ||
1282 | +12, | ||
1283 | +244, | ||
1284 | +250, | ||
1285 | +0, | ||
1286 | +27, | ||
1287 | +0, | ||
1288 | +12, | ||
1289 | +27, | ||
1290 | +36, | ||
1291 | +247, | ||
1292 | +244, | ||
1293 | +0, | ||
1294 | +247, | ||
1295 | +0, | ||
1296 | +0, | ||
1297 | +40, | ||
1298 | +0, | ||
1299 | +0, | ||
1300 | +248, | ||
1301 | +0, | ||
1302 | +0, | ||
1303 | +0, | ||
1304 | +0, | ||
1305 | +247, | ||
1306 | +0, | ||
1307 | +244, | ||
1308 | +247, | ||
1309 | +36, | ||
1310 | +27, | ||
1311 | +12, | ||
1312 | +0, | ||
1313 | +27, | ||
1314 | +0, | ||
1315 | +250, | ||
1316 | +244, | ||
1317 | +12, | ||
1318 | +250, | ||
1319 | +4, | ||
1320 | +0, | ||
1321 | +0, | ||
1322 | +0, | ||
1323 | +248, | ||
1324 | +0, | ||
1325 | +0, | ||
1326 | +40, | ||
1327 | +0, | ||
1328 | +4, | ||
1329 | +250, | ||
1330 | +12, | ||
1331 | +244, | ||
1332 | +250, | ||
1333 | +0, | ||
1334 | +27, | ||
1335 | +0, | ||
1336 | +12, | ||
1337 | +27, | ||
1338 | +36, | ||
1339 | +247, | ||
1340 | +244, | ||
1341 | +0, | ||
1342 | +247, | ||
1343 | +0, | ||
1344 | +0, | ||
1345 | +40, | ||
1346 | +0, | ||
1347 | +0, | ||
1348 | +248, | ||
1349 | +0, | ||
1350 | +0, | ||
1351 | +0, | ||
1352 | +0, | ||
1353 | +247, | ||
1354 | +0, | ||
1355 | +244, | ||
1356 | +247, | ||
1357 | +36, | ||
1358 | +27, | ||
1359 | +12, | ||
1360 | +0, | ||
1361 | +27, | ||
1362 | +0, | ||
1363 | +250, | ||
1364 | +244, | ||
1365 | +12, | ||
1366 | +250, | ||
1367 | +4, | ||
1368 | +0, | ||
1369 | +0, | ||
1370 | +0, | ||
1371 | +248, | ||
1372 | +0, | ||
1373 | +0, | ||
1374 | +40, | ||
1375 | +0, | ||
1376 | +4, | ||
1377 | +250, | ||
1378 | +12, | ||
1379 | +244, | ||
1380 | +250, | ||
1381 | +0, | ||
1382 | +27, | ||
1383 | +0, | ||
1384 | +12, | ||
1385 | +27, | ||
1386 | +36, | ||
1387 | +247, | ||
1388 | +244, | ||
1389 | +0, | ||
1390 | +247, | ||
1391 | +0, | ||
1392 | +0, | ||
1393 | +40, | ||
1394 | +0, | ||
1395 | +0, | ||
1396 | +248, | ||
1397 | +0, | ||
1398 | +0, | ||
1399 | +0, | ||
1400 | +4, | ||
1401 | +250, | ||
1402 | +12, | ||
1403 | +244, | ||
1404 | +250, | ||
1405 | +0, | ||
1406 | +27, | ||
1407 | +0, | ||
1408 | +12, | ||
1409 | +27, | ||
1410 | +36, | ||
1411 | +247, | ||
1412 | +244, | ||
1413 | +0, | ||
1414 | +247, | ||
1415 | +0, | ||
1416 | +0, | ||
1417 | +0, | ||
1418 | +0, | ||
1419 | +248, | ||
1420 | +0, | ||
1421 | +0, | ||
1422 | +40, | ||
1423 | +0, | ||
1424 | +0, | ||
1425 | +247, | ||
1426 | +0, | ||
1427 | +244, | ||
1428 | +247, | ||
1429 | +36, | ||
1430 | +27, | ||
1431 | +12, | ||
1432 | +0, | ||
1433 | +27, | ||
1434 | +0, | ||
1435 | +250, | ||
1436 | +244, | ||
1437 | +12, | ||
1438 | +250, | ||
1439 | +4, | ||
1440 | +0, | ||
1441 | +40, | ||
1442 | +0, | ||
1443 | +0, | ||
1444 | +248, | ||
1445 | +0, | ||
1446 | +0, | ||
1447 | +0, | ||
1448 | +4, | ||
1449 | +250, | ||
1450 | +12, | ||
1451 | +244, | ||
1452 | +250, | ||
1453 | +0, | ||
1454 | +27, | ||
1455 | +0, | ||
1456 | +12, | ||
1457 | +27, | ||
1458 | +36, | ||
1459 | +247, | ||
1460 | +244, | ||
1461 | +0, | ||
1462 | +247, | ||
1463 | +0, | ||
1464 | +0, | ||
1465 | +0, | ||
1466 | +0, | ||
1467 | +248, | ||
1468 | +0, | ||
1469 | +0, | ||
1470 | +40, | ||
1471 | +0, | ||
1472 | +0, | ||
1473 | +247, | ||
1474 | +0, | ||
1475 | +244, | ||
1476 | +247, | ||
1477 | +36, | ||
1478 | +27, | ||
1479 | +12, | ||
1480 | +0, | ||
1481 | +27, | ||
1482 | +0, | ||
1483 | +250, | ||
1484 | +244, | ||
1485 | +12, | ||
1486 | +250, | ||
1487 | +4, | ||
1488 | +0, | ||
1489 | +40, | ||
1490 | +0, | ||
1491 | +0, | ||
1492 | +248, | ||
1493 | +0, | ||
1494 | +0, | ||
1495 | +0, | ||
1496 | +4, | ||
1497 | +250, | ||
1498 | +12, | ||
1499 | +244, | ||
1500 | +250, | ||
1501 | +0, | ||
1502 | +27, | ||
1503 | +0, | ||
1504 | +12, | ||
1505 | +27, | ||
1506 | +36, | ||
1507 | +247, | ||
1508 | +244, | ||
1509 | +0, | ||
1510 | +247, | ||
1511 | +0, | ||
1512 | +0, | ||
1513 | +0, | ||
1514 | +0, | ||
1515 | +248, | ||
1516 | +0, | ||
1517 | +0, | ||
1518 | +40, | ||
1519 | +0, | ||
1520 | +0, | ||
1521 | +247, | ||
1522 | +0, | ||
1523 | +244, | ||
1524 | +247, | ||
1525 | +36, | ||
1526 | +27, | ||
1527 | +12, | ||
1528 | +0, | ||
1529 | +27, | ||
1530 | +0, | ||
1531 | +250, | ||
1532 | +244, | ||
1533 | +12, | ||
1534 | +250, | ||
1535 | +4, | ||
1536 | +0, | ||
1537 | +40, | ||
1538 | +0, | ||
1539 | +0, | ||
1540 | +248, | ||
1541 | +0, | ||
1542 | +0, | ||
1543 | +0, | ||
1544 | +244, | ||
1545 | +12, | ||
1546 | +250, | ||
1547 | +4, | ||
1548 | +0, | ||
1549 | +27, | ||
1550 | +0, | ||
1551 | +250, | ||
1552 | +247, | ||
1553 | +36, | ||
1554 | +27, | ||
1555 | +12, | ||
1556 | +0, | ||
1557 | +247, | ||
1558 | +0, | ||
1559 | +244, | ||
1560 | +248, | ||
1561 | +0, | ||
1562 | +0, | ||
1563 | +0, | ||
1564 | +0, | ||
1565 | +40, | ||
1566 | +0, | ||
1567 | +0, | ||
1568 | +244, | ||
1569 | +0, | ||
1570 | +247, | ||
1571 | +0, | ||
1572 | +12, | ||
1573 | +27, | ||
1574 | +36, | ||
1575 | +247, | ||
1576 | +250, | ||
1577 | +0, | ||
1578 | +27, | ||
1579 | +0, | ||
1580 | +4, | ||
1581 | +250, | ||
1582 | +12, | ||
1583 | +244, | ||
1584 | +0, | ||
1585 | +0, | ||
1586 | +40, | ||
1587 | +0, | ||
1588 | +0, | ||
1589 | +0, | ||
1590 | +0, | ||
1591 | +248, | ||
1592 | +244, | ||
1593 | +12, | ||
1594 | +250, | ||
1595 | +4, | ||
1596 | +0, | ||
1597 | +27, | ||
1598 | +0, | ||
1599 | +250, | ||
1600 | +247, | ||
1601 | +36, | ||
1602 | +27, | ||
1603 | +12, | ||
1604 | +0, | ||
1605 | +247, | ||
1606 | +0, | ||
1607 | +244, | ||
1608 | +248, | ||
1609 | +0, | ||
1610 | +0, | ||
1611 | +0, | ||
1612 | +0, | ||
1613 | +40, | ||
1614 | +0, | ||
1615 | +0, | ||
1616 | +244, | ||
1617 | +0, | ||
1618 | +247, | ||
1619 | +0, | ||
1620 | +12, | ||
1621 | +27, | ||
1622 | +36, | ||
1623 | +247, | ||
1624 | +250, | ||
1625 | +0, | ||
1626 | +27, | ||
1627 | +0, | ||
1628 | +4, | ||
1629 | +250, | ||
1630 | +12, | ||
1631 | +244, | ||
1632 | +0, | ||
1633 | +0, | ||
1634 | +40, | ||
1635 | +0, | ||
1636 | +0, | ||
1637 | +0, | ||
1638 | +0, | ||
1639 | +248, | ||
1640 | +244, | ||
1641 | +12, | ||
1642 | +250, | ||
1643 | +4, | ||
1644 | +0, | ||
1645 | +27, | ||
1646 | +0, | ||
1647 | +250, | ||
1648 | +247, | ||
1649 | +36, | ||
1650 | +27, | ||
1651 | +12, | ||
1652 | +0, | ||
1653 | +247, | ||
1654 | +0, | ||
1655 | +244, | ||
1656 | +248, | ||
1657 | +0, | ||
1658 | +0, | ||
1659 | +0, | ||
1660 | +0, | ||
1661 | +40, | ||
1662 | +0, | ||
1663 | +0, | ||
1664 | +244, | ||
1665 | +0, | ||
1666 | +247, | ||
1667 | +0, | ||
1668 | +12, | ||
1669 | +27, | ||
1670 | +36, | ||
1671 | +247, | ||
1672 | +250, | ||
1673 | +0, | ||
1674 | +27, | ||
1675 | +0, | ||
1676 | +4, | ||
1677 | +250, | ||
1678 | +12, | ||
1679 | +244, | ||
1680 | +0, | ||
1681 | +0, | ||
1682 | +40, | ||
1683 | +0, | ||
1684 | +0, | ||
1685 | +0, | ||
1686 | +0, | ||
1687 | +248 | ||
1688 | + | ||
1689 | diff --git a/drivers/media/video/isp/greengamma_table.h b/drivers/media/video/isp/greengamma_table.h | ||
1690 | new file mode 100644 | ||
1691 | index 0000000..0f5c5e4 | ||
1692 | --- /dev/null | ||
1693 | +++ b/drivers/media/video/isp/greengamma_table.h | ||
1694 | @@ -0,0 +1,1040 @@ | ||
1695 | +/* | ||
1696 | + * greengamma_table.h | ||
1697 | + * | ||
1698 | + * Gamma Table values for GREEN for TI's OMAP3 Camera ISP | ||
1699 | + * | ||
1700 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
1701 | + * | ||
1702 | + * This package is free software; you can redistribute it and/or modify | ||
1703 | + * it under the terms of the GNU General Public License version 2 as | ||
1704 | + * published by the Free Software Foundation. | ||
1705 | + * | ||
1706 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
1707 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
1708 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
1709 | + */ | ||
1710 | + | ||
1711 | +0, | ||
1712 | +0, | ||
1713 | +1, | ||
1714 | +2, | ||
1715 | +3, | ||
1716 | +3, | ||
1717 | +4, | ||
1718 | +5, | ||
1719 | +6, | ||
1720 | +8, | ||
1721 | +10, | ||
1722 | +12, | ||
1723 | +14, | ||
1724 | +16, | ||
1725 | +18, | ||
1726 | +20, | ||
1727 | +22, | ||
1728 | +23, | ||
1729 | +25, | ||
1730 | +26, | ||
1731 | +28, | ||
1732 | +29, | ||
1733 | +31, | ||
1734 | +32, | ||
1735 | +34, | ||
1736 | +35, | ||
1737 | +36, | ||
1738 | +37, | ||
1739 | +39, | ||
1740 | +40, | ||
1741 | +41, | ||
1742 | +42, | ||
1743 | +43, | ||
1744 | +44, | ||
1745 | +45, | ||
1746 | +46, | ||
1747 | +47, | ||
1748 | +48, | ||
1749 | +49, | ||
1750 | +50, | ||
1751 | +51, | ||
1752 | +52, | ||
1753 | +52, | ||
1754 | +53, | ||
1755 | +54, | ||
1756 | +55, | ||
1757 | +56, | ||
1758 | +57, | ||
1759 | +58, | ||
1760 | +59, | ||
1761 | +60, | ||
1762 | +61, | ||
1763 | +62, | ||
1764 | +63, | ||
1765 | +63, | ||
1766 | +64, | ||
1767 | +65, | ||
1768 | +66, | ||
1769 | +66, | ||
1770 | +67, | ||
1771 | +68, | ||
1772 | +69, | ||
1773 | +69, | ||
1774 | +70, | ||
1775 | +71, | ||
1776 | +72, | ||
1777 | +72, | ||
1778 | +73, | ||
1779 | +74, | ||
1780 | +75, | ||
1781 | +75, | ||
1782 | +76, | ||
1783 | +77, | ||
1784 | +78, | ||
1785 | +78, | ||
1786 | +79, | ||
1787 | +80, | ||
1788 | +81, | ||
1789 | +81, | ||
1790 | +82, | ||
1791 | +83, | ||
1792 | +84, | ||
1793 | +84, | ||
1794 | +85, | ||
1795 | +86, | ||
1796 | +87, | ||
1797 | +88, | ||
1798 | +88, | ||
1799 | +89, | ||
1800 | +90, | ||
1801 | +91, | ||
1802 | +91, | ||
1803 | +92, | ||
1804 | +93, | ||
1805 | +94, | ||
1806 | +94, | ||
1807 | +95, | ||
1808 | +96, | ||
1809 | +97, | ||
1810 | +97, | ||
1811 | +98, | ||
1812 | +98, | ||
1813 | +99, | ||
1814 | +99, | ||
1815 | +100, | ||
1816 | +100, | ||
1817 | +101, | ||
1818 | +101, | ||
1819 | +102, | ||
1820 | +103, | ||
1821 | +104, | ||
1822 | +104, | ||
1823 | +105, | ||
1824 | +106, | ||
1825 | +107, | ||
1826 | +108, | ||
1827 | +108, | ||
1828 | +109, | ||
1829 | +110, | ||
1830 | +111, | ||
1831 | +111, | ||
1832 | +112, | ||
1833 | +113, | ||
1834 | +114, | ||
1835 | +114, | ||
1836 | +115, | ||
1837 | +116, | ||
1838 | +117, | ||
1839 | +117, | ||
1840 | +118, | ||
1841 | +119, | ||
1842 | +119, | ||
1843 | +120, | ||
1844 | +120, | ||
1845 | +121, | ||
1846 | +121, | ||
1847 | +122, | ||
1848 | +122, | ||
1849 | +123, | ||
1850 | +123, | ||
1851 | +124, | ||
1852 | +124, | ||
1853 | +125, | ||
1854 | +125, | ||
1855 | +126, | ||
1856 | +126, | ||
1857 | +127, | ||
1858 | +127, | ||
1859 | +128, | ||
1860 | +128, | ||
1861 | +129, | ||
1862 | +129, | ||
1863 | +130, | ||
1864 | +130, | ||
1865 | +131, | ||
1866 | +131, | ||
1867 | +132, | ||
1868 | +132, | ||
1869 | +133, | ||
1870 | +133, | ||
1871 | +134, | ||
1872 | +134, | ||
1873 | +135, | ||
1874 | +135, | ||
1875 | +136, | ||
1876 | +136, | ||
1877 | +137, | ||
1878 | +137, | ||
1879 | +138, | ||
1880 | +138, | ||
1881 | +139, | ||
1882 | +139, | ||
1883 | +140, | ||
1884 | +140, | ||
1885 | +141, | ||
1886 | +141, | ||
1887 | +142, | ||
1888 | +142, | ||
1889 | +143, | ||
1890 | +143, | ||
1891 | +144, | ||
1892 | +144, | ||
1893 | +145, | ||
1894 | +145, | ||
1895 | +146, | ||
1896 | +146, | ||
1897 | +147, | ||
1898 | +147, | ||
1899 | +148, | ||
1900 | +148, | ||
1901 | +149, | ||
1902 | +149, | ||
1903 | +150, | ||
1904 | +150, | ||
1905 | +151, | ||
1906 | +151, | ||
1907 | +152, | ||
1908 | +152, | ||
1909 | +153, | ||
1910 | +153, | ||
1911 | +153, | ||
1912 | +153, | ||
1913 | +154, | ||
1914 | +154, | ||
1915 | +154, | ||
1916 | +154, | ||
1917 | +155, | ||
1918 | +155, | ||
1919 | +156, | ||
1920 | +156, | ||
1921 | +157, | ||
1922 | +157, | ||
1923 | +158, | ||
1924 | +158, | ||
1925 | +158, | ||
1926 | +159, | ||
1927 | +159, | ||
1928 | +159, | ||
1929 | +160, | ||
1930 | +160, | ||
1931 | +160, | ||
1932 | +161, | ||
1933 | +161, | ||
1934 | +162, | ||
1935 | +162, | ||
1936 | +163, | ||
1937 | +163, | ||
1938 | +164, | ||
1939 | +164, | ||
1940 | +164, | ||
1941 | +164, | ||
1942 | +165, | ||
1943 | +165, | ||
1944 | +165, | ||
1945 | +165, | ||
1946 | +166, | ||
1947 | +166, | ||
1948 | +167, | ||
1949 | +167, | ||
1950 | +168, | ||
1951 | +168, | ||
1952 | +169, | ||
1953 | +169, | ||
1954 | +170, | ||
1955 | +170, | ||
1956 | +170, | ||
1957 | +170, | ||
1958 | +171, | ||
1959 | +171, | ||
1960 | +171, | ||
1961 | +171, | ||
1962 | +172, | ||
1963 | +172, | ||
1964 | +173, | ||
1965 | +173, | ||
1966 | +174, | ||
1967 | +174, | ||
1968 | +175, | ||
1969 | +175, | ||
1970 | +176, | ||
1971 | +176, | ||
1972 | +176, | ||
1973 | +176, | ||
1974 | +177, | ||
1975 | +177, | ||
1976 | +177, | ||
1977 | +177, | ||
1978 | +178, | ||
1979 | +178, | ||
1980 | +178, | ||
1981 | +178, | ||
1982 | +179, | ||
1983 | +179, | ||
1984 | +179, | ||
1985 | +179, | ||
1986 | +180, | ||
1987 | +180, | ||
1988 | +180, | ||
1989 | +180, | ||
1990 | +181, | ||
1991 | +181, | ||
1992 | +181, | ||
1993 | +181, | ||
1994 | +182, | ||
1995 | +182, | ||
1996 | +182, | ||
1997 | +182, | ||
1998 | +183, | ||
1999 | +183, | ||
2000 | +183, | ||
2001 | +183, | ||
2002 | +184, | ||
2003 | +184, | ||
2004 | +184, | ||
2005 | +184, | ||
2006 | +185, | ||
2007 | +185, | ||
2008 | +185, | ||
2009 | +185, | ||
2010 | +186, | ||
2011 | +186, | ||
2012 | +186, | ||
2013 | +186, | ||
2014 | +187, | ||
2015 | +187, | ||
2016 | +187, | ||
2017 | +187, | ||
2018 | +188, | ||
2019 | +188, | ||
2020 | +188, | ||
2021 | +188, | ||
2022 | +189, | ||
2023 | +189, | ||
2024 | +189, | ||
2025 | +189, | ||
2026 | +190, | ||
2027 | +190, | ||
2028 | +190, | ||
2029 | +190, | ||
2030 | +191, | ||
2031 | +191, | ||
2032 | +191, | ||
2033 | +191, | ||
2034 | +192, | ||
2035 | +192, | ||
2036 | +192, | ||
2037 | +192, | ||
2038 | +193, | ||
2039 | +193, | ||
2040 | +193, | ||
2041 | +193, | ||
2042 | +194, | ||
2043 | +194, | ||
2044 | +194, | ||
2045 | +194, | ||
2046 | +195, | ||
2047 | +195, | ||
2048 | +195, | ||
2049 | +195, | ||
2050 | +196, | ||
2051 | +196, | ||
2052 | +196, | ||
2053 | +196, | ||
2054 | +197, | ||
2055 | +197, | ||
2056 | +197, | ||
2057 | +197, | ||
2058 | +198, | ||
2059 | +198, | ||
2060 | +198, | ||
2061 | +198, | ||
2062 | +199, | ||
2063 | +199, | ||
2064 | +199, | ||
2065 | +199, | ||
2066 | +200, | ||
2067 | +200, | ||
2068 | +200, | ||
2069 | +200, | ||
2070 | +201, | ||
2071 | +201, | ||
2072 | +201, | ||
2073 | +201, | ||
2074 | +202, | ||
2075 | +202, | ||
2076 | +202, | ||
2077 | +203, | ||
2078 | +203, | ||
2079 | +203, | ||
2080 | +203, | ||
2081 | +204, | ||
2082 | +204, | ||
2083 | +204, | ||
2084 | +204, | ||
2085 | +205, | ||
2086 | +205, | ||
2087 | +205, | ||
2088 | +205, | ||
2089 | +206, | ||
2090 | +206, | ||
2091 | +206, | ||
2092 | +206, | ||
2093 | +207, | ||
2094 | +207, | ||
2095 | +207, | ||
2096 | +207, | ||
2097 | +208, | ||
2098 | +208, | ||
2099 | +208, | ||
2100 | +208, | ||
2101 | +209, | ||
2102 | +209, | ||
2103 | +209, | ||
2104 | +209, | ||
2105 | +210, | ||
2106 | +210, | ||
2107 | +210, | ||
2108 | +210, | ||
2109 | +210, | ||
2110 | +210, | ||
2111 | +210, | ||
2112 | +210, | ||
2113 | +210, | ||
2114 | +210, | ||
2115 | +210, | ||
2116 | +210, | ||
2117 | +211, | ||
2118 | +211, | ||
2119 | +211, | ||
2120 | +211, | ||
2121 | +211, | ||
2122 | +211, | ||
2123 | +211, | ||
2124 | +211, | ||
2125 | +211, | ||
2126 | +211, | ||
2127 | +211, | ||
2128 | +212, | ||
2129 | +212, | ||
2130 | +212, | ||
2131 | +212, | ||
2132 | +213, | ||
2133 | +213, | ||
2134 | +213, | ||
2135 | +213, | ||
2136 | +213, | ||
2137 | +213, | ||
2138 | +213, | ||
2139 | +213, | ||
2140 | +213, | ||
2141 | +213, | ||
2142 | +213, | ||
2143 | +213, | ||
2144 | +214, | ||
2145 | +214, | ||
2146 | +214, | ||
2147 | +214, | ||
2148 | +215, | ||
2149 | +215, | ||
2150 | +215, | ||
2151 | +215, | ||
2152 | +215, | ||
2153 | +215, | ||
2154 | +215, | ||
2155 | +215, | ||
2156 | +215, | ||
2157 | +215, | ||
2158 | +215, | ||
2159 | +216, | ||
2160 | +216, | ||
2161 | +216, | ||
2162 | +216, | ||
2163 | +217, | ||
2164 | +217, | ||
2165 | +217, | ||
2166 | +217, | ||
2167 | +218, | ||
2168 | +218, | ||
2169 | +218, | ||
2170 | +218, | ||
2171 | +219, | ||
2172 | +219, | ||
2173 | +219, | ||
2174 | +219, | ||
2175 | +219, | ||
2176 | +219, | ||
2177 | +219, | ||
2178 | +219, | ||
2179 | +219, | ||
2180 | +219, | ||
2181 | +219, | ||
2182 | +219, | ||
2183 | +220, | ||
2184 | +220, | ||
2185 | +220, | ||
2186 | +220, | ||
2187 | +221, | ||
2188 | +221, | ||
2189 | +221, | ||
2190 | +221, | ||
2191 | +221, | ||
2192 | +221, | ||
2193 | +221, | ||
2194 | +221, | ||
2195 | +221, | ||
2196 | +221, | ||
2197 | +221, | ||
2198 | +222, | ||
2199 | +222, | ||
2200 | +222, | ||
2201 | +222, | ||
2202 | +223, | ||
2203 | +223, | ||
2204 | +223, | ||
2205 | +223, | ||
2206 | +223, | ||
2207 | +223, | ||
2208 | +223, | ||
2209 | +223, | ||
2210 | +223, | ||
2211 | +223, | ||
2212 | +223, | ||
2213 | +223, | ||
2214 | +224, | ||
2215 | +224, | ||
2216 | +224, | ||
2217 | +224, | ||
2218 | +225, | ||
2219 | +225, | ||
2220 | +225, | ||
2221 | +225, | ||
2222 | +225, | ||
2223 | +225, | ||
2224 | +225, | ||
2225 | +225, | ||
2226 | +225, | ||
2227 | +225, | ||
2228 | +225, | ||
2229 | +225, | ||
2230 | +225, | ||
2231 | +225, | ||
2232 | +225, | ||
2233 | +225, | ||
2234 | +225, | ||
2235 | +225, | ||
2236 | +225, | ||
2237 | +226, | ||
2238 | +226, | ||
2239 | +226, | ||
2240 | +226, | ||
2241 | +227, | ||
2242 | +227, | ||
2243 | +227, | ||
2244 | +227, | ||
2245 | +227, | ||
2246 | +227, | ||
2247 | +227, | ||
2248 | +227, | ||
2249 | +227, | ||
2250 | +227, | ||
2251 | +227, | ||
2252 | +227, | ||
2253 | +228, | ||
2254 | +228, | ||
2255 | +228, | ||
2256 | +229, | ||
2257 | +229, | ||
2258 | +229, | ||
2259 | +229, | ||
2260 | +229, | ||
2261 | +229, | ||
2262 | +229, | ||
2263 | +229, | ||
2264 | +229, | ||
2265 | +229, | ||
2266 | +229, | ||
2267 | +229, | ||
2268 | +230, | ||
2269 | +230, | ||
2270 | +230, | ||
2271 | +230, | ||
2272 | +231, | ||
2273 | +231, | ||
2274 | +231, | ||
2275 | +231, | ||
2276 | +231, | ||
2277 | +231, | ||
2278 | +231, | ||
2279 | +231, | ||
2280 | +231, | ||
2281 | +231, | ||
2282 | +231, | ||
2283 | +231, | ||
2284 | +232, | ||
2285 | +232, | ||
2286 | +232, | ||
2287 | +232, | ||
2288 | +232, | ||
2289 | +232, | ||
2290 | +232, | ||
2291 | +232, | ||
2292 | +232, | ||
2293 | +232, | ||
2294 | +232, | ||
2295 | +232, | ||
2296 | +232, | ||
2297 | +232, | ||
2298 | +232, | ||
2299 | +232, | ||
2300 | +232, | ||
2301 | +232, | ||
2302 | +232, | ||
2303 | +233, | ||
2304 | +233, | ||
2305 | +233, | ||
2306 | +233, | ||
2307 | +234, | ||
2308 | +234, | ||
2309 | +234, | ||
2310 | +234, | ||
2311 | +234, | ||
2312 | +234, | ||
2313 | +234, | ||
2314 | +234, | ||
2315 | +234, | ||
2316 | +234, | ||
2317 | +234, | ||
2318 | +235, | ||
2319 | +235, | ||
2320 | +235, | ||
2321 | +235, | ||
2322 | +236, | ||
2323 | +236, | ||
2324 | +236, | ||
2325 | +236, | ||
2326 | +236, | ||
2327 | +236, | ||
2328 | +236, | ||
2329 | +236, | ||
2330 | +236, | ||
2331 | +236, | ||
2332 | +236, | ||
2333 | +236, | ||
2334 | +236, | ||
2335 | +236, | ||
2336 | +236, | ||
2337 | +236, | ||
2338 | +236, | ||
2339 | +236, | ||
2340 | +236, | ||
2341 | +237, | ||
2342 | +237, | ||
2343 | +237, | ||
2344 | +237, | ||
2345 | +238, | ||
2346 | +238, | ||
2347 | +238, | ||
2348 | +238, | ||
2349 | +238, | ||
2350 | +238, | ||
2351 | +238, | ||
2352 | +238, | ||
2353 | +238, | ||
2354 | +238, | ||
2355 | +238, | ||
2356 | +238, | ||
2357 | +238, | ||
2358 | +238, | ||
2359 | +238, | ||
2360 | +238, | ||
2361 | +238, | ||
2362 | +238, | ||
2363 | +238, | ||
2364 | +238, | ||
2365 | +238, | ||
2366 | +238, | ||
2367 | +238, | ||
2368 | +238, | ||
2369 | +238, | ||
2370 | +238, | ||
2371 | +238, | ||
2372 | +239, | ||
2373 | +239, | ||
2374 | +239, | ||
2375 | +239, | ||
2376 | +240, | ||
2377 | +240, | ||
2378 | +240, | ||
2379 | +240, | ||
2380 | +240, | ||
2381 | +240, | ||
2382 | +240, | ||
2383 | +240, | ||
2384 | +240, | ||
2385 | +240, | ||
2386 | +240, | ||
2387 | +240, | ||
2388 | +240, | ||
2389 | +240, | ||
2390 | +240, | ||
2391 | +240, | ||
2392 | +240, | ||
2393 | +240, | ||
2394 | +240, | ||
2395 | +240, | ||
2396 | +240, | ||
2397 | +240, | ||
2398 | +240, | ||
2399 | +240, | ||
2400 | +240, | ||
2401 | +240, | ||
2402 | +240, | ||
2403 | +241, | ||
2404 | +241, | ||
2405 | +241, | ||
2406 | +241, | ||
2407 | +242, | ||
2408 | +242, | ||
2409 | +242, | ||
2410 | +242, | ||
2411 | +242, | ||
2412 | +242, | ||
2413 | +242, | ||
2414 | +242, | ||
2415 | +242, | ||
2416 | +242, | ||
2417 | +242, | ||
2418 | +242, | ||
2419 | +242, | ||
2420 | +242, | ||
2421 | +242, | ||
2422 | +242, | ||
2423 | +242, | ||
2424 | +242, | ||
2425 | +242, | ||
2426 | +242, | ||
2427 | +242, | ||
2428 | +242, | ||
2429 | +242, | ||
2430 | +242, | ||
2431 | +242, | ||
2432 | +242, | ||
2433 | +243, | ||
2434 | +243, | ||
2435 | +243, | ||
2436 | +243, | ||
2437 | +244, | ||
2438 | +244, | ||
2439 | +244, | ||
2440 | +244, | ||
2441 | +244, | ||
2442 | +244, | ||
2443 | +244, | ||
2444 | +244, | ||
2445 | +244, | ||
2446 | +244, | ||
2447 | +244, | ||
2448 | +244, | ||
2449 | +244, | ||
2450 | +244, | ||
2451 | +244, | ||
2452 | +244, | ||
2453 | +244, | ||
2454 | +244, | ||
2455 | +244, | ||
2456 | +244, | ||
2457 | +244, | ||
2458 | +244, | ||
2459 | +244, | ||
2460 | +244, | ||
2461 | +244, | ||
2462 | +244, | ||
2463 | +244, | ||
2464 | +245, | ||
2465 | +245, | ||
2466 | +245, | ||
2467 | +245, | ||
2468 | +246, | ||
2469 | +246, | ||
2470 | +246, | ||
2471 | +246, | ||
2472 | +246, | ||
2473 | +246, | ||
2474 | +246, | ||
2475 | +246, | ||
2476 | +246, | ||
2477 | +246, | ||
2478 | +246, | ||
2479 | +246, | ||
2480 | +246, | ||
2481 | +246, | ||
2482 | +246, | ||
2483 | +246, | ||
2484 | +246, | ||
2485 | +246, | ||
2486 | +246, | ||
2487 | +246, | ||
2488 | +246, | ||
2489 | +246, | ||
2490 | +246, | ||
2491 | +246, | ||
2492 | +246, | ||
2493 | +246, | ||
2494 | +246, | ||
2495 | +246, | ||
2496 | +246, | ||
2497 | +246, | ||
2498 | +246, | ||
2499 | +246, | ||
2500 | +246, | ||
2501 | +246, | ||
2502 | +247, | ||
2503 | +247, | ||
2504 | +247, | ||
2505 | +247, | ||
2506 | +248, | ||
2507 | +248, | ||
2508 | +248, | ||
2509 | +248, | ||
2510 | +248, | ||
2511 | +248, | ||
2512 | +248, | ||
2513 | +248, | ||
2514 | +248, | ||
2515 | +248, | ||
2516 | +248, | ||
2517 | +248, | ||
2518 | +248, | ||
2519 | +248, | ||
2520 | +248, | ||
2521 | +248, | ||
2522 | +248, | ||
2523 | +248, | ||
2524 | +248, | ||
2525 | +248, | ||
2526 | +248, | ||
2527 | +248, | ||
2528 | +248, | ||
2529 | +248, | ||
2530 | +248, | ||
2531 | +248, | ||
2532 | +248, | ||
2533 | +249, | ||
2534 | +249, | ||
2535 | +249, | ||
2536 | +249, | ||
2537 | +250, | ||
2538 | +250, | ||
2539 | +250, | ||
2540 | +250, | ||
2541 | +250, | ||
2542 | +250, | ||
2543 | +250, | ||
2544 | +250, | ||
2545 | +250, | ||
2546 | +250, | ||
2547 | +250, | ||
2548 | +250, | ||
2549 | +250, | ||
2550 | +250, | ||
2551 | +250, | ||
2552 | +250, | ||
2553 | +250, | ||
2554 | +250, | ||
2555 | +250, | ||
2556 | +250, | ||
2557 | +250, | ||
2558 | +250, | ||
2559 | +250, | ||
2560 | +250, | ||
2561 | +250, | ||
2562 | +250, | ||
2563 | +250, | ||
2564 | +250, | ||
2565 | +250, | ||
2566 | +250, | ||
2567 | +250, | ||
2568 | +250, | ||
2569 | +250, | ||
2570 | +250, | ||
2571 | +250, | ||
2572 | +250, | ||
2573 | +250, | ||
2574 | +250, | ||
2575 | +250, | ||
2576 | +250, | ||
2577 | +250, | ||
2578 | +250, | ||
2579 | +251, | ||
2580 | +251, | ||
2581 | +251, | ||
2582 | +251, | ||
2583 | +252, | ||
2584 | +252, | ||
2585 | +252, | ||
2586 | +252, | ||
2587 | +252, | ||
2588 | +252, | ||
2589 | +252, | ||
2590 | +252, | ||
2591 | +252, | ||
2592 | +252, | ||
2593 | +252, | ||
2594 | +252, | ||
2595 | +252, | ||
2596 | +252, | ||
2597 | +252, | ||
2598 | +252, | ||
2599 | +252, | ||
2600 | +252, | ||
2601 | +252, | ||
2602 | +252, | ||
2603 | +252, | ||
2604 | +252, | ||
2605 | +252, | ||
2606 | +252, | ||
2607 | +252, | ||
2608 | +252, | ||
2609 | +252, | ||
2610 | +252, | ||
2611 | +252, | ||
2612 | +252, | ||
2613 | +252, | ||
2614 | +252, | ||
2615 | +252, | ||
2616 | +252, | ||
2617 | +252, | ||
2618 | +252, | ||
2619 | +252, | ||
2620 | +252, | ||
2621 | +252, | ||
2622 | +252, | ||
2623 | +252, | ||
2624 | +252, | ||
2625 | +252, | ||
2626 | +252, | ||
2627 | +252, | ||
2628 | +252, | ||
2629 | +252, | ||
2630 | +252, | ||
2631 | +252, | ||
2632 | +252, | ||
2633 | +252, | ||
2634 | +252, | ||
2635 | +252, | ||
2636 | +252, | ||
2637 | +252, | ||
2638 | +252, | ||
2639 | +252, | ||
2640 | +252, | ||
2641 | +252, | ||
2642 | +252, | ||
2643 | +252, | ||
2644 | +252, | ||
2645 | +252, | ||
2646 | +252, | ||
2647 | +253, | ||
2648 | +253, | ||
2649 | +253, | ||
2650 | +253, | ||
2651 | +253, | ||
2652 | +253, | ||
2653 | +253, | ||
2654 | +253, | ||
2655 | +253, | ||
2656 | +253, | ||
2657 | +253, | ||
2658 | +253, | ||
2659 | +253, | ||
2660 | +253, | ||
2661 | +253, | ||
2662 | +253, | ||
2663 | +253, | ||
2664 | +253, | ||
2665 | +253, | ||
2666 | +253, | ||
2667 | +253, | ||
2668 | +253, | ||
2669 | +253, | ||
2670 | +253, | ||
2671 | +253, | ||
2672 | +253, | ||
2673 | +253, | ||
2674 | +253, | ||
2675 | +253, | ||
2676 | +253, | ||
2677 | +253, | ||
2678 | +253, | ||
2679 | +253, | ||
2680 | +253, | ||
2681 | +253, | ||
2682 | +253, | ||
2683 | +253, | ||
2684 | +253, | ||
2685 | +253, | ||
2686 | +253, | ||
2687 | +253, | ||
2688 | +253, | ||
2689 | +253, | ||
2690 | +253, | ||
2691 | +253, | ||
2692 | +253, | ||
2693 | +253, | ||
2694 | +253, | ||
2695 | +253, | ||
2696 | +253, | ||
2697 | +253, | ||
2698 | +253, | ||
2699 | +253, | ||
2700 | +253, | ||
2701 | +253, | ||
2702 | +253, | ||
2703 | +253, | ||
2704 | +254, | ||
2705 | +254, | ||
2706 | +254, | ||
2707 | +254, | ||
2708 | +255, | ||
2709 | +255, | ||
2710 | +255, | ||
2711 | +255, | ||
2712 | +255, | ||
2713 | +255, | ||
2714 | +255, | ||
2715 | +255, | ||
2716 | +255, | ||
2717 | +255, | ||
2718 | +255, | ||
2719 | +255, | ||
2720 | +255, | ||
2721 | +255, | ||
2722 | +255, | ||
2723 | +255, | ||
2724 | +255, | ||
2725 | +255, | ||
2726 | +255, | ||
2727 | +255, | ||
2728 | +255, | ||
2729 | +255, | ||
2730 | +255, | ||
2731 | +255, | ||
2732 | +255, | ||
2733 | +255, | ||
2734 | +255 | ||
2735 | diff --git a/drivers/media/video/isp/luma_enhance_table.h b/drivers/media/video/isp/luma_enhance_table.h | ||
2736 | new file mode 100644 | ||
2737 | index 0000000..99c8b05 | ||
2738 | --- /dev/null | ||
2739 | +++ b/drivers/media/video/isp/luma_enhance_table.h | ||
2740 | @@ -0,0 +1,144 @@ | ||
2741 | +/* | ||
2742 | + * luma_enhance_table.h | ||
2743 | + * | ||
2744 | + * Luminance Enhancement table values for TI's OMAP3 Camera ISP | ||
2745 | + * | ||
2746 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
2747 | + * | ||
2748 | + * This package is free software; you can redistribute it and/or modify | ||
2749 | + * it under the terms of the GNU General Public License version 2 as | ||
2750 | + * published by the Free Software Foundation. | ||
2751 | + * | ||
2752 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
2753 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
2754 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
2755 | + */ | ||
2756 | + | ||
2757 | +1047552, | ||
2758 | +1047552, | ||
2759 | +1047552, | ||
2760 | +1047552, | ||
2761 | +1047552, | ||
2762 | +1047552, | ||
2763 | +1047552, | ||
2764 | +1047552, | ||
2765 | +1047552, | ||
2766 | +1047552, | ||
2767 | +1047552, | ||
2768 | +1047552, | ||
2769 | +1047552, | ||
2770 | +1047552, | ||
2771 | +1047552, | ||
2772 | +1047552, | ||
2773 | +1047552, | ||
2774 | +1047552, | ||
2775 | +1047552, | ||
2776 | +1047552, | ||
2777 | +1047552, | ||
2778 | +1047552, | ||
2779 | +1047552, | ||
2780 | +1047552, | ||
2781 | +1047552, | ||
2782 | +1047552, | ||
2783 | +1047552, | ||
2784 | +1047552, | ||
2785 | +1048575, | ||
2786 | +1047551, | ||
2787 | +1046527, | ||
2788 | +1045503, | ||
2789 | +1044479, | ||
2790 | +1043455, | ||
2791 | +1042431, | ||
2792 | +1041407, | ||
2793 | +1040383, | ||
2794 | +1039359, | ||
2795 | +1038335, | ||
2796 | +1037311, | ||
2797 | +1036287, | ||
2798 | +1035263, | ||
2799 | +1034239, | ||
2800 | +1033215, | ||
2801 | +1032191, | ||
2802 | +1031167, | ||
2803 | +1030143, | ||
2804 | +1028096, | ||
2805 | +1028096, | ||
2806 | +1028096, | ||
2807 | +1028096, | ||
2808 | +1028096, | ||
2809 | +1028096, | ||
2810 | +1028096, | ||
2811 | +1028096, | ||
2812 | +1028096, | ||
2813 | +1028096, | ||
2814 | +1028100, | ||
2815 | +1032196, | ||
2816 | +1036292, | ||
2817 | +1040388, | ||
2818 | +1044484, | ||
2819 | +0, | ||
2820 | +0, | ||
2821 | +0, | ||
2822 | +5, | ||
2823 | +5125, | ||
2824 | +10245, | ||
2825 | +15365, | ||
2826 | +20485, | ||
2827 | +25605, | ||
2828 | +30720, | ||
2829 | +30720, | ||
2830 | +30720, | ||
2831 | +30720, | ||
2832 | +30720, | ||
2833 | +30720, | ||
2834 | +30720, | ||
2835 | +30720, | ||
2836 | +30720, | ||
2837 | +30720, | ||
2838 | +30720, | ||
2839 | +31743, | ||
2840 | +30719, | ||
2841 | +29695, | ||
2842 | +28671, | ||
2843 | +27647, | ||
2844 | +26623, | ||
2845 | +25599, | ||
2846 | +24575, | ||
2847 | +23551, | ||
2848 | +22527, | ||
2849 | +21503, | ||
2850 | +20479, | ||
2851 | +19455, | ||
2852 | +18431, | ||
2853 | +17407, | ||
2854 | +16383, | ||
2855 | +15359, | ||
2856 | +14335, | ||
2857 | +13311, | ||
2858 | +12287, | ||
2859 | +11263, | ||
2860 | +10239, | ||
2861 | +9215, | ||
2862 | +8191, | ||
2863 | +7167, | ||
2864 | +6143, | ||
2865 | +5119, | ||
2866 | +4095, | ||
2867 | +3071, | ||
2868 | +1024, | ||
2869 | +1024, | ||
2870 | +1024, | ||
2871 | +1024, | ||
2872 | +1024, | ||
2873 | +1024, | ||
2874 | +1024, | ||
2875 | +1024, | ||
2876 | +1024, | ||
2877 | +1024, | ||
2878 | +1024, | ||
2879 | +1024, | ||
2880 | +1024, | ||
2881 | +1024, | ||
2882 | +1024, | ||
2883 | +1024, | ||
2884 | +1024 | ||
2885 | diff --git a/drivers/media/video/isp/noise_filter_table.h b/drivers/media/video/isp/noise_filter_table.h | ||
2886 | new file mode 100644 | ||
2887 | index 0000000..7345f90 | ||
2888 | --- /dev/null | ||
2889 | +++ b/drivers/media/video/isp/noise_filter_table.h | ||
2890 | @@ -0,0 +1,79 @@ | ||
2891 | +/* | ||
2892 | + * noise_filter_table.h | ||
2893 | + * | ||
2894 | + * Noise Filter Table values for TI's OMAP3 Camera ISP | ||
2895 | + * | ||
2896 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
2897 | + * | ||
2898 | + * This package is free software; you can redistribute it and/or modify | ||
2899 | + * it under the terms of the GNU General Public License version 2 as | ||
2900 | + * published by the Free Software Foundation. | ||
2901 | + * | ||
2902 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
2903 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
2904 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
2905 | + */ | ||
2906 | +16, | ||
2907 | +16, | ||
2908 | +16, | ||
2909 | +16, | ||
2910 | +16, | ||
2911 | +16, | ||
2912 | +16, | ||
2913 | +16, | ||
2914 | +16, | ||
2915 | +16, | ||
2916 | +16, | ||
2917 | +16, | ||
2918 | +16, | ||
2919 | +16, | ||
2920 | +16, | ||
2921 | +16, | ||
2922 | +16, | ||
2923 | +16, | ||
2924 | +16, | ||
2925 | +16, | ||
2926 | +16, | ||
2927 | +16, | ||
2928 | +16, | ||
2929 | +16, | ||
2930 | +16, | ||
2931 | +16, | ||
2932 | +16, | ||
2933 | +16, | ||
2934 | +16, | ||
2935 | +16, | ||
2936 | +16, | ||
2937 | +16, | ||
2938 | +31, | ||
2939 | +31, | ||
2940 | +31, | ||
2941 | +31, | ||
2942 | +31, | ||
2943 | +31, | ||
2944 | +31, | ||
2945 | +31, | ||
2946 | +31, | ||
2947 | +31, | ||
2948 | +31, | ||
2949 | +31, | ||
2950 | +31, | ||
2951 | +31, | ||
2952 | +31, | ||
2953 | +31, | ||
2954 | +31, | ||
2955 | +31, | ||
2956 | +31, | ||
2957 | +31, | ||
2958 | +31, | ||
2959 | +31, | ||
2960 | +31, | ||
2961 | +31, | ||
2962 | +31, | ||
2963 | +31, | ||
2964 | +31, | ||
2965 | +31, | ||
2966 | +31, | ||
2967 | +31, | ||
2968 | +31, | ||
2969 | +31 | ||
2970 | diff --git a/drivers/media/video/isp/redgamma_table.h b/drivers/media/video/isp/redgamma_table.h | ||
2971 | new file mode 100644 | ||
2972 | index 0000000..ad0232a | ||
2973 | --- /dev/null | ||
2974 | +++ b/drivers/media/video/isp/redgamma_table.h | ||
2975 | @@ -0,0 +1,1040 @@ | ||
2976 | +/* | ||
2977 | + * redgamma_table.h | ||
2978 | + * | ||
2979 | + * Gamma Table values for RED for TI's OMAP3 Camera ISP | ||
2980 | + * | ||
2981 | + * Copyright (C) 2009 Texas Instruments, Inc. | ||
2982 | + * | ||
2983 | + * This package is free software; you can redistribute it and/or modify | ||
2984 | + * it under the terms of the GNU General Public License version 2 as | ||
2985 | + * published by the Free Software Foundation. | ||
2986 | + * | ||
2987 | + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
2988 | + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
2989 | + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
2990 | + */ | ||
2991 | + | ||
2992 | +0, | ||
2993 | +0, | ||
2994 | +1, | ||
2995 | +2, | ||
2996 | +3, | ||
2997 | +3, | ||
2998 | +4, | ||
2999 | +5, | ||
3000 | +6, | ||
3001 | +8, | ||
3002 | +10, | ||
3003 | +12, | ||
3004 | +14, | ||
3005 | +16, | ||
3006 | +18, | ||
3007 | +20, | ||
3008 | +22, | ||
3009 | +23, | ||
3010 | +25, | ||
3011 | +26, | ||
3012 | +28, | ||
3013 | +29, | ||
3014 | +31, | ||
3015 | +32, | ||
3016 | +34, | ||
3017 | +35, | ||
3018 | +36, | ||
3019 | +37, | ||
3020 | +39, | ||
3021 | +40, | ||
3022 | +41, | ||
3023 | +42, | ||
3024 | +43, | ||
3025 | +44, | ||
3026 | +45, | ||
3027 | +46, | ||
3028 | +47, | ||
3029 | +48, | ||
3030 | +49, | ||
3031 | +50, | ||
3032 | +51, | ||
3033 | +52, | ||
3034 | +52, | ||
3035 | +53, | ||
3036 | +54, | ||
3037 | +55, | ||
3038 | +56, | ||
3039 | +57, | ||
3040 | +58, | ||
3041 | +59, | ||
3042 | +60, | ||
3043 | +61, | ||
3044 | +62, | ||
3045 | +63, | ||
3046 | +63, | ||
3047 | +64, | ||
3048 | +65, | ||
3049 | +66, | ||
3050 | +66, | ||
3051 | +67, | ||
3052 | +68, | ||
3053 | +69, | ||
3054 | +69, | ||
3055 | +70, | ||
3056 | +71, | ||
3057 | +72, | ||
3058 | +72, | ||
3059 | +73, | ||
3060 | +74, | ||
3061 | +75, | ||
3062 | +75, | ||
3063 | +76, | ||
3064 | +77, | ||
3065 | +78, | ||
3066 | +78, | ||
3067 | +79, | ||
3068 | +80, | ||
3069 | +81, | ||
3070 | +81, | ||
3071 | +82, | ||
3072 | +83, | ||
3073 | +84, | ||
3074 | +84, | ||
3075 | +85, | ||
3076 | +86, | ||
3077 | +87, | ||
3078 | +88, | ||
3079 | +88, | ||
3080 | +89, | ||
3081 | +90, | ||
3082 | +91, | ||
3083 | +91, | ||
3084 | +92, | ||
3085 | +93, | ||
3086 | +94, | ||
3087 | +94, | ||
3088 | +95, | ||
3089 | +96, | ||
3090 | +97, | ||
3091 | +97, | ||
3092 | +98, | ||
3093 | +98, | ||
3094 | +99, | ||
3095 | +99, | ||
3096 | +100, | ||
3097 | +100, | ||
3098 | +101, | ||
3099 | +101, | ||
3100 | +102, | ||
3101 | +103, | ||
3102 | +104, | ||
3103 | +104, | ||
3104 | +105, | ||
3105 | +106, | ||
3106 | +107, | ||
3107 | +108, | ||
3108 | +108, | ||
3109 | +109, | ||
3110 | +110, | ||
3111 | +111, | ||
3112 | +111, | ||
3113 | +112, | ||
3114 | +113, | ||
3115 | +114, | ||
3116 | +114, | ||
3117 | +115, | ||
3118 | +116, | ||
3119 | +117, | ||
3120 | +117, | ||
3121 | +118, | ||
3122 | +119, | ||
3123 | +119, | ||
3124 | +120, | ||
3125 | +120, | ||
3126 | +121, | ||
3127 | +121, | ||
3128 | +122, | ||
3129 | +122, | ||
3130 | +123, | ||
3131 | +123, | ||
3132 | +124, | ||
3133 | +124, | ||
3134 | +125, | ||
3135 | +125, | ||
3136 | +126, | ||
3137 | +126, | ||
3138 | +127, | ||
3139 | +127, | ||
3140 | +128, | ||
3141 | +128, | ||
3142 | +129, | ||
3143 | +129, | ||
3144 | +130, | ||
3145 | +130, | ||
3146 | +131, | ||
3147 | +131, | ||
3148 | +132, | ||
3149 | +132, | ||
3150 | +133, | ||
3151 | +133, | ||
3152 | +134, | ||
3153 | +134, | ||
3154 | +135, | ||
3155 | +135, | ||
3156 | +136, | ||
3157 | +136, | ||
3158 | +137, | ||
3159 | +137, | ||
3160 | +138, | ||
3161 | +138, | ||
3162 | +139, | ||
3163 | +139, | ||
3164 | +140, | ||
3165 | +140, | ||
3166 | +141, | ||
3167 | +141, | ||
3168 | +142, | ||
3169 | +142, | ||
3170 | +143, | ||
3171 | +143, | ||
3172 | +144, | ||
3173 | +144, | ||
3174 | +145, | ||
3175 | +145, | ||
3176 | +146, | ||
3177 | +146, | ||
3178 | +147, | ||
3179 | +147, | ||
3180 | +148, | ||
3181 | +148, | ||
3182 | +149, | ||
3183 | +149, | ||
3184 | +150, | ||
3185 | +150, | ||
3186 | +151, | ||
3187 | +151, | ||
3188 | +152, | ||
3189 | +152, | ||
3190 | +153, | ||
3191 | +153, | ||
3192 | +153, | ||
3193 | +153, | ||
3194 | +154, | ||
3195 | +154, | ||
3196 | +154, | ||
3197 | +154, | ||
3198 | +155, | ||
3199 | +155, | ||
3200 | +156, | ||
3201 | +156, | ||
3202 | +157, | ||
3203 | +157, | ||
3204 | +158, | ||
3205 | +158, | ||
3206 | +158, | ||
3207 | +159, | ||
3208 | +159, | ||
3209 | +159, | ||
3210 | +160, | ||
3211 | +160, | ||
3212 | +160, | ||
3213 | +161, | ||
3214 | +161, | ||
3215 | +162, | ||
3216 | +162, | ||
3217 | +163, | ||
3218 | +163, | ||
3219 | +164, | ||
3220 | +164, | ||
3221 | +164, | ||
3222 | +164, | ||
3223 | +165, | ||
3224 | +165, | ||
3225 | +165, | ||
3226 | +165, | ||
3227 | +166, | ||
3228 | +166, | ||
3229 | +167, | ||
3230 | +167, | ||
3231 | +168, | ||
3232 | +168, | ||
3233 | +169, | ||
3234 | +169, | ||
3235 | +170, | ||
3236 | +170, | ||
3237 | +170, | ||
3238 | +170, | ||
3239 | +171, | ||
3240 | +171, | ||
3241 | +171, | ||
3242 | +171, | ||
3243 | +172, | ||
3244 | +172, | ||
3245 | +173, | ||
3246 | +173, | ||
3247 | +174, | ||
3248 | +174, | ||
3249 | +175, | ||
3250 | +175, | ||
3251 | +176, | ||
3252 | +176, | ||
3253 | +176, | ||
3254 | +176, | ||
3255 | +177, | ||
3256 | +177, | ||
3257 | +177, | ||
3258 | +177, | ||
3259 | +178, | ||
3260 | +178, | ||
3261 | +178, | ||
3262 | +178, | ||
3263 | +179, | ||
3264 | +179, | ||
3265 | +179, | ||
3266 | +179, | ||
3267 | +180, | ||
3268 | +180, | ||
3269 | +180, | ||
3270 | +180, | ||
3271 | +181, | ||
3272 | +181, | ||
3273 | +181, | ||
3274 | +181, | ||
3275 | +182, | ||
3276 | +182, | ||
3277 | +182, | ||
3278 | +182, | ||
3279 | +183, | ||
3280 | +183, | ||
3281 | +183, | ||
3282 | +183, | ||
3283 | +184, | ||
3284 | +184, | ||
3285 | +184, | ||
3286 | +184, | ||
3287 | +185, | ||
3288 | +185, | ||
3289 | +185, | ||
3290 | +185, | ||
3291 | +186, | ||
3292 | +186, | ||
3293 | +186, | ||
3294 | +186, | ||
3295 | +187, | ||
3296 | +187, | ||
3297 | +187, | ||
3298 | +187, | ||
3299 | +188, | ||
3300 | +188, | ||
3301 | +188, | ||
3302 | +188, | ||
3303 | +189, | ||
3304 | +189, | ||
3305 | +189, | ||
3306 | +189, | ||
3307 | +190, | ||
3308 | +190, | ||
3309 | +190, | ||
3310 | +190, | ||
3311 | +191, | ||
3312 | +191, | ||
3313 | +191, | ||
3314 | +191, | ||
3315 | +192, | ||
3316 | +192, | ||
3317 | +192, | ||
3318 | +192, | ||
3319 | +193, | ||
3320 | +193, | ||
3321 | +193, | ||
3322 | +193, | ||
3323 | +194, | ||
3324 | +194, | ||
3325 | +194, | ||
3326 | +194, | ||
3327 | +195, | ||
3328 | +195, | ||
3329 | +195, | ||
3330 | +195, | ||
3331 | +196, | ||
3332 | +196, | ||
3333 | +196, | ||
3334 | +196, | ||
3335 | +197, | ||
3336 | +197, | ||
3337 | +197, | ||
3338 | +197, | ||
3339 | +198, | ||
3340 | +198, | ||
3341 | +198, | ||
3342 | +198, | ||
3343 | +199, | ||
3344 | +199, | ||
3345 | +199, | ||
3346 | +199, | ||
3347 | +200, | ||
3348 | +200, | ||
3349 | +200, | ||
3350 | +200, | ||
3351 | +201, | ||
3352 | +201, | ||
3353 | +201, | ||
3354 | +201, | ||
3355 | +202, | ||
3356 | +202, | ||
3357 | +202, | ||
3358 | +203, | ||
3359 | +203, | ||
3360 | +203, | ||
3361 | +203, | ||
3362 | +204, | ||
3363 | +204, | ||
3364 | +204, | ||
3365 | +204, | ||
3366 | +205, | ||
3367 | +205, | ||
3368 | +205, | ||
3369 | +205, | ||
3370 | +206, | ||
3371 | +206, | ||
3372 | +206, | ||
3373 | +206, | ||
3374 | +207, | ||
3375 | +207, | ||
3376 | +207, | ||
3377 | +207, | ||
3378 | +208, | ||
3379 | +208, | ||
3380 | +208, | ||
3381 | +208, | ||
3382 | +209, | ||
3383 | +209, | ||
3384 | +209, | ||
3385 | +209, | ||
3386 | +210, | ||
3387 | +210, | ||
3388 | +210, | ||
3389 | +210, | ||
3390 | +210, | ||
3391 | +210, | ||
3392 | +210, | ||
3393 | +210, | ||
3394 | +210, | ||
3395 | +210, | ||
3396 | +210, | ||
3397 | +210, | ||
3398 | +211, | ||
3399 | +211, | ||
3400 | +211, | ||
3401 | +211, | ||
3402 | +211, | ||
3403 | +211, | ||
3404 | +211, | ||
3405 | +211, | ||
3406 | +211, | ||
3407 | +211, | ||
3408 | +211, | ||
3409 | +212, | ||
3410 | +212, | ||
3411 | +212, | ||
3412 | +212, | ||
3413 | +213, | ||
3414 | +213, | ||
3415 | +213, | ||
3416 | +213, | ||
3417 | +213, | ||
3418 | +213, | ||
3419 | +213, | ||
3420 | +213, | ||
3421 | +213, | ||
3422 | +213, | ||
3423 | +213, | ||
3424 | +213, | ||
3425 | +214, | ||
3426 | +214, | ||
3427 | +214, | ||
3428 | +214, | ||
3429 | +215, | ||
3430 | +215, | ||
3431 | +215, | ||
3432 | +215, | ||
3433 | +215, | ||
3434 | +215, | ||
3435 | +215, | ||
3436 | +215, | ||
3437 | +215, | ||
3438 | +215, | ||
3439 | +215, | ||
3440 | +216, | ||
3441 | +216, | ||
3442 | +216, | ||
3443 | +216, | ||
3444 | +217, | ||
3445 | +217, | ||
3446 | +217, | ||
3447 | +217, | ||
3448 | +218, | ||
3449 | +218, | ||
3450 | +218, | ||
3451 | +218, | ||
3452 | +219, | ||
3453 | +219, | ||
3454 | +219, | ||
3455 | +219, | ||
3456 | +219, | ||
3457 | +219, | ||
3458 | +219, | ||
3459 | +219, | ||
3460 | +219, | ||
3461 | +219, | ||
3462 | +219, | ||
3463 | +219, | ||
3464 | +220, | ||
3465 | +220, | ||
3466 | +220, | ||
3467 | +220, | ||
3468 | +221, | ||
3469 | +221, | ||
3470 | +221, | ||
3471 | +221, | ||
3472 | +221, | ||
3473 | +221, | ||
3474 | +221, | ||
3475 | +221, | ||
3476 | +221, | ||
3477 | +221, | ||
3478 | +221, | ||
3479 | +222, | ||
3480 | +222, | ||
3481 | +222, | ||
3482 | +222, | ||
3483 | +223, | ||
3484 | +223, | ||
3485 | +223, | ||
3486 | +223, | ||
3487 | +223, | ||
3488 | +223, | ||
3489 | +223, | ||
3490 | +223, | ||
3491 | +223, | ||
3492 | +223, | ||
3493 | +223, | ||
3494 | +223, | ||
3495 | +224, | ||
3496 | +224, | ||
3497 | +224, | ||
3498 | +224, | ||
3499 | +225, | ||
3500 | +225, | ||
3501 | +225, | ||
3502 | +225, | ||
3503 | +225, | ||
3504 | +225, | ||
3505 | +225, | ||
3506 | +225, | ||
3507 | +225, | ||
3508 | +225, | ||
3509 | +225, | ||
3510 | +225, | ||
3511 | +225, | ||
3512 | +225, | ||
3513 | +225, | ||
3514 | +225, | ||
3515 | +225, | ||
3516 | +225, | ||
3517 | +225, | ||
3518 | +226, | ||
3519 | +226, | ||
3520 | +226, | ||
3521 | +226, | ||
3522 | +227, | ||
3523 | +227, | ||
3524 | +227, | ||
3525 | +227, | ||
3526 | +227, | ||
3527 | +227, | ||
3528 | +227, | ||
3529 | +227, | ||
3530 | +227, | ||
3531 | +227, | ||
3532 | +227, | ||
3533 | +227, | ||
3534 | +228, | ||
3535 | +228, | ||
3536 | +228, | ||
3537 | +229, | ||
3538 | +229, | ||
3539 | +229, | ||
3540 | +229, | ||
3541 | +229, | ||
3542 | +229, | ||
3543 | +229, | ||
3544 | +229, | ||
3545 | +229, | ||
3546 | +229, | ||
3547 | +229, | ||
3548 | +229, | ||
3549 | +230, | ||
3550 | +230, | ||
3551 | +230, | ||
3552 | +230, | ||
3553 | +231, | ||
3554 | +231, | ||
3555 | +231, | ||
3556 | +231, | ||
3557 | +231, | ||
3558 | +231, | ||
3559 | +231, | ||
3560 | +231, | ||
3561 | +231, | ||
3562 | +231, | ||
3563 | +231, | ||
3564 | +231, | ||
3565 | +232, | ||
3566 | +232, | ||
3567 | +232, | ||
3568 | +232, | ||
3569 | +232, | ||
3570 | +232, | ||
3571 | +232, | ||
3572 | +232, | ||
3573 | +232, | ||
3574 | +232, | ||
3575 | +232, | ||
3576 | +232, | ||
3577 | +232, | ||
3578 | +232, | ||
3579 | +232, | ||
3580 | +232, | ||
3581 | +232, | ||
3582 | +232, | ||
3583 | +232, | ||
3584 | +233, | ||
3585 | +233, | ||
3586 | +233, | ||
3587 | +233, | ||
3588 | +234, | ||
3589 | +234, | ||
3590 | +234, | ||
3591 | +234, | ||
3592 | +234, | ||
3593 | +234, | ||
3594 | +234, | ||
3595 | +234, | ||
3596 | +234, | ||
3597 | +234, | ||
3598 | +234, | ||
3599 | +235, | ||
3600 | +235, | ||
3601 | +235, | ||
3602 | +235, | ||
3603 | +236, | ||
3604 | +236, | ||
3605 | +236, | ||
3606 | +236, | ||
3607 | +236, | ||
3608 | +236, | ||
3609 | +236, | ||
3610 | +236, | ||
3611 | +236, | ||
3612 | +236, | ||
3613 | +236, | ||
3614 | +236, | ||
3615 | +236, | ||
3616 | +236, | ||
3617 | +236, | ||
3618 | +236, | ||
3619 | +236, | ||
3620 | +236, | ||
3621 | +236, | ||
3622 | +237, | ||
3623 | +237, | ||
3624 | +237, | ||
3625 | +237, | ||
3626 | +238, | ||
3627 | +238, | ||
3628 | +238, | ||
3629 | +238, | ||
3630 | +238, | ||
3631 | +238, | ||
3632 | +238, | ||
3633 | +238, | ||
3634 | +238, | ||
3635 | +238, | ||
3636 | +238, | ||
3637 | +238, | ||
3638 | +238, | ||
3639 | +238, | ||
3640 | +238, | ||
3641 | +238, | ||
3642 | +238, | ||
3643 | +238, | ||
3644 | +238, | ||
3645 | +238, | ||
3646 | +238, | ||
3647 | +238, | ||
3648 | +238, | ||
3649 | +238, | ||
3650 | +238, | ||
3651 | +238, | ||
3652 | +238, | ||
3653 | +239, | ||
3654 | +239, | ||
3655 | +239, | ||
3656 | +239, | ||
3657 | +240, | ||
3658 | +240, | ||
3659 | +240, | ||
3660 | +240, | ||
3661 | +240, | ||
3662 | +240, | ||
3663 | +240, | ||
3664 | +240, | ||
3665 | +240, | ||
3666 | +240, | ||
3667 | +240, | ||
3668 | +240, | ||
3669 | +240, | ||
3670 | +240, | ||
3671 | +240, | ||
3672 | +240, | ||
3673 | +240, | ||
3674 | +240, | ||
3675 | +240, | ||
3676 | +240, | ||
3677 | +240, | ||
3678 | +240, | ||
3679 | +240, | ||
3680 | +240, | ||
3681 | +240, | ||
3682 | +240, | ||
3683 | +240, | ||
3684 | +241, | ||
3685 | +241, | ||
3686 | +241, | ||
3687 | +241, | ||
3688 | +242, | ||
3689 | +242, | ||
3690 | +242, | ||
3691 | +242, | ||
3692 | +242, | ||
3693 | +242, | ||
3694 | +242, | ||
3695 | +242, | ||
3696 | +242, | ||
3697 | +242, | ||
3698 | +242, | ||
3699 | +242, | ||
3700 | +242, | ||
3701 | +242, | ||
3702 | +242, | ||
3703 | +242, | ||
3704 | +242, | ||
3705 | +242, | ||
3706 | +242, | ||
3707 | +242, | ||
3708 | +242, | ||
3709 | +242, | ||
3710 | +242, | ||
3711 | +242, | ||
3712 | +242, | ||
3713 | +242, | ||
3714 | +243, | ||
3715 | +243, | ||
3716 | +243, | ||
3717 | +243, | ||
3718 | +244, | ||
3719 | +244, | ||
3720 | +244, | ||
3721 | +244, | ||
3722 | +244, | ||
3723 | +244, | ||
3724 | +244, | ||
3725 | +244, | ||
3726 | +244, | ||
3727 | +244, | ||
3728 | +244, | ||
3729 | +244, | ||
3730 | +244, | ||
3731 | +244, | ||
3732 | +244, | ||
3733 | +244, | ||
3734 | +244, | ||
3735 | +244, | ||
3736 | +244, | ||
3737 | +244, | ||
3738 | +244, | ||
3739 | +244, | ||
3740 | +244, | ||
3741 | +244, | ||
3742 | +244, | ||
3743 | +244, | ||
3744 | +244, | ||
3745 | +245, | ||
3746 | +245, | ||
3747 | +245, | ||
3748 | +245, | ||
3749 | +246, | ||
3750 | +246, | ||
3751 | +246, | ||
3752 | +246, | ||
3753 | +246, | ||
3754 | +246, | ||
3755 | +246, | ||
3756 | +246, | ||
3757 | +246, | ||
3758 | +246, | ||
3759 | +246, | ||
3760 | +246, | ||
3761 | +246, | ||
3762 | +246, | ||
3763 | +246, | ||
3764 | +246, | ||
3765 | +246, | ||
3766 | +246, | ||
3767 | +246, | ||
3768 | +246, | ||
3769 | +246, | ||
3770 | +246, | ||
3771 | +246, | ||
3772 | +246, | ||
3773 | +246, | ||
3774 | +246, | ||
3775 | +246, | ||
3776 | +246, | ||
3777 | +246, | ||
3778 | +246, | ||
3779 | +246, | ||
3780 | +246, | ||
3781 | +246, | ||
3782 | +246, | ||
3783 | +247, | ||
3784 | +247, | ||
3785 | +247, | ||
3786 | +247, | ||
3787 | +248, | ||
3788 | +248, | ||
3789 | +248, | ||
3790 | +248, | ||
3791 | +248, | ||
3792 | +248, | ||
3793 | +248, | ||
3794 | +248, | ||
3795 | +248, | ||
3796 | +248, | ||
3797 | +248, | ||
3798 | +248, | ||
3799 | +248, | ||
3800 | +248, | ||
3801 | +248, | ||
3802 | +248, | ||
3803 | +248, | ||
3804 | +248, | ||
3805 | +248, | ||
3806 | +248, | ||
3807 | +248, | ||
3808 | +248, | ||
3809 | +248, | ||
3810 | +248, | ||
3811 | +248, | ||
3812 | +248, | ||
3813 | +248, | ||
3814 | +249, | ||
3815 | +249, | ||
3816 | +249, | ||
3817 | +249, | ||
3818 | +250, | ||
3819 | +250, | ||
3820 | +250, | ||
3821 | +250, | ||
3822 | +250, | ||
3823 | +250, | ||
3824 | +250, | ||
3825 | +250, | ||
3826 | +250, | ||
3827 | +250, | ||
3828 | +250, | ||
3829 | +250, | ||
3830 | +250, | ||
3831 | +250, | ||
3832 | +250, | ||
3833 | +250, | ||
3834 | +250, | ||
3835 | +250, | ||
3836 | +250, | ||
3837 | +250, | ||
3838 | +250, | ||
3839 | +250, | ||
3840 | +250, | ||
3841 | +250, | ||
3842 | +250, | ||
3843 | +250, | ||
3844 | +250, | ||
3845 | +250, | ||
3846 | +250, | ||
3847 | +250, | ||
3848 | +250, | ||
3849 | +250, | ||
3850 | +250, | ||
3851 | +250, | ||
3852 | +250, | ||
3853 | +250, | ||
3854 | +250, | ||
3855 | +250, | ||
3856 | +250, | ||
3857 | +250, | ||
3858 | +250, | ||
3859 | +250, | ||
3860 | +251, | ||
3861 | +251, | ||
3862 | +251, | ||
3863 | +251, | ||
3864 | +252, | ||
3865 | +252, | ||
3866 | +252, | ||
3867 | +252, | ||
3868 | +252, | ||
3869 | +252, | ||
3870 | +252, | ||
3871 | +252, | ||
3872 | +252, | ||
3873 | +252, | ||
3874 | +252, | ||
3875 | +252, | ||
3876 | +252, | ||
3877 | +252, | ||
3878 | +252, | ||
3879 | +252, | ||
3880 | +252, | ||
3881 | +252, | ||
3882 | +252, | ||
3883 | +252, | ||
3884 | +252, | ||
3885 | +252, | ||
3886 | +252, | ||
3887 | +252, | ||
3888 | +252, | ||
3889 | +252, | ||
3890 | +252, | ||
3891 | +252, | ||
3892 | +252, | ||
3893 | +252, | ||
3894 | +252, | ||
3895 | +252, | ||
3896 | +252, | ||
3897 | +252, | ||
3898 | +252, | ||
3899 | +252, | ||
3900 | +252, | ||
3901 | +252, | ||
3902 | +252, | ||
3903 | +252, | ||
3904 | +252, | ||
3905 | +252, | ||
3906 | +252, | ||
3907 | +252, | ||
3908 | +252, | ||
3909 | +252, | ||
3910 | +252, | ||
3911 | +252, | ||
3912 | +252, | ||
3913 | +252, | ||
3914 | +252, | ||
3915 | +252, | ||
3916 | +252, | ||
3917 | +252, | ||
3918 | +252, | ||
3919 | +252, | ||
3920 | +252, | ||
3921 | +252, | ||
3922 | +252, | ||
3923 | +252, | ||
3924 | +252, | ||
3925 | +252, | ||
3926 | +252, | ||
3927 | +252, | ||
3928 | +253, | ||
3929 | +253, | ||
3930 | +253, | ||
3931 | +253, | ||
3932 | +253, | ||
3933 | +253, | ||
3934 | +253, | ||
3935 | +253, | ||
3936 | +253, | ||
3937 | +253, | ||
3938 | +253, | ||
3939 | +253, | ||
3940 | +253, | ||
3941 | +253, | ||
3942 | +253, | ||
3943 | +253, | ||
3944 | +253, | ||
3945 | +253, | ||
3946 | +253, | ||
3947 | +253, | ||
3948 | +253, | ||
3949 | +253, | ||
3950 | +253, | ||
3951 | +253, | ||
3952 | +253, | ||
3953 | +253, | ||
3954 | +253, | ||
3955 | +253, | ||
3956 | +253, | ||
3957 | +253, | ||
3958 | +253, | ||
3959 | +253, | ||
3960 | +253, | ||
3961 | +253, | ||
3962 | +253, | ||
3963 | +253, | ||
3964 | +253, | ||
3965 | +253, | ||
3966 | +253, | ||
3967 | +253, | ||
3968 | +253, | ||
3969 | +253, | ||
3970 | +253, | ||
3971 | +253, | ||
3972 | +253, | ||
3973 | +253, | ||
3974 | +253, | ||
3975 | +253, | ||
3976 | +253, | ||
3977 | +253, | ||
3978 | +253, | ||
3979 | +253, | ||
3980 | +253, | ||
3981 | +253, | ||
3982 | +253, | ||
3983 | +253, | ||
3984 | +253, | ||
3985 | +254, | ||
3986 | +254, | ||
3987 | +254, | ||
3988 | +254, | ||
3989 | +255, | ||
3990 | +255, | ||
3991 | +255, | ||
3992 | +255, | ||
3993 | +255, | ||
3994 | +255, | ||
3995 | +255, | ||
3996 | +255, | ||
3997 | +255, | ||
3998 | +255, | ||
3999 | +255, | ||
4000 | +255, | ||
4001 | +255, | ||
4002 | +255, | ||
4003 | +255, | ||
4004 | +255, | ||
4005 | +255, | ||
4006 | +255, | ||
4007 | +255, | ||
4008 | +255, | ||
4009 | +255, | ||
4010 | +255, | ||
4011 | +255, | ||
4012 | +255, | ||
4013 | +255, | ||
4014 | +255, | ||
4015 | +255 | ||
4016 | -- | ||
4017 | 1.5.6.5 | ||
4018 | |||
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0009-omap34xxcam-Add-camera-driver.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0009-omap34xxcam-Add-camera-driver.patch new file mode 100644 index 0000000000..22074be148 --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0009-omap34xxcam-Add-camera-driver.patch | |||
@@ -0,0 +1,2249 @@ | |||
1 | From 0edf5a50dc0164db5bc71b1a5d1aa8bb1838262c Mon Sep 17 00:00:00 2001 | ||
2 | From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
3 | Date: Tue, 10 Mar 2009 10:49:03 +0200 | ||
4 | Subject: [PATCH] omap34xxcam: Add camera driver | ||
5 | |||
6 | This is the camera driver for the OMAP 3 camera ISP and v4l2-int-device | ||
7 | sensors, lenses and (led) flashes. There are a few connections to OMAP | ||
8 | 3 left but after those have been broken this is hardware independent. | ||
9 | Namely, the OMAP 3 ISP must offer a standard interface through | ||
10 | v4l2_subdev (or v4l2-int-device) first. | ||
11 | |||
12 | This driver has originated from the omap24xxcam camera driver written | ||
13 | specifically for OMAP 2. | ||
14 | |||
15 | TODO: | ||
16 | |||
17 | - Convert to use v4l2_subdev instead of v4l2-int-device. | ||
18 | |||
19 | Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com> | ||
20 | --- | ||
21 | drivers/media/video/Kconfig | 9 + | ||
22 | drivers/media/video/Makefile | 2 + | ||
23 | drivers/media/video/omap34xxcam.c | 1966 +++++++++++++++++++++++++++++++++++++ | ||
24 | drivers/media/video/omap34xxcam.h | 207 ++++ | ||
25 | 4 files changed, 2184 insertions(+), 0 deletions(-) | ||
26 | create mode 100644 drivers/media/video/omap34xxcam.c | ||
27 | create mode 100644 drivers/media/video/omap34xxcam.h | ||
28 | |||
29 | diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig | ||
30 | index 19cf3b8..3cdb5a4 100644 | ||
31 | --- a/drivers/media/video/Kconfig | ||
32 | +++ b/drivers/media/video/Kconfig | ||
33 | @@ -711,6 +711,15 @@ config VIDEO_CAFE_CCIC | ||
34 | CMOS camera controller. This is the controller found on first- | ||
35 | generation OLPC systems. | ||
36 | |||
37 | +config VIDEO_OMAP3 | ||
38 | + tristate "OMAP 3 Camera support" | ||
39 | + select VIDEOBUF_GEN | ||
40 | + select VIDEOBUF_DMA_SG | ||
41 | + select OMAP_IOMMU | ||
42 | + depends on VIDEO_V4L2 && ARCH_OMAP34XX | ||
43 | + ---help--- | ||
44 | + Driver for an OMAP 3 camera controller. | ||
45 | + | ||
46 | config SOC_CAMERA | ||
47 | tristate "SoC camera support" | ||
48 | depends on VIDEO_V4L2 && HAS_DMA | ||
49 | diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile | ||
50 | index e654270..74a684e 100644 | ||
51 | --- a/drivers/media/video/Makefile | ||
52 | +++ b/drivers/media/video/Makefile | ||
53 | @@ -108,6 +108,8 @@ obj-$(CONFIG_VIDEO_OV7670) += ov7670.o | ||
54 | |||
55 | obj-y += isp/ | ||
56 | |||
57 | +obj-$(CONFIG_VIDEO_OMAP3) += omap34xxcam.o | ||
58 | + | ||
59 | obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o | ||
60 | |||
61 | obj-$(CONFIG_USB_DABUSB) += dabusb.o | ||
62 | diff --git a/drivers/media/video/omap34xxcam.c b/drivers/media/video/omap34xxcam.c | ||
63 | new file mode 100644 | ||
64 | index 0000000..00fdbf2 | ||
65 | --- /dev/null | ||
66 | +++ b/drivers/media/video/omap34xxcam.c | ||
67 | @@ -0,0 +1,1966 @@ | ||
68 | +/* | ||
69 | + * omap34xxcam.c | ||
70 | + * | ||
71 | + * Copyright (C) 2006--2009 Nokia Corporation | ||
72 | + * Copyright (C) 2007--2009 Texas Instruments | ||
73 | + * | ||
74 | + * Contact: Sakari Ailus <sakari.ailus@nokia.com> | ||
75 | + * Tuukka Toivonen <tuukka.o.toivonen@nokia.com> | ||
76 | + * | ||
77 | + * Originally based on the OMAP 2 camera driver. | ||
78 | + * | ||
79 | + * Written by Sakari Ailus <sakari.ailus@nokia.com> | ||
80 | + * Tuukka Toivonen <tuukka.o.toivonen@nokia.com> | ||
81 | + * Sergio Aguirre <saaguirre@ti.com> | ||
82 | + * Mohit Jalori | ||
83 | + * Sameer Venkatraman | ||
84 | + * Leonides Martinez | ||
85 | + * | ||
86 | + * This program is free software; you can redistribute it and/or | ||
87 | + * modify it under the terms of the GNU General Public License | ||
88 | + * version 2 as published by the Free Software Foundation. | ||
89 | + * | ||
90 | + * This program is distributed in the hope that it will be useful, but | ||
91 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
92 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
93 | + * General Public License for more details. | ||
94 | + * | ||
95 | + * You should have received a copy of the GNU General Public License | ||
96 | + * along with this program; if not, write to the Free Software | ||
97 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
98 | + * 02110-1301 USA | ||
99 | + * | ||
100 | + */ | ||
101 | + | ||
102 | +#include <linux/io.h> | ||
103 | +#include <linux/clk.h> | ||
104 | +#include <linux/pci.h> /* needed for videobufs */ | ||
105 | +#include <linux/delay.h> | ||
106 | +#include <linux/kernel.h> | ||
107 | +#include <linux/interrupt.h> | ||
108 | +#include <linux/videodev2.h> | ||
109 | +#include <linux/version.h> | ||
110 | +#include <linux/platform_device.h> | ||
111 | + | ||
112 | +#include <media/v4l2-common.h> | ||
113 | +#include <media/v4l2-ioctl.h> | ||
114 | + | ||
115 | +#include "omap34xxcam.h" | ||
116 | +#include "isp/isp.h" | ||
117 | +#include "isp/ispmmu.h" | ||
118 | +#include "isp/ispreg.h" | ||
119 | +#include "isp/ispccdc.h" | ||
120 | +#include "isp/isph3a.h" | ||
121 | +#include "isp/isp_af.h" | ||
122 | +#include "isp/isphist.h" | ||
123 | +#include "isp/isppreview.h" | ||
124 | +#include "isp/ispresizer.h" | ||
125 | + | ||
126 | +#define OMAP34XXCAM_VERSION KERNEL_VERSION(0, 0, 0) | ||
127 | + | ||
128 | +/* global variables */ | ||
129 | +static struct omap34xxcam_device *omap34xxcam; | ||
130 | + | ||
131 | +/* | ||
132 | + * | ||
133 | + * Sensor handling. | ||
134 | + * | ||
135 | + */ | ||
136 | + | ||
137 | +/** | ||
138 | + * omap34xxcam_slave_power_set - set slave power state | ||
139 | + * @vdev: per-video device data structure | ||
140 | + * @power: new power state | ||
141 | + */ | ||
142 | +static int omap34xxcam_slave_power_set(struct omap34xxcam_videodev *vdev, | ||
143 | + enum v4l2_power power, | ||
144 | + int mask) | ||
145 | +{ | ||
146 | + int rval = 0, i = 0; | ||
147 | + | ||
148 | + BUG_ON(!mutex_is_locked(&vdev->mutex)); | ||
149 | + | ||
150 | +#ifdef OMAP34XXCAM_POWEROFF_DELAY | ||
151 | + vdev->power_state_wish = -1; | ||
152 | +#endif | ||
153 | + | ||
154 | + for (i = 0; i <= OMAP34XXCAM_SLAVE_FLASH; i++) { | ||
155 | + if (vdev->slave[i] == v4l2_int_device_dummy()) | ||
156 | + continue; | ||
157 | + | ||
158 | + if (!(mask & (1 << i)) | ||
159 | + || power == vdev->power_state[i]) | ||
160 | + continue; | ||
161 | + | ||
162 | + rval = vidioc_int_s_power(vdev->slave[i], power); | ||
163 | + | ||
164 | + if (rval && power != V4L2_POWER_OFF) { | ||
165 | + power = V4L2_POWER_OFF; | ||
166 | + goto out; | ||
167 | + } | ||
168 | + | ||
169 | + vdev->power_state[i] = power; | ||
170 | + } | ||
171 | + | ||
172 | + return 0; | ||
173 | + | ||
174 | +out: | ||
175 | + for (i--; i >= 0; i--) { | ||
176 | + if (vdev->slave[i] == v4l2_int_device_dummy()) | ||
177 | + continue; | ||
178 | + | ||
179 | + if (!(mask & (1 << i))) | ||
180 | + continue; | ||
181 | + | ||
182 | + vidioc_int_s_power(vdev->slave[i], power); | ||
183 | + vdev->power_state[i] = power; | ||
184 | + } | ||
185 | + | ||
186 | + return rval; | ||
187 | +} | ||
188 | + | ||
189 | +#ifdef OMAP34XXCAM_POWEROFF_DELAY | ||
190 | +static void omap34xxcam_slave_power_work(struct work_struct *work) | ||
191 | +{ | ||
192 | + struct omap34xxcam_videodev *vdev = | ||
193 | + container_of(work, struct omap34xxcam_videodev, poweroff_work); | ||
194 | + | ||
195 | + mutex_lock(&vdev->mutex); | ||
196 | + | ||
197 | + if (vdev->power_state_wish != -1) | ||
198 | + omap34xxcam_slave_power_set(vdev, vdev->power_state_wish, | ||
199 | + vdev->power_state_mask); | ||
200 | + | ||
201 | + mutex_unlock(&vdev->mutex); | ||
202 | +} | ||
203 | + | ||
204 | +static void omap34xxcam_slave_power_timer(unsigned long ptr) | ||
205 | +{ | ||
206 | + struct omap34xxcam_videodev *vdev = (void *)ptr; | ||
207 | + | ||
208 | + schedule_work(&vdev->poweroff_work); | ||
209 | +} | ||
210 | + | ||
211 | +/** | ||
212 | + * omap34xxcam_slave_power_suggest - delayed power state change | ||
213 | + * | ||
214 | + * @vdev: per-video device data structure | ||
215 | + * @power: new power state | ||
216 | + */ | ||
217 | +static void omap34xxcam_slave_power_suggest(struct omap34xxcam_videodev *vdev, | ||
218 | + enum v4l2_power power, | ||
219 | + int mask) | ||
220 | +{ | ||
221 | + BUG_ON(!mutex_is_locked(&vdev->mutex)); | ||
222 | + | ||
223 | + del_timer(&vdev->poweroff_timer); | ||
224 | + | ||
225 | + vdev->power_state_wish = power; | ||
226 | + vdev->power_state_mask = mask; | ||
227 | + | ||
228 | + mod_timer(&vdev->poweroff_timer, jiffies + OMAP34XXCAM_POWEROFF_DELAY); | ||
229 | +} | ||
230 | +#else /* OMAP34XXCAM_POWEROFF_DELAY */ | ||
231 | +#define omap34xxcam_slave_power_suggest(a, b, c) do {} while (0) | ||
232 | +#endif /* OMAP34XXCAM_POWEROFF_DELAY */ | ||
233 | + | ||
234 | +/** | ||
235 | + * omap34xxcam_update_vbq - Updates VBQ with completed input buffer | ||
236 | + * @vb: ptr. to standard V4L2 video buffer structure | ||
237 | + * | ||
238 | + * Updates video buffer queue with completed buffer passed as | ||
239 | + * input parameter. Also updates ISP H3A timestamp and field count | ||
240 | + * statistics. | ||
241 | + */ | ||
242 | +void omap34xxcam_vbq_complete(struct videobuf_buffer *vb, void *priv) | ||
243 | +{ | ||
244 | + struct omap34xxcam_fh *fh = priv; | ||
245 | + | ||
246 | + do_gettimeofday(&vb->ts); | ||
247 | + vb->field_count = atomic_add_return(2, &fh->field_count); | ||
248 | + | ||
249 | + wake_up(&vb->done); | ||
250 | +} | ||
251 | + | ||
252 | +/** | ||
253 | + * omap34xxcam_vbq_setup - Calcs size and num of buffs allowed in queue | ||
254 | + * @vbq: ptr. to standard V4L2 video buffer queue structure | ||
255 | + * @cnt: ptr to location to hold the count of buffers to be in the queue | ||
256 | + * @size: ptr to location to hold the size of a frame | ||
257 | + * | ||
258 | + * Calculates the number of buffers of current image size that can be | ||
259 | + * supported by the available capture memory. | ||
260 | + */ | ||
261 | +static int omap34xxcam_vbq_setup(struct videobuf_queue *vbq, unsigned int *cnt, | ||
262 | + unsigned int *size) | ||
263 | +{ | ||
264 | + struct omap34xxcam_fh *fh = vbq->priv_data; | ||
265 | + struct omap34xxcam_videodev *vdev = fh->vdev; | ||
266 | + | ||
267 | + if (*cnt <= 0) | ||
268 | + *cnt = VIDEO_MAX_FRAME; /* supply a default number of buffers */ | ||
269 | + | ||
270 | + if (*cnt > VIDEO_MAX_FRAME) | ||
271 | + *cnt = VIDEO_MAX_FRAME; | ||
272 | + | ||
273 | + *size = vdev->pix.sizeimage; | ||
274 | + | ||
275 | + while (*size * *cnt > fh->vdev->vdev_sensor_config.capture_mem) | ||
276 | + (*cnt)--; | ||
277 | + | ||
278 | + return isp_vbq_setup(vbq, cnt, size); | ||
279 | +} | ||
280 | + | ||
281 | +/** | ||
282 | + * omap34xxcam_vbq_release - Free resources for input VBQ and VB | ||
283 | + * @vbq: ptr. to standard V4L2 video buffer queue structure | ||
284 | + * @vb: ptr to standard V4L2 video buffer structure | ||
285 | + * | ||
286 | + * Unmap and free all memory associated with input VBQ and VB, also | ||
287 | + * unmap the address in ISP MMU. Reset the VB state. | ||
288 | + */ | ||
289 | +static void omap34xxcam_vbq_release(struct videobuf_queue *vbq, | ||
290 | + struct videobuf_buffer *vb) | ||
291 | +{ | ||
292 | + if (!vbq->streaming) { | ||
293 | + isp_vbq_release(vbq, vb); | ||
294 | + videobuf_dma_unmap(vbq, videobuf_to_dma(vb)); | ||
295 | + videobuf_dma_free(videobuf_to_dma(vb)); | ||
296 | + vb->state = VIDEOBUF_NEEDS_INIT; | ||
297 | + } | ||
298 | + return; | ||
299 | +} | ||
300 | + | ||
301 | +/** | ||
302 | + * omap34xxcam_vbq_prepare - V4L2 video ops buf_prepare handler | ||
303 | + * @vbq: ptr. to standard V4L2 video buffer queue structure | ||
304 | + * @vb: ptr to standard V4L2 video buffer structure | ||
305 | + * @field: standard V4L2 field enum | ||
306 | + * | ||
307 | + * Verifies there is sufficient locked memory for the requested | ||
308 | + * buffer, or if there is not, allocates, locks and initializes | ||
309 | + * it. | ||
310 | + */ | ||
311 | +static int omap34xxcam_vbq_prepare(struct videobuf_queue *vbq, | ||
312 | + struct videobuf_buffer *vb, | ||
313 | + enum v4l2_field field) | ||
314 | +{ | ||
315 | + struct omap34xxcam_fh *fh = vbq->priv_data; | ||
316 | + struct omap34xxcam_videodev *vdev = fh->vdev; | ||
317 | + int err = 0; | ||
318 | + | ||
319 | + /* | ||
320 | + * Accessing pix here is okay since it's constant while | ||
321 | + * streaming is on (and we only get called then). | ||
322 | + */ | ||
323 | + if (vb->baddr) { | ||
324 | + /* This is a userspace buffer. */ | ||
325 | + if (vdev->pix.sizeimage > vb->bsize) | ||
326 | + /* The buffer isn't big enough. */ | ||
327 | + return -EINVAL; | ||
328 | + } else { | ||
329 | + if (vb->state != VIDEOBUF_NEEDS_INIT | ||
330 | + && vdev->pix.sizeimage > vb->bsize) | ||
331 | + /* | ||
332 | + * We have a kernel bounce buffer that has | ||
333 | + * already been allocated. | ||
334 | + */ | ||
335 | + omap34xxcam_vbq_release(vbq, vb); | ||
336 | + } | ||
337 | + | ||
338 | + vb->size = vdev->pix.bytesperline * vdev->pix.height; | ||
339 | + vb->width = vdev->pix.width; | ||
340 | + vb->height = vdev->pix.height; | ||
341 | + vb->field = field; | ||
342 | + | ||
343 | + if (vb->state == VIDEOBUF_NEEDS_INIT) { | ||
344 | + err = videobuf_iolock(vbq, vb, NULL); | ||
345 | + if (!err) { | ||
346 | + /* isp_addr will be stored locally inside isp code */ | ||
347 | + err = isp_vbq_prepare(vbq, vb, field); | ||
348 | + } | ||
349 | + } | ||
350 | + | ||
351 | + if (!err) | ||
352 | + vb->state = VIDEOBUF_PREPARED; | ||
353 | + else | ||
354 | + omap34xxcam_vbq_release(vbq, vb); | ||
355 | + | ||
356 | + return err; | ||
357 | +} | ||
358 | + | ||
359 | +/** | ||
360 | + * omap34xxcam_vbq_queue - V4L2 video ops buf_queue handler | ||
361 | + * @vbq: ptr. to standard V4L2 video buffer queue structure | ||
362 | + * @vb: ptr to standard V4L2 video buffer structure | ||
363 | + * | ||
364 | + * Maps the video buffer to sgdma and through the isp, sets | ||
365 | + * the isp buffer done callback and sets the video buffer state | ||
366 | + * to active. | ||
367 | + */ | ||
368 | +static void omap34xxcam_vbq_queue(struct videobuf_queue *vbq, | ||
369 | + struct videobuf_buffer *vb) | ||
370 | +{ | ||
371 | + struct omap34xxcam_fh *fh = vbq->priv_data; | ||
372 | + | ||
373 | + vb->state = VIDEOBUF_ACTIVE; | ||
374 | + | ||
375 | + isp_buf_queue(vb, omap34xxcam_vbq_complete, (void *)fh); | ||
376 | +} | ||
377 | + | ||
378 | +static struct videobuf_queue_ops omap34xxcam_vbq_ops = { | ||
379 | + .buf_setup = omap34xxcam_vbq_setup, | ||
380 | + .buf_prepare = omap34xxcam_vbq_prepare, | ||
381 | + .buf_queue = omap34xxcam_vbq_queue, | ||
382 | + .buf_release = omap34xxcam_vbq_release, | ||
383 | +}; | ||
384 | + | ||
385 | +/* | ||
386 | + * | ||
387 | + * IOCTL interface. | ||
388 | + * | ||
389 | + */ | ||
390 | + | ||
391 | +/** | ||
392 | + * vidioc_querycap - V4L2 query capabilities IOCTL handler | ||
393 | + * @file: ptr. to system file structure | ||
394 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
395 | + * @cap: ptr to standard V4L2 capability structure | ||
396 | + * | ||
397 | + * Fill in the V4L2 capabliity structure for the camera device | ||
398 | + */ | ||
399 | +static int vidioc_querycap(struct file *file, void *fh, | ||
400 | + struct v4l2_capability *cap) | ||
401 | +{ | ||
402 | + struct omap34xxcam_fh *ofh = fh; | ||
403 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
404 | + | ||
405 | + strlcpy(cap->driver, CAM_SHORT_NAME, sizeof(cap->driver)); | ||
406 | + strlcpy(cap->card, vdev->vfd->name, sizeof(cap->card)); | ||
407 | + cap->version = OMAP34XXCAM_VERSION; | ||
408 | + if (vdev->vdev_sensor != v4l2_int_device_dummy()) | ||
409 | + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | ||
410 | + | ||
411 | + return 0; | ||
412 | +} | ||
413 | + | ||
414 | +/** | ||
415 | + * vidioc_enum_fmt_vid_cap - V4L2 enumerate format capabilities IOCTL handler | ||
416 | + * @file: ptr. to system file structure | ||
417 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
418 | + * @f: ptr to standard V4L2 format description structure | ||
419 | + * | ||
420 | + * Fills in enumerate format capabilities information for sensor (if SOC | ||
421 | + * sensor attached) or ISP (if raw sensor attached). | ||
422 | + */ | ||
423 | +static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, | ||
424 | + struct v4l2_fmtdesc *f) | ||
425 | +{ | ||
426 | + struct omap34xxcam_fh *ofh = fh; | ||
427 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
428 | + int rval; | ||
429 | + | ||
430 | + if (vdev->vdev_sensor == v4l2_int_device_dummy()) | ||
431 | + return -EINVAL; | ||
432 | + | ||
433 | + if (vdev->vdev_sensor_config.sensor_isp) | ||
434 | + rval = vidioc_int_enum_fmt_cap(vdev->vdev_sensor, f); | ||
435 | + else | ||
436 | + rval = isp_enum_fmt_cap(f); | ||
437 | + | ||
438 | + return rval; | ||
439 | +} | ||
440 | + | ||
441 | +/** | ||
442 | + * vidioc_g_fmt_vid_cap - V4L2 get format capabilities IOCTL handler | ||
443 | + * @file: ptr. to system file structure | ||
444 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
445 | + * @f: ptr to standard V4L2 format structure | ||
446 | + * | ||
447 | + * Fills in format capabilities for sensor (if SOC sensor attached) or ISP | ||
448 | + * (if raw sensor attached). | ||
449 | + */ | ||
450 | +static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, | ||
451 | + struct v4l2_format *f) | ||
452 | +{ | ||
453 | + struct omap34xxcam_fh *ofh = fh; | ||
454 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
455 | + | ||
456 | + if (vdev->vdev_sensor == v4l2_int_device_dummy()) | ||
457 | + return -EINVAL; | ||
458 | + | ||
459 | + mutex_lock(&vdev->mutex); | ||
460 | + f->fmt.pix = vdev->pix; | ||
461 | + mutex_unlock(&vdev->mutex); | ||
462 | + | ||
463 | + return 0; | ||
464 | +} | ||
465 | + | ||
466 | +static int try_pix_parm(struct omap34xxcam_videodev *vdev, | ||
467 | + struct v4l2_pix_format *best_pix_in, | ||
468 | + struct v4l2_pix_format *wanted_pix_out, | ||
469 | + struct v4l2_fract *best_ival) | ||
470 | +{ | ||
471 | + int fps; | ||
472 | + int fmtd_index; | ||
473 | + int rval; | ||
474 | + struct v4l2_pix_format best_pix_out; | ||
475 | + | ||
476 | + if (best_ival->numerator == 0 | ||
477 | + || best_ival->denominator == 0) | ||
478 | + *best_ival = vdev->vdev_sensor_config.ival_default; | ||
479 | + | ||
480 | + fps = best_ival->denominator / best_ival->numerator; | ||
481 | + | ||
482 | + best_ival->denominator = 0; | ||
483 | + best_pix_out.height = INT_MAX >> 1; | ||
484 | + best_pix_out.width = best_pix_out.height; | ||
485 | + | ||
486 | + for (fmtd_index = 0; ; fmtd_index++) { | ||
487 | + int size_index; | ||
488 | + struct v4l2_fmtdesc fmtd; | ||
489 | + | ||
490 | + fmtd.index = fmtd_index; | ||
491 | + fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
492 | + rval = vidioc_int_enum_fmt_cap(vdev->vdev_sensor, &fmtd); | ||
493 | + if (rval) | ||
494 | + break; | ||
495 | + dev_info(&vdev->vfd->dev, "trying fmt %8.8x (%d)\n", | ||
496 | + fmtd.pixelformat, fmtd_index); | ||
497 | + /* | ||
498 | + * Get supported resolutions. | ||
499 | + */ | ||
500 | + for (size_index = 0; ; size_index++) { | ||
501 | + struct v4l2_frmsizeenum frms; | ||
502 | + struct v4l2_pix_format pix_tmp_in, pix_tmp_out; | ||
503 | + int ival_index; | ||
504 | + | ||
505 | + frms.index = size_index; | ||
506 | + frms.pixel_format = fmtd.pixelformat; | ||
507 | + | ||
508 | + rval = vidioc_int_enum_framesizes(vdev->vdev_sensor, | ||
509 | + &frms); | ||
510 | + if (rval) | ||
511 | + break; | ||
512 | + | ||
513 | + pix_tmp_in.pixelformat = frms.pixel_format; | ||
514 | + pix_tmp_in.width = frms.discrete.width; | ||
515 | + pix_tmp_in.height = frms.discrete.height; | ||
516 | + pix_tmp_out = *wanted_pix_out; | ||
517 | + /* Don't do upscaling. */ | ||
518 | + if (pix_tmp_out.width > pix_tmp_in.width) | ||
519 | + pix_tmp_out.width = pix_tmp_in.width; | ||
520 | + if (pix_tmp_out.height > pix_tmp_in.height) | ||
521 | + pix_tmp_out.height = pix_tmp_in.height; | ||
522 | + rval = isp_try_fmt_cap(&pix_tmp_in, &pix_tmp_out); | ||
523 | + if (rval) | ||
524 | + return rval; | ||
525 | + | ||
526 | + dev_info(&vdev->vfd->dev, "this w %d\th %d\tfmt %8.8x\t" | ||
527 | + "-> w %d\th %d\t fmt %8.8x" | ||
528 | + "\twanted w %d\th %d\t fmt %8.8x\n", | ||
529 | + pix_tmp_in.width, pix_tmp_in.height, | ||
530 | + pix_tmp_in.pixelformat, | ||
531 | + pix_tmp_out.width, pix_tmp_out.height, | ||
532 | + pix_tmp_out.pixelformat, | ||
533 | + wanted_pix_out->width, wanted_pix_out->height, | ||
534 | + wanted_pix_out->pixelformat); | ||
535 | + | ||
536 | +#define IS_SMALLER_OR_EQUAL(pix1, pix2) \ | ||
537 | + ((pix1)->width + (pix1)->height \ | ||
538 | + < (pix2)->width + (pix2)->height) | ||
539 | +#define SIZE_DIFF(pix1, pix2) \ | ||
540 | + (abs((pix1)->width - (pix2)->width) \ | ||
541 | + + abs((pix1)->height - (pix2)->height)) | ||
542 | + | ||
543 | + /* | ||
544 | + * Don't use modes that are farther from wanted size | ||
545 | + * that what we already got. | ||
546 | + */ | ||
547 | + if (SIZE_DIFF(&pix_tmp_out, wanted_pix_out) | ||
548 | + > SIZE_DIFF(&best_pix_out, wanted_pix_out)) { | ||
549 | + dev_info(&vdev->vfd->dev, "size diff bigger: " | ||
550 | + "w %d\th %d\tw %d\th %d\n", | ||
551 | + pix_tmp_out.width, pix_tmp_out.height, | ||
552 | + best_pix_out.width, | ||
553 | + best_pix_out.height); | ||
554 | + continue; | ||
555 | + } | ||
556 | + | ||
557 | + /* | ||
558 | + * There's an input mode that can provide output | ||
559 | + * closer to wanted. | ||
560 | + */ | ||
561 | + if (SIZE_DIFF(&pix_tmp_out, wanted_pix_out) | ||
562 | + < SIZE_DIFF(&best_pix_out, wanted_pix_out)) { | ||
563 | + /* Force renegotation of fps etc. */ | ||
564 | + best_ival->denominator = 0; | ||
565 | + dev_info(&vdev->vfd->dev, "renegotiate: " | ||
566 | + "w %d\th %d\tw %d\th %d\n", | ||
567 | + pix_tmp_out.width, pix_tmp_out.height, | ||
568 | + best_pix_out.width, | ||
569 | + best_pix_out.height); | ||
570 | + } | ||
571 | + | ||
572 | + for (ival_index = 0; ; ival_index++) { | ||
573 | + struct v4l2_frmivalenum frmi; | ||
574 | + | ||
575 | + frmi.index = ival_index; | ||
576 | + frmi.pixel_format = frms.pixel_format; | ||
577 | + frmi.width = frms.discrete.width; | ||
578 | + frmi.height = frms.discrete.height; | ||
579 | + /* FIXME: try to fix standard... */ | ||
580 | + frmi.reserved[0] = 0xdeafbeef; | ||
581 | + | ||
582 | + rval = vidioc_int_enum_frameintervals( | ||
583 | + vdev->vdev_sensor, &frmi); | ||
584 | + if (rval) | ||
585 | + break; | ||
586 | + | ||
587 | + dev_info(&vdev->vfd->dev, "fps %d\n", | ||
588 | + frmi.discrete.denominator | ||
589 | + / frmi.discrete.numerator); | ||
590 | + | ||
591 | + if (best_ival->denominator == 0) | ||
592 | + goto do_it_now; | ||
593 | + | ||
594 | + /* | ||
595 | + * We aim to use maximum resolution | ||
596 | + * from the sensor, provided that the | ||
597 | + * fps is at least as close as on the | ||
598 | + * current mode. | ||
599 | + */ | ||
600 | +#define FPS_ABS_DIFF(fps, ival) abs(fps - (ival).denominator / (ival).numerator) | ||
601 | + | ||
602 | + /* Select mode with closest fps. */ | ||
603 | + if (FPS_ABS_DIFF(fps, frmi.discrete) | ||
604 | + < FPS_ABS_DIFF(fps, *best_ival)) { | ||
605 | + dev_info(&vdev->vfd->dev, "closer fps: " | ||
606 | + "fps %d\t fps %d\n", | ||
607 | + FPS_ABS_DIFF(fps, | ||
608 | + frmi.discrete), | ||
609 | + FPS_ABS_DIFF(fps, *best_ival)); | ||
610 | + goto do_it_now; | ||
611 | + } | ||
612 | + | ||
613 | + /* | ||
614 | + * Select bigger resolution if it's available | ||
615 | + * at same fps. | ||
616 | + */ | ||
617 | + if (frmi.width + frmi.height | ||
618 | + > best_pix_in->width + best_pix_in->height | ||
619 | + && FPS_ABS_DIFF(fps, frmi.discrete) | ||
620 | + <= FPS_ABS_DIFF(fps, *best_ival)) { | ||
621 | + dev_info(&vdev->vfd->dev, "bigger res, " | ||
622 | + "same fps: " | ||
623 | + "w %d\th %d\tw %d\th %d\n", | ||
624 | + frmi.width, frmi.height, | ||
625 | + best_pix_in->width, | ||
626 | + best_pix_in->height); | ||
627 | + goto do_it_now; | ||
628 | + } | ||
629 | + | ||
630 | + dev_info(&vdev->vfd->dev, "falling through\n"); | ||
631 | + | ||
632 | + continue; | ||
633 | + | ||
634 | +do_it_now: | ||
635 | + *best_ival = frmi.discrete; | ||
636 | + best_pix_out = pix_tmp_out; | ||
637 | + best_pix_in->width = frmi.width; | ||
638 | + best_pix_in->height = frmi.height; | ||
639 | + best_pix_in->pixelformat = frmi.pixel_format; | ||
640 | + | ||
641 | + dev_info(&vdev->vfd->dev, | ||
642 | + "best_pix_in: w %d\th %d\tfmt %8.8x" | ||
643 | + "\tival %d/%d\n", | ||
644 | + best_pix_in->width, | ||
645 | + best_pix_in->height, | ||
646 | + best_pix_in->pixelformat, | ||
647 | + best_ival->numerator, | ||
648 | + best_ival->denominator); | ||
649 | + } | ||
650 | + } | ||
651 | + } | ||
652 | + | ||
653 | + if (best_ival->denominator == 0) | ||
654 | + return -EINVAL; | ||
655 | + | ||
656 | + *wanted_pix_out = best_pix_out; | ||
657 | + | ||
658 | + dev_info(&vdev->vfd->dev, "w %d, h %d, fmt %8.8x -> w %d, h %d\n", | ||
659 | + best_pix_in->width, best_pix_in->height, | ||
660 | + best_pix_in->pixelformat, | ||
661 | + best_pix_out.width, best_pix_out.height); | ||
662 | + | ||
663 | + return isp_try_fmt_cap(best_pix_in, wanted_pix_out); | ||
664 | +} | ||
665 | + | ||
666 | +static int s_pix_parm(struct omap34xxcam_videodev *vdev, | ||
667 | + struct v4l2_pix_format *best_pix, | ||
668 | + struct v4l2_pix_format *pix, | ||
669 | + struct v4l2_fract *best_ival) | ||
670 | +{ | ||
671 | + struct v4l2_streamparm a; | ||
672 | + struct v4l2_format fmt; | ||
673 | + int rval; | ||
674 | + | ||
675 | + rval = try_pix_parm(vdev, best_pix, pix, best_ival); | ||
676 | + if (rval) | ||
677 | + return rval; | ||
678 | + | ||
679 | + rval = isp_s_fmt_cap(best_pix, pix); | ||
680 | + if (rval) | ||
681 | + return rval; | ||
682 | + | ||
683 | + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
684 | + fmt.fmt.pix = *best_pix; | ||
685 | + rval = vidioc_int_s_fmt_cap(vdev->vdev_sensor, &fmt); | ||
686 | + if (rval) | ||
687 | + return rval; | ||
688 | + | ||
689 | + a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
690 | + a.parm.capture.timeperframe = *best_ival; | ||
691 | + rval = vidioc_int_s_parm(vdev->vdev_sensor, &a); | ||
692 | + | ||
693 | + return rval; | ||
694 | +} | ||
695 | + | ||
696 | +/** | ||
697 | + * vidioc_s_fmt_vid_cap - V4L2 set format capabilities IOCTL handler | ||
698 | + * @file: ptr. to system file structure | ||
699 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
700 | + * @f: ptr to standard V4L2 format structure | ||
701 | + * | ||
702 | + * Attempts to set input format with the sensor driver (first) and then the | ||
703 | + * ISP. Returns the return code from vidioc_g_fmt_vid_cap(). | ||
704 | + */ | ||
705 | +static int vidioc_s_fmt_vid_cap(struct file *file, void *fh, | ||
706 | + struct v4l2_format *f) | ||
707 | +{ | ||
708 | + struct omap34xxcam_fh *ofh = fh; | ||
709 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
710 | + struct v4l2_pix_format pix_tmp; | ||
711 | + struct v4l2_fract timeperframe; | ||
712 | + int rval; | ||
713 | + | ||
714 | + if (vdev->vdev_sensor == v4l2_int_device_dummy()) | ||
715 | + return -EINVAL; | ||
716 | + | ||
717 | + mutex_lock(&vdev->mutex); | ||
718 | + if (vdev->streaming) { | ||
719 | + rval = -EBUSY; | ||
720 | + goto out; | ||
721 | + } | ||
722 | + | ||
723 | + vdev->want_pix = f->fmt.pix; | ||
724 | + | ||
725 | + timeperframe = vdev->want_timeperframe; | ||
726 | + | ||
727 | + rval = s_pix_parm(vdev, &pix_tmp, &f->fmt.pix, &timeperframe); | ||
728 | + if (!rval) | ||
729 | + vdev->pix = f->fmt.pix; | ||
730 | + | ||
731 | +out: | ||
732 | + mutex_unlock(&vdev->mutex); | ||
733 | + | ||
734 | + return rval; | ||
735 | +} | ||
736 | + | ||
737 | +/** | ||
738 | + * vidioc_try_fmt_vid_cap - V4L2 try format capabilities IOCTL handler | ||
739 | + * @file: ptr. to system file structure | ||
740 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
741 | + * @f: ptr to standard V4L2 format structure | ||
742 | + * | ||
743 | + * Checks if the given format is supported by the sensor driver and | ||
744 | + * by the ISP. | ||
745 | + */ | ||
746 | +static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, | ||
747 | + struct v4l2_format *f) | ||
748 | +{ | ||
749 | + struct omap34xxcam_fh *ofh = fh; | ||
750 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
751 | + struct v4l2_pix_format pix_tmp; | ||
752 | + struct v4l2_fract timeperframe; | ||
753 | + int rval; | ||
754 | + | ||
755 | + if (vdev->vdev_sensor == v4l2_int_device_dummy()) | ||
756 | + return -EINVAL; | ||
757 | + | ||
758 | + mutex_lock(&vdev->mutex); | ||
759 | + | ||
760 | + timeperframe = vdev->want_timeperframe; | ||
761 | + | ||
762 | + rval = try_pix_parm(vdev, &pix_tmp, &f->fmt.pix, &timeperframe); | ||
763 | + | ||
764 | + mutex_unlock(&vdev->mutex); | ||
765 | + | ||
766 | + return rval; | ||
767 | +} | ||
768 | + | ||
769 | +/** | ||
770 | + * vidioc_reqbufs - V4L2 request buffers IOCTL handler | ||
771 | + * @file: ptr. to system file structure | ||
772 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
773 | + * @b: ptr to standard V4L2 request buffers structure | ||
774 | + * | ||
775 | + * Attempts to get a buffer from the buffer queue associated with the | ||
776 | + * fh through the video buffer library API. | ||
777 | + */ | ||
778 | +static int vidioc_reqbufs(struct file *file, void *fh, | ||
779 | + struct v4l2_requestbuffers *b) | ||
780 | +{ | ||
781 | + struct omap34xxcam_fh *ofh = fh; | ||
782 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
783 | + int rval; | ||
784 | + | ||
785 | + if (vdev->vdev_sensor == v4l2_int_device_dummy()) | ||
786 | + return -EINVAL; | ||
787 | + | ||
788 | + mutex_lock(&vdev->mutex); | ||
789 | + if (vdev->streaming) { | ||
790 | + mutex_unlock(&vdev->mutex); | ||
791 | + return -EBUSY; | ||
792 | + } | ||
793 | + | ||
794 | + rval = videobuf_reqbufs(&ofh->vbq, b); | ||
795 | + | ||
796 | + mutex_unlock(&vdev->mutex); | ||
797 | + | ||
798 | + /* | ||
799 | + * Either videobuf_reqbufs failed or the buffers are not | ||
800 | + * memory-mapped (which would need special attention). | ||
801 | + */ | ||
802 | + if (rval < 0 || b->memory != V4L2_MEMORY_MMAP) | ||
803 | + goto out; | ||
804 | + | ||
805 | +out: | ||
806 | + return rval; | ||
807 | +} | ||
808 | + | ||
809 | +/** | ||
810 | + * vidioc_querybuf - V4L2 query buffer IOCTL handler | ||
811 | + * @file: ptr. to system file structure | ||
812 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
813 | + * @b: ptr to standard V4L2 buffer structure | ||
814 | + * | ||
815 | + * Attempts to fill in the v4l2_buffer structure for the buffer queue | ||
816 | + * associated with the fh through the video buffer library API. | ||
817 | + */ | ||
818 | +static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *b) | ||
819 | +{ | ||
820 | + struct omap34xxcam_fh *ofh = fh; | ||
821 | + | ||
822 | + return videobuf_querybuf(&ofh->vbq, b); | ||
823 | +} | ||
824 | + | ||
825 | +/** | ||
826 | + * vidioc_qbuf - V4L2 queue buffer IOCTL handler | ||
827 | + * @file: ptr. to system file structure | ||
828 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
829 | + * @b: ptr to standard V4L2 buffer structure | ||
830 | + * | ||
831 | + * Attempts to queue the v4l2_buffer on the buffer queue | ||
832 | + * associated with the fh through the video buffer library API. | ||
833 | + */ | ||
834 | +static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) | ||
835 | +{ | ||
836 | + struct omap34xxcam_fh *ofh = fh; | ||
837 | + | ||
838 | + return videobuf_qbuf(&ofh->vbq, b); | ||
839 | +} | ||
840 | + | ||
841 | +/** | ||
842 | + * vidioc_dqbuf - V4L2 dequeue buffer IOCTL handler | ||
843 | + * @file: ptr. to system file structure | ||
844 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
845 | + * @b: ptr to standard V4L2 buffer structure | ||
846 | + * | ||
847 | + * Attempts to dequeue the v4l2_buffer from the buffer queue | ||
848 | + * associated with the fh through the video buffer library API. If the | ||
849 | + * buffer is a user space buffer, then this function will also requeue it, | ||
850 | + * as user does not expect to do this. | ||
851 | + */ | ||
852 | +static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) | ||
853 | +{ | ||
854 | + struct omap34xxcam_fh *ofh = fh; | ||
855 | + int rval; | ||
856 | + | ||
857 | +videobuf_dqbuf_again: | ||
858 | + rval = videobuf_dqbuf(&ofh->vbq, b, file->f_flags & O_NONBLOCK); | ||
859 | + | ||
860 | + /* | ||
861 | + * This is a hack. We don't want to show -EIO to the user | ||
862 | + * space. Requeue the buffer and try again if we're not doing | ||
863 | + * this in non-blocking mode. | ||
864 | + */ | ||
865 | + if (rval == -EIO) { | ||
866 | + videobuf_qbuf(&ofh->vbq, b); | ||
867 | + if (!(file->f_flags & O_NONBLOCK)) | ||
868 | + goto videobuf_dqbuf_again; | ||
869 | + /* | ||
870 | + * We don't have a videobuf_buffer now --- maybe next | ||
871 | + * time... | ||
872 | + */ | ||
873 | + rval = -EAGAIN; | ||
874 | + } | ||
875 | + | ||
876 | + return rval; | ||
877 | +} | ||
878 | + | ||
879 | +/** | ||
880 | + * vidioc_streamon - V4L2 streamon IOCTL handler | ||
881 | + * @file: ptr. to system file structure | ||
882 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
883 | + * @i: V4L2 buffer type | ||
884 | + * | ||
885 | + * Attempts to start streaming by enabling the sensor interface and turning | ||
886 | + * on video buffer streaming through the video buffer library API. Upon | ||
887 | + * success the function returns 0, otherwise an error code is returned. | ||
888 | + */ | ||
889 | +static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) | ||
890 | +{ | ||
891 | + struct omap34xxcam_fh *ofh = fh; | ||
892 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
893 | + int rval; | ||
894 | + | ||
895 | + if (vdev->vdev_sensor == v4l2_int_device_dummy()) | ||
896 | + return -EINVAL; | ||
897 | + | ||
898 | + mutex_lock(&vdev->mutex); | ||
899 | + if (vdev->streaming) { | ||
900 | + rval = -EBUSY; | ||
901 | + goto out; | ||
902 | + } | ||
903 | + | ||
904 | + rval = omap34xxcam_slave_power_set(vdev, V4L2_POWER_ON, | ||
905 | + OMAP34XXCAM_SLAVE_POWER_SENSOR_LENS); | ||
906 | + if (rval) { | ||
907 | + dev_dbg(&vdev->vfd->dev, | ||
908 | + "omap34xxcam_slave_power_set failed\n"); | ||
909 | + goto out; | ||
910 | + } | ||
911 | + | ||
912 | + rval = videobuf_streamon(&ofh->vbq); | ||
913 | + if (rval) | ||
914 | + omap34xxcam_slave_power_set( | ||
915 | + vdev, V4L2_POWER_OFF, | ||
916 | + OMAP34XXCAM_SLAVE_POWER_SENSOR_LENS); | ||
917 | + else | ||
918 | + vdev->streaming = file; | ||
919 | + | ||
920 | +out: | ||
921 | + mutex_unlock(&vdev->mutex); | ||
922 | + | ||
923 | + return rval; | ||
924 | +} | ||
925 | + | ||
926 | +/** | ||
927 | + * vidioc_streamoff - V4L2 streamoff IOCTL handler | ||
928 | + * @file: ptr. to system file structure | ||
929 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
930 | + * @i: V4L2 buffer type | ||
931 | + * | ||
932 | + * Attempts to stop streaming by flushing all scheduled work, waiting on | ||
933 | + * any queued buffers to complete and then stopping the ISP and turning | ||
934 | + * off video buffer streaming through the video buffer library API. Upon | ||
935 | + * success the function returns 0, otherwise an error code is returned. | ||
936 | + */ | ||
937 | +static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) | ||
938 | +{ | ||
939 | + struct omap34xxcam_fh *ofh = fh; | ||
940 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
941 | + struct videobuf_queue *q = &ofh->vbq; | ||
942 | + int rval; | ||
943 | + | ||
944 | + mutex_lock(&vdev->mutex); | ||
945 | + | ||
946 | + if (vdev->streaming == file) | ||
947 | + isp_stop(); | ||
948 | + | ||
949 | + rval = videobuf_streamoff(q); | ||
950 | + if (!rval) { | ||
951 | + vdev->streaming = NULL; | ||
952 | + | ||
953 | + omap34xxcam_slave_power_set(vdev, V4L2_POWER_STANDBY, | ||
954 | + OMAP34XXCAM_SLAVE_POWER_SENSOR); | ||
955 | + omap34xxcam_slave_power_suggest(vdev, V4L2_POWER_STANDBY, | ||
956 | + OMAP34XXCAM_SLAVE_POWER_LENS); | ||
957 | + } | ||
958 | + | ||
959 | + mutex_unlock(&vdev->mutex); | ||
960 | + | ||
961 | + return rval; | ||
962 | +} | ||
963 | + | ||
964 | +/** | ||
965 | + * vidioc_enum_input - V4L2 enumerate input IOCTL handler | ||
966 | + * @file: ptr. to system file structure | ||
967 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
968 | + * @inp: V4L2 input type information structure | ||
969 | + * | ||
970 | + * Fills in v4l2_input structure. Returns 0. | ||
971 | + */ | ||
972 | +static int vidioc_enum_input(struct file *file, void *fh, | ||
973 | + struct v4l2_input *inp) | ||
974 | +{ | ||
975 | + if (inp->index > 0) | ||
976 | + return -EINVAL; | ||
977 | + | ||
978 | + strlcpy(inp->name, "camera", sizeof(inp->name)); | ||
979 | + inp->type = V4L2_INPUT_TYPE_CAMERA; | ||
980 | + | ||
981 | + return 0; | ||
982 | +} | ||
983 | + | ||
984 | +/** | ||
985 | + * vidioc_g_input - V4L2 get input IOCTL handler | ||
986 | + * @file: ptr. to system file structure | ||
987 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
988 | + * @i: address to hold index of input supported | ||
989 | + * | ||
990 | + * Sets index to 0. | ||
991 | + */ | ||
992 | +static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) | ||
993 | +{ | ||
994 | + *i = 0; | ||
995 | + | ||
996 | + return 0; | ||
997 | +} | ||
998 | + | ||
999 | +/** | ||
1000 | + * vidioc_s_input - V4L2 set input IOCTL handler | ||
1001 | + * @file: ptr. to system file structure | ||
1002 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
1003 | + * @i: index of input selected | ||
1004 | + * | ||
1005 | + * 0 is only index supported. | ||
1006 | + */ | ||
1007 | +static int vidioc_s_input(struct file *file, void *fh, unsigned int i) | ||
1008 | +{ | ||
1009 | + if (i > 0) | ||
1010 | + return -EINVAL; | ||
1011 | + | ||
1012 | + return 0; | ||
1013 | +} | ||
1014 | + | ||
1015 | +/** | ||
1016 | + * vidioc_queryctrl - V4L2 query control IOCTL handler | ||
1017 | + * @file: ptr. to system file structure | ||
1018 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
1019 | + * @a: standard V4L2 query control ioctl structure | ||
1020 | + * | ||
1021 | + * If the requested control is supported, returns the control information | ||
1022 | + * in the v4l2_queryctrl structure. Otherwise, returns -EINVAL if the | ||
1023 | + * control is not supported. If the sensor being used is a "smart sensor", | ||
1024 | + * this request is passed to the sensor driver, otherwise the ISP is | ||
1025 | + * queried and if it does not support the requested control, the request | ||
1026 | + * is forwarded to the "raw" sensor driver to see if it supports it. | ||
1027 | + */ | ||
1028 | +static int vidioc_queryctrl(struct file *file, void *fh, | ||
1029 | + struct v4l2_queryctrl *a) | ||
1030 | +{ | ||
1031 | + struct omap34xxcam_fh *ofh = fh; | ||
1032 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1033 | + struct v4l2_queryctrl a_tmp; | ||
1034 | + int best_slave = -1; | ||
1035 | + u32 best_ctrl = (u32)-1; | ||
1036 | + int i; | ||
1037 | + | ||
1038 | + if (vdev->vdev_sensor_config.sensor_isp) | ||
1039 | + return vidioc_int_queryctrl(vdev->vdev_sensor, a); | ||
1040 | + | ||
1041 | + /* No next flags: try slaves directly. */ | ||
1042 | + if (!(a->id & V4L2_CTRL_FLAG_NEXT_CTRL)) { | ||
1043 | + for (i = 0; i <= OMAP34XXCAM_SLAVE_FLASH; i++) { | ||
1044 | + if (!vidioc_int_queryctrl(vdev->slave[i], a)) | ||
1045 | + return 0; | ||
1046 | + } | ||
1047 | + return isp_queryctrl(a); | ||
1048 | + } | ||
1049 | + | ||
1050 | + /* Find slave with smallest next control id. */ | ||
1051 | + for (i = 0; i <= OMAP34XXCAM_SLAVE_FLASH; i++) { | ||
1052 | + a_tmp = *a; | ||
1053 | + | ||
1054 | + if (vidioc_int_queryctrl(vdev->slave[i], &a_tmp)) | ||
1055 | + continue; | ||
1056 | + | ||
1057 | + if (a_tmp.id < best_ctrl) { | ||
1058 | + best_slave = i; | ||
1059 | + best_ctrl = a_tmp.id; | ||
1060 | + } | ||
1061 | + } | ||
1062 | + | ||
1063 | + a_tmp = *a; | ||
1064 | + if (!isp_queryctrl(&a_tmp)) { | ||
1065 | + if (a_tmp.id < best_ctrl) { | ||
1066 | + *a = a_tmp; | ||
1067 | + | ||
1068 | + return 0; | ||
1069 | + } | ||
1070 | + } | ||
1071 | + | ||
1072 | + if (best_slave == -1) | ||
1073 | + return -EINVAL; | ||
1074 | + | ||
1075 | + a->id = best_ctrl; | ||
1076 | + return vidioc_int_queryctrl(vdev->slave[best_slave], a); | ||
1077 | +} | ||
1078 | + | ||
1079 | +/** | ||
1080 | + * vidioc_querymenu - V4L2 query menu IOCTL handler | ||
1081 | + * @file: ptr. to system file structure | ||
1082 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
1083 | + * @a: standard V4L2 query menu ioctl structure | ||
1084 | + * | ||
1085 | + * If the requested control is supported, returns the menu information | ||
1086 | + * in the v4l2_querymenu structure. Otherwise, returns -EINVAL if the | ||
1087 | + * control is not supported or is not a menu. If the sensor being used | ||
1088 | + * is a "smart sensor", this request is passed to the sensor driver, | ||
1089 | + * otherwise the ISP is queried and if it does not support the requested | ||
1090 | + * menu control, the request is forwarded to the "raw" sensor driver to | ||
1091 | + * see if it supports it. | ||
1092 | + */ | ||
1093 | +static int vidioc_querymenu(struct file *file, void *fh, | ||
1094 | + struct v4l2_querymenu *a) | ||
1095 | +{ | ||
1096 | + struct omap34xxcam_fh *ofh = fh; | ||
1097 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1098 | + int i; | ||
1099 | + | ||
1100 | + if (vdev->vdev_sensor_config.sensor_isp) | ||
1101 | + return vidioc_int_querymenu(vdev->vdev_sensor, a); | ||
1102 | + | ||
1103 | + /* Try slaves directly. */ | ||
1104 | + for (i = 0; i <= OMAP34XXCAM_SLAVE_FLASH; i++) { | ||
1105 | + if (!vidioc_int_querymenu(vdev->slave[i], a)) | ||
1106 | + return 0; | ||
1107 | + } | ||
1108 | + return isp_querymenu(a); | ||
1109 | +} | ||
1110 | + | ||
1111 | +static int vidioc_g_ext_ctrls(struct file *file, void *fh, | ||
1112 | + struct v4l2_ext_controls *a) | ||
1113 | +{ | ||
1114 | + struct omap34xxcam_fh *ofh = fh; | ||
1115 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1116 | + int i, ctrl_idx, rval = 0; | ||
1117 | + | ||
1118 | + mutex_lock(&vdev->mutex); | ||
1119 | + | ||
1120 | + for (ctrl_idx = 0; ctrl_idx < a->count; ctrl_idx++) { | ||
1121 | + struct v4l2_control ctrl; | ||
1122 | + | ||
1123 | + ctrl.id = a->controls[ctrl_idx].id; | ||
1124 | + | ||
1125 | + if (vdev->vdev_sensor_config.sensor_isp) { | ||
1126 | + rval = vidioc_int_g_ctrl(vdev->vdev_sensor, &ctrl); | ||
1127 | + } else { | ||
1128 | + for (i = 0; i <= OMAP34XXCAM_SLAVE_FLASH; i++) { | ||
1129 | + rval = vidioc_int_g_ctrl(vdev->slave[i], &ctrl); | ||
1130 | + if (!rval) | ||
1131 | + break; | ||
1132 | + } | ||
1133 | + } | ||
1134 | + | ||
1135 | + if (rval) | ||
1136 | + rval = isp_g_ctrl(&ctrl); | ||
1137 | + | ||
1138 | + if (rval) { | ||
1139 | + a->error_idx = ctrl_idx; | ||
1140 | + break; | ||
1141 | + } | ||
1142 | + | ||
1143 | + a->controls[ctrl_idx].value = ctrl.value; | ||
1144 | + } | ||
1145 | + | ||
1146 | + mutex_unlock(&vdev->mutex); | ||
1147 | + | ||
1148 | + return rval; | ||
1149 | +} | ||
1150 | + | ||
1151 | +static int vidioc_s_ext_ctrls(struct file *file, void *fh, | ||
1152 | + struct v4l2_ext_controls *a) | ||
1153 | +{ | ||
1154 | + struct omap34xxcam_fh *ofh = fh; | ||
1155 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1156 | + int i, ctrl_idx, rval = 0; | ||
1157 | + | ||
1158 | + mutex_lock(&vdev->mutex); | ||
1159 | + | ||
1160 | + for (ctrl_idx = 0; ctrl_idx < a->count; ctrl_idx++) { | ||
1161 | + struct v4l2_control ctrl; | ||
1162 | + | ||
1163 | + ctrl.id = a->controls[ctrl_idx].id; | ||
1164 | + ctrl.value = a->controls[ctrl_idx].value; | ||
1165 | + | ||
1166 | + if (vdev->vdev_sensor_config.sensor_isp) { | ||
1167 | + rval = vidioc_int_s_ctrl(vdev->vdev_sensor, &ctrl); | ||
1168 | + } else { | ||
1169 | + for (i = 0; i <= OMAP34XXCAM_SLAVE_FLASH; i++) { | ||
1170 | + rval = vidioc_int_s_ctrl(vdev->slave[i], &ctrl); | ||
1171 | + if (!rval) | ||
1172 | + break; | ||
1173 | + } | ||
1174 | + } | ||
1175 | + | ||
1176 | + if (rval) | ||
1177 | + rval = isp_s_ctrl(&ctrl); | ||
1178 | + | ||
1179 | + if (rval) { | ||
1180 | + a->error_idx = ctrl_idx; | ||
1181 | + break; | ||
1182 | + } | ||
1183 | + | ||
1184 | + a->controls[ctrl_idx].value = ctrl.value; | ||
1185 | + } | ||
1186 | + | ||
1187 | + mutex_unlock(&vdev->mutex); | ||
1188 | + | ||
1189 | + return rval; | ||
1190 | +} | ||
1191 | + | ||
1192 | +/** | ||
1193 | + * vidioc_g_parm - V4L2 get parameters IOCTL handler | ||
1194 | + * @file: ptr. to system file structure | ||
1195 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
1196 | + * @a: standard V4L2 stream parameters structure | ||
1197 | + * | ||
1198 | + * If request is for video capture buffer type, handles request by | ||
1199 | + * forwarding to sensor driver. | ||
1200 | + */ | ||
1201 | +static int vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) | ||
1202 | +{ | ||
1203 | + struct omap34xxcam_fh *ofh = fh; | ||
1204 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1205 | + int rval; | ||
1206 | + | ||
1207 | + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1208 | + return -EINVAL; | ||
1209 | + | ||
1210 | + mutex_lock(&vdev->mutex); | ||
1211 | + rval = vidioc_int_g_parm(vdev->vdev_sensor, a); | ||
1212 | + mutex_unlock(&vdev->mutex); | ||
1213 | + | ||
1214 | + return rval; | ||
1215 | +} | ||
1216 | + | ||
1217 | +/** | ||
1218 | + * vidioc_s_parm - V4L2 set parameters IOCTL handler | ||
1219 | + * @file: ptr. to system file structure | ||
1220 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
1221 | + * @a: standard V4L2 stream parameters structure | ||
1222 | + * | ||
1223 | + * If request is for video capture buffer type, handles request by | ||
1224 | + * first getting current stream parameters from sensor, then forwarding | ||
1225 | + * request to set new parameters to sensor driver. It then attempts to | ||
1226 | + * enable the sensor interface with the new parameters. If this fails, it | ||
1227 | + * reverts back to the previous parameters. | ||
1228 | + */ | ||
1229 | +static int vidioc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) | ||
1230 | +{ | ||
1231 | + struct omap34xxcam_fh *ofh = fh; | ||
1232 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1233 | + struct v4l2_pix_format pix_tmp_sensor, pix_tmp; | ||
1234 | + int rval; | ||
1235 | + | ||
1236 | + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1237 | + return -EINVAL; | ||
1238 | + | ||
1239 | + if (vdev->vdev_sensor == v4l2_int_device_dummy()) | ||
1240 | + return -EINVAL; | ||
1241 | + | ||
1242 | + mutex_lock(&vdev->mutex); | ||
1243 | + if (vdev->streaming) { | ||
1244 | + rval = -EBUSY; | ||
1245 | + goto out; | ||
1246 | + } | ||
1247 | + | ||
1248 | + vdev->want_timeperframe = a->parm.capture.timeperframe; | ||
1249 | + | ||
1250 | + pix_tmp = vdev->want_pix; | ||
1251 | + | ||
1252 | + rval = s_pix_parm(vdev, &pix_tmp_sensor, &pix_tmp, | ||
1253 | + &a->parm.capture.timeperframe); | ||
1254 | + | ||
1255 | +out: | ||
1256 | + mutex_unlock(&vdev->mutex); | ||
1257 | + | ||
1258 | + return rval; | ||
1259 | +} | ||
1260 | + | ||
1261 | +/** | ||
1262 | + * vidioc_cropcap - V4L2 crop capture IOCTL handler | ||
1263 | + * @file: ptr. to system file structure | ||
1264 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
1265 | + * @a: standard V4L2 crop capture structure | ||
1266 | + * | ||
1267 | + * If using a "smart" sensor, just forwards request to the sensor driver, | ||
1268 | + * otherwise fills in the v4l2_cropcap values locally. | ||
1269 | + */ | ||
1270 | +static int vidioc_cropcap(struct file *file, void *fh, struct v4l2_cropcap *a) | ||
1271 | +{ | ||
1272 | + struct omap34xxcam_fh *ofh = fh; | ||
1273 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1274 | + struct v4l2_cropcap *cropcap = a; | ||
1275 | + int rval; | ||
1276 | + | ||
1277 | + if (vdev->vdev_sensor == v4l2_int_device_dummy()) | ||
1278 | + return -EINVAL; | ||
1279 | + | ||
1280 | + mutex_lock(&vdev->mutex); | ||
1281 | + | ||
1282 | + rval = vidioc_int_cropcap(vdev->vdev_sensor, a); | ||
1283 | + | ||
1284 | + if (rval && !vdev->vdev_sensor_config.sensor_isp) { | ||
1285 | + struct v4l2_format f; | ||
1286 | + | ||
1287 | + /* cropcap failed, try to do this via g_fmt_cap */ | ||
1288 | + rval = vidioc_int_g_fmt_cap(vdev->vdev_sensor, &f); | ||
1289 | + if (!rval) { | ||
1290 | + cropcap->bounds.top = 0; | ||
1291 | + cropcap->bounds.left = 0; | ||
1292 | + cropcap->bounds.width = f.fmt.pix.width; | ||
1293 | + cropcap->bounds.height = f.fmt.pix.height; | ||
1294 | + cropcap->defrect = cropcap->bounds; | ||
1295 | + cropcap->pixelaspect.numerator = 1; | ||
1296 | + cropcap->pixelaspect.denominator = 1; | ||
1297 | + } | ||
1298 | + } | ||
1299 | + | ||
1300 | + mutex_unlock(&vdev->mutex); | ||
1301 | + | ||
1302 | + return rval; | ||
1303 | +} | ||
1304 | + | ||
1305 | +/** | ||
1306 | + * vidioc_g_crop - V4L2 get capture crop IOCTL handler | ||
1307 | + * @file: ptr. to system file structure | ||
1308 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
1309 | + * @a: standard V4L2 crop structure | ||
1310 | + * | ||
1311 | + * If using a "smart" sensor, just forwards request to the sensor driver, | ||
1312 | + * otherwise calls the isp functions to fill in current crop values. | ||
1313 | + */ | ||
1314 | +static int vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *a) | ||
1315 | +{ | ||
1316 | + struct omap34xxcam_fh *ofh = fh; | ||
1317 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1318 | + int rval = 0; | ||
1319 | + | ||
1320 | + if (vdev->vdev_sensor == v4l2_int_device_dummy()) | ||
1321 | + return -EINVAL; | ||
1322 | + | ||
1323 | + mutex_lock(&vdev->mutex); | ||
1324 | + | ||
1325 | + if (vdev->vdev_sensor_config.sensor_isp) | ||
1326 | + rval = vidioc_int_g_crop(vdev->vdev_sensor, a); | ||
1327 | + else | ||
1328 | + rval = isp_g_crop(a); | ||
1329 | + | ||
1330 | + mutex_unlock(&vdev->mutex); | ||
1331 | + | ||
1332 | + return rval; | ||
1333 | +} | ||
1334 | + | ||
1335 | +/** | ||
1336 | + * vidioc_s_crop - V4L2 set capture crop IOCTL handler | ||
1337 | + * @file: ptr. to system file structure | ||
1338 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
1339 | + * @a: standard V4L2 crop structure | ||
1340 | + * | ||
1341 | + * If using a "smart" sensor, just forwards request to the sensor driver, | ||
1342 | + * otherwise calls the isp functions to set the current crop values. | ||
1343 | + */ | ||
1344 | +static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *a) | ||
1345 | +{ | ||
1346 | + struct omap34xxcam_fh *ofh = fh; | ||
1347 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1348 | + int rval = 0; | ||
1349 | + | ||
1350 | + if (vdev->vdev_sensor == v4l2_int_device_dummy()) | ||
1351 | + return -EINVAL; | ||
1352 | + | ||
1353 | + mutex_lock(&vdev->mutex); | ||
1354 | + | ||
1355 | + if (vdev->vdev_sensor_config.sensor_isp) | ||
1356 | + rval = vidioc_int_s_crop(vdev->vdev_sensor, a); | ||
1357 | + else | ||
1358 | + rval = isp_s_crop(a, &vdev->pix); | ||
1359 | + | ||
1360 | + mutex_unlock(&vdev->mutex); | ||
1361 | + | ||
1362 | + return rval; | ||
1363 | +} | ||
1364 | + | ||
1365 | +static int vidioc_enum_framesizes(struct file *file, void *fh, | ||
1366 | + struct v4l2_frmsizeenum *frms) | ||
1367 | +{ | ||
1368 | + struct omap34xxcam_fh *ofh = fh; | ||
1369 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1370 | + u32 pixel_format; | ||
1371 | + int rval; | ||
1372 | + | ||
1373 | + mutex_lock(&vdev->mutex); | ||
1374 | + | ||
1375 | + if (vdev->vdev_sensor_config.sensor_isp) { | ||
1376 | + rval = vidioc_int_enum_framesizes(vdev->vdev_sensor, frms); | ||
1377 | + } else { | ||
1378 | + pixel_format = frms->pixel_format; | ||
1379 | + frms->pixel_format = -1; /* ISP does format conversion */ | ||
1380 | + rval = vidioc_int_enum_framesizes(vdev->vdev_sensor, frms); | ||
1381 | + frms->pixel_format = pixel_format; | ||
1382 | + } | ||
1383 | + | ||
1384 | + mutex_unlock(&vdev->mutex); | ||
1385 | + return rval; | ||
1386 | +} | ||
1387 | + | ||
1388 | +static int vidioc_enum_frameintervals(struct file *file, void *fh, | ||
1389 | + struct v4l2_frmivalenum *frmi) | ||
1390 | +{ | ||
1391 | + struct omap34xxcam_fh *ofh = fh; | ||
1392 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1393 | + u32 pixel_format; | ||
1394 | + int rval; | ||
1395 | + | ||
1396 | + mutex_lock(&vdev->mutex); | ||
1397 | + | ||
1398 | + if (vdev->vdev_sensor_config.sensor_isp) { | ||
1399 | + rval = vidioc_int_enum_frameintervals(vdev->vdev_sensor, frmi); | ||
1400 | + } else { | ||
1401 | + pixel_format = frmi->pixel_format; | ||
1402 | + frmi->pixel_format = -1; /* ISP does format conversion */ | ||
1403 | + rval = vidioc_int_enum_frameintervals(vdev->vdev_sensor, frmi); | ||
1404 | + frmi->pixel_format = pixel_format; | ||
1405 | + } | ||
1406 | + | ||
1407 | + mutex_unlock(&vdev->mutex); | ||
1408 | + return rval; | ||
1409 | +} | ||
1410 | + | ||
1411 | +/** | ||
1412 | + * vidioc_default - private IOCTL handler | ||
1413 | + * @file: ptr. to system file structure | ||
1414 | + * @fh: ptr to hold address of omap34xxcam_fh struct (per-filehandle data) | ||
1415 | + * @cmd: ioctl cmd value | ||
1416 | + * @arg: ioctl arg value | ||
1417 | + * | ||
1418 | + * If the sensor being used is a "smart sensor", this request is returned to | ||
1419 | + * caller with -EINVAL err code. Otherwise if the control id is the private | ||
1420 | + * VIDIOC_PRIVATE_ISP_AEWB_REQ to update the analog gain or exposure, | ||
1421 | + * then this request is forwared directly to the sensor to incorporate the | ||
1422 | + * feedback. The request is then passed on to the ISP private IOCTL handler, | ||
1423 | + * isp_handle_private() | ||
1424 | + */ | ||
1425 | +static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) | ||
1426 | +{ | ||
1427 | + struct omap34xxcam_fh *ofh = file->private_data; | ||
1428 | + struct omap34xxcam_videodev *vdev = ofh->vdev; | ||
1429 | + int rval; | ||
1430 | + | ||
1431 | + if (vdev->vdev_sensor_config.sensor_isp) { | ||
1432 | + rval = -EINVAL; | ||
1433 | + } else { | ||
1434 | + switch (cmd) { | ||
1435 | + case VIDIOC_PRIVATE_ISP_AEWB_REQ: | ||
1436 | + { | ||
1437 | + /* Need to update sensor first */ | ||
1438 | + struct isph3a_aewb_data *data; | ||
1439 | + struct v4l2_control vc; | ||
1440 | + | ||
1441 | + data = (struct isph3a_aewb_data *) arg; | ||
1442 | + if (data->update & SET_EXPOSURE) { | ||
1443 | + dev_info(&vdev->vfd->dev, "using " | ||
1444 | + "VIDIOC_PRIVATE_ISP_AEWB_REQ to set " | ||
1445 | + "exposure is deprecated!\n"); | ||
1446 | + vc.id = V4L2_CID_EXPOSURE; | ||
1447 | + vc.value = data->shutter; | ||
1448 | + mutex_lock(&vdev->mutex); | ||
1449 | + rval = vidioc_int_s_ctrl(vdev->vdev_sensor, | ||
1450 | + &vc); | ||
1451 | + mutex_unlock(&vdev->mutex); | ||
1452 | + if (rval) | ||
1453 | + goto out; | ||
1454 | + } | ||
1455 | + if (data->update & SET_ANALOG_GAIN) { | ||
1456 | + dev_info(&vdev->vfd->dev, "using " | ||
1457 | + "VIDIOC_PRIVATE_ISP_AEWB_REQ to set " | ||
1458 | + "gain is deprecated!\n"); | ||
1459 | + vc.id = V4L2_CID_GAIN; | ||
1460 | + vc.value = data->gain; | ||
1461 | + mutex_lock(&vdev->mutex); | ||
1462 | + rval = vidioc_int_s_ctrl(vdev->vdev_sensor, | ||
1463 | + &vc); | ||
1464 | + mutex_unlock(&vdev->mutex); | ||
1465 | + if (rval) | ||
1466 | + goto out; | ||
1467 | + } | ||
1468 | + } | ||
1469 | + break; | ||
1470 | + case VIDIOC_PRIVATE_ISP_AF_REQ: { | ||
1471 | + /* Need to update lens first */ | ||
1472 | + struct isp_af_data *data; | ||
1473 | + struct v4l2_control vc; | ||
1474 | + | ||
1475 | + if (!vdev->vdev_lens) { | ||
1476 | + rval = -EINVAL; | ||
1477 | + goto out; | ||
1478 | + } | ||
1479 | + data = (struct isp_af_data *) arg; | ||
1480 | + if (data->update & LENS_DESIRED_POSITION) { | ||
1481 | + dev_info(&vdev->vfd->dev, "using " | ||
1482 | + "VIDIOC_PRIVATE_ISP_AF_REQ to set " | ||
1483 | + "lens position is deprecated!\n"); | ||
1484 | + vc.id = V4L2_CID_FOCUS_ABSOLUTE; | ||
1485 | + vc.value = data->desired_lens_direction; | ||
1486 | + mutex_lock(&vdev->mutex); | ||
1487 | + rval = vidioc_int_s_ctrl(vdev->vdev_lens, &vc); | ||
1488 | + mutex_unlock(&vdev->mutex); | ||
1489 | + if (rval) | ||
1490 | + goto out; | ||
1491 | + } | ||
1492 | + } | ||
1493 | + break; | ||
1494 | + } | ||
1495 | + | ||
1496 | + mutex_lock(&vdev->mutex); | ||
1497 | + rval = isp_handle_private(cmd, arg); | ||
1498 | + mutex_unlock(&vdev->mutex); | ||
1499 | + } | ||
1500 | +out: | ||
1501 | + return rval; | ||
1502 | +} | ||
1503 | + | ||
1504 | +/* | ||
1505 | + * | ||
1506 | + * File operations. | ||
1507 | + * | ||
1508 | + */ | ||
1509 | + | ||
1510 | +/** | ||
1511 | + * omap34xxcam_poll - file operations poll handler | ||
1512 | + * @file: ptr. to system file structure | ||
1513 | + * @wait: system poll table structure | ||
1514 | + * | ||
1515 | + */ | ||
1516 | +static unsigned int omap34xxcam_poll(struct file *file, | ||
1517 | + struct poll_table_struct *wait) | ||
1518 | +{ | ||
1519 | + struct omap34xxcam_fh *fh = file->private_data; | ||
1520 | + struct omap34xxcam_videodev *vdev = fh->vdev; | ||
1521 | + struct videobuf_buffer *vb; | ||
1522 | + | ||
1523 | + mutex_lock(&vdev->mutex); | ||
1524 | + if (vdev->streaming != file) { | ||
1525 | + mutex_unlock(&vdev->mutex); | ||
1526 | + return POLLERR; | ||
1527 | + } | ||
1528 | + mutex_unlock(&vdev->mutex); | ||
1529 | + | ||
1530 | + mutex_lock(&fh->vbq.vb_lock); | ||
1531 | + if (list_empty(&fh->vbq.stream)) { | ||
1532 | + mutex_unlock(&fh->vbq.vb_lock); | ||
1533 | + return POLLERR; | ||
1534 | + } | ||
1535 | + vb = list_entry(fh->vbq.stream.next, struct videobuf_buffer, stream); | ||
1536 | + mutex_unlock(&fh->vbq.vb_lock); | ||
1537 | + | ||
1538 | + poll_wait(file, &vb->done, wait); | ||
1539 | + | ||
1540 | + if (vb->state == VIDEOBUF_DONE || vb->state == VIDEOBUF_ERROR) | ||
1541 | + return POLLIN | POLLRDNORM; | ||
1542 | + | ||
1543 | + return 0; | ||
1544 | +} | ||
1545 | + | ||
1546 | +/** | ||
1547 | + * omap34xxcam_mmap - file operations mmap handler | ||
1548 | + * @file: ptr. to system file structure | ||
1549 | + * @vma: system virt. mem. area structure | ||
1550 | + * | ||
1551 | + * Maps a virtual memory area via the video buffer API | ||
1552 | + */ | ||
1553 | +static int omap34xxcam_mmap(struct file *file, struct vm_area_struct *vma) | ||
1554 | +{ | ||
1555 | + struct omap34xxcam_fh *fh = file->private_data; | ||
1556 | + return videobuf_mmap_mapper(&fh->vbq, vma); | ||
1557 | +} | ||
1558 | + | ||
1559 | +/** | ||
1560 | + * omap34xxcam_open - file operations open handler | ||
1561 | + * @inode: ptr. to system inode structure | ||
1562 | + * @file: ptr. to system file structure | ||
1563 | + * | ||
1564 | + * Allocates and initializes the per-filehandle data (omap34xxcam_fh), | ||
1565 | + * enables the sensor, opens/initializes the ISP interface and the | ||
1566 | + * video buffer queue. Note that this function will allow multiple | ||
1567 | + * file handles to be open simultaneously, however only the first | ||
1568 | + * handle opened will initialize the ISP. It is the application | ||
1569 | + * responsibility to only use one handle for streaming and the others | ||
1570 | + * for control only. | ||
1571 | + * This function returns 0 upon success and -ENODEV upon error. | ||
1572 | + */ | ||
1573 | +static int omap34xxcam_open(struct file *file) | ||
1574 | +{ | ||
1575 | + int rval = 0; | ||
1576 | + struct omap34xxcam_videodev *vdev = NULL; | ||
1577 | + struct omap34xxcam_device *cam = omap34xxcam; | ||
1578 | + struct omap34xxcam_fh *fh; | ||
1579 | + struct v4l2_format format; | ||
1580 | + int i; | ||
1581 | + | ||
1582 | + for (i = 0; i < OMAP34XXCAM_VIDEODEVS; i++) { | ||
1583 | + if (cam->vdevs[i].vfd | ||
1584 | + && cam->vdevs[i].vfd->minor == | ||
1585 | + iminor(file->f_dentry->d_inode)) { | ||
1586 | + vdev = &cam->vdevs[i]; | ||
1587 | + break; | ||
1588 | + } | ||
1589 | + } | ||
1590 | + | ||
1591 | + if (!vdev || !vdev->vfd) | ||
1592 | + return -ENODEV; | ||
1593 | + | ||
1594 | + fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
1595 | + if (fh == NULL) | ||
1596 | + return -ENOMEM; | ||
1597 | + | ||
1598 | + mutex_lock(&vdev->mutex); | ||
1599 | + for (i = 0; i <= OMAP34XXCAM_SLAVE_FLASH; i++) { | ||
1600 | + if (vdev->slave[i] != v4l2_int_device_dummy() | ||
1601 | + && !try_module_get(vdev->slave[i]->module)) { | ||
1602 | + mutex_unlock(&vdev->mutex); | ||
1603 | + dev_err(&vdev->vfd->dev, "can't try_module_get %s\n", | ||
1604 | + vdev->slave[i]->name); | ||
1605 | + rval = -ENODEV; | ||
1606 | + goto out_try_module_get; | ||
1607 | + } | ||
1608 | + } | ||
1609 | + | ||
1610 | + if (atomic_inc_return(&vdev->users) == 1) { | ||
1611 | + rval = isp_get(); | ||
1612 | + if (rval < 0) { | ||
1613 | + dev_err(&vdev->vfd->dev, "can't get isp\n"); | ||
1614 | + goto out_isp_get; | ||
1615 | + } | ||
1616 | + if (omap34xxcam_slave_power_set(vdev, V4L2_POWER_ON, | ||
1617 | + OMAP34XXCAM_SLAVE_POWER_ALL)) { | ||
1618 | + dev_err(&vdev->vfd->dev, "can't power up slaves\n"); | ||
1619 | + rval = -EBUSY; | ||
1620 | + goto out_slave_power_set_standby; | ||
1621 | + } | ||
1622 | + omap34xxcam_slave_power_set( | ||
1623 | + vdev, V4L2_POWER_STANDBY, | ||
1624 | + OMAP34XXCAM_SLAVE_POWER_SENSOR); | ||
1625 | + omap34xxcam_slave_power_suggest( | ||
1626 | + vdev, V4L2_POWER_STANDBY, | ||
1627 | + OMAP34XXCAM_SLAVE_POWER_LENS); | ||
1628 | + } | ||
1629 | + | ||
1630 | + fh->vdev = vdev; | ||
1631 | + | ||
1632 | + if (!vdev->pix.width | ||
1633 | + && vdev->vdev_sensor != v4l2_int_device_dummy()) { | ||
1634 | + memset(&format, 0, sizeof(format)); | ||
1635 | + if (vidioc_int_g_fmt_cap(vdev->vdev_sensor, &format)) { | ||
1636 | + dev_err(&vdev->vfd->dev, | ||
1637 | + "can't get current pix from sensor!\n"); | ||
1638 | + goto out_vidioc_int_g_fmt_cap; | ||
1639 | + } | ||
1640 | + if (!vdev->vdev_sensor_config.sensor_isp) { | ||
1641 | + struct v4l2_pix_format pix = format.fmt.pix; | ||
1642 | + if (isp_s_fmt_cap(&pix, &format.fmt.pix)) { | ||
1643 | + dev_err(&vdev->vfd->dev, | ||
1644 | + "isp doesn't like the sensor!\n"); | ||
1645 | + goto out_isp_s_fmt_cap; | ||
1646 | + } | ||
1647 | + } | ||
1648 | + vdev->pix = format.fmt.pix; | ||
1649 | + } | ||
1650 | + | ||
1651 | + mutex_unlock(&vdev->mutex); | ||
1652 | + | ||
1653 | + file->private_data = fh; | ||
1654 | + | ||
1655 | + spin_lock_init(&fh->vbq_lock); | ||
1656 | + | ||
1657 | + videobuf_queue_sg_init(&fh->vbq, &omap34xxcam_vbq_ops, NULL, | ||
1658 | + &fh->vbq_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
1659 | + V4L2_FIELD_NONE, | ||
1660 | + sizeof(struct videobuf_buffer), fh); | ||
1661 | + | ||
1662 | + return 0; | ||
1663 | + | ||
1664 | +out_isp_s_fmt_cap: | ||
1665 | +out_vidioc_int_g_fmt_cap: | ||
1666 | + omap34xxcam_slave_power_set(vdev, V4L2_POWER_OFF, | ||
1667 | + OMAP34XXCAM_SLAVE_POWER_ALL); | ||
1668 | +out_slave_power_set_standby: | ||
1669 | + isp_put(); | ||
1670 | + | ||
1671 | +out_isp_get: | ||
1672 | + atomic_dec(&vdev->users); | ||
1673 | + mutex_unlock(&vdev->mutex); | ||
1674 | + | ||
1675 | +out_try_module_get: | ||
1676 | + for (i--; i >= 0; i--) | ||
1677 | + if (vdev->slave[i] != v4l2_int_device_dummy()) | ||
1678 | + module_put(vdev->slave[i]->module); | ||
1679 | + | ||
1680 | + kfree(fh); | ||
1681 | + | ||
1682 | + return rval; | ||
1683 | +} | ||
1684 | + | ||
1685 | +/** | ||
1686 | + * omap34xxcam_release - file operations release handler | ||
1687 | + * @inode: ptr. to system inode structure | ||
1688 | + * @file: ptr. to system file structure | ||
1689 | + * | ||
1690 | + * Complement of omap34xxcam_open. This function will flush any scheduled | ||
1691 | + * work, disable the sensor, close the ISP interface, stop the | ||
1692 | + * video buffer queue from streaming and free the per-filehandle data | ||
1693 | + * (omap34xxcam_fh). Note that because multiple open file handles | ||
1694 | + * are allowed, this function will only close the ISP and disable the | ||
1695 | + * sensor when the last open file handle (by count) is closed. | ||
1696 | + * This function returns 0. | ||
1697 | + */ | ||
1698 | +static int omap34xxcam_release(struct file *file) | ||
1699 | +{ | ||
1700 | + struct omap34xxcam_fh *fh = file->private_data; | ||
1701 | + struct omap34xxcam_videodev *vdev = fh->vdev; | ||
1702 | + int i; | ||
1703 | + | ||
1704 | + mutex_lock(&vdev->mutex); | ||
1705 | + if (vdev->streaming == file) { | ||
1706 | + isp_stop(); | ||
1707 | + videobuf_streamoff(&fh->vbq); | ||
1708 | + omap34xxcam_slave_power_set( | ||
1709 | + vdev, V4L2_POWER_STANDBY, | ||
1710 | + OMAP34XXCAM_SLAVE_POWER_SENSOR); | ||
1711 | + omap34xxcam_slave_power_suggest( | ||
1712 | + vdev, V4L2_POWER_STANDBY, | ||
1713 | + OMAP34XXCAM_SLAVE_POWER_LENS); | ||
1714 | + vdev->streaming = NULL; | ||
1715 | + } | ||
1716 | + | ||
1717 | + if (atomic_dec_return(&vdev->users) == 0) { | ||
1718 | + omap34xxcam_slave_power_set(vdev, V4L2_POWER_OFF, | ||
1719 | + OMAP34XXCAM_SLAVE_POWER_ALL); | ||
1720 | + isp_put(); | ||
1721 | + } | ||
1722 | + mutex_unlock(&vdev->mutex); | ||
1723 | + | ||
1724 | + file->private_data = NULL; | ||
1725 | + | ||
1726 | + for (i = 0; i <= OMAP34XXCAM_SLAVE_FLASH; i++) | ||
1727 | + if (vdev->slave[i] != v4l2_int_device_dummy()) | ||
1728 | + module_put(vdev->slave[i]->module); | ||
1729 | + | ||
1730 | + kfree(fh); | ||
1731 | + | ||
1732 | + return 0; | ||
1733 | +} | ||
1734 | + | ||
1735 | +static struct v4l2_file_operations omap34xxcam_fops = { | ||
1736 | + .owner = THIS_MODULE, | ||
1737 | + .unlocked_ioctl = video_ioctl2, | ||
1738 | + .poll = omap34xxcam_poll, | ||
1739 | + .mmap = omap34xxcam_mmap, | ||
1740 | + .open = omap34xxcam_open, | ||
1741 | + .release = omap34xxcam_release, | ||
1742 | +}; | ||
1743 | + | ||
1744 | +static void omap34xxcam_vfd_name_update(struct omap34xxcam_videodev *vdev) | ||
1745 | +{ | ||
1746 | + struct video_device *vfd = vdev->vfd; | ||
1747 | + int i; | ||
1748 | + | ||
1749 | + strlcpy(vfd->name, CAM_SHORT_NAME, sizeof(vfd->name)); | ||
1750 | + for (i = 0; i <= OMAP34XXCAM_SLAVE_FLASH; i++) { | ||
1751 | + strlcat(vfd->name, "/", sizeof(vfd->name)); | ||
1752 | + if (vdev->slave[i] == v4l2_int_device_dummy()) | ||
1753 | + continue; | ||
1754 | + strlcat(vfd->name, vdev->slave[i]->name, sizeof(vfd->name)); | ||
1755 | + } | ||
1756 | + dev_info(&vdev->vfd->dev, "video%d is now %s\n", vfd->num, vfd->name); | ||
1757 | +} | ||
1758 | + | ||
1759 | +/** | ||
1760 | + * omap34xxcam_device_unregister - V4L2 detach handler | ||
1761 | + * @s: ptr. to standard V4L2 device information structure | ||
1762 | + * | ||
1763 | + * Detach sensor and unregister and release the video device. | ||
1764 | + */ | ||
1765 | +static void omap34xxcam_device_unregister(struct v4l2_int_device *s) | ||
1766 | +{ | ||
1767 | + struct omap34xxcam_videodev *vdev = s->u.slave->master->priv; | ||
1768 | + struct omap34xxcam_hw_config hwc; | ||
1769 | + | ||
1770 | + BUG_ON(vidioc_int_g_priv(s, &hwc) < 0); | ||
1771 | + | ||
1772 | + mutex_lock(&vdev->mutex); | ||
1773 | + | ||
1774 | + if (vdev->slave[hwc.dev_type] != v4l2_int_device_dummy()) { | ||
1775 | + vdev->slave[hwc.dev_type] = v4l2_int_device_dummy(); | ||
1776 | + vdev->slaves--; | ||
1777 | + omap34xxcam_vfd_name_update(vdev); | ||
1778 | + } | ||
1779 | + | ||
1780 | + if (vdev->slaves == 0 && vdev->vfd) { | ||
1781 | + if (vdev->vfd->minor == -1) { | ||
1782 | + /* | ||
1783 | + * The device was never registered, so release the | ||
1784 | + * video_device struct directly. | ||
1785 | + */ | ||
1786 | + video_device_release(vdev->vfd); | ||
1787 | + } else { | ||
1788 | + /* | ||
1789 | + * The unregister function will release the | ||
1790 | + * video_device struct as well as | ||
1791 | + * unregistering it. | ||
1792 | + */ | ||
1793 | + video_unregister_device(vdev->vfd); | ||
1794 | + } | ||
1795 | + vdev->vfd = NULL; | ||
1796 | + } | ||
1797 | + | ||
1798 | + mutex_unlock(&vdev->mutex); | ||
1799 | +} | ||
1800 | + | ||
1801 | +static const struct v4l2_ioctl_ops omap34xxcam_ioctl_ops = { | ||
1802 | + .vidioc_querycap = vidioc_querycap, | ||
1803 | + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | ||
1804 | + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | ||
1805 | + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | ||
1806 | + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | ||
1807 | + .vidioc_reqbufs = vidioc_reqbufs, | ||
1808 | + .vidioc_querybuf = vidioc_querybuf, | ||
1809 | + .vidioc_qbuf = vidioc_qbuf, | ||
1810 | + .vidioc_dqbuf = vidioc_dqbuf, | ||
1811 | + .vidioc_streamon = vidioc_streamon, | ||
1812 | + .vidioc_streamoff = vidioc_streamoff, | ||
1813 | + .vidioc_enum_input = vidioc_enum_input, | ||
1814 | + .vidioc_g_input = vidioc_g_input, | ||
1815 | + .vidioc_s_input = vidioc_s_input, | ||
1816 | + .vidioc_queryctrl = vidioc_queryctrl, | ||
1817 | + .vidioc_querymenu = vidioc_querymenu, | ||
1818 | + .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, | ||
1819 | + .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, | ||
1820 | + .vidioc_g_parm = vidioc_g_parm, | ||
1821 | + .vidioc_s_parm = vidioc_s_parm, | ||
1822 | + .vidioc_cropcap = vidioc_cropcap, | ||
1823 | + .vidioc_g_crop = vidioc_g_crop, | ||
1824 | + .vidioc_s_crop = vidioc_s_crop, | ||
1825 | + .vidioc_enum_framesizes = vidioc_enum_framesizes, | ||
1826 | + .vidioc_enum_frameintervals = vidioc_enum_frameintervals, | ||
1827 | + .vidioc_default = vidioc_default, | ||
1828 | +}; | ||
1829 | + | ||
1830 | +/** | ||
1831 | + * omap34xxcam_device_register - V4L2 attach handler | ||
1832 | + * @s: ptr. to standard V4L2 device information structure | ||
1833 | + * | ||
1834 | + * Allocates and initializes the V4L2 video_device structure, initializes | ||
1835 | + * the sensor, and finally | ||
1836 | + registers the device with V4L2 based on the | ||
1837 | + * video_device structure. | ||
1838 | + * | ||
1839 | + * Returns 0 on success, otherwise an appropriate error code on | ||
1840 | + * failure. | ||
1841 | + */ | ||
1842 | +static int omap34xxcam_device_register(struct v4l2_int_device *s) | ||
1843 | +{ | ||
1844 | + struct omap34xxcam_videodev *vdev = s->u.slave->master->priv; | ||
1845 | + struct omap34xxcam_hw_config hwc; | ||
1846 | + int rval; | ||
1847 | + | ||
1848 | + /* We need to check rval just once. The place is here. */ | ||
1849 | + if (vidioc_int_g_priv(s, &hwc)) | ||
1850 | + return -ENODEV; | ||
1851 | + | ||
1852 | + if (vdev->index != hwc.dev_index) | ||
1853 | + return -ENODEV; | ||
1854 | + | ||
1855 | + if (hwc.dev_type < 0 || hwc.dev_type > OMAP34XXCAM_SLAVE_FLASH) | ||
1856 | + return -EINVAL; | ||
1857 | + | ||
1858 | + if (vdev->slave[hwc.dev_type] != v4l2_int_device_dummy()) | ||
1859 | + return -EBUSY; | ||
1860 | + | ||
1861 | + mutex_lock(&vdev->mutex); | ||
1862 | + if (atomic_read(&vdev->users)) { | ||
1863 | + printk(KERN_ERR "%s: we're open (%d), can't register\n", | ||
1864 | + __func__, atomic_read(&vdev->users)); | ||
1865 | + mutex_unlock(&vdev->mutex); | ||
1866 | + return -EBUSY; | ||
1867 | + } | ||
1868 | + | ||
1869 | + vdev->slaves++; | ||
1870 | + vdev->slave[hwc.dev_type] = s; | ||
1871 | + vdev->slave_config[hwc.dev_type] = hwc; | ||
1872 | + | ||
1873 | + if (hwc.dev_type == OMAP34XXCAM_SLAVE_SENSOR) { | ||
1874 | + rval = isp_get(); | ||
1875 | + if (rval < 0) { | ||
1876 | + printk(KERN_ERR "%s: can't get ISP, " | ||
1877 | + "sensor init failed\n", __func__); | ||
1878 | + goto err; | ||
1879 | + } | ||
1880 | + } | ||
1881 | + rval = omap34xxcam_slave_power_set(vdev, V4L2_POWER_ON, | ||
1882 | + 1 << hwc.dev_type); | ||
1883 | + if (rval) | ||
1884 | + goto err_omap34xxcam_slave_power_set; | ||
1885 | + if (hwc.dev_type == OMAP34XXCAM_SLAVE_SENSOR) { | ||
1886 | + struct v4l2_format format; | ||
1887 | + | ||
1888 | + format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1889 | + rval = vidioc_int_g_fmt_cap(vdev->vdev_sensor, &format); | ||
1890 | + if (rval) | ||
1891 | + rval = -EBUSY; | ||
1892 | + | ||
1893 | + vdev->want_pix = format.fmt.pix; | ||
1894 | + } | ||
1895 | + omap34xxcam_slave_power_set(vdev, V4L2_POWER_OFF, 1 << hwc.dev_type); | ||
1896 | + if (hwc.dev_type == OMAP34XXCAM_SLAVE_SENSOR) | ||
1897 | + isp_put(); | ||
1898 | + | ||
1899 | + if (rval) | ||
1900 | + goto err; | ||
1901 | + | ||
1902 | + /* Are we the first slave? */ | ||
1903 | + if (vdev->slaves == 1) { | ||
1904 | + /* initialize the video_device struct */ | ||
1905 | + vdev->vfd = video_device_alloc(); | ||
1906 | + if (!vdev->vfd) { | ||
1907 | + printk(KERN_ERR "%s: could not allocate " | ||
1908 | + "video device struct\n", __func__); | ||
1909 | + rval = -ENOMEM; | ||
1910 | + goto err; | ||
1911 | + } | ||
1912 | + vdev->vfd->release = video_device_release; | ||
1913 | + vdev->vfd->minor = -1; | ||
1914 | + vdev->vfd->fops = &omap34xxcam_fops; | ||
1915 | + vdev->vfd->ioctl_ops = &omap34xxcam_ioctl_ops; | ||
1916 | + video_set_drvdata(vdev->vfd, vdev); | ||
1917 | + | ||
1918 | + if (video_register_device(vdev->vfd, VFL_TYPE_GRABBER, | ||
1919 | + hwc.dev_minor) < 0) { | ||
1920 | + printk(KERN_ERR "%s: could not register V4L device\n", | ||
1921 | + __func__); | ||
1922 | + vdev->vfd->minor = -1; | ||
1923 | + rval = -EBUSY; | ||
1924 | + goto err; | ||
1925 | + } | ||
1926 | + } | ||
1927 | + | ||
1928 | + omap34xxcam_vfd_name_update(vdev); | ||
1929 | + | ||
1930 | + mutex_unlock(&vdev->mutex); | ||
1931 | + | ||
1932 | + return 0; | ||
1933 | + | ||
1934 | +err_omap34xxcam_slave_power_set: | ||
1935 | + if (hwc.dev_type == OMAP34XXCAM_SLAVE_SENSOR) | ||
1936 | + isp_put(); | ||
1937 | + | ||
1938 | +err: | ||
1939 | + if (s == vdev->slave[hwc.dev_type]) { | ||
1940 | + vdev->slave[hwc.dev_type] = v4l2_int_device_dummy(); | ||
1941 | + vdev->slaves--; | ||
1942 | + } | ||
1943 | + | ||
1944 | + mutex_unlock(&vdev->mutex); | ||
1945 | + omap34xxcam_device_unregister(s); | ||
1946 | + | ||
1947 | + return rval; | ||
1948 | +} | ||
1949 | + | ||
1950 | +static struct v4l2_int_master omap34xxcam_master = { | ||
1951 | + .attach = omap34xxcam_device_register, | ||
1952 | + .detach = omap34xxcam_device_unregister, | ||
1953 | +}; | ||
1954 | + | ||
1955 | +/* | ||
1956 | + * | ||
1957 | + * Module initialisation and deinitialisation | ||
1958 | + * | ||
1959 | + */ | ||
1960 | + | ||
1961 | +static void omap34xxcam_exit(void) | ||
1962 | +{ | ||
1963 | + struct omap34xxcam_device *cam = omap34xxcam; | ||
1964 | + int i; | ||
1965 | + | ||
1966 | + if (!cam) | ||
1967 | + return; | ||
1968 | + | ||
1969 | + for (i = 0; i < OMAP34XXCAM_VIDEODEVS; i++) { | ||
1970 | + if (cam->vdevs[i].cam == NULL) | ||
1971 | + continue; | ||
1972 | + | ||
1973 | + v4l2_int_device_unregister(&cam->vdevs[i].master); | ||
1974 | + cam->vdevs[i].cam = NULL; | ||
1975 | + } | ||
1976 | + | ||
1977 | + omap34xxcam = NULL; | ||
1978 | + | ||
1979 | + kfree(cam); | ||
1980 | +} | ||
1981 | + | ||
1982 | +static int __init omap34xxcam_init(void) | ||
1983 | +{ | ||
1984 | + struct omap34xxcam_device *cam; | ||
1985 | + int i; | ||
1986 | + | ||
1987 | + cam = kzalloc(sizeof(*cam), GFP_KERNEL); | ||
1988 | + if (!cam) { | ||
1989 | + printk(KERN_ERR "%s: could not allocate memory\n", __func__); | ||
1990 | + return -ENOMEM; | ||
1991 | + } | ||
1992 | + | ||
1993 | + omap34xxcam = cam; | ||
1994 | + | ||
1995 | + for (i = 0; i < OMAP34XXCAM_VIDEODEVS; i++) { | ||
1996 | + struct omap34xxcam_videodev *vdev = &cam->vdevs[i]; | ||
1997 | + struct v4l2_int_device *m = &vdev->master; | ||
1998 | + | ||
1999 | + m->module = THIS_MODULE; | ||
2000 | + strlcpy(m->name, CAM_NAME, sizeof(m->name)); | ||
2001 | + m->type = v4l2_int_type_master; | ||
2002 | + m->u.master = &omap34xxcam_master; | ||
2003 | + m->priv = vdev; | ||
2004 | + | ||
2005 | + mutex_init(&vdev->mutex); | ||
2006 | + vdev->index = i; | ||
2007 | + vdev->cam = cam; | ||
2008 | + vdev->vdev_sensor = | ||
2009 | + vdev->vdev_lens = | ||
2010 | + vdev->vdev_flash = v4l2_int_device_dummy(); | ||
2011 | +#ifdef OMAP34XXCAM_POWEROFF_DELAY | ||
2012 | + setup_timer(&vdev->poweroff_timer, | ||
2013 | + omap34xxcam_slave_power_timer, (unsigned long)vdev); | ||
2014 | + INIT_WORK(&vdev->poweroff_work, omap34xxcam_slave_power_work); | ||
2015 | +#endif /* OMAP34XXCAM_POWEROFF_DELAY */ | ||
2016 | + | ||
2017 | + if (v4l2_int_device_register(m)) | ||
2018 | + goto err; | ||
2019 | + } | ||
2020 | + | ||
2021 | + return 0; | ||
2022 | + | ||
2023 | +err: | ||
2024 | + omap34xxcam_exit(); | ||
2025 | + return -ENODEV; | ||
2026 | +} | ||
2027 | + | ||
2028 | +MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>"); | ||
2029 | +MODULE_DESCRIPTION("OMAP34xx Video for Linux camera driver"); | ||
2030 | +MODULE_LICENSE("GPL"); | ||
2031 | + | ||
2032 | +late_initcall(omap34xxcam_init); | ||
2033 | +module_exit(omap34xxcam_exit); | ||
2034 | diff --git a/drivers/media/video/omap34xxcam.h b/drivers/media/video/omap34xxcam.h | ||
2035 | new file mode 100644 | ||
2036 | index 0000000..9859d15 | ||
2037 | --- /dev/null | ||
2038 | +++ b/drivers/media/video/omap34xxcam.h | ||
2039 | @@ -0,0 +1,207 @@ | ||
2040 | +/* | ||
2041 | + * omap34xxcam.h | ||
2042 | + * | ||
2043 | + * Copyright (C) 2006--2009 Nokia Corporation | ||
2044 | + * Copyright (C) 2007--2009 Texas Instruments | ||
2045 | + * | ||
2046 | + * Contact: Sakari Ailus <sakari.ailus@nokia.com> | ||
2047 | + * Tuukka Toivonen <tuukka.o.toivonen@nokia.com> | ||
2048 | + * | ||
2049 | + * Originally based on the OMAP 2 camera driver. | ||
2050 | + * | ||
2051 | + * Written by Sakari Ailus <sakari.ailus@nokia.com> | ||
2052 | + * Tuukka Toivonen <tuukka.o.toivonen@nokia.com> | ||
2053 | + * Sergio Aguirre <saaguirre@ti.com> | ||
2054 | + * Mohit Jalori | ||
2055 | + * Sameer Venkatraman | ||
2056 | + * Leonides Martinez | ||
2057 | + * | ||
2058 | + * This program is free software; you can redistribute it and/or | ||
2059 | + * modify it under the terms of the GNU General Public License | ||
2060 | + * version 2 as published by the Free Software Foundation. | ||
2061 | + * | ||
2062 | + * This program is distributed in the hope that it will be useful, but | ||
2063 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2064 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
2065 | + * General Public License for more details. | ||
2066 | + * | ||
2067 | + * You should have received a copy of the GNU General Public License | ||
2068 | + * along with this program; if not, write to the Free Software | ||
2069 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
2070 | + * 02110-1301 USA | ||
2071 | + * | ||
2072 | + */ | ||
2073 | + | ||
2074 | +#ifndef OMAP34XXCAM_H | ||
2075 | +#define OMAP34XXCAM_H | ||
2076 | + | ||
2077 | +#include <media/v4l2-int-device.h> | ||
2078 | +#include "isp/isp.h" | ||
2079 | + | ||
2080 | +#define CAM_NAME "omap34xxcam" | ||
2081 | +#define CAM_SHORT_NAME "omap3" | ||
2082 | + | ||
2083 | +#define OMAP_ISP_AF (1 << 4) | ||
2084 | +#define OMAP_ISP_HIST (1 << 5) | ||
2085 | +#define OMAP34XXCAM_XCLK_NONE -1 | ||
2086 | +#define OMAP34XXCAM_XCLK_A 0 | ||
2087 | +#define OMAP34XXCAM_XCLK_B 1 | ||
2088 | + | ||
2089 | +#define OMAP34XXCAM_SLAVE_SENSOR 0 | ||
2090 | +#define OMAP34XXCAM_SLAVE_LENS 1 | ||
2091 | +#define OMAP34XXCAM_SLAVE_FLASH 2 /* This is the last slave! */ | ||
2092 | + | ||
2093 | +/* mask for omap34xxcam_slave_power_set */ | ||
2094 | +#define OMAP34XXCAM_SLAVE_POWER_SENSOR (1 << OMAP34XXCAM_SLAVE_SENSOR) | ||
2095 | +#define OMAP34XXCAM_SLAVE_POWER_LENS (1 << OMAP34XXCAM_SLAVE_LENS) | ||
2096 | +#define OMAP34XXCAM_SLAVE_POWER_SENSOR_LENS \ | ||
2097 | + (OMAP34XXCAM_SLAVE_POWER_SENSOR | OMAP34XXCAM_SLAVE_POWER_LENS) | ||
2098 | +#define OMAP34XXCAM_SLAVE_POWER_FLASH (1 << OMAP34XXCAM_SLAVE_FLASH) | ||
2099 | +#define OMAP34XXCAM_SLAVE_POWER_ALL -1 | ||
2100 | + | ||
2101 | +#define OMAP34XXCAM_VIDEODEVS 4 | ||
2102 | + | ||
2103 | +/* #define OMAP34XXCAM_POWEROFF_DELAY (2 * HZ) */ | ||
2104 | + | ||
2105 | +struct omap34xxcam_device; | ||
2106 | +struct omap34xxcam_videodev; | ||
2107 | + | ||
2108 | +struct omap34xxcam_sensor_config { | ||
2109 | + int xclk; | ||
2110 | + int sensor_isp; | ||
2111 | + u32 capture_mem; | ||
2112 | + struct v4l2_fract ival_default; | ||
2113 | +}; | ||
2114 | + | ||
2115 | +struct omap34xxcam_lens_config { | ||
2116 | +}; | ||
2117 | + | ||
2118 | +struct omap34xxcam_flash_config { | ||
2119 | +}; | ||
2120 | + | ||
2121 | +/** | ||
2122 | + * struct omap34xxcam_hw_config - struct for vidioc_int_g_priv ioctl | ||
2123 | + * @xclk: OMAP34XXCAM_XCLK_A or OMAP34XXCAM_XCLK_B | ||
2124 | + * @sensor_isp: Is sensor smart/SOC or raw | ||
2125 | + * @s_pix_sparm: Access function to set pix and sparm. | ||
2126 | + * Pix will override sparm | ||
2127 | + */ | ||
2128 | +struct omap34xxcam_hw_config { | ||
2129 | + int dev_index; /* Index in omap34xxcam_sensors */ | ||
2130 | + int dev_minor; /* Video device minor number */ | ||
2131 | + int dev_type; /* OMAP34XXCAM_SLAVE_* */ | ||
2132 | + union { | ||
2133 | + struct omap34xxcam_sensor_config sensor; | ||
2134 | + struct omap34xxcam_lens_config lens; | ||
2135 | + struct omap34xxcam_flash_config flash; | ||
2136 | + } u; | ||
2137 | +}; | ||
2138 | + | ||
2139 | +/** | ||
2140 | + * struct omap34xxcam_videodev - per /dev/video* structure | ||
2141 | + * @mutex: serialises access to this structure | ||
2142 | + * @cam: pointer to cam hw structure | ||
2143 | + * @master: we are v4l2_int_device master | ||
2144 | + * @sensor: sensor device | ||
2145 | + * @lens: lens device | ||
2146 | + * @flash: flash device | ||
2147 | + * @slaves: how many slaves we have at the moment | ||
2148 | + * @vfd: our video device | ||
2149 | + * @capture_mem: maximum kernel-allocated capture memory | ||
2150 | + * @if_u: sensor interface stuff | ||
2151 | + * @index: index of this structure in cam->vdevs | ||
2152 | + * @users: how many users we have | ||
2153 | + * @power_state: Current power state | ||
2154 | + * @power_state_wish: New power state when poweroff_timer expires | ||
2155 | + * @power_state_mask: Bitmask of devices to set the new power state | ||
2156 | + * @poweroff_timer: Timer for dispatching poweroff_work | ||
2157 | + * @poweroff_work: Work for slave power state change | ||
2158 | + * @sensor_config: ISP-speicific sensor configuration | ||
2159 | + * @lens_config: ISP-speicific lens configuration | ||
2160 | + * @flash_config: ISP-speicific flash configuration | ||
2161 | + * @want_timeperframe: Desired timeperframe | ||
2162 | + * @want_pix: Desired pix | ||
2163 | + * @pix: Current pix | ||
2164 | + * @streaming: streaming file handle, if streaming is enabled | ||
2165 | + */ | ||
2166 | +struct omap34xxcam_videodev { | ||
2167 | + struct mutex mutex; /* serialises access to this structure */ | ||
2168 | + | ||
2169 | + struct omap34xxcam_device *cam; | ||
2170 | + struct v4l2_int_device master; | ||
2171 | + | ||
2172 | +#define vdev_sensor slave[OMAP34XXCAM_SLAVE_SENSOR] | ||
2173 | +#define vdev_lens slave[OMAP34XXCAM_SLAVE_LENS] | ||
2174 | +#define vdev_flash slave[OMAP34XXCAM_SLAVE_FLASH] | ||
2175 | + struct v4l2_int_device *slave[OMAP34XXCAM_SLAVE_FLASH + 1]; | ||
2176 | + | ||
2177 | + /* number of slaves attached */ | ||
2178 | + int slaves; | ||
2179 | + | ||
2180 | + /*** video device parameters ***/ | ||
2181 | + struct video_device *vfd; | ||
2182 | + int capture_mem; | ||
2183 | + | ||
2184 | + /*** general driver state information ***/ | ||
2185 | + int index; | ||
2186 | + atomic_t users; | ||
2187 | + enum v4l2_power power_state[OMAP34XXCAM_SLAVE_FLASH + 1]; | ||
2188 | +#ifdef OMAP34XXCAM_POWEROFF_DELAY | ||
2189 | + enum v4l2_power power_state_wish; | ||
2190 | + int power_state_mask; | ||
2191 | + struct timer_list poweroff_timer; | ||
2192 | + struct work_struct poweroff_work; | ||
2193 | +#endif /* OMAP34XXCAM_POWEROFF_DELAY */ | ||
2194 | + | ||
2195 | +#define vdev_sensor_config slave_config[OMAP34XXCAM_SLAVE_SENSOR].u.sensor | ||
2196 | +#define vdev_lens_config slave_config[OMAP34XXCAM_SLAVE_LENS].u.lens | ||
2197 | +#define vdev_flash_config slave_config[OMAP34XXCAM_SLAVE_FLASH].u.flash | ||
2198 | + struct omap34xxcam_hw_config slave_config[OMAP34XXCAM_SLAVE_FLASH + 1]; | ||
2199 | + | ||
2200 | + /*** capture data ***/ | ||
2201 | + struct file *streaming; | ||
2202 | + struct v4l2_fract want_timeperframe; | ||
2203 | + struct v4l2_pix_format want_pix; | ||
2204 | + spinlock_t pix_lock; | ||
2205 | + struct v4l2_pix_format pix; | ||
2206 | +}; | ||
2207 | + | ||
2208 | +/** | ||
2209 | + * struct omap34xxcam_device - per-device data structure | ||
2210 | + * @mutex: mutex serialises access to this structure | ||
2211 | + * @sgdma_in_queue: Number or sgdma requests in scatter-gather queue, | ||
2212 | + * protected by the lock above. | ||
2213 | + * @sgdma: ISP sgdma subsystem information structure | ||
2214 | + * @dma_notify: DMA notify flag | ||
2215 | + * @dev: device structure | ||
2216 | + * @vdevs: /dev/video specific structures | ||
2217 | + * @fck: camera module fck clock information | ||
2218 | + * @ick: camera module ick clock information | ||
2219 | + */ | ||
2220 | +struct omap34xxcam_device { | ||
2221 | + struct mutex mutex; /* serialises access to this structure */ | ||
2222 | + | ||
2223 | + /*** interfaces and device ***/ | ||
2224 | + struct omap34xxcam_videodev vdevs[OMAP34XXCAM_VIDEODEVS]; | ||
2225 | + | ||
2226 | + /*** camera module clocks ***/ | ||
2227 | + struct clk *fck; | ||
2228 | + struct clk *ick; | ||
2229 | + bool sensor_if_enabled; | ||
2230 | +}; | ||
2231 | + | ||
2232 | +/** | ||
2233 | + * struct omap34xxcam_fh - per-filehandle data structure | ||
2234 | + * @vbq_lock: spinlock for the videobuf queue | ||
2235 | + * @vbq: V4L2 video buffer queue structure | ||
2236 | + * @field_count: field counter for videobuf_buffer | ||
2237 | + * @vdev: our /dev/video specific structure | ||
2238 | + */ | ||
2239 | +struct omap34xxcam_fh { | ||
2240 | + spinlock_t vbq_lock; /* spinlock for the videobuf queue */ | ||
2241 | + struct videobuf_queue vbq; | ||
2242 | + atomic_t field_count; | ||
2243 | + struct omap34xxcam_videodev *vdev; | ||
2244 | +}; | ||
2245 | + | ||
2246 | +#endif /* ifndef OMAP34XXCAM_H */ | ||
2247 | -- | ||
2248 | 1.5.6.5 | ||
2249 | |||