tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / media / sprd_dcam / tshark / dcam_drv.c
1 /*
2  * Copyright (C) 2012 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/interrupt.h>
16 #include <linux/bitops.h>
17 #include <linux/semaphore.h>
18 #include <linux/delay.h>
19 #include <linux/clk.h>
20 #include <linux/err.h>
21 #include <asm/io.h>
22 #include <linux/kthread.h>
23 #include <soc/sprd/hardware.h>
24 #include <mach/irqs.h>
25 #include <soc/sprd/sci.h>
26 #include <soc/sprd/sci_glb_regs.h>
27 #include <linux/vmalloc.h>
28 #include <linux/videodev2.h>
29 #include <linux/wakelock.h>
30 #include "dcam_drv.h"
31 #include "gen_scale_coef.h"
32
33 #define LOCAL static
34 /*#define LOCAL*/
35
36 #define DCAM_DRV_DEBUG
37 #define DCAM_LOWEST_ADDR                               0x800
38 #define DCAM_ADDR_INVALID(addr)                       ((uint32_t)(addr) < DCAM_LOWEST_ADDR)
39 #define DCAM_YUV_ADDR_INVALID(y,u,v) \
40         (DCAM_ADDR_INVALID(y) && \
41         DCAM_ADDR_INVALID(u) && \
42         DCAM_ADDR_INVALID(v))
43
44 #define DCAM_SC1_H_TAB_OFFSET                          0x400
45 #define DCAM_SC1_V_TAB_OFFSET                          0x4F0
46 #define DCAM_SC1_V_CHROMA_TAB_OFFSET                   0x8F0
47
48 #define DCAM_SC2_H_TAB_OFFSET                          0x1400
49 #define DCAM_SC2_V_TAB_OFFSET                          0x14F0
50 #define DCAM_SC2_V_CHROMA_TAB_OFFSET                   0x18F0
51
52 #define DCAM_SC_COEFF_BUF_SIZE                         (24 << 10)
53 #define DCAM_SC_COEFF_COEF_SIZE                        (1 << 10)
54 #define DCAM_SC_COEFF_TMP_SIZE                         (21 << 10)
55 #define DCAM_SC_COEFF_BUF_COUNT                        2
56
57
58 #define DCAM_SC_H_COEF_SIZE                            (0xC0)
59 #define DCAM_SC_V_COEF_SIZE                            (0x210)
60 #define DCAM_SC_V_CHROM_COEF_SIZE                      (0x210)
61
62 #define DCAM_SC_COEFF_H_NUM                            (DCAM_SC_H_COEF_SIZE/4)
63 #define DCAM_SC_COEFF_V_NUM                            (DCAM_SC_V_COEF_SIZE/4)
64 #define DCAM_SC_COEFF_V_CHROMA_NUM                     (DCAM_SC_V_CHROM_COEF_SIZE/4)
65
66 #define DCAM_AXI_STOP_TIMEOUT                          1000
67 #define DCAM_CLK_DOMAIN_AHB                            1
68 #define DCAM_CLK_DOMAIN_DCAM                           0
69
70 #ifdef CONFIG_SC_FPGA
71 #define DCAM_PATH_TIMEOUT                              msecs_to_jiffies(500*10)
72 #else
73 #define DCAM_PATH_TIMEOUT                              msecs_to_jiffies(500)
74 #endif
75
76 #define DCAM_FRM_QUEUE_LENGTH                          4
77
78 #define DCAM_STATE_QUICKQUIT                           0x01
79
80 #define DCAM_CHECK_PARAM_ZERO_POINTER(n) \
81         do { \
82                 if (0 == (int)(n)) \
83                         return -DCAM_RTN_PARA_ERR; \
84         } while(0)
85
86 #define DCAM_CLEAR(a) \
87         do { \
88                 memset((void *)(a), 0, sizeof(*(a))); \
89         } while(0)
90
91 #define DEBUG_STR                                      "Error L %d, %s \n"
92 #define DEBUG_ARGS                                     __LINE__,__FUNCTION__
93 #define DCAM_RTN_IF_ERR \
94         do { \
95                 if(rtn) { \
96                         printk(DEBUG_STR, DEBUG_ARGS); \
97                         return -(rtn); \
98                 } \
99         } while(0)
100
101 #define DCAM_IRQ_LINE_MASK                             0x011FFFFFUL
102
103 typedef void (*dcam_isr)(void);
104
105 enum {
106         DCAM_FRM_UNLOCK = 0,
107         DCAM_FRM_LOCK_WRITE = 0x10011001,
108         DCAM_FRM_LOCK_READ = 0x01100110
109 };
110
111 enum {
112         DCAM_ST_STOP = 0,
113         DCAM_ST_START,
114 };
115
116 #define DCAM_IRQ_ERR_MASK \
117         ((1 << DCAM_PATH0_OV) | (1 << DCAM_PATH1_OV) | (1 << DCAM_PATH2_OV) | \
118         (1 << DCAM_SN_LINE_ERR) | (1 << DCAM_SN_FRAME_ERR) | \
119         (1 << DCAM_ISP_OV) | (1 << DCAM_MIPI_OV))
120
121 #define DCAM_IRQ_JPEG_OV_MASK                          (1 << DCAM_JPEG_BUF_OV)
122
123 #define DCAM_CHECK_ZERO(a) \
124         do { \
125                 if (DCAM_ADDR_INVALID(a)) { \
126                         printk("DCAM, zero pointer \n"); \
127                         printk(DEBUG_STR, DEBUG_ARGS); \
128                         return -EFAULT; \
129                 } \
130         } while(0)
131
132 #define DCAM_CHECK_ZERO_VOID(a) \
133         do { \
134                 if (DCAM_ADDR_INVALID(a)) { \
135                         printk("DCAM, zero pointer \n"); \
136                         printk(DEBUG_STR, DEBUG_ARGS); \
137                         return; \
138                 } \
139         } while(0)
140
141 struct dcam_cap_desc {
142         uint32_t                   interface;
143         uint32_t                   input_format;
144         uint32_t                   frame_deci_factor;
145         uint32_t                   img_x_deci_factor;
146         uint32_t                   img_y_deci_factor;
147 };
148
149 struct dcam_path_valid {
150         uint32_t                   input_size    :1;
151         uint32_t                   input_rect    :1;
152         uint32_t                   output_size   :1;
153         uint32_t                   output_format :1;
154         uint32_t                   src_sel       :1;
155         uint32_t                   data_endian   :1;
156         uint32_t                   frame_deci    :1;
157         uint32_t                   scale_tap     :1;
158         uint32_t                   v_deci        :1;
159         uint32_t                   rot_mode      :1;
160         uint32_t                   shrink        :1;
161 };
162
163 struct dcam_frm_queue {
164         struct dcam_frame          frm_array[DCAM_FRM_QUEUE_LENGTH];
165         uint32_t                   valid_cnt;
166 };
167
168 struct dcam_buf_queue {
169         struct dcam_frame           frame[DCAM_FRM_CNT_MAX];
170         struct dcam_frame           *write;
171         struct dcam_frame           *read;
172         spinlock_t                  lock;
173 };
174
175 struct dcam_path_desc {
176         struct dcam_size           input_size;
177         struct dcam_rect           input_rect;
178         struct dcam_size           sc_input_size;
179         struct dcam_size           output_size;
180         struct dcam_frame          input_frame;
181         struct dcam_frm_queue      frame_queue;
182         struct dcam_buf_queue      buf_queue;
183         //struct dcam_frame          *output_frame_head;
184         //struct dcam_frame          *output_frame_cur;
185         struct dcam_endian_sel     data_endian;
186         struct dcam_sc_tap         scale_tap;
187         struct dcam_deci           deci_val;
188         uint32_t                   shrink;
189         struct dcam_path_valid     valid_param;
190         uint32_t                   frame_base_id;
191         uint32_t                   output_frame_count;
192         uint32_t                   output_format;
193         uint32_t                   src_sel;
194         uint32_t                   rot_mode;
195         uint32_t                   frame_deci;
196         uint32_t                   valide;
197         uint32_t                   status;
198         struct semaphore           tx_done_sema;
199         struct semaphore           sof_sema;
200         uint32_t                   wait_for_done;
201         uint32_t                   is_update;
202         uint32_t                   wait_for_sof;
203         uint32_t                   need_stop;
204         uint32_t                   need_wait;
205         int32_t                    sof_cnt;
206 };
207
208 struct dcam_module {
209         uint32_t                   dcam_mode;
210         uint32_t                   module_addr;
211         struct dcam_cap_desc       dcam_cap;
212         struct dcam_path_desc      dcam_path0;
213         struct dcam_path_desc      dcam_path1;
214         struct dcam_path_desc      dcam_path2;
215         struct dcam_frame          path0_frame[DCAM_PATH_0_FRM_CNT_MAX];
216         struct dcam_frame          path1_frame[DCAM_PATH_1_FRM_CNT_MAX];
217         struct dcam_frame          path2_frame[DCAM_PATH_2_FRM_CNT_MAX];
218         struct dcam_frame          path0_reserved_frame;
219         struct dcam_frame          path1_reserved_frame;
220         struct dcam_frame          path2_reserved_frame;
221         struct semaphore           stop_sema;
222         uint32_t                   wait_stop;
223         struct semaphore           resize_done_sema;
224         uint32_t                   wait_resize_done;
225         struct semaphore           rotation_done_sema;
226         uint32_t                   wait_rotation_done;
227         uint32_t                   err_happened;
228         struct semaphore           scale_coeff_mem_sema;
229         uint32_t                   state;
230 };
231
232 struct dcam_sc_coeff {
233         uint32_t                   buf[DCAM_SC_COEFF_BUF_SIZE];
234         uint32_t                   flag;
235         struct dcam_path_desc      dcam_path1;
236 };
237
238 struct dcam_sc_array {
239         struct dcam_sc_coeff       scaling_coeff[DCAM_SC_COEFF_BUF_COUNT];
240         struct dcam_sc_coeff       *scaling_coeff_queue[DCAM_SC_COEFF_BUF_COUNT];
241         uint32_t                   valid_cnt;
242         uint32_t                   is_smooth_zoom;
243 };
244
245 LOCAL atomic_t                 s_dcam_users = ATOMIC_INIT(0);
246 LOCAL atomic_t                 s_resize_flag = ATOMIC_INIT(0);
247 LOCAL atomic_t                 s_rotation_flag = ATOMIC_INIT(0);
248 LOCAL struct clk*              s_dcam_clk = NULL;
249 LOCAL struct dcam_module*      s_p_dcam_mod = 0;
250 LOCAL uint32_t                 s_dcam_irq = 0x5A0000A5;
251 LOCAL dcam_isr_func            s_user_func[DCAM_IRQ_NUMBER];
252 LOCAL void*                    s_user_data[DCAM_IRQ_NUMBER];
253 LOCAL struct dcam_sc_array*    s_dcam_sc_array = NULL;
254 LOCAL struct wake_lock         dcam_wakelock;
255
256 LOCAL DEFINE_MUTEX(dcam_sem);
257 LOCAL DEFINE_MUTEX(dcam_scale_sema);
258 LOCAL DEFINE_MUTEX(dcam_rot_sema);
259 LOCAL DEFINE_MUTEX(dcam_module_sema);
260 LOCAL DEFINE_SPINLOCK(dcam_mod_lock);
261 LOCAL DEFINE_SPINLOCK(dcam_lock);
262 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_cfg_lock);
263 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_control_lock);
264 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_mask_lock);
265 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_clr_lock);
266 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_ahbm_sts_lock);
267 LOCAL DEFINE_SPINLOCK(dcam_glb_reg_endian_lock);
268
269 LOCAL void        _dcam_path0_set(void);
270 LOCAL void        _dcam_path1_set(struct dcam_path_desc *path);
271 LOCAL void        _dcam_path2_set(void);
272 LOCAL void        _dcam_frm_clear(enum dcam_path_index path_index);
273 LOCAL void        _dcam_link_frm(uint32_t base_id);
274 LOCAL int32_t     _dcam_path_set_next_frm(enum dcam_path_index path_index, uint32_t is_1st_frm);
275 /*LOCAL int32_t     _dcam_path_trim(enum dcam_path_index path_index);*/
276 LOCAL int32_t     _dcam_path_scaler(enum dcam_path_index path_index);
277 LOCAL int32_t     _dcam_calc_sc_size(enum dcam_path_index path_index);
278 LOCAL int32_t     _dcam_set_sc_coeff(enum dcam_path_index path_index);
279 LOCAL void        _dcam_force_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy);
280 LOCAL void        _dcam_auto_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy);
281 LOCAL void        _dcam_force_copy(enum dcam_path_index path_index);
282 LOCAL void        _dcam_auto_copy(enum dcam_path_index path_index);
283 LOCAL void        _dcam_reg_trace(void);
284 LOCAL void        _dcam_sensor_sof(void);
285 LOCAL void        _dcam_sensor_eof(void);
286 LOCAL void        _dcam_cap_sof(void);
287 LOCAL void        _dcam_cap_eof(void);
288 LOCAL void        _dcam_path0_done(void);
289 LOCAL void        _dcam_path0_overflow(void);
290 LOCAL void        _dcam_path1_done(void);
291 LOCAL void        _dcam_path1_overflow(void);
292 LOCAL void        _dcam_sensor_line_err(void);
293 LOCAL void        _dcam_sensor_frame_err(void);
294 LOCAL void        _dcam_jpeg_buf_ov(void);
295 LOCAL void        _dcam_path2_done(void);
296 LOCAL void        _dcam_path2_ov(void);
297 LOCAL void        _dcam_isp_ov(void);
298 LOCAL void        _dcam_mipi_ov(void);
299 LOCAL void        _dcam_path1_slice_done(void);
300 LOCAL void        _dcam_path2_slice_done(void);
301 LOCAL void        _dcam_raw_slice_done(void);
302 LOCAL void        _dcam_path0_sof(void);
303 LOCAL void        _dcam_path1_sof(void);
304 LOCAL void        _dcam_path2_sof(void);
305 LOCAL irqreturn_t _dcam_isr_root(int irq, void *dev_id);
306 LOCAL void        _dcam_stopped_notice(void);
307 LOCAL void        _dcam_stopped(void);
308 LOCAL int32_t     _dcam_path_check_deci(enum dcam_path_index path_index, uint32_t *is_deci);
309 extern void       _dcam_isp_root(void);
310 LOCAL int         _dcam_internal_init(void);
311 LOCAL void        _dcam_internal_deinit(void);
312 LOCAL void        _dcam_wait_path_done(enum dcam_path_index path_index, uint32_t *p_flag);
313 LOCAL void        _dcam_path_done_notice(enum dcam_path_index path_index);
314 LOCAL void        _dcam_rot_done(void);
315 LOCAL int32_t     _dcam_err_pre_proc(void);
316 LOCAL void        _dcam_frm_queue_clear(struct dcam_frm_queue *queue);
317 LOCAL int32_t     _dcam_frame_enqueue(struct dcam_frm_queue *queue, struct dcam_frame *frame);
318 LOCAL int32_t     _dcam_frame_dequeue(struct dcam_frm_queue *queue, struct dcam_frame *frame);
319 LOCAL void        _dcam_buf_queue_init(struct dcam_buf_queue *queue);
320 LOCAL int32_t     _dcam_buf_queue_write(struct dcam_buf_queue *queue, struct dcam_frame *frame);
321 LOCAL int32_t     _dcam_buf_queue_read(struct dcam_buf_queue *queue, struct dcam_frame *frame);
322 LOCAL void        _dcam_wait_update_done(enum dcam_path_index path_index, uint32_t *p_flag);
323 LOCAL void        _dcam_path_updated_notice(enum dcam_path_index path_index);
324 LOCAL int32_t     _dcam_get_valid_sc_coeff(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff);
325 LOCAL int32_t     _dcam_push_sc_buf(struct dcam_sc_array *sc, uint32_t index);
326 LOCAL int32_t     _dcam_pop_sc_buf(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff);
327 LOCAL int32_t     _dcam_calc_sc_coeff(enum dcam_path_index path_index);
328 LOCAL int32_t     _dcam_write_sc_coeff(enum dcam_path_index path_index);
329 LOCAL void        _dcam_wait_for_quickstop(enum dcam_path_index path_index);
330
331 LOCAL const dcam_isr isr_list[DCAM_IRQ_NUMBER] = {
332         NULL,//_dcam_isp_root,
333         _dcam_sensor_eof,
334         _dcam_cap_sof,
335         _dcam_cap_eof,
336         _dcam_path0_done,
337         _dcam_path0_overflow,
338         _dcam_path1_done,
339         _dcam_path1_overflow,
340         _dcam_path2_done,
341         _dcam_path2_ov,
342         _dcam_sensor_line_err,
343         _dcam_sensor_frame_err,
344         _dcam_jpeg_buf_ov,
345         _dcam_isp_ov,
346         _dcam_mipi_ov,
347         _dcam_rot_done,
348         _dcam_path1_slice_done,
349         _dcam_path2_slice_done,
350         _dcam_raw_slice_done,
351         _dcam_path1_sof,
352         _dcam_path2_sof,
353         NULL,
354         NULL,
355         NULL,
356         _dcam_path0_sof,
357 };
358
359 void dcam_glb_reg_awr(uint32_t addr, uint32_t val, uint32_t reg_id)
360 {
361         unsigned long flag;
362
363         switch(reg_id) {
364         case DCAM_CFG_REG:
365                 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
366                 REG_WR(addr, REG_RD(addr) & (val));
367                 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
368                 break;
369         case DCAM_CONTROL_REG:
370                 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
371                 REG_WR(addr, REG_RD(addr) & (val));
372                 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
373                 break;
374         case DCAM_INIT_MASK_REG:
375                 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
376                 REG_WR(addr, REG_RD(addr) & (val));
377                 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
378                 break;
379         case DCAM_INIT_CLR_REG:
380                 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
381                 REG_WR(addr, REG_RD(addr) & (val));
382                 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
383                 break;
384         case DCAM_AHBM_STS_REG:
385                 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
386                 REG_WR(addr, REG_RD(addr) & (val));
387                 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
388                 break;
389         case DCAM_ENDIAN_REG:
390                 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
391                 REG_WR(addr, REG_RD(addr) & (val));
392                 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
393                 break;
394         default:
395                 REG_WR(addr, REG_RD(addr) & (val));
396                 break;
397         }
398 }
399
400 void dcam_glb_reg_owr(uint32_t addr, uint32_t val, uint32_t reg_id)
401 {
402         unsigned long flag;
403
404         switch(reg_id) {
405         case DCAM_CFG_REG:
406                 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
407                 REG_WR(addr, REG_RD(addr) | (val));
408                 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
409                 break;
410         case DCAM_CONTROL_REG:
411                 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
412                 REG_WR(addr, REG_RD(addr) | (val));
413                 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
414                 break;
415         case DCAM_INIT_MASK_REG:
416                 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
417                 REG_WR(addr, REG_RD(addr) | (val));
418                 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
419                 break;
420         case DCAM_INIT_CLR_REG:
421                 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
422                 REG_WR(addr, REG_RD(addr) | (val));
423                 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
424                 break;
425         case DCAM_AHBM_STS_REG:
426                 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
427                 REG_WR(addr, REG_RD(addr) | (val));
428                 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
429                 break;
430         case DCAM_ENDIAN_REG:
431                 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
432                 REG_WR(addr, REG_RD(addr) | (val));
433                 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
434                 break;
435         default:
436                 REG_WR(addr, REG_RD(addr) | (val));
437                 break;
438         }
439 }
440
441 void dcam_glb_reg_mwr(uint32_t addr, uint32_t mask, uint32_t val, uint32_t reg_id)
442 {
443         unsigned long flag;
444         uint32_t tmp = 0;
445
446         switch(reg_id) {
447         case DCAM_CFG_REG:
448                 spin_lock_irqsave(&dcam_glb_reg_cfg_lock, flag);
449                 {
450                         tmp = REG_RD(addr);
451                         tmp &= ~(mask);
452                         REG_WR(addr, tmp | ((mask) & (val)));
453                 }
454                 spin_unlock_irqrestore(&dcam_glb_reg_cfg_lock, flag);
455                 break;
456         case DCAM_CONTROL_REG:
457                 spin_lock_irqsave(&dcam_glb_reg_control_lock, flag);
458                 {
459                         tmp = REG_RD(addr);
460                         tmp &= ~(mask);
461                         REG_WR(addr, tmp | ((mask) & (val)));
462                 }
463                 spin_unlock_irqrestore(&dcam_glb_reg_control_lock, flag);
464                 break;
465         case DCAM_INIT_MASK_REG:
466                 spin_lock_irqsave(&dcam_glb_reg_mask_lock, flag);
467                 {
468                         tmp = REG_RD(addr);
469                         tmp &= ~(mask);
470                         REG_WR(addr, tmp | ((mask) & (val)));
471                 }
472                 spin_unlock_irqrestore(&dcam_glb_reg_mask_lock, flag);
473                 break;
474         case DCAM_INIT_CLR_REG:
475                 spin_lock_irqsave(&dcam_glb_reg_clr_lock, flag);
476                 {
477                         tmp = REG_RD(addr);
478                         tmp &= ~(mask);
479                         REG_WR(addr, tmp | ((mask) & (val)));
480                 }
481                 spin_unlock_irqrestore(&dcam_glb_reg_clr_lock, flag);
482                 break;
483         case DCAM_AHBM_STS_REG:
484                 spin_lock_irqsave(&dcam_glb_reg_ahbm_sts_lock, flag);
485                 {
486                         tmp = REG_RD(addr);
487                         tmp &= ~(mask);
488                         REG_WR(addr, tmp | ((mask) & (val)));
489                 }
490                 spin_unlock_irqrestore(&dcam_glb_reg_ahbm_sts_lock, flag);
491                 break;
492         case DCAM_ENDIAN_REG:
493                 spin_lock_irqsave(&dcam_glb_reg_endian_lock, flag);
494                 {
495                         tmp = REG_RD(addr);
496                         tmp &= ~(mask);
497                         REG_WR(addr, tmp | ((mask) & (val)));
498                 }
499                 spin_unlock_irqrestore(&dcam_glb_reg_endian_lock, flag);
500                 break;
501         default:
502                 {
503                         tmp = REG_RD(addr);
504                         tmp &= ~(mask);
505                         REG_WR(addr, tmp | ((mask) & (val)));
506                 }
507                 break;
508         }
509 }
510
511 int32_t dcam_module_init(enum dcam_cap_if_mode if_mode,
512                       enum dcam_cap_sensor_mode sn_mode)
513 {
514         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
515         struct dcam_cap_desc    *cap_desc = NULL;
516
517         if (if_mode >= DCAM_CAP_IF_MODE_MAX) {
518                 rtn = -DCAM_RTN_CAP_IF_MODE_ERR;
519         } else {
520                 if (sn_mode >= DCAM_CAP_MODE_MAX) {
521                         rtn = -DCAM_RTN_CAP_SENSOR_MODE_ERR;
522                 } else {
523                         _dcam_internal_init();
524                         _dcam_link_frm(0); /* set default base frame index as 0 */
525                         _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path0.buf_queue);
526                         _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path1.buf_queue);
527                         _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path2.buf_queue);
528                         cap_desc = &s_p_dcam_mod->dcam_cap;
529                         cap_desc->interface = if_mode;
530                         cap_desc->input_format = sn_mode;
531                         /*REG_OWR(DCAM_EB, BIT_13);//MM_EB*/
532                         /*REG_OWR(DCAM_MATRIX_EB, BIT_10|BIT_5);*/
533                         if (DCAM_CAP_IF_CSI2 == if_mode) {
534                         /*      REG_OWR(CSI2_DPHY_EB, MIPI_EB_BIT);*/
535                                 //ret = _dcam_mipi_clk_en();
536                                 dcam_glb_reg_owr(DCAM_CFG, BIT_9, DCAM_CFG_REG);
537                                 REG_MWR(CAP_MIPI_CTRL, BIT_2 | BIT_1, sn_mode << 1);
538                         } else {
539                                 /*REG_OWR(DCAM_EB, CCIR_IN_EB_BIT);
540                                 REG_OWR(DCAM_EB, CCIR_EB_BIT);*/
541                                 //ret = _dcam_ccir_clk_en();
542                                 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
543                                 REG_MWR(CAP_CCIR_CTRL, BIT_2 | BIT_1, sn_mode << 1);
544                         }
545                         rtn = DCAM_RTN_SUCCESS;
546                 }
547         }
548
549         return -rtn;
550 }
551
552 int32_t dcam_module_deinit(enum dcam_cap_if_mode if_mode,
553                       enum dcam_cap_sensor_mode sn_mode)
554 {
555         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
556
557         if (DCAM_CAP_IF_CSI2 == if_mode) {
558                 /*REG_MWR(CSI2_DPHY_EB, MIPI_EB_BIT, 0 << 10);*/
559                 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
560                 //_dcam_mipi_clk_dis();
561         } else {
562                 /*REG_MWR(DCAM_EB, CCIR_IN_EB_BIT, 0 << 2);
563                 REG_MWR(DCAM_EB, CCIR_EB_BIT, 0 << 9);*/
564                 dcam_glb_reg_mwr(DCAM_CFG, BIT_9, 0 << 9, DCAM_CFG_REG);
565                 //_dcam_ccir_clk_dis();
566         }
567
568         _dcam_internal_deinit();
569
570         return -rtn;
571 }
572
573 int dcam_scale_coeff_alloc(void)
574 {
575         int ret = 0;
576
577         if (NULL == s_dcam_sc_array) {
578                 s_dcam_sc_array = (struct dcam_sc_array*)vzalloc(sizeof(struct dcam_sc_array));
579                 if (NULL == s_dcam_sc_array) {
580                         printk("DCAM: _dcam_scale_coeff_alloc fail.\n");
581                         ret = -1;
582                 }
583         }
584
585         return ret;
586 }
587
588 void dcam_scale_coeff_free(void)
589 {
590         if (s_dcam_sc_array) {
591                 vfree(s_dcam_sc_array);
592                 s_dcam_sc_array = NULL;
593         }
594 }
595
596 LOCAL uint32_t *dcam_get_scale_coeff_addr(uint32_t *index)
597 {
598         uint32_t i;
599
600         if (DCAM_ADDR_INVALID(s_dcam_sc_array)) {
601                 printk("DCAM: scale addr, invalid param 0x%x \n",
602                         (uint32_t)s_dcam_sc_array);
603                 return NULL;
604         }
605
606         for (i = 0; i < DCAM_SC_COEFF_BUF_COUNT; i++) {
607                 if (0 == s_dcam_sc_array->scaling_coeff[i].flag) {
608                         *index = i;
609                         DCAM_TRACE("dcam: get buf index %d \n", i);
610                         return s_dcam_sc_array->scaling_coeff[i].buf;
611                 }
612         }
613         printk("dcam: get buf index %d \n", i);
614
615         return NULL;
616 }
617
618 int32_t dcam_module_en(struct device_node *dn)
619 {
620         int             ret = 0;
621         unsigned int    irq_no = 0;
622
623         DCAM_TRACE("DCAM: dcam_module_en, In %d \n", s_dcam_users.counter);
624
625         mutex_lock(&dcam_module_sema);
626         if (atomic_inc_return(&s_dcam_users) == 1) {
627
628                 wake_lock_init(&dcam_wakelock, WAKE_LOCK_SUSPEND,
629                         "pm_message_wakelock_dcam");
630
631                 wake_lock(&dcam_wakelock);
632
633                 ret = clk_mm_i_eb(dn,1);
634                 if (ret) {
635                         ret = -DCAM_RTN_MAX;
636                         goto fail_exit;
637                 }
638
639                 ret = dcam_set_clk(dn,DCAM_CLK_312M);
640                 if (ret) {
641                         clk_mm_i_eb(dn,0);
642                         ret = -DCAM_RTN_MAX;
643                         goto fail_exit;
644                 }
645
646                 parse_baseaddress(dn);
647
648                 dcam_reset(DCAM_RST_ALL, 0);
649                 atomic_set(&s_resize_flag, 0);
650                 atomic_set(&s_rotation_flag, 0);
651                 memset((void*)s_user_func, 0, sizeof(s_user_func));
652                 memset((void*)s_user_data, 0, sizeof(s_user_data));
653                 printk("DCAM: register isr, 0x%x \n", REG_RD(DCAM_INT_MASK));
654
655                 irq_no = parse_irq(dn);
656                 printk("DCAM: irq_no = 0x%x \n", irq_no);
657                 ret = request_irq(irq_no,
658                                 _dcam_isr_root,
659                                 IRQF_SHARED,
660                                 "DCAM",
661                                 (void*)&s_dcam_irq);
662                 if (ret) {
663                         printk("DCAM: dcam_start, error %d \n", ret);
664                         dcam_set_clk(dn,DCAM_CLK_NONE);
665                         clk_mm_i_eb(dn,0);
666                         ret = -DCAM_RTN_MAX;
667                         goto fail_exit;
668                 }
669
670                 DCAM_TRACE("DCAM: dcam_module_en end \n");
671         }
672         DCAM_TRACE("DCAM: dcam_module_en, Out %d \n", s_dcam_users.counter);
673         mutex_unlock(&dcam_module_sema);
674         return 0;
675
676 fail_exit:
677         wake_unlock(&dcam_wakelock);
678         wake_lock_destroy(&dcam_wakelock);
679         atomic_dec(&s_dcam_users);
680         mutex_unlock(&dcam_module_sema);
681         return ret;
682 }
683
684 int32_t dcam_module_dis(struct device_node *dn)
685 {
686         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
687         int                     ret = 0;
688         unsigned int            irq_no = 0;
689
690         DCAM_TRACE("DCAM: dcam_module_dis, In %d \n", s_dcam_users.counter);
691
692         mutex_lock(&dcam_module_sema);
693         if (atomic_dec_return(&s_dcam_users) == 0) {
694
695                 sci_glb_clr(DCAM_EB, DCAM_EB_BIT);
696                 dcam_set_clk(dn,DCAM_CLK_NONE);
697                 printk("DCAM: un register isr \n");
698                 irq_no = parse_irq(dn);
699                 free_irq(irq_no, (void*)&s_dcam_irq);
700                 ret = clk_mm_i_eb(dn,0);
701                 if (ret) {
702                         rtn = -DCAM_RTN_MAX;
703                 }
704                 wake_unlock(&dcam_wakelock);
705                 wake_lock_destroy(&dcam_wakelock);
706         }
707
708         DCAM_TRACE("DCAM: dcam_module_dis, Out %d \n", s_dcam_users.counter);
709         mutex_unlock(&dcam_module_sema);
710
711         return rtn;
712 }
713
714 int32_t dcam_reset(enum dcam_rst_mode reset_mode, uint32_t is_isr)
715 {
716         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
717         uint32_t                time_out = 0;
718
719         DCAM_TRACE("DCAM: reset: %d \n", reset_mode);
720
721         if (!is_isr) {
722                 mutex_lock(&dcam_scale_sema);
723                 mutex_lock(&dcam_rot_sema);
724         }
725
726         if (DCAM_RST_ALL == reset_mode) {
727                 if (atomic_read(&s_dcam_users)) {
728                         /* firstly, stop AXI writing */
729                         dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_6, DCAM_AHBM_STS_REG);
730                 }
731
732                 /* then wait for AHB busy cleared */
733                 while (++time_out < DCAM_AXI_STOP_TIMEOUT) {
734                         if (0 == (REG_RD(DCAM_AHBM_STS) & BIT_0))
735                                 break;
736                 }
737                 if (time_out >= DCAM_AXI_STOP_TIMEOUT) {
738                         printk("DCAM: reset TO: %d \n", time_out);
739                         return DCAM_RTN_TIMEOUT;
740                 }
741         }
742
743         /* do reset action */
744         switch (reset_mode) {
745         case DCAM_RST_PATH0:
746                 sci_glb_set(DCAM_RST, PATH0_RST_BIT);
747                 sci_glb_clr(DCAM_RST, PATH0_RST_BIT);
748                 DCAM_TRACE("DCAM: reset path0 \n");
749                 break;
750
751         case DCAM_RST_PATH1:
752                 sci_glb_set(DCAM_RST, PATH1_RST_BIT);
753                 sci_glb_clr(DCAM_RST, PATH1_RST_BIT);
754                 DCAM_TRACE("DCAM: reset path1 \n");
755                 break;
756
757         case DCAM_RST_PATH2:
758                 sci_glb_set(DCAM_RST, PATH2_RST_BIT);
759                 sci_glb_clr(DCAM_RST, PATH2_RST_BIT);
760                 DCAM_TRACE("DCAM: reset path2 \n");
761                 break;
762
763         case DCAM_RST_ALL:
764                 sci_glb_set(DCAM_RST, DCAM_MOD_RST_BIT | CCIR_RST_BIT);
765                 sci_glb_clr(DCAM_RST, DCAM_MOD_RST_BIT | CCIR_RST_BIT);
766                 dcam_glb_reg_owr(DCAM_INT_CLR,
767                                         DCAM_IRQ_LINE_MASK,
768                                         DCAM_INIT_CLR_REG);
769                 dcam_glb_reg_owr(DCAM_INT_MASK,
770                                                 DCAM_IRQ_LINE_MASK,
771                                                 DCAM_INIT_MASK_REG);
772                 printk("DCAM: reset all \n");
773                 break;
774         default:
775                 rtn = DCAM_RTN_PARA_ERR;
776                 break;
777         }
778
779         if (DCAM_RST_ALL == reset_mode) {
780                 if (atomic_read(&s_dcam_users)) {
781                         /* the end, enable AXI writing */
782                         dcam_glb_reg_awr(DCAM_AHBM_STS, ~BIT_6, DCAM_AHBM_STS_REG);
783                 }
784         }
785
786         if (!is_isr) {
787                 mutex_unlock(&dcam_rot_sema);
788                 mutex_unlock(&dcam_scale_sema);
789         }
790
791         DCAM_TRACE("DCAM: reset_mode=%x  end \n", reset_mode);
792
793         return -rtn;
794 }
795
796 int32_t dcam_set_clk(struct device_node *dn, enum dcam_clk_sel clk_sel)
797 {
798 #ifdef CONFIG_SC_FPGA_CLK
799         return 0;
800 #else
801         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
802         struct clk              *clk_parent;
803         char                    *parent = "clk_312m";
804         int                     ret = 0;
805
806         switch (clk_sel) {
807         case DCAM_CLK_312M:
808                 parent = "clk_312m";
809                 break;
810         case DCAM_CLK_256M:
811                 parent = "clk_256m";
812                 break;
813         case DCAM_CLK_128M:
814                 parent = "clk_128m";
815                 break;
816         case DCAM_CLK_76M8:
817                 parent = "clk_76p8m";
818                 break;
819         case DCAM_CLK_NONE:
820                 printk("DCAM close CLK %d \n", (int)clk_get_rate(s_dcam_clk));
821                 if (s_dcam_clk) {
822                         clk_disable(s_dcam_clk);
823                         clk_put(s_dcam_clk);
824                         s_dcam_clk = NULL;
825                 }
826                 return 0;
827         default:
828                 parent = "clk_128m";
829                 break;
830         }
831
832         if (NULL == s_dcam_clk) {
833                 s_dcam_clk = parse_clk(dn,"clk_dcam");
834                 if (IS_ERR(s_dcam_clk)) {
835                         printk("DCAM: clk_get fail, %d \n", (int)s_dcam_clk);
836                         return -1;
837                 } else {
838                         DCAM_TRACE("DCAM: get clk_parent ok \n");
839                 }
840         } else {
841                 clk_disable(s_dcam_clk);
842         }
843
844         clk_parent = clk_get(NULL, parent);
845         if (IS_ERR(clk_parent)) {
846                 printk("DCAM: dcam_set_clk fail, %d \n", (int)clk_parent);
847                 return -1;
848         } else {
849                 DCAM_TRACE("DCAM: get clk_parent ok \n");
850         }
851
852         ret = clk_set_parent(s_dcam_clk, clk_parent);
853         if(ret){
854                 printk("DCAM: clk_set_parent fail, %d \n", ret);
855         }
856
857         ret = clk_enable(s_dcam_clk);
858         if (ret) {
859                 printk("enable dcam clk error.\n");
860                 return -1;
861         }
862         return rtn;
863 #endif
864 }
865
866 int32_t dcam_update_path(enum dcam_path_index path_index, struct dcam_size *in_size,
867                 struct dcam_rect *in_rect, struct dcam_size *out_size)
868 {
869         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
870         unsigned long           flags;
871         uint32_t                is_deci = 0;
872
873         DCAM_CHECK_ZERO(s_p_dcam_mod);
874         DCAM_CHECK_ZERO(s_dcam_sc_array);
875
876         DCAM_TRACE("DCAM:update path \n");
877         DCAM_TRACE("path_index %d s_p_dcam_mod->dcam_path0.valide %d \n", path_index, s_p_dcam_mod->dcam_path0.valide);
878         if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
879                 rtn = dcam_path0_cfg(DCAM_PATH_INPUT_SIZE, in_size);
880                 DCAM_RTN_IF_ERR;
881                 rtn = dcam_path0_cfg(DCAM_PATH_INPUT_RECT, in_rect);
882                 DCAM_RTN_IF_ERR;
883                 rtn = dcam_path0_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
884                 DCAM_RTN_IF_ERR;
885                 printk("DCAM: To update path0 \n");
886                 //_dcam_auto_copy(DCAM_PATH_IDX_0);
887         }
888
889         if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
890                 rtn = dcam_path1_cfg(DCAM_PATH_INPUT_SIZE, in_size);
891                 DCAM_RTN_IF_ERR;
892                 rtn = dcam_path1_cfg(DCAM_PATH_INPUT_RECT, in_rect);
893                 DCAM_RTN_IF_ERR;
894                 rtn = dcam_path1_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
895                 DCAM_RTN_IF_ERR;
896                 rtn = _dcam_path_check_deci(DCAM_PATH_IDX_1, &is_deci);
897                 DCAM_RTN_IF_ERR;
898                 DCAM_TRACE("DCAM: To update path1 \n");
899                 rtn = _dcam_path_scaler(DCAM_PATH_IDX_1);
900                 DCAM_RTN_IF_ERR;
901                 DCAM_TRACE("DCAM: dcam_update_path 1 \n");
902                         if (s_dcam_sc_array->is_smooth_zoom) {
903                                 spin_lock_irqsave(&dcam_lock, flags);
904                                 s_p_dcam_mod->dcam_path1.is_update = 1;
905                                 spin_unlock_irqrestore(&dcam_lock, flags);
906                         } else {
907                                 _dcam_wait_update_done(DCAM_PATH_IDX_1, &s_p_dcam_mod->dcam_path1.is_update);
908                         }
909                 if (!s_dcam_sc_array->is_smooth_zoom) {
910                         _dcam_wait_update_done(DCAM_PATH_IDX_1, NULL);
911                 }
912         }
913
914         if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
915                 local_irq_save(flags);
916                 if(s_p_dcam_mod->dcam_path2.is_update){
917                         local_irq_restore(flags);
918                         DCAM_TRACE("DCAM: dcam_update_path 2:  updating return \n");
919                         return rtn;
920                 }
921                 local_irq_restore(flags);
922
923                 rtn = dcam_path2_cfg(DCAM_PATH_INPUT_SIZE, in_size);
924                 DCAM_RTN_IF_ERR;
925                 rtn = dcam_path2_cfg(DCAM_PATH_INPUT_RECT, in_rect);
926                 DCAM_RTN_IF_ERR;
927                 rtn = dcam_path2_cfg(DCAM_PATH_OUTPUT_SIZE, out_size);
928                 DCAM_RTN_IF_ERR;
929
930                 rtn = _dcam_path_scaler(DCAM_PATH_IDX_2);
931                 DCAM_RTN_IF_ERR;
932
933                 local_irq_save(flags);
934                 s_p_dcam_mod->dcam_path2.is_update = 1;
935                 local_irq_restore(flags);
936         }
937
938         DCAM_TRACE("DCAM: dcam_update_path: done \n");
939
940         return -rtn;
941 }
942
943 int32_t dcam_start_path(enum dcam_path_index path_index)
944 {
945         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
946         uint32_t                cap_en = 0;
947
948         DCAM_CHECK_ZERO(s_p_dcam_mod);
949
950         DCAM_TRACE("DCAM: start_path: path %d, mode %x path 0,1,2 {%d %d %d} \n",
951                 path_index,
952                 s_p_dcam_mod->dcam_mode,
953                 s_p_dcam_mod->dcam_path0.valide,
954                 s_p_dcam_mod->dcam_path1.valide,
955                 s_p_dcam_mod->dcam_path2.valide);
956
957         dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_8, DCAM_AHBM_STS_REG); // aiden add: write arbit mode
958
959         cap_en = REG_RD(DCAM_CONTROL) & BIT_2;
960         DCAM_TRACE("DCAM: cap_eb %d \n", cap_en);
961         if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
962                 _dcam_path0_set();
963                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, true);
964                 DCAM_RTN_IF_ERR;
965                 //_dcam_force_copy(DCAM_PATH_IDX_0);
966                 _dcam_auto_copy(DCAM_PATH_IDX_0);
967 #if 0
968                 if (cap_en) {
969                         /* if cap is already open, the sequence is:
970                            cap force copy -> path 0 enable -> cap auto copy */
971                         dcam_glb_reg_mwr(DCAM_CONTROL, BIT_0, 1 << 0, DCAM_CONTROL_REG); /* Cap force copy */
972                         dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG);             /* Enable Path 0 */
973                         dcam_glb_reg_mwr(DCAM_CONTROL, BIT_1, 1 << 1, DCAM_CONTROL_REG); /* Cap auto copy, trigger path 0 enable */
974                 } else {
975                         dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG);             /* Enable Path 0 */
976                 }
977 #endif
978         }
979
980         if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
981
982                 //rtn = _dcam_path_trim(DCAM_PATH_IDX_1);
983                 //DCAM_RTN_IF_ERR;
984                 rtn = _dcam_path_scaler(DCAM_PATH_IDX_1);
985                 DCAM_RTN_IF_ERR;
986
987                 _dcam_path1_set(&s_p_dcam_mod->dcam_path1);
988                 DCAM_TRACE("DCAM: start path: path_control=%x \n", REG_RD(DCAM_CONTROL));
989
990                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, true);
991                 DCAM_RTN_IF_ERR;
992                 _dcam_force_copy_ext(DCAM_PATH_IDX_1, true, true);
993                 DCAM_TRACE("DCAM: int= %x \n", REG_RD(DCAM_INT_STS));
994                 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
995         }
996
997         if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
998                 rtn = _dcam_path_scaler(DCAM_PATH_IDX_2);
999                 DCAM_RTN_IF_ERR;
1000
1001                 _dcam_path2_set();
1002
1003                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, true);
1004                 DCAM_RTN_IF_ERR;
1005                 _dcam_force_copy_ext(DCAM_PATH_IDX_2, true, true);
1006         }
1007
1008         if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
1009                 //rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
1010                 //DCAM_RTN_IF_ERR;
1011                 //_dcam_auto_copy(DCAM_PATH_IDX_0);
1012                 s_p_dcam_mod->dcam_path0.need_wait = 0;
1013                 s_p_dcam_mod->dcam_path0.status = DCAM_ST_START;
1014                 dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG);                         /* Enable Path 0 */
1015         }
1016
1017         if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
1018                 s_p_dcam_mod->dcam_path1.need_wait = 0;
1019                 s_p_dcam_mod->dcam_path1.status = DCAM_ST_START;
1020                 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
1021         }
1022
1023         if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
1024                 s_p_dcam_mod->dcam_path2.need_wait = 0;
1025                 s_p_dcam_mod->dcam_path2.status = DCAM_ST_START;
1026                 dcam_glb_reg_owr(DCAM_CFG, BIT_2, DCAM_CFG_REG);
1027         }
1028
1029         if (0 == cap_en) {
1030 #if  0  //def DCAM_DEBUG
1031                 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_5 | BIT_4, 0 << 4);
1032                 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_3|BIT_2|BIT_1|BIT_0, 0x07);
1033                 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_5 | BIT_4, 1 << 4);
1034                 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_3|BIT_2|BIT_1|BIT_0, 0x07);
1035 #endif
1036                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_0, 1 << 0, DCAM_CONTROL_REG); /* Cap force copy */
1037                 //REG_MWR(DCAM_CONTROL, BIT_1, 1 << 1); /* Cap auto  copy */
1038                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 1 << 2, DCAM_CONTROL_REG); /* Cap Enable */
1039         }
1040
1041         if (DCAM_PATH_IDX_ALL != path_index) {
1042                 if ((DCAM_PATH_IDX_0 & path_index)) {
1043                         _dcam_wait_path_done(DCAM_PATH_IDX_0, NULL);
1044                 } else if ((DCAM_PATH_IDX_1 & path_index)) {
1045                         _dcam_wait_path_done(DCAM_PATH_IDX_1, NULL);
1046                 } else if ((DCAM_PATH_IDX_2 & path_index)) {
1047                         _dcam_wait_path_done(DCAM_PATH_IDX_2, NULL);
1048                 }
1049         }
1050
1051         printk("DCAM PATH S: %d \n", path_index);
1052
1053         _dcam_reg_trace();
1054
1055         DCAM_TRACE("DCAM: start_path E\n");
1056         return -rtn;
1057 }
1058
1059 int32_t dcam_start(void)
1060 {
1061         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1062         int                     ret = 0;
1063
1064         DCAM_CHECK_ZERO(s_p_dcam_mod);
1065
1066         DCAM_TRACE("DCAM: dcam_start %x \n", s_p_dcam_mod->dcam_mode);
1067
1068         ret = dcam_start_path(DCAM_PATH_IDX_ALL);
1069         //ret = dcam_start_path(DCAM_PATH_IDX_1);
1070
1071         return -rtn;
1072 }
1073
1074 int32_t dcam_stop_cap(void)
1075 {
1076         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1077 #if 0
1078         DCAM_CHECK_ZERO(s_p_dcam_mod);
1079
1080         printk("DCAM: stop cap %d \n", s_p_dcam_mod->dcam_mode);
1081         dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 0, DCAM_CONTROL_REG); /* Cap Enable */
1082         DCAM_TRACE("DCAM: stop cap, s_resize_flag %d \n", atomic_read(&s_resize_flag));
1083         if (atomic_read(&s_resize_flag)) {
1084                 s_p_dcam_mod->wait_resize_done = 1;
1085                 rtn = down_timeout(&s_p_dcam_mod->resize_done_sema, DCAM_PATH_TIMEOUT);
1086         }
1087         if (atomic_read(&s_rotation_flag)) {
1088                 s_p_dcam_mod->wait_rotation_done = 1;
1089                 rtn = down_timeout(&s_p_dcam_mod->rotation_done_sema, DCAM_PATH_TIMEOUT);
1090         }
1091
1092         dcam_reset(DCAM_RST_ALL, 0);
1093         DCAM_TRACE("DCAM: stop cap, Out \n");
1094 #endif
1095         return -rtn;
1096 }
1097
1098 int32_t _dcam_stop_path(enum dcam_path_index path_index)
1099 {
1100         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1101         struct dcam_path_desc   *p_path = NULL;
1102         unsigned long           flag;
1103
1104         spin_lock_irqsave(&dcam_lock, flag);
1105
1106         if (DCAM_PATH_IDX_0 == path_index) {
1107                 p_path = &s_p_dcam_mod->dcam_path0;
1108         } else if(DCAM_PATH_IDX_1 == path_index) {
1109                 p_path = &s_p_dcam_mod->dcam_path1;
1110         } else if(DCAM_PATH_IDX_2 == path_index) {
1111                 p_path = &s_p_dcam_mod->dcam_path2;
1112         } else {
1113                 printk("DCAM: stop path Wrong index 0x%x \n", path_index);
1114                 spin_unlock_irqrestore(&dcam_lock, flag);
1115                 return -rtn;
1116         }
1117
1118         _dcam_wait_for_quickstop(path_index);
1119         p_path->status = DCAM_ST_STOP;
1120         p_path->valide = 0;
1121         _dcam_frm_clear(path_index);
1122
1123         spin_unlock_irqrestore(&dcam_lock, flag);
1124
1125         return rtn;
1126 }
1127
1128 int32_t dcam_stop_path(enum dcam_path_index path_index)
1129 {
1130         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1131
1132         DCAM_CHECK_ZERO(s_p_dcam_mod);
1133
1134         printk("DCAM: stop_path 0x%x \n", path_index);
1135
1136         if (path_index < DCAM_PATH_IDX_0 ||
1137                 path_index >= DCAM_PATH_IDX_ALL) {
1138                 printk("DCAM: error path_index \n");
1139                 return -rtn;
1140         }
1141
1142         if ((DCAM_PATH_IDX_0 & path_index) && s_p_dcam_mod->dcam_path0.valide) {
1143                 _dcam_wait_path_done(DCAM_PATH_IDX_0, &s_p_dcam_mod->dcam_path0.need_stop);
1144                 _dcam_stop_path(DCAM_PATH_IDX_0);
1145         }
1146
1147         if ((DCAM_PATH_IDX_1 & path_index) && s_p_dcam_mod->dcam_path1.valide) {
1148                 _dcam_wait_path_done(DCAM_PATH_IDX_1, &s_p_dcam_mod->dcam_path1.need_stop);
1149                 _dcam_stop_path(DCAM_PATH_IDX_1);
1150         }
1151
1152         if ((DCAM_PATH_IDX_2 & path_index) && s_p_dcam_mod->dcam_path2.valide) {
1153                 DCAM_TRACE("DCAM: stop path2 In \n");
1154                 _dcam_wait_path_done(DCAM_PATH_IDX_2, &s_p_dcam_mod->dcam_path2.need_stop);
1155                 _dcam_stop_path(DCAM_PATH_IDX_2);
1156         }
1157
1158         DCAM_TRACE("DCAM dcam_stop_path E: %d \n", path_index);
1159
1160         return -rtn;
1161 }
1162
1163 LOCAL void    _dcam_wait_for_channel_stop(enum dcam_path_index path_index)
1164 {
1165         int                     time_out = 5000;
1166         uint32_t                ret = 0;
1167
1168         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
1169
1170         /* wait for AHB path busy cleared */
1171         while (time_out) {
1172                 if (s_p_dcam_mod->dcam_path1.valide && (DCAM_PATH_IDX_1 & path_index)) {
1173                         ret = REG_RD(DCAM_AHBM_STS) & BIT_17;
1174                 } else if (s_p_dcam_mod->dcam_path2.valide && (DCAM_PATH_IDX_2 & path_index)) {
1175                         ret = REG_RD(DCAM_AHBM_STS) & BIT_18;
1176 #ifdef VERSION3D
1177                 } else if (s_p_dcam_mod->dcam_path0.valide && (DCAM_PATH_IDX_0 & path_index)) {
1178                         ret = REG_RD(DCAM_AHBM_STS) & BIT_19;
1179 #endif
1180                 } else {
1181                         /*nothing*/
1182                 }
1183                 if (!ret) {
1184                         break;
1185                 }
1186                 time_out --;
1187         }
1188
1189         DCAM_TRACE("DCAM: wait channel stop %d %d \n", ret, time_out);
1190
1191         return;
1192 }
1193
1194 LOCAL void    _dcam_quickstop_set(enum dcam_path_index path_index, uint32_t path_rst, uint32_t path_bit,
1195         uint32_t cfg_bit, uint32_t ahbm_bit, uint32_t auto_copy_bit)
1196 {
1197         dcam_glb_reg_owr(DCAM_AHBM_STS, ahbm_bit, DCAM_AHBM_STS_REG);
1198         udelay(1000);
1199         dcam_glb_reg_mwr(DCAM_CFG, cfg_bit, ~cfg_bit, DCAM_CFG_REG);
1200         _dcam_wait_for_channel_stop(path_index);
1201         _dcam_force_copy(path_index);
1202         dcam_reset(path_rst, 1);
1203         dcam_glb_reg_awr(DCAM_AHBM_STS, ~ahbm_bit, DCAM_AHBM_STS_REG);
1204
1205         return;
1206 }
1207
1208 #define DCAM_IRQ_MASK_PATH0                            (0x0f|(0x03<<4)|(1<<12)|(1<<21))  //let other module continue
1209 #define DCAM_IRQ_MASK_PATH1                            (0x0f|(0x03<<6)|(1<<16)|(1<<19)|(1<<22))
1210 #define DCAM_IRQ_MASK_PATH2                            (0x0f|(0x03<<8)|(1<<17)|(1<<20)|(1<<23))
1211
1212 LOCAL void    _dcam_quickstop_set_all(enum dcam_path_index path_index, uint32_t path_bit, uint32_t cfg_bit, uint32_t ahbm_bit)
1213 {
1214         dcam_glb_reg_owr(DCAM_AHBM_STS, BIT_3 | BIT_4 | BIT_5, DCAM_AHBM_STS_REG);
1215         udelay(10);
1216         dcam_glb_reg_awr(DCAM_CFG, ~(BIT_0 | BIT_1 | BIT_2), DCAM_CFG_REG);
1217         dcam_glb_reg_owr(DCAM_CONTROL, BIT_8 | BIT_10 | BIT_12, DCAM_CONTROL_REG);
1218         dcam_glb_reg_awr(DCAM_CONTROL, ~(BIT_8 | BIT_10 | BIT_12), DCAM_CONTROL_REG);
1219         _dcam_wait_for_channel_stop(DCAM_PATH_IDX_0);
1220         _dcam_wait_for_channel_stop(DCAM_PATH_IDX_1);
1221         _dcam_wait_for_channel_stop(DCAM_PATH_IDX_2);
1222
1223         return;
1224 }
1225
1226 LOCAL void    _dcam_wait_for_quickstop(enum dcam_path_index path_index)
1227 {
1228         int                     time_out = 5000;
1229
1230         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
1231
1232         DCAM_TRACE("DCAM: state  before stop   0x%x\n", s_p_dcam_mod->state);
1233
1234         if (DCAM_PATH_IDX_ALL == path_index) {
1235                 _dcam_quickstop_set_all(0, 0, 0, 0);
1236         } else {
1237                 if (s_p_dcam_mod->dcam_path0.valide && (DCAM_PATH_IDX_0 & path_index)) {
1238                         _dcam_quickstop_set(DCAM_PATH_IDX_0, DCAM_RST_PATH0, DCAM_IRQ_MASK_PATH0, BIT_0, BIT_3, BIT_9);
1239                 }
1240                 if (s_p_dcam_mod->dcam_path1.valide && (DCAM_PATH_IDX_1 & path_index)) {
1241                         _dcam_quickstop_set(DCAM_PATH_IDX_1, DCAM_RST_PATH1, DCAM_IRQ_MASK_PATH1, BIT_1, BIT_4, BIT_11);
1242                 }
1243                 if (s_p_dcam_mod->dcam_path2.valide && (DCAM_PATH_IDX_2 & path_index)) {
1244                         _dcam_quickstop_set(DCAM_PATH_IDX_2, DCAM_RST_PATH2, DCAM_IRQ_MASK_PATH2, BIT_2, BIT_5, BIT_13);
1245                 }
1246         }
1247
1248         DCAM_TRACE("DCAM: exit _dcam_wait_for_quickstop %d state: 0x%x \n ", time_out, s_p_dcam_mod->state);
1249
1250         return;
1251 }
1252
1253 int32_t dcam_stop(void)
1254 {
1255         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1256         unsigned long           flag;
1257
1258         DCAM_CHECK_ZERO(s_p_dcam_mod);
1259
1260         s_p_dcam_mod->state |= DCAM_STATE_QUICKQUIT;
1261         printk("DCAM dcam_stop In \n");
1262         if (atomic_read(&s_resize_flag)) {
1263                 s_p_dcam_mod->wait_resize_done = 1;
1264                 rtn = down_timeout(&s_p_dcam_mod->resize_done_sema, DCAM_PATH_TIMEOUT);
1265         }
1266         if (atomic_read(&s_rotation_flag)) {
1267                 s_p_dcam_mod->wait_rotation_done = 1;
1268                 rtn = down_timeout(&s_p_dcam_mod->rotation_done_sema, DCAM_PATH_TIMEOUT);
1269         }
1270
1271         mutex_lock(&dcam_sem);
1272         printk("DCAM dcam_stop get  dcam_sem\n");
1273         spin_lock_irqsave(&dcam_lock, flag);
1274
1275         dcam_glb_reg_owr(DCAM_INT_MASK,
1276                                                 DCAM_IRQ_LINE_MASK,
1277                                                 DCAM_INIT_MASK_REG);
1278
1279         _dcam_wait_for_quickstop(DCAM_PATH_IDX_ALL);
1280         s_p_dcam_mod->dcam_path0.status = DCAM_ST_STOP;
1281         s_p_dcam_mod->dcam_path0.valide = 0;
1282         s_p_dcam_mod->dcam_path1.status = DCAM_ST_STOP;
1283         s_p_dcam_mod->dcam_path1.valide = 0;
1284         s_p_dcam_mod->dcam_path2.status = DCAM_ST_STOP;
1285         s_p_dcam_mod->dcam_path2.valide = 0;
1286         _dcam_frm_clear(DCAM_PATH_IDX_0);
1287         _dcam_frm_clear(DCAM_PATH_IDX_1);
1288         _dcam_frm_clear(DCAM_PATH_IDX_2);
1289         spin_unlock_irqrestore(&dcam_lock, flag);
1290
1291         dcam_reset(DCAM_RST_ALL, 0);
1292         s_p_dcam_mod->state &= ~DCAM_STATE_QUICKQUIT;
1293         mutex_unlock(&dcam_sem);
1294
1295         printk("DCAM: dcam_stop Out, s_resize_flag %d \n", atomic_read(&s_resize_flag));
1296
1297         return -rtn;
1298 }
1299
1300 int32_t dcam_resume(void)
1301 {
1302         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1303
1304         DCAM_CHECK_ZERO(s_p_dcam_mod);
1305
1306         if (s_p_dcam_mod->dcam_path0.valide) {
1307                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, true);
1308                 DCAM_RTN_IF_ERR;
1309                 _dcam_force_copy(DCAM_PATH_IDX_0);
1310                 _dcam_frm_clear(DCAM_PATH_IDX_0);
1311         }
1312
1313         if (s_p_dcam_mod->dcam_path1.valide) {
1314                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, true);
1315                 DCAM_RTN_IF_ERR;
1316                 _dcam_force_copy(DCAM_PATH_IDX_1);
1317                 _dcam_frm_clear(DCAM_PATH_IDX_1);
1318         }
1319
1320         if (s_p_dcam_mod->dcam_path2.valide) {
1321                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, true);
1322                 DCAM_RTN_IF_ERR;
1323                 _dcam_force_copy(DCAM_PATH_IDX_2);
1324                 _dcam_frm_clear(DCAM_PATH_IDX_2);
1325         }
1326
1327
1328         if (s_p_dcam_mod->dcam_path0.valide) {
1329                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
1330                 DCAM_RTN_IF_ERR;
1331                 dcam_glb_reg_owr(DCAM_CFG, BIT_0, DCAM_CFG_REG);
1332                 _dcam_auto_copy_ext(DCAM_PATH_IDX_0, true, true);
1333         }
1334
1335         if (s_p_dcam_mod->dcam_path1.valide) {
1336                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, false);
1337                 DCAM_RTN_IF_ERR;
1338                 dcam_glb_reg_owr(DCAM_CFG, BIT_1, DCAM_CFG_REG);
1339                 _dcam_auto_copy_ext(DCAM_PATH_IDX_1, true, true);
1340         }
1341
1342         if (s_p_dcam_mod->dcam_path2.valide) {
1343                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, false);
1344                 DCAM_RTN_IF_ERR;
1345                 dcam_glb_reg_owr(DCAM_CFG, BIT_2, DCAM_CFG_REG);
1346                 _dcam_auto_copy_ext(DCAM_PATH_IDX_2, true, true);
1347         }
1348
1349         printk("DCAM R \n");
1350
1351         dcam_glb_reg_owr(DCAM_CONTROL, BIT_2, DCAM_CONTROL_REG); /* Enable CAP */
1352         return -rtn;
1353 }
1354
1355 int32_t dcam_pause(void)
1356 {
1357         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1358
1359         dcam_glb_reg_awr(DCAM_CONTROL, ~BIT_2, DCAM_CONTROL_REG); /* Disable CAP */
1360         printk("DCAM P \n");
1361         return -rtn;
1362 }
1363
1364 int32_t dcam_reg_isr(enum dcam_irq_id id, dcam_isr_func user_func, void* user_data)
1365 {
1366         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1367         unsigned long           flag;
1368
1369         if(id >= DCAM_IRQ_NUMBER) {
1370                 rtn = DCAM_RTN_ISR_ID_ERR;
1371         } else {
1372                 spin_lock_irqsave(&dcam_lock, flag);
1373                 s_user_func[id] = user_func;
1374                 s_user_data[id] = user_data;
1375                 spin_unlock_irqrestore(&dcam_lock, flag);
1376         }
1377         return -rtn;
1378 }
1379
1380 int32_t dcam_cap_cfg(enum dcam_cfg_id id, void *param)
1381 {
1382         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1383         struct dcam_cap_desc    *cap_desc = NULL;
1384
1385         DCAM_CHECK_ZERO(s_p_dcam_mod);
1386         DCAM_CHECK_ZERO(s_dcam_sc_array);
1387         cap_desc = &s_p_dcam_mod->dcam_cap;
1388         switch (id) {
1389         case DCAM_CAP_SYNC_POL:
1390         {
1391                 struct dcam_cap_sync_pol *sync_pol = (struct dcam_cap_sync_pol*)param;
1392
1393                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1394
1395                 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1396
1397                         if (sync_pol->vsync_pol > 1 ||
1398                             sync_pol->hsync_pol > 1 ||
1399                             sync_pol->pclk_pol > 1) {
1400                                 rtn = DCAM_RTN_CAP_SYNC_POL_ERR;
1401                         } else {
1402                                 sci_glb_set(DCAM_CCIR_PCLK_EB, CCIR_PCLK_EB_BIT);
1403                                 REG_MWR(CAP_CCIR_CTRL, BIT_3, sync_pol->hsync_pol << 3);
1404                                 REG_MWR(CAP_CCIR_CTRL, BIT_4, sync_pol->vsync_pol << 4);
1405                                 //REG_MWR(CLK_DLY_CTRL,  BIT_19, sync_pol->pclk_pol << 19); // aiden todo
1406
1407                                 if (sync_pol->pclk_src == 0x00) {
1408                                         sci_glb_clr(CAP_CCIR_PLCK_SRC, (BIT_25 | BIT_26));
1409                                         DCAM_TRACE("DCAM: set pclk src0\n");
1410                                 } else if (sync_pol->pclk_src == 0x01) {
1411                                         sci_glb_clr(CAP_CCIR_PLCK_SRC, (BIT_25 | BIT_26));
1412                                         sci_glb_set(CAP_CCIR_PLCK_SRC, (BIT_25));
1413                                         DCAM_TRACE("DCAM: set pclk src1\n");
1414                                 } else {
1415                                         DCAM_TRACE("DCAM: set pclk src default\n");
1416                                 }
1417                         }
1418                 } else {
1419                         if (sync_pol->need_href) {
1420                                 REG_MWR(CAP_MIPI_CTRL, BIT_5, 1 << 5);
1421                         } else {
1422                                 REG_MWR(CAP_MIPI_CTRL, BIT_5, 0 << 5);
1423                         }
1424                 }
1425                 break;
1426         }
1427
1428         case DCAM_CAP_DATA_BITS:
1429         {
1430                 enum dcam_cap_data_bits bits = *(enum dcam_cap_data_bits*)param;
1431
1432                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1433
1434                 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1435                         if (DCAM_CAP_8_BITS == bits || DCAM_CAP_10_BITS == bits) {
1436                                 REG_MWR(CAP_CCIR_CTRL,  BIT_10 | BIT_9, 0 << 9);
1437                         } else if (DCAM_CAP_4_BITS == bits) {
1438                                 REG_MWR(CAP_CCIR_CTRL,  BIT_10 | BIT_9, 1 << 9);
1439                         } else if (DCAM_CAP_2_BITS == bits) {
1440                                 REG_MWR(CAP_CCIR_CTRL,  BIT_10 | BIT_9, 2 << 9);
1441                         } else if (DCAM_CAP_1_BITS == bits) {
1442                                 REG_MWR(CAP_CCIR_CTRL,  BIT_10 | BIT_9, 3 << 9);
1443                         } else {
1444                                 rtn = DCAM_RTN_CAP_IN_BITS_ERR;
1445                         }
1446
1447                 } else {
1448                         if (DCAM_CAP_12_BITS == bits) {
1449                                 REG_MWR(CAP_MIPI_CTRL,  BIT_4 | BIT_3, 2 << 3);
1450                         } else if (DCAM_CAP_10_BITS == bits) {
1451                                 REG_MWR(CAP_MIPI_CTRL,  BIT_4 | BIT_3, 1 << 3);
1452                         } else if (DCAM_CAP_8_BITS == bits) {
1453                                 REG_MWR(CAP_MIPI_CTRL,  BIT_4 | BIT_3, 0 << 3);
1454                         } else {
1455                                 rtn = DCAM_RTN_CAP_IN_BITS_ERR;
1456                         }
1457                 }
1458                 break;
1459         }
1460
1461         case DCAM_CAP_YUV_TYPE:
1462         {
1463                 enum dcam_cap_pattern pat = *(enum dcam_cap_pattern*)param;
1464
1465                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1466
1467                 if (pat < DCAM_PATTERN_MAX) {
1468                         if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1469                                 REG_MWR(CAP_CCIR_CTRL, BIT_8 | BIT_7, pat << 7);
1470                         else
1471                                 REG_MWR(CAP_MIPI_CTRL, BIT_8 | BIT_7, pat << 7);
1472                 } else {
1473                         rtn = DCAM_RTN_CAP_IN_YUV_ERR;
1474                 }
1475                 break;
1476         }
1477
1478         case DCAM_CAP_PRE_SKIP_CNT:
1479         {
1480                 uint32_t skip_num = *(uint32_t*)param;
1481
1482                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1483
1484                 if (skip_num > DCAM_CAP_SKIP_FRM_MAX) {
1485                         rtn = DCAM_RTN_CAP_SKIP_FRAME_ERR;
1486                 } else {
1487                         if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1488                                 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_3 | BIT_2 | BIT_1 | BIT_0, skip_num);
1489                         else
1490                                 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_3 | BIT_2 | BIT_1 | BIT_0, skip_num);
1491                 }
1492                 break;
1493         }
1494
1495         case DCAM_CAP_FRM_DECI:
1496         {
1497                 uint32_t deci_factor = *(uint32_t*)param;
1498
1499                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1500
1501                 if (deci_factor < DCAM_FRM_DECI_FAC_MAX) {
1502                         if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1503                                 REG_MWR(CAP_CCIR_FRM_CTRL, BIT_5 | BIT_4, deci_factor << 4);
1504                         else
1505                                 REG_MWR(CAP_MIPI_FRM_CTRL, BIT_5 | BIT_4, deci_factor << 4);
1506                 } else {
1507                         rtn = DCAM_RTN_CAP_FRAME_DECI_ERR;
1508                 }
1509                 break;
1510         }
1511
1512         case DCAM_CAP_FRM_COUNT_CLR:
1513                 if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1514                         REG_MWR(CAP_CCIR_FRM_CTRL, BIT_22, 1 << 22);
1515                 else
1516                         REG_MWR(CAP_MIPI_FRM_CTRL, BIT_22, 1 << 22);
1517                 break;
1518
1519         case DCAM_CAP_INPUT_RECT:
1520         {
1521                 struct dcam_rect *rect = (struct dcam_rect*)param;
1522                 uint32_t         tmp = 0;
1523
1524                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1525 #if 0
1526                 if (rect->x > DCAM_CAP_FRAME_WIDTH_MAX ||
1527                 rect->y > DCAM_CAP_FRAME_HEIGHT_MAX ||
1528                 rect->w > DCAM_CAP_FRAME_WIDTH_MAX ||
1529                 rect->h > DCAM_CAP_FRAME_HEIGHT_MAX ) {
1530                         rtn = DCAM_RTN_CAP_FRAME_SIZE_ERR;
1531                         return -rtn;
1532                 }
1533 #endif
1534
1535                 if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1536                         if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1537                                 tmp = rect->x | (rect->y << 16);
1538                                 REG_WR(CAP_CCIR_START, tmp);
1539                                 tmp = (rect->x + rect->w - 1);
1540                                 tmp |= (rect->y + rect->h - 1) << 16;
1541                                 REG_WR(CAP_CCIR_END, tmp);
1542                         } else {
1543                                 tmp = (rect->x << 1) | (rect->y << 16);
1544                                 REG_WR(CAP_CCIR_START, tmp);
1545                                 tmp = ((rect->x + rect->w) << 1) - 1;
1546                                 tmp |= (rect->y + rect->h - 1) << 16;
1547                                 REG_WR(CAP_CCIR_END, tmp);
1548                         }
1549                 } else {
1550                         tmp = rect->x | (rect->y << 16);
1551                         REG_WR(CAP_MIPI_START, tmp);
1552                         tmp = (rect->x + rect->w - 1);
1553                         tmp |= (rect->y + rect->h - 1) << 16;
1554                         REG_WR(CAP_MIPI_END, tmp);
1555                 }
1556                 break;
1557         }
1558
1559         case DCAM_CAP_IMAGE_XY_DECI:
1560         {
1561                 struct dcam_cap_dec *cap_dec = (struct dcam_cap_dec*)param;
1562
1563                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1564
1565                 if (cap_dec->x_factor > DCAM_CAP_X_DECI_FAC_MAX ||
1566                 cap_dec->y_factor > DCAM_CAP_Y_DECI_FAC_MAX ) {
1567                         rtn = DCAM_RTN_CAP_XY_DECI_ERR;
1568                 } else {
1569                         if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1570                                 if (cap_dec->x_factor > 1 ||
1571                                     cap_dec->y_factor > 1) {
1572                                         rtn = DCAM_RTN_CAP_XY_DECI_ERR;
1573                                 }
1574                         }
1575                         if (DCAM_CAP_IF_CCIR == cap_desc->interface) {
1576                                 REG_MWR(CAP_CCIR_IMG_DECI, BIT_1 | BIT_0, cap_dec->x_factor);
1577                                 REG_MWR(CAP_CCIR_IMG_DECI, BIT_3 | BIT_2, cap_dec->y_factor << 2);
1578                         } else {
1579                                 if (DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1580                                         // REG_MWR(CAP_MIPI_IMG_DECI, BIT_0, cap_dec->x_factor); // for camera path
1581                                         REG_MWR(CAP_MIPI_IMG_DECI, BIT_1, cap_dec->x_factor << 1);//for ISP
1582                                 } else {
1583                                         REG_MWR(CAP_MIPI_IMG_DECI, BIT_1 | BIT_0, cap_dec->x_factor);
1584                                         REG_MWR(CAP_MIPI_IMG_DECI, BIT_3 | BIT_2, cap_dec->y_factor << 2);
1585                                 }
1586                         }
1587                 }
1588
1589                 break;
1590         }
1591
1592         case DCAM_CAP_JPEG_SET_BUF_LEN:
1593         {
1594                 uint32_t jpg_buf_size = *(uint32_t*)param;
1595
1596                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1597                 jpg_buf_size = jpg_buf_size/DCAM_JPG_BUF_UNIT;
1598                 if (jpg_buf_size >= DCAM_JPG_UNITS) {
1599                         rtn = DCAM_RTN_CAP_JPEG_BUF_LEN_ERR;
1600                 } else {
1601                         if (DCAM_CAP_IF_CCIR == cap_desc->interface)
1602                                 REG_WR(CAP_CCIR_JPG_CTRL,jpg_buf_size);
1603                         else
1604                                 REG_WR(CAP_MIPI_JPG_CTRL,jpg_buf_size);
1605                 }
1606                 break;
1607         }
1608
1609         case DCAM_CAP_TO_ISP:
1610         {
1611                 uint32_t need_isp = *(uint32_t*)param;
1612
1613                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1614
1615                 if (need_isp) {
1616                         dcam_glb_reg_mwr(DCAM_CFG, BIT_7, 1 << 7, DCAM_CFG_REG);
1617                 } else {
1618                         dcam_glb_reg_mwr(DCAM_CFG, BIT_7, 0 << 7, DCAM_CFG_REG);
1619                 }
1620                 break;
1621         }
1622
1623         case DCAM_CAP_DATA_PACKET:
1624         {
1625                 uint32_t is_loose = *(uint32_t*)param;
1626
1627                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1628
1629                 if (DCAM_CAP_IF_CSI2 == cap_desc->interface &&
1630                         DCAM_CAP_MODE_RAWRGB == cap_desc->input_format) {
1631                         if (is_loose) {
1632                                 REG_MWR(CAP_MIPI_CTRL, BIT_0, 1);
1633                         } else {
1634                                 REG_MWR(CAP_MIPI_CTRL, BIT_0, 0);
1635                         }
1636                 } else {
1637                         rtn = DCAM_RTN_MODE_ERR;
1638                 }
1639
1640                 break;
1641         }
1642
1643         case DCAM_CAP_SAMPLE_MODE:
1644         {
1645                 enum dcam_capture_mode samp_mode = *(enum dcam_capture_mode*)param;
1646
1647                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1648
1649                 if (samp_mode >= DCAM_CAPTURE_MODE_MAX) {
1650                         rtn = DCAM_RTN_MODE_ERR;
1651                 } else {
1652                         if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1653                                 REG_MWR(CAP_MIPI_CTRL, BIT_6, samp_mode << 6);
1654                         } else {
1655                                 REG_MWR(CAP_CCIR_CTRL, BIT_6, samp_mode << 6);
1656                         }
1657                         s_p_dcam_mod->dcam_mode = samp_mode;
1658                 }
1659                 break;
1660         }
1661
1662         case DCAM_CAP_ZOOM_MODE:
1663         {
1664                 uint32_t zoom_mode = *(uint32_t*)param;
1665
1666                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1667
1668                 //Zoom operation issue fix in Z3. enable smooth_zoom
1669                 s_dcam_sc_array->is_smooth_zoom = 1;
1670                 break;
1671         }
1672         default:
1673                 rtn = DCAM_RTN_IO_ID_ERR;
1674                 break;
1675
1676         }
1677
1678         return -rtn;
1679 }
1680
1681 int32_t dcam_cap_get_info(enum dcam_cfg_id id, void *param)
1682 {
1683         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1684         struct dcam_cap_desc    *cap_desc = NULL;
1685
1686         DCAM_CHECK_ZERO(s_p_dcam_mod);
1687
1688         cap_desc = &s_p_dcam_mod->dcam_cap;
1689         DCAM_CHECK_PARAM_ZERO_POINTER(param);
1690
1691         switch(id) {
1692                 case DCAM_CAP_FRM_COUNT_GET:
1693                         if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1694                                 *(uint32_t*)param = REG_RD(CAP_MIPI_FRM_CTRL) >> 16;
1695                         } else {
1696                                 *(uint32_t*)param = REG_RD(CAP_CCIR_FRM_CTRL) >> 16;
1697                         }
1698                         break;
1699
1700                 case DCAM_CAP_JPEG_GET_LENGTH:
1701                         if (DCAM_CAP_IF_CSI2 == cap_desc->interface) {
1702                                 *(uint32_t*)param = REG_RD(CAP_MIPI_FRM_SIZE);
1703                         } else {
1704                                 *(uint32_t*)param = REG_RD(CAP_CCIR_FRM_SIZE);
1705                         }
1706                         break;
1707                 default:
1708                         rtn = DCAM_RTN_IO_ID_ERR;
1709                         break;
1710         }
1711         return -rtn;
1712 }
1713
1714 int32_t dcam_path0_cfg(enum dcam_cfg_id id, void *param)
1715 {
1716         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1717         struct dcam_path_desc   *path = NULL;
1718
1719         DCAM_CHECK_ZERO(s_p_dcam_mod);
1720         path = &s_p_dcam_mod->dcam_path0;
1721         switch (id) {
1722
1723         case DCAM_PATH_INPUT_SIZE:
1724         {
1725                 struct dcam_size *size = (struct dcam_size*)param;
1726
1727                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1728
1729                 DCAM_TRACE("DCAM: DCAM_PATH0_INPUT_SIZE {%d %d} \n", size->w, size->h);
1730 #if 0
1731                 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1732                 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1733                         rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1734                 } else
1735 #endif
1736                  {
1737                         path->input_size.w = size->w;
1738                         path->input_size.h = size->h;
1739                         path->valid_param.input_size = 1;
1740                 }
1741                 break;
1742         }
1743
1744         case DCAM_PATH_INPUT_RECT:
1745         {
1746                 struct dcam_rect *rect = (struct dcam_rect*)param;
1747
1748                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1749
1750                 DCAM_TRACE("DCAM: DCAM_PATH0_INPUT_RECT  {%d %d %d %d} \n",
1751                         rect->x,
1752                         rect->y,
1753                         rect->w,
1754                         rect->h);
1755
1756                 if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
1757                 rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
1758                 rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1759                 rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1760                         rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
1761                 } else {
1762                         memcpy((void*)&path->input_rect,
1763                                 (void*)rect,
1764                                 sizeof(struct dcam_rect));
1765                         //if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
1766                         //      path->input_rect.h--;
1767                         //}
1768                         /* path0  output size is different with other paths */
1769                         path->output_size.w = rect->w;
1770                         path->output_size.h = rect->h;
1771                         path->valid_param.input_rect = 1;
1772                 }
1773                 break;
1774         }
1775         case DCAM_PATH_OUTPUT_SIZE:
1776         {
1777                 struct dcam_size *size = (struct dcam_size*)param;
1778
1779                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1780
1781                 DCAM_TRACE("DCAM: DCAM_PATH2_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
1782                 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1783                 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1784                         rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1785                 } else {
1786                         path->output_size.w = size->w;
1787                         path->output_size.h = size->h;
1788                         path->valid_param.output_size = 1;
1789                 }
1790                 break;
1791         }
1792
1793         case DCAM_PATH_SRC_SEL:
1794         {
1795                 uint32_t       src_sel = *(uint32_t*)param;
1796
1797                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1798
1799                 if (src_sel >= DCAM_PATH_FROM_NONE) {
1800                         rtn = DCAM_RTN_PATH_SRC_ERR;
1801                 } else {
1802                         path->src_sel = src_sel;
1803                         path->valid_param.src_sel = 1;
1804                 }
1805                 break;
1806         }
1807
1808         case DCAM_PATH_OUTPUT_FORMAT:
1809         {
1810                 enum dcam_output_mode format = *(enum dcam_output_mode*)param;
1811
1812                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1813
1814                 if((DCAM_OUTPUT_WORD != format) &&
1815                 (DCAM_OUTPUT_HALF_WORD != format) &&
1816                 (DCAM_OUTPUT_YVYU_1FRAME != format) &&
1817                 (DCAM_OUTPUT_YUV420 != format)){
1818                         rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
1819                         path->output_format = DCAM_FTM_MAX;
1820                 }else{
1821                         path->output_format = format;
1822                         path->valid_param.output_format = 1;
1823                 }
1824                 break;
1825         }
1826
1827         case DCAM_PATH_FRAME_BASE_ID:
1828         {
1829                 uint32_t          base_id = *(uint32_t*)param, i;
1830
1831                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1832
1833                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
1834                 s_p_dcam_mod->dcam_path0.frame_base_id = base_id;
1835                 break;
1836         }
1837
1838         case DCAM_PATH_FRAME_TYPE:
1839         {
1840                 struct dcam_frame *frame  = &s_p_dcam_mod->dcam_path0.buf_queue.frame[0];
1841                 uint32_t          frm_type = *(uint32_t*)param, i;
1842
1843                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1844
1845                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
1846                 for (i = 0; i < DCAM_PATH_0_FRM_CNT_MAX; i++) {
1847                         (frame+i)->type = frm_type;
1848                 }
1849                 break;
1850         }
1851
1852         case DCAM_PATH_OUTPUT_ADDR:
1853         {
1854                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1855
1856                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1857                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1858                         rtn = DCAM_RTN_PATH_ADDR_ERR;
1859                 } else {
1860                         struct dcam_frame frame;
1861                         memset((void*)&frame, 0, sizeof(struct dcam_frame));
1862                         frame.yaddr = p_addr->yaddr;
1863                         frame.uaddr = p_addr->uaddr;
1864                         frame.vaddr = p_addr->vaddr;
1865                         frame.yaddr_vir = p_addr->yaddr_vir;
1866                         frame.uaddr_vir = p_addr->uaddr_vir;
1867                         frame.vaddr_vir = p_addr->vaddr_vir;
1868                         frame.type  = DCAM_PATH0;
1869                         frame.fid   = s_p_dcam_mod->dcam_path0.frame_base_id;
1870                         DCAM_TRACE("DCAM: Path 0 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1871                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1872                         _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path0.buf_queue, &frame);
1873                 }
1874                 break;
1875         }
1876
1877         case DCAM_PATH_OUTPUT_RESERVED_ADDR:
1878         {
1879                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
1880
1881                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1882
1883                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
1884                         rtn = DCAM_RTN_PATH_ADDR_ERR;
1885                 } else {
1886                         struct dcam_frame *frame  = &s_p_dcam_mod->path0_reserved_frame;
1887                         frame->yaddr = p_addr->yaddr;
1888                         frame->uaddr = p_addr->uaddr;
1889                         frame->vaddr = p_addr->vaddr;
1890                         frame->yaddr_vir = p_addr->yaddr_vir;
1891                         frame->uaddr_vir = p_addr->uaddr_vir;
1892                         frame->vaddr_vir = p_addr->vaddr_vir;
1893
1894                         DCAM_TRACE("DCAM: Path 0 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
1895                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
1896                 }
1897                 break;
1898         }
1899
1900         case DCAM_PATH_FRM_DECI:
1901         {
1902                 uint32_t deci_factor = *(uint32_t*)param;
1903
1904                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1905
1906                 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
1907                         rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
1908                 } else {
1909                         path->frame_deci = deci_factor;
1910                         path->valid_param.frame_deci = 1;
1911                 }
1912                 break;
1913         }
1914
1915         case DCAM_PATH_DATA_ENDIAN:
1916         {
1917                 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
1918
1919                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1920
1921                 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
1922                         endian->uv_endian >= DCAM_ENDIAN_MAX) {
1923                         rtn = DCAM_RTN_PATH_ENDIAN_ERR;
1924                 } else {
1925                         path->data_endian.y_endian      = endian->y_endian;
1926                         path->data_endian.uv_endian = endian->uv_endian; /*Bug449569 NV12 support*/
1927                         path->valid_param.data_endian = 1;
1928                 }
1929                 break;
1930         }
1931
1932
1933         case DCAM_PATH_ENABLE:
1934         {
1935                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1936                 path->valide = *(uint32_t*)param;
1937                 break;
1938         }
1939
1940         case DCAM_PATH_ROT_MODE:
1941         {
1942                 uint32_t rot_mode = *(uint32_t*)param;
1943                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1944                 if (rot_mode >= DCAM_PATH_FRAME_ROT_MAX) {
1945                         rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
1946                 }else{
1947                         path->rot_mode = rot_mode;
1948                         path->valid_param.rot_mode = 1;
1949                         printk("zcf dcam_path0_cfg rot: = %d\n",path->rot_mode);
1950                 }
1951                 break;
1952         }
1953
1954         default:
1955                 rtn = DCAM_RTN_IO_ID_ERR;
1956                 break;
1957         }
1958
1959         return -rtn;
1960 }
1961
1962 int32_t dcam_path1_cfg(enum dcam_cfg_id id, void *param)
1963 {
1964         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
1965         struct dcam_path_desc   *path = NULL;
1966
1967         DCAM_CHECK_ZERO(s_p_dcam_mod);
1968         path = &s_p_dcam_mod->dcam_path1;
1969         switch (id) {
1970
1971         case DCAM_PATH_INPUT_SIZE:
1972         {
1973                 struct dcam_size *size = (struct dcam_size*)param;
1974
1975                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1976
1977                 DCAM_TRACE("DCAM: DCAM_PATH1_INPUT_SIZE {%d %d} \n", size->w, size->h);
1978                 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
1979                 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
1980                         rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
1981                 } else {
1982                         path->input_size.w = size->w;
1983                         path->input_size.h = size->h;
1984                         path->valid_param.input_size = 1;
1985                 }
1986                 break;
1987         }
1988
1989         case DCAM_PATH_INPUT_RECT:
1990         {
1991                 struct dcam_rect *rect = (struct dcam_rect*)param;
1992
1993                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
1994
1995                 DCAM_TRACE("DCAM: DCAM_PATH1_INPUT_RECT  {%d %d %d %d} \n",
1996                         rect->x,
1997                         rect->y,
1998                         rect->w,
1999                         rect->h);
2000
2001                 if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
2002                 rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
2003                 rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2004                 rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2005                         rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
2006                 } else {
2007                         memcpy((void*)&path->input_rect,
2008                                 (void*)rect,
2009                                 sizeof(struct dcam_rect));
2010                         //if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
2011                         //      path->input_rect.h--;
2012                         //}
2013                         path->valid_param.input_rect = 1;
2014                 }
2015                 break;
2016         }
2017
2018         case DCAM_PATH_OUTPUT_SIZE:
2019         {
2020                 struct dcam_size *size = (struct dcam_size*)param;
2021
2022                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2023
2024                 DCAM_TRACE("DCAM: DCAM_PATH1_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
2025                 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2026                 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2027                         rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2028                 } else {
2029                         path->output_size.w = size->w;
2030                         path->output_size.h = size->h;
2031                         path->valid_param.output_size = 1;
2032                 }
2033                 break;
2034         }
2035
2036         case DCAM_PATH_OUTPUT_FORMAT:
2037         {
2038                 enum dcam_fmt format = *(enum dcam_fmt*)param;
2039
2040                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2041
2042                 path->output_format = format;
2043
2044                 if((DCAM_YUV422 != format) &&
2045                 (DCAM_YUV420 != format) &&
2046                 (DCAM_YUV420_3FRAME != format)){
2047                         rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
2048                         path->output_format = DCAM_FTM_MAX;
2049                 }else{
2050                         path->valid_param.output_format = 1;
2051                 }
2052                 break;
2053         }
2054
2055         case DCAM_PATH_OUTPUT_ADDR:
2056         {
2057                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2058
2059                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2060                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2061                         rtn = DCAM_RTN_PATH_ADDR_ERR;
2062                 } else {
2063                         struct dcam_frame frame;
2064                         memset((void*)&frame, 0, sizeof(struct dcam_frame));
2065                         frame.yaddr = p_addr->yaddr;
2066                         frame.uaddr = p_addr->uaddr;
2067                         frame.vaddr = p_addr->vaddr;
2068                         frame.yaddr_vir = p_addr->yaddr_vir;
2069                         frame.uaddr_vir = p_addr->uaddr_vir;
2070                         frame.vaddr_vir = p_addr->vaddr_vir;
2071                         frame.type  = DCAM_PATH1;
2072                         frame.fid   = s_p_dcam_mod->dcam_path1.frame_base_id;
2073                         DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2074                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2075                         _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path1.buf_queue, &frame);
2076                 }
2077                 break;
2078         }
2079
2080         case DCAM_PATH_OUTPUT_RESERVED_ADDR:
2081         {
2082                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2083
2084                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2085
2086                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2087                         rtn = DCAM_RTN_PATH_ADDR_ERR;
2088                 } else {
2089                         struct dcam_frame *frame  = &s_p_dcam_mod->path1_reserved_frame;
2090                         frame->yaddr = p_addr->yaddr;
2091                         frame->uaddr = p_addr->uaddr;
2092                         frame->vaddr = p_addr->vaddr;
2093                         frame->yaddr_vir = p_addr->yaddr_vir;
2094                         frame->uaddr_vir = p_addr->uaddr_vir;
2095                         frame->vaddr_vir = p_addr->vaddr_vir;
2096                         DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2097                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2098                 }
2099                 break;
2100         }
2101
2102         case DCAM_PATH_SRC_SEL:
2103         {
2104                 uint32_t       src_sel = *(uint32_t*)param;
2105
2106                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2107
2108                 if (src_sel >= DCAM_PATH_FROM_NONE) {
2109                         rtn = DCAM_RTN_PATH_SRC_ERR;
2110                 } else {
2111                         path->src_sel = src_sel;
2112                         path->valid_param.src_sel = 1;
2113                 }
2114                 break;
2115         }
2116
2117         case DCAM_PATH_FRAME_BASE_ID:
2118         {
2119                 uint32_t          base_id = *(uint32_t*)param, i;
2120
2121                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2122
2123                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
2124                 s_p_dcam_mod->dcam_path1.frame_base_id = base_id;
2125                 break;
2126         }
2127
2128         case DCAM_PATH_DATA_ENDIAN:
2129         {
2130                 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
2131
2132                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2133
2134                 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
2135                         endian->uv_endian >= DCAM_ENDIAN_MAX) {
2136                         rtn = DCAM_RTN_PATH_ENDIAN_ERR;
2137                 } else {
2138                         path->data_endian.y_endian  = endian->y_endian;
2139                         path->data_endian.uv_endian = endian->uv_endian;
2140                         path->valid_param.data_endian = 1;
2141                 }
2142                 break;
2143         }
2144
2145         case DCAM_PATH_ENABLE:
2146         {
2147                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2148                 path->valide = *(uint32_t*)param;
2149                 break;
2150         }
2151
2152         case DCAM_PATH_FRAME_TYPE:
2153         {
2154                 struct dcam_frame *frame  = &s_p_dcam_mod->dcam_path1.buf_queue.frame[0];
2155                 uint32_t          frm_type = *(uint32_t*)param, i;
2156
2157                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2158
2159                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
2160                 for (i = 0; i < DCAM_PATH_1_FRM_CNT_MAX; i++) {
2161                         (frame+i)->type = frm_type;
2162                 }
2163                 break;
2164         }
2165
2166         case DCAM_PATH_FRM_DECI:
2167         {
2168                 uint32_t deci_factor = *(uint32_t*)param;
2169
2170                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2171
2172                 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
2173                         rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2174                 } else {
2175                         path->frame_deci = deci_factor;
2176                         path->valid_param.frame_deci = 1;
2177                 }
2178                 break;
2179         }
2180
2181         case DCAM_PATH_SHRINK:
2182         {
2183                 uint32_t shrink = *(uint32_t*)param;
2184
2185                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2186
2187                 if (shrink == 1) {
2188                         path->shrink = 1;
2189                 } else {
2190                         path->shrink = 0;
2191                 }
2192                 path->valid_param.shrink = 1;
2193                 break;
2194         }
2195
2196         case DCAM_PATH_ROT_MODE:
2197         {
2198                 uint32_t rot_mode = *(uint32_t*)param;
2199                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2200                 if (rot_mode >= DCAM_PATH_FRAME_ROT_MAX) {
2201                         rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2202                 }else{
2203                         path->rot_mode = rot_mode;
2204                         path->valid_param.rot_mode = 1;
2205                         printk("zcf dcam_path1_cfg rot:\n",path->rot_mode);
2206                 }
2207                 break;
2208         }
2209         
2210         default:
2211                 break;
2212         }
2213
2214         return -rtn;
2215 }
2216
2217 int32_t dcam_path2_cfg(enum dcam_cfg_id id, void *param)
2218 {
2219         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
2220         struct dcam_path_desc   *path = NULL;
2221
2222         DCAM_CHECK_ZERO(s_p_dcam_mod);
2223         path = &s_p_dcam_mod->dcam_path2;
2224         switch (id) {
2225
2226         case DCAM_PATH_INPUT_SIZE:
2227         {
2228                 struct dcam_size *size = (struct dcam_size*)param;
2229
2230                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2231
2232                 DCAM_TRACE("DCAM: DCAM_PATH2_INPUT_SIZE {%d %d} \n", size->w, size->h);
2233                 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2234                 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2235                         rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2236                 } else {
2237                         path->input_size.w = size->w;
2238                         path->input_size.h = size->h;
2239                         path->valid_param.input_size = 1;
2240
2241                 }
2242                 break;
2243         }
2244
2245         case DCAM_PATH_INPUT_RECT:
2246         {
2247                 struct dcam_rect *rect = (struct dcam_rect*)param;
2248
2249                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2250
2251                 DCAM_TRACE("DCAM: DCAM_PATH2_INPUT_RECT {%d %d %d %d} \n",
2252                         rect->x,
2253                         rect->y,
2254                         rect->w,
2255                         rect->h);
2256
2257                 if (rect->x > DCAM_PATH_FRAME_WIDTH_MAX ||
2258                 rect->y > DCAM_PATH_FRAME_HEIGHT_MAX ||
2259                 rect->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2260                 rect->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2261                         rtn = DCAM_RTN_PATH_TRIM_SIZE_ERR;
2262                 } else {
2263                         memcpy((void*)&path->input_rect,
2264                                 (void*)rect,
2265                                 sizeof(struct dcam_rect));
2266 #if 0
2267                         if (path->input_rect.h >= DCAM_HEIGHT_MIN) {
2268                                 path->input_rect.h--;
2269                         }
2270 #endif
2271                         path->valid_param.input_rect = 1;
2272                 }
2273                 break;
2274         }
2275
2276         case DCAM_PATH_OUTPUT_SIZE:
2277         {
2278                 struct dcam_size *size = (struct dcam_size*)param;
2279
2280                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2281
2282                 DCAM_TRACE("DCAM: DCAM_PATH2_OUTPUT_SIZE {%d %d} \n", size->w, size->h);
2283                 if (size->w > DCAM_PATH_FRAME_WIDTH_MAX ||
2284                 size->h > DCAM_PATH_FRAME_HEIGHT_MAX) {
2285                         rtn = DCAM_RTN_PATH_SRC_SIZE_ERR;
2286                 } else {
2287                         path->output_size.w = size->w;
2288                         path->output_size.h = size->h;
2289                         path->valid_param.output_size = 1;
2290                 }
2291                 break;
2292         }
2293
2294         case DCAM_PATH_OUTPUT_FORMAT:
2295         {
2296                 enum dcam_fmt format = *(enum dcam_fmt*)param;
2297
2298                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2299
2300                 if((DCAM_YUV422 != format) &&
2301                 (DCAM_YUV420 != format) &&
2302                 (DCAM_YUV420_3FRAME != format)){
2303                         rtn = DCAM_RTN_PATH_OUT_FMT_ERR;
2304                         path->output_format = DCAM_FTM_MAX;
2305                 }else{
2306                         path->output_format = format;
2307                         path->valid_param.output_format = 1;
2308                 }
2309                 break;
2310         }
2311
2312         case DCAM_PATH_OUTPUT_ADDR:
2313         {
2314                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2315
2316                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2317                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2318                         rtn = DCAM_RTN_PATH_ADDR_ERR;
2319                 } else {
2320                         struct dcam_frame frame;
2321                         memset((void*)&frame, 0, sizeof(struct dcam_frame));
2322                         frame.yaddr = p_addr->yaddr;
2323                         frame.uaddr = p_addr->uaddr;
2324                         frame.vaddr = p_addr->vaddr;
2325                         frame.yaddr_vir = p_addr->yaddr_vir;
2326                         frame.uaddr_vir = p_addr->uaddr_vir;
2327                         frame.vaddr_vir = p_addr->vaddr_vir;
2328                         frame.type  = DCAM_PATH2;
2329                         frame.fid   = s_p_dcam_mod->dcam_path2.frame_base_id;
2330                         DCAM_TRACE("DCAM: Path 2 DCAM_PATH_OUTPUT_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2331                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2332                         _dcam_buf_queue_write(&s_p_dcam_mod->dcam_path2.buf_queue, &frame);
2333                 }
2334                 break;
2335         }
2336
2337         case DCAM_PATH_OUTPUT_RESERVED_ADDR:
2338         {
2339                 struct dcam_addr *p_addr = (struct dcam_addr*)param;
2340
2341                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2342
2343                 if (DCAM_YUV_ADDR_INVALID(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) {
2344                         rtn = DCAM_RTN_PATH_ADDR_ERR;
2345                 } else {
2346                         struct dcam_frame *frame  = &s_p_dcam_mod->path2_reserved_frame;
2347                         frame->yaddr = p_addr->yaddr;
2348                         frame->uaddr = p_addr->uaddr;
2349                         frame->vaddr = p_addr->vaddr;
2350                         frame->yaddr_vir = p_addr->yaddr_vir;
2351                         frame->uaddr_vir = p_addr->uaddr_vir;
2352                         frame->vaddr_vir = p_addr->vaddr_vir;
2353                         DCAM_TRACE("DCAM: Path 1 DCAM_PATH_OUTPUT_RESERVED_ADDR, i=%d, y=0x%x, u=0x%x, v=0x%x \n",
2354                                 path->output_frame_count, p_addr->yaddr, p_addr->uaddr, p_addr->vaddr);
2355                 }
2356                 break;
2357         }
2358
2359         case DCAM_PATH_SRC_SEL:
2360         {
2361                 uint32_t       src_sel = *(uint32_t*)param;
2362
2363                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2364
2365                 if (src_sel >= DCAM_PATH_FROM_NONE) {
2366                         rtn = DCAM_RTN_PATH_SRC_ERR;
2367                 } else {
2368                         path->src_sel = src_sel;
2369                         path->valid_param.src_sel = 1;
2370
2371                 }
2372                 break;
2373         }
2374
2375         case DCAM_PATH_FRAME_BASE_ID:
2376         {
2377                 uint32_t          base_id = *(uint32_t*)param, i;
2378
2379                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2380
2381                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_BASE_ID 0x%x \n", base_id);
2382                 s_p_dcam_mod->dcam_path2.frame_base_id = base_id;
2383                 break;
2384         }
2385
2386         case DCAM_PATH_DATA_ENDIAN:
2387         {
2388                 struct dcam_endian_sel *endian = (struct dcam_endian_sel*)param;
2389
2390                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2391
2392                 if (endian->y_endian >= DCAM_ENDIAN_MAX ||
2393                         endian->uv_endian >= DCAM_ENDIAN_MAX) {
2394                         rtn = DCAM_RTN_PATH_ENDIAN_ERR;
2395                 } else {
2396                         path->data_endian.y_endian  = endian->y_endian;
2397                         path->data_endian.uv_endian = endian->uv_endian;
2398                         path->valid_param.data_endian = 1;
2399                 }
2400                 break;
2401         }
2402
2403         case DCAM_PATH_ENABLE:
2404         {
2405                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2406
2407                 path->valide = *(uint32_t*)param;
2408
2409                 break;
2410         }
2411
2412         case DCAM_PATH_FRAME_TYPE:
2413         {
2414                 struct dcam_frame *frame  = &s_p_dcam_mod->dcam_path2.buf_queue.frame[0];
2415                 uint32_t          frm_type = *(uint32_t*)param, i;
2416
2417                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2418
2419                 DCAM_TRACE("DCAM: DCAM_PATH_FRAME_TYPE 0x%x \n", frm_type);
2420                 for (i = 0; i < DCAM_PATH_2_FRM_CNT_MAX; i++) {
2421                         (frame+i)->type = frm_type;
2422                 }
2423                 break;
2424         }
2425
2426         case DCAM_PATH_FRM_DECI:
2427         {
2428                 uint32_t deci_factor = *(uint32_t*)param;
2429
2430                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2431
2432                 if (deci_factor >= DCAM_FRM_DECI_FAC_MAX) {
2433                         rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2434                 } else {
2435                         path->frame_deci = deci_factor;
2436                         path->valid_param.frame_deci = 1;
2437                 }
2438                 break;
2439         }
2440
2441         case DCAM_PATH_SHRINK:
2442         {
2443                 uint32_t shrink = *(uint32_t*)param;
2444
2445                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2446
2447                 if (shrink == 1) {
2448                         path->shrink = 1;
2449                 } else {
2450                         path->shrink = 0;
2451                 }
2452                 path->valid_param.shrink = 1;
2453                 break;
2454         }
2455
2456         case DCAM_PATH_ROT_MODE:
2457         {
2458                 uint32_t rot_mode = *(uint32_t*)param;
2459                 DCAM_CHECK_PARAM_ZERO_POINTER(param);
2460                 if (rot_mode >= DCAM_PATH_FRAME_ROT_MAX) {
2461                         rtn = DCAM_RTN_PATH_FRM_DECI_ERR;
2462                 }else{
2463                         path->rot_mode = rot_mode;
2464                         path->valid_param.rot_mode = 1;
2465                         printk("zcf dcam_path2_cfg rot:\n",path->rot_mode);
2466                 }
2467                 break;
2468         }
2469         
2470         default:
2471                 break;
2472         }
2473
2474         return -rtn;
2475 }
2476
2477 int32_t    dcam_get_resizer(uint32_t wait_opt)
2478 {
2479         int32_t                 rtn = 0;
2480
2481         printk("resizer_get:%d\n",current->pid);
2482
2483         
2484         if( 0 == wait_opt) {
2485                 rtn = mutex_trylock(&dcam_sem) ? 0 : 1;
2486                 return rtn;
2487         } else if (DCAM_WAIT_FOREVER == wait_opt){
2488                 mutex_lock(&dcam_sem);
2489                 return rtn;
2490         } else {
2491                 return 0;//mutex_timeout(&dcam_sem, wait_opt);
2492         }
2493 }
2494
2495 int32_t    dcam_rel_resizer(void)
2496 {
2497         printk("resizer_put:%d\n",current->pid);
2498         mutex_unlock(&dcam_sem);
2499         return 0;
2500 }
2501
2502 int32_t    dcam_resize_start(void)
2503 {
2504         atomic_inc(&s_resize_flag);
2505         mutex_lock(&dcam_scale_sema);
2506         return 0;
2507 }
2508
2509 int32_t    dcam_resize_end(void)
2510 {
2511         unsigned long flag;
2512
2513         atomic_dec(&s_resize_flag);
2514         mutex_unlock(&dcam_scale_sema);
2515
2516         spin_lock_irqsave(&dcam_mod_lock, flag);
2517         if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
2518                 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2519                 return 0;
2520         }
2521
2522         if (s_p_dcam_mod) {
2523                 if (s_p_dcam_mod->wait_resize_done) {
2524                         up(&s_p_dcam_mod->resize_done_sema);
2525                         s_p_dcam_mod->wait_resize_done = 0;
2526                 }
2527         }
2528         spin_unlock_irqrestore(&dcam_mod_lock, flag);
2529         return 0;
2530 }
2531
2532 int32_t    dcam_rotation_start(void)
2533 {
2534         atomic_inc(&s_rotation_flag);
2535         mutex_lock(&dcam_rot_sema);
2536         return 0;
2537 }
2538
2539 int32_t    dcam_rotation_end(void)
2540 {
2541         unsigned long flag;
2542
2543         atomic_dec(&s_rotation_flag);
2544         mutex_unlock(&dcam_rot_sema);
2545
2546         spin_lock_irqsave(&dcam_mod_lock, flag);
2547         if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
2548                 spin_unlock_irqrestore(&dcam_mod_lock, flag);
2549                 return 0;
2550         }
2551
2552         if (s_p_dcam_mod) {
2553                 if (s_p_dcam_mod->wait_rotation_done) {
2554                         up(&s_p_dcam_mod->rotation_done_sema);
2555                         s_p_dcam_mod->wait_rotation_done = 0;
2556                 }
2557         }
2558         spin_unlock_irqrestore(&dcam_mod_lock, flag);
2559         return 0;
2560 }
2561
2562 void dcam_int_en(void)
2563 {
2564         if (atomic_read(&s_dcam_users) == 1) {
2565                 enable_irq(DCAM_IRQ);
2566         }
2567 }
2568
2569 void dcam_int_dis(void)
2570 {
2571         if (atomic_read(&s_dcam_users) == 1) {
2572                 disable_irq(DCAM_IRQ);
2573         }
2574 }
2575
2576 int32_t dcam_frame_is_locked(struct dcam_frame *frame)
2577 {
2578         uint32_t                rtn = 0;
2579         unsigned long           flags;
2580
2581         /*To disable irq*/
2582         local_irq_save(flags);
2583         if (frame)
2584                 rtn = frame->lock == DCAM_FRM_LOCK_WRITE ? 1 : 0;
2585         local_irq_restore(flags);
2586         /*To enable irq*/
2587
2588         return -rtn;
2589 }
2590
2591 int32_t dcam_frame_lock(struct dcam_frame *frame)
2592 {
2593         uint32_t                rtn = 0;
2594         unsigned long           flags;
2595
2596         DCAM_CHECK_ZERO(s_p_dcam_mod);
2597
2598         DCAM_TRACE("DCAM: lock %d \n", (uint32_t)(0xF&frame->fid));
2599
2600         /*To disable irq*/
2601         local_irq_save(flags);
2602         if (likely(frame))
2603                 frame->lock = DCAM_FRM_LOCK_WRITE;
2604         else
2605                 rtn = DCAM_RTN_PARA_ERR;
2606         local_irq_restore(flags);
2607         /*To enable irq*/
2608
2609         return -rtn;
2610 }
2611
2612 int32_t dcam_frame_unlock(struct dcam_frame *frame)
2613 {
2614         uint32_t                rtn = 0;
2615         unsigned long           flags;
2616
2617         DCAM_CHECK_ZERO(s_p_dcam_mod);
2618
2619         DCAM_TRACE("DCAM: unlock %d \n", (uint32_t)(0xF&frame->fid));
2620
2621         /*To disable irq*/
2622         local_irq_save(flags);
2623         if (likely(frame))
2624                 frame->lock = DCAM_FRM_UNLOCK;
2625         else
2626                 rtn = DCAM_RTN_PARA_ERR;
2627         local_irq_restore(flags);
2628         /*To enable irq*/
2629
2630         return -rtn;
2631 }
2632
2633 int32_t    dcam_read_registers(uint32_t* reg_buf, uint32_t *buf_len)
2634 {
2635         uint32_t                *reg_addr = (uint32_t*)DCAM_BASE;
2636
2637         if (NULL == reg_buf || NULL == buf_len || 0 != (*buf_len % 4)) {
2638                 return -1;
2639         }
2640
2641         while (buf_len != 0 && (uint32_t)reg_addr < DCAM_END) {
2642                 *reg_buf++ = REG_RD(reg_addr);
2643                 reg_addr++;
2644                 *buf_len -= 4;
2645         }
2646
2647         *buf_len = (uint32_t)reg_addr - DCAM_BASE;
2648         return 0;
2649 }
2650
2651 int32_t    dcam_get_path_id(struct dcam_get_path_id *path_id, uint32_t *channel_id)
2652 {
2653         int                      ret = DCAM_RTN_SUCCESS;
2654
2655         if (NULL == path_id || NULL == channel_id) {
2656                 return -1;
2657         }
2658
2659         printk("DCAM: fourcc 0x%x, input w %d, h %d output w %d, h %d input_trim %d %d %d %d shrink %d need_isp %d id:%d\n", path_id->fourcc,
2660                 path_id->input_size.w, path_id->input_size.h,
2661                 path_id->output_size.w, path_id->output_size.h,
2662                 path_id->input_trim.x, path_id->input_trim.y, path_id->input_trim.w, path_id->input_trim.h,
2663                 path_id->need_shrink, path_id->need_isp, path_id->camera_id);
2664
2665         if (path_id->need_isp_tool) {
2666                 *channel_id = DCAM_PATH0;
2667         } else if (V4L2_PIX_FMT_GREY == path_id->fourcc && !path_id->is_path_work[DCAM_PATH0]) {
2668                 *channel_id = DCAM_PATH0;
2669         } else if (V4L2_PIX_FMT_JPEG == path_id->fourcc && !path_id->is_path_work[DCAM_PATH0]) {
2670                 *channel_id = DCAM_PATH0;
2671         } else if (path_id->output_size.w <= DCAM_PATH1_LINE_BUF_LENGTH  && !path_id->is_path_work[DCAM_PATH1]) {
2672                 *channel_id = DCAM_PATH1;
2673 #ifdef VERSION3D
2674         } else if (!path_id->need_shrink && path_id->need_isp && !path_id->is_path_work[DCAM_PATH0]
2675                                 && path_id->output_size.w == path_id->input_trim.w && path_id->output_size.h == path_id->input_trim.h) {
2676                 *channel_id = DCAM_PATH0;
2677                 if (1 == path_id->camera_id) {
2678                         *channel_id = DCAM_PATH2;
2679                 }
2680 #endif
2681         } else if (path_id->output_size.w <= DCAM_PATH2_LINE_BUF_LENGTH  && !path_id->is_path_work[DCAM_PATH2]) {
2682                 *channel_id = DCAM_PATH2;
2683         } else {
2684                 *channel_id = DCAM_PATH0;
2685         }
2686         printk("DCAM: path id %d \n", *channel_id);
2687
2688         return ret;
2689 }
2690
2691 int32_t    dcam_get_path_capability(struct dcam_path_capability *capacity)
2692 {
2693         int                      ret = DCAM_RTN_SUCCESS;
2694
2695         if (NULL == capacity) {
2696                 return -1;
2697         }
2698
2699         capacity->count = 3;
2700         capacity->path_info[DCAM_PATH0].line_buf = 0;
2701 #ifdef VERSION3D
2702         capacity->path_info[DCAM_PATH0].support_yuv = 1;
2703 #else
2704         capacity->path_info[DCAM_PATH0].support_yuv = 0;
2705 #endif
2706         capacity->path_info[DCAM_PATH0].support_raw = 1;
2707         capacity->path_info[DCAM_PATH0].support_jpeg = 1;
2708         capacity->path_info[DCAM_PATH0].support_scaling = 0;
2709         capacity->path_info[DCAM_PATH0].support_trim = 0;
2710         capacity->path_info[DCAM_PATH0].is_scaleing_path = 0;
2711
2712         capacity->path_info[DCAM_PATH1].line_buf = DCAM_PATH1_LINE_BUF_LENGTH;
2713         capacity->path_info[DCAM_PATH1].support_yuv = 1;
2714         capacity->path_info[DCAM_PATH1].support_raw = 0;
2715         capacity->path_info[DCAM_PATH1].support_jpeg = 0;
2716         capacity->path_info[DCAM_PATH1].support_scaling = 1;
2717         capacity->path_info[DCAM_PATH1].support_trim = 1;
2718         capacity->path_info[DCAM_PATH1].is_scaleing_path = 0;
2719
2720         capacity->path_info[DCAM_PATH2].line_buf = DCAM_PATH2_LINE_BUF_LENGTH;
2721         capacity->path_info[DCAM_PATH2].support_yuv = 1;
2722         capacity->path_info[DCAM_PATH2].support_raw = 0;
2723         capacity->path_info[DCAM_PATH2].support_jpeg = 0;
2724         capacity->path_info[DCAM_PATH2].support_scaling = 1;
2725         capacity->path_info[DCAM_PATH2].support_trim = 1;
2726         capacity->path_info[DCAM_PATH2].is_scaleing_path = 1;
2727
2728         return ret;
2729 }
2730
2731
2732 LOCAL irqreturn_t _dcam_isr_root(int irq, void *dev_id)
2733 {
2734         uint32_t                irq_line, status;
2735         unsigned long           flag;
2736         int32_t                 i;
2737
2738         DCAM_TRACE("DCAM: ISR 0x%x \n", REG_RD(DCAM_INT_STS));
2739         status = REG_RD(DCAM_INT_STS) & DCAM_IRQ_LINE_MASK;
2740         if (unlikely(0 == status)) {
2741                 return IRQ_NONE;
2742         }
2743
2744         irq_line = status;
2745         if (unlikely(DCAM_IRQ_ERR_MASK & status)) {
2746                 if (_dcam_err_pre_proc()) {
2747                         return IRQ_NONE;
2748                 }
2749         }
2750
2751         spin_lock_irqsave(&dcam_lock,flag);
2752
2753         //for (i = DCAM_IRQ_NUMBER - 1; i >= 0; i--) {
2754         for (i = 0; i < DCAM_IRQ_NUMBER; i++) {
2755                 if (irq_line & (1 << (uint32_t)i)) {
2756                         if (isr_list[i]) {
2757                                 isr_list[i]();
2758                         }
2759                 }
2760                 irq_line &= ~(uint32_t)(1 << (uint32_t)i); //clear the interrupt flag
2761                 if(!irq_line) //no interrupt source left
2762                         break;
2763         }
2764
2765         REG_WR(DCAM_INT_CLR, status);
2766         DCAM_TRACE("DCAM: status 0x%x, ISR 0x%x \n", status, REG_RD(DCAM_INT_STS));
2767
2768         spin_unlock_irqrestore(&dcam_lock, flag);
2769
2770         return IRQ_HANDLED;
2771 }
2772
2773 LOCAL void _dcam_path0_set(void)
2774 {
2775         uint32_t                reg_val = 0;
2776         struct dcam_path_desc   *path = NULL;
2777
2778         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2779         path = &s_p_dcam_mod->dcam_path0;
2780         if (path->valid_param.input_size) {
2781                 reg_val = path->input_size.w | (path->input_size.h << 16);
2782                 REG_WR(DCAM_PATH0_SRC_SIZE, reg_val);
2783         }
2784
2785         if (path->valid_param.input_rect) {
2786                 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2787                 REG_WR(DCAM_PATH0_TRIM_START, reg_val);
2788                 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2789                 REG_WR(DCAM_PATH0_TRIM_SIZE, reg_val);
2790                 DCAM_TRACE("DCAM: path0 set: rect {%d %d %d %d} \n",
2791                         path->input_rect.x,
2792                         path->input_rect.y,
2793                         path->input_rect.w,
2794                         path->input_rect.h);
2795         }
2796
2797         if (path->valid_param.src_sel) {
2798                 REG_MWR(DCAM_CFG, BIT_10 , path->src_sel << 10);
2799                 DCAM_TRACE("DCAM: path 0: src_sel=0x%x \n", path->src_sel);
2800         }
2801
2802         if (path->valid_param.frame_deci) {
2803                 REG_MWR(DCAM_PATH0_CFG, BIT_1 | BIT_0, path->frame_deci << 0);
2804         }
2805
2806         if (path->valid_param.output_format) {
2807                 enum dcam_output_mode format = path->output_format;
2808                 REG_MWR(DCAM_PATH0_CFG, BIT_2 | BIT_3, format << 2);
2809                 DCAM_TRACE("DCAM: path 0: output_format=0x%x \n", format);
2810         }
2811
2812         if (path->valid_param.data_endian) {
2813                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_5 | BIT_4, path->data_endian.y_endian << 4, DCAM_ENDIAN_REG);
2814                 if (DCAM_ENDIAN_BIG == path->data_endian.y_endian) {
2815                         if (DCAM_ENDIAN_LITTLE == path->data_endian.uv_endian ||
2816                                 DCAM_ENDIAN_HALFBIG == path->data_endian.uv_endian) {
2817                                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 1 << 20, DCAM_ENDIAN_REG);
2818                         } else {
2819                                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 0, DCAM_ENDIAN_REG);
2820                         }
2821                 } else if (DCAM_ENDIAN_LITTLE == path->data_endian.y_endian) {
2822                         if (DCAM_ENDIAN_BIG == path->data_endian.uv_endian ||
2823                                 DCAM_ENDIAN_HALFBIG == path->data_endian.uv_endian) {
2824                                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 1 << 20, DCAM_ENDIAN_REG);
2825                         } else {
2826                                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_20, 0, DCAM_ENDIAN_REG);
2827                         }
2828                 } else {
2829                         printk("DCAM DRV: endian, do nothing u %d, v %d \n",
2830                                 path->data_endian.y_endian,
2831                                 path->data_endian.uv_endian);
2832                 }
2833
2834                 if(path->valid_param.rot_mode) {
2835                         path->valid_param.rot_mode = 0;
2836                         printk("zcf dcam_path2_set  rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH2_CFG));
2837                         REG_MWR(DCAM_PATH2_CFG, BIT_10 | BIT_9, path->rot_mode << 9);
2838                         printk("zcf dcam_path2_set  rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH2_CFG));               
2839                 }
2840
2841                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2842                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2843                 DCAM_TRACE("DCAM DRV: path 0: data_endian y=0x%x, uv=0x%x \n",
2844                         path->data_endian.y_endian, path->data_endian.uv_endian);
2845         }
2846
2847 }
2848 LOCAL void _dcam_path1_set(struct dcam_path_desc *path)
2849 {
2850         uint32_t                reg_val = 0;
2851
2852         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2853         DCAM_CHECK_ZERO_VOID(path);
2854
2855         if (path->valid_param.input_size) {
2856                 reg_val = path->input_size.w | (path->input_size.h << 16);
2857                 REG_WR(DCAM_PATH1_SRC_SIZE, reg_val);
2858                 DCAM_TRACE("DCAM: path1 set: src {%d %d} \n",path->input_size.w, path->input_size.h);
2859         }
2860
2861         if (path->valid_param.input_rect) {
2862                 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2863                 REG_WR(DCAM_PATH1_TRIM_START, reg_val);
2864                 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2865                 REG_WR(DCAM_PATH1_TRIM_SIZE, reg_val);
2866                 DCAM_TRACE("DCAM: path1 set: rect {%d %d %d %d} \n",
2867                         path->input_rect.x,
2868                         path->input_rect.y,
2869                         path->input_rect.w,
2870                         path->input_rect.h);
2871         }
2872
2873         if (path->valid_param.output_size) {
2874                 reg_val = path->output_size.w | (path->output_size.h << 16);
2875                 REG_WR(DCAM_PATH1_DST_SIZE, reg_val);
2876                 DCAM_TRACE("DCAM: path1 set: dst {%d %d} \n",path->output_size.w, path->output_size.h);
2877         }
2878
2879         if (path->valid_param.output_format) {
2880                 enum dcam_fmt format = path->output_format;
2881                 if (DCAM_YUV422 == format) {
2882                         REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 0 << 6);
2883                 } else if (DCAM_YUV420 == format) {
2884                         REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 1 << 6);
2885                 } else if (DCAM_YUV420_3FRAME == format) {
2886                         REG_MWR(DCAM_PATH1_CFG, BIT_7 | BIT_6, 3 << 6);
2887                 } else {
2888                         DCAM_TRACE("DCAM: invalid path 1 output format %d \n", format);
2889                 }
2890                 DCAM_TRACE("DCAM: path 1: output_format=0x%x \n", format);
2891         }
2892
2893         if (path->valid_param.src_sel) {
2894                 REG_MWR(DCAM_CFG, BIT_12 | BIT_11, path->src_sel << 11);
2895                 DCAM_TRACE("DCAM: path 1: src_sel=0x%x \n", path->src_sel);
2896         }
2897
2898         if (path->valid_param.data_endian) {
2899                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_7 | BIT_6, path->data_endian.y_endian << 6, DCAM_ENDIAN_REG);
2900                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_9 | BIT_8, path->data_endian.uv_endian << 8, DCAM_ENDIAN_REG);
2901                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
2902                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
2903                 DCAM_TRACE("DCAM: path 1: data_endian y=0x%x, uv=0x%x \n",
2904                         path->data_endian.y_endian, path->data_endian.uv_endian);
2905         }
2906
2907         if (path->valid_param.frame_deci) {
2908                 REG_MWR(DCAM_PATH0_CFG, BIT_24 | BIT_23, path->frame_deci << 23);
2909                 DCAM_TRACE("DCAM: path 1: frame_deci=0x%x \n", path->frame_deci);
2910         }
2911
2912         if (path->valid_param.scale_tap) {
2913                 path->valid_param.scale_tap = 0;
2914                 REG_MWR(DCAM_PATH1_CFG, BIT_19 | BIT_18 | BIT_17 | BIT_16, (path->scale_tap.y_tap & 0x0F) << 16);
2915                 REG_MWR(DCAM_PATH1_CFG, BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11, (path->scale_tap.uv_tap & 0x1F) << 11);
2916                 DCAM_TRACE("DCAM: path 1: scale_tap, y=0x%x, uv=0x%x \n", path->scale_tap.y_tap, path->scale_tap.uv_tap);
2917         }
2918
2919         if (path->valid_param.v_deci) {
2920                 path->valid_param.v_deci = 0;
2921                 REG_MWR(DCAM_PATH1_CFG, BIT_2, path->deci_val.deci_x_en << 2);
2922                 REG_MWR(DCAM_PATH1_CFG, BIT_1 | BIT_0, path->deci_val.deci_x);
2923
2924                 REG_MWR(DCAM_PATH1_CFG, BIT_5, path->deci_val.deci_y_en << 5);
2925                 REG_MWR(DCAM_PATH1_CFG, BIT_4 | BIT_3, path->deci_val.deci_y << 3);
2926                 DCAM_TRACE("DCAM: path 1: deci, x_en=%d, x=%d, y_en=%d, y=%d \n",
2927                         path->deci_val.deci_x_en, path->deci_val.deci_x, path->deci_val.deci_y_en, path->deci_val.deci_y);
2928         }
2929
2930         if(path->valid_param.rot_mode){
2931                 path->valid_param.rot_mode = 0;
2932                 printk("zcf dcam_path1_set 1 rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH1_CFG));
2933                 REG_MWR(DCAM_PATH1_CFG, BIT_10 | BIT_9, path->rot_mode << 9);
2934                 printk("zcf dcam_path1_set 1 rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH1_CFG));
2935         }
2936
2937         if (path->valid_param.shrink) {
2938                 path->valid_param.shrink = 0;
2939                 REG_MWR(DCAM_PATH1_CFG, BIT_25 | BIT_26, path->shrink << 25);
2940                 printk("DCAM: path 1: shrink, %d \n", path->shrink);
2941         }
2942
2943 }
2944
2945 LOCAL void _dcam_path2_set(void)
2946 {
2947         struct dcam_path_desc   *path = NULL;
2948         uint32_t                reg_val = 0;
2949
2950         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
2951         path = &s_p_dcam_mod->dcam_path2;
2952         if (path->valid_param.input_size) {
2953                 reg_val = path->input_size.w | (path->input_size.h << 16);
2954                 REG_WR(DCAM_PATH2_SRC_SIZE, reg_val);
2955                 DCAM_TRACE("DCAM: path2 set: src {%d %d} \n",path->input_size.w, path->input_size.h);
2956         }
2957
2958         if (path->valid_param.input_rect) {
2959                 reg_val = path->input_rect.x | (path->input_rect.y << 16);
2960                 REG_WR(DCAM_PATH2_TRIM_START, reg_val);
2961                 reg_val = path->input_rect.w | (path->input_rect.h << 16);
2962                 REG_WR(DCAM_PATH2_TRIM_SIZE, reg_val);
2963                 DCAM_TRACE("DCAM: path2 set: rect {%d %d %d %d} \n",
2964                         path->input_rect.x,
2965                         path->input_rect.y,
2966                         path->input_rect.w,
2967                         path->input_rect.h);
2968         }
2969
2970         if(path->valid_param.output_size){
2971                 reg_val = path->output_size.w | (path->output_size.h << 16);
2972                 REG_WR(DCAM_PATH2_DST_SIZE, reg_val);
2973                 DCAM_TRACE("DCAM: path2 set: dst {%d %d} \n",path->output_size.w, path->output_size.h);
2974         }
2975
2976         if (path->valid_param.output_format) {
2977                 enum dcam_fmt format = path->output_format;
2978
2979                 // REG_MWR(DCAM_PATH2_CFG, BIT_8, 0 << 8); // aiden todo
2980
2981                 if (DCAM_YUV422 == format) {
2982                         REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 0 << 6);
2983                 } else if (DCAM_YUV420 == format) {
2984                         REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 1 << 6);
2985                 } else if (DCAM_YUV420_3FRAME == format) {
2986                         REG_MWR(DCAM_PATH2_CFG, BIT_7 | BIT_6, 3 << 6);
2987                 } else {
2988                         DCAM_TRACE("DCAM: invalid path 2 output format %d \n", format);
2989                 }
2990                 DCAM_TRACE("DCAM: path 2: output_format=0x%x \n", format);
2991         }
2992
2993         if (path->valid_param.src_sel) {
2994                 REG_MWR(DCAM_CFG, BIT_14 | BIT_13, path->src_sel << 13);
2995         }
2996
2997         if (path->valid_param.data_endian) {
2998                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_11 | BIT_10, path->data_endian.y_endian << 10,DCAM_ENDIAN_REG );
2999                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_13 | BIT_12, path->data_endian.uv_endian << 12, DCAM_ENDIAN_REG);
3000                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_18, BIT_18, DCAM_ENDIAN_REG); // axi write
3001                 dcam_glb_reg_mwr(DCAM_ENDIAN_SEL, BIT_19, BIT_19, DCAM_ENDIAN_REG); // axi read
3002                 DCAM_TRACE("DCAM: path 2: data_endian y=0x%x, uv=0x%x \n",
3003                         path->data_endian.y_endian, path->data_endian.uv_endian);
3004         }
3005
3006         if (path->valid_param.frame_deci) {
3007                 REG_MWR(DCAM_PATH0_CFG, BIT_24 | BIT_23, path->frame_deci << 23);
3008                 DCAM_TRACE("DCAM: path 2: frame_deci=0x%x \n", path->frame_deci);
3009         }
3010
3011         if (path->valid_param.scale_tap) {
3012                 path->valid_param.scale_tap = 0;
3013                 REG_MWR(DCAM_PATH2_CFG, BIT_19 | BIT_18 | BIT_17 | BIT_16, (path->scale_tap.y_tap & 0x0F) << 16);
3014                 REG_MWR(DCAM_PATH2_CFG, BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11, (path->scale_tap.uv_tap & 0x1F) << 11);
3015                 DCAM_TRACE("DCAM: path 2: scale_tap, y=0x%x, uv=0x%x \n",
3016                         path->scale_tap.y_tap, path->scale_tap.uv_tap);
3017         }
3018
3019         if (path->valid_param.v_deci) {
3020                 path->valid_param.v_deci = 0;
3021                 REG_MWR(DCAM_PATH2_CFG, BIT_2, path->deci_val.deci_x_en << 2);
3022                 REG_MWR(DCAM_PATH2_CFG, BIT_1 | BIT_0, path->deci_val.deci_x);
3023
3024                 REG_MWR(DCAM_PATH2_CFG, BIT_5, path->deci_val.deci_y_en << 5);
3025                 REG_MWR(DCAM_PATH2_CFG, BIT_4 | BIT_3, path->deci_val.deci_y << 3);
3026                 DCAM_TRACE("DCAM: path 2: deci, x_en=%d, x=%d, y_en=%d, y=%d \n",
3027                         path->deci_val.deci_x_en, path->deci_val.deci_x, path->deci_val.deci_y_en, path->deci_val.deci_y);
3028         }
3029
3030         if (path->valid_param.rot_mode){
3031                 path->valid_param.rot_mode = 0;
3032                 printk("zcf dcam_path2_set  rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH2_CFG));
3033                 REG_MWR(DCAM_PATH2_CFG, BIT_10 | BIT_9, path->rot_mode << 9);
3034                 printk("zcf dcam_path2_set  rot_mod :%d reg:%x\n",path->rot_mode,REG_RD(DCAM_PATH2_CFG));
3035         }
3036
3037         if (path->valid_param.shrink) {
3038                 path->valid_param.shrink = 0;
3039                 REG_MWR(DCAM_PATH2_CFG, BIT_25 | BIT_26, path->shrink << 25);
3040                 printk("DCAM: path 2: shrink, %d \n", path->shrink);
3041         }
3042
3043 }
3044
3045 LOCAL void _dcam_buf_queue_init(struct dcam_buf_queue *queue)
3046 {
3047         if (DCAM_ADDR_INVALID(queue)) {
3048                 printk("DCAM: invalid heap 0x%x \n", (uint32_t)queue);
3049                 return;
3050         }
3051
3052         memset((void*)queue, 0, sizeof(struct dcam_buf_queue));
3053         queue->write = &queue->frame[0];
3054         queue->read  = &queue->frame[0];
3055         spin_lock_init(&queue->lock);
3056         return;
3057 }
3058
3059 LOCAL int32_t _dcam_buf_queue_write(struct dcam_buf_queue *queue, struct dcam_frame *frame)
3060 {
3061         int                      ret = DCAM_RTN_SUCCESS;
3062         struct dcam_frame         *ori_frame;
3063         unsigned long            flag;
3064
3065         if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
3066                 printk("DCAM: enq, invalid param 0x%x, 0x%x \n",
3067                         (uint32_t)queue,
3068                         (uint32_t)frame);
3069                 return -EINVAL;
3070         }
3071
3072         spin_lock_irqsave(&queue->lock, flag);
3073         ori_frame = queue->write;
3074         DCAM_TRACE("DCAM: _dcam_buf_queue_write \n");
3075         *queue->write++ = *frame;
3076         if (queue->write > &queue->frame[DCAM_FRM_CNT_MAX-1]) {
3077                 queue->write = &queue->frame[0];
3078         }
3079
3080         if (queue->write == queue->read) {
3081                 queue->write = ori_frame;
3082                 printk("DCAM: warning, queue is full, cannot write 0x%lx \n", frame->yaddr);
3083         }
3084         spin_unlock_irqrestore(&queue->lock, flag);
3085         DCAM_TRACE("DCAM: _dcam_buf_queue_write type %d \n", frame->type);
3086         return ret;
3087 }
3088
3089 LOCAL int32_t _dcam_buf_queue_read(struct dcam_buf_queue *queue, struct dcam_frame *frame)
3090 {
3091         int                      ret = DCAM_RTN_SUCCESS;
3092         unsigned long            flag;
3093
3094         if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
3095                 printk("DCAM: deq, invalid param 0x%x, 0x%x \n",
3096                         (uint32_t)queue,
3097                         (uint32_t)frame);
3098                 return -EINVAL;
3099         }
3100
3101         DCAM_TRACE("DCAM: _dcam_buf_queue_read \n");
3102
3103         spin_lock_irqsave(&queue->lock, flag);
3104         if (queue->read != queue->write) {
3105                 *frame = *queue->read++;
3106                 if (queue->read > &queue->frame[DCAM_FRM_CNT_MAX-1]) {
3107                         queue->read = &queue->frame[0];
3108                 }
3109         } else {
3110                 ret = EAGAIN;
3111         }
3112         spin_unlock_irqrestore(&queue->lock, flag);
3113         DCAM_TRACE("DCAM: _dcam_buf_queue_read type %d \n", frame->type);
3114         return ret;
3115 }
3116
3117 LOCAL void _dcam_frm_queue_clear(struct dcam_frm_queue *queue)
3118 {
3119         if (DCAM_ADDR_INVALID(queue)) {
3120                 printk("DCAM: invalid heap 0x%x \n", (uint32_t)queue);
3121                 return;
3122         }
3123
3124         memset((void*)queue, 0, sizeof(struct dcam_frm_queue));
3125         return;
3126 }
3127
3128 LOCAL int32_t _dcam_frame_enqueue(struct dcam_frm_queue *queue, struct dcam_frame *frame)
3129 {
3130         if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
3131                 printk("DCAM: enq, invalid param 0x%x, 0x%x \n",
3132                         (uint32_t)queue,
3133                         (uint32_t)frame);
3134                 return -1;
3135         }
3136         if (queue->valid_cnt >= DCAM_FRM_QUEUE_LENGTH) {
3137                 printk("DCAM: q over flow \n");
3138                 return -1;
3139         }
3140         //queue->frm_array[queue->valid_cnt] = frame;
3141         memcpy(&queue->frm_array[queue->valid_cnt], frame, sizeof(struct dcam_frame));
3142         queue->valid_cnt ++;
3143         DCAM_TRACE("DCAM: en queue, %d, %d, 0x%x, 0x%x \n",
3144                 (0xF & frame->fid),
3145                 queue->valid_cnt,
3146                 frame->yaddr,
3147                 frame->uaddr);
3148         return 0;
3149 }
3150
3151 LOCAL int32_t _dcam_frame_dequeue(struct dcam_frm_queue *queue, struct dcam_frame *frame)
3152 {
3153         uint32_t                i = 0;
3154
3155         if (DCAM_ADDR_INVALID(queue) || DCAM_ADDR_INVALID(frame)) {
3156                 printk("DCAM: deq, invalid param 0x%x, 0x%x \n",
3157                         (uint32_t)queue,
3158                         (uint32_t)frame);
3159                 return -1;
3160         }
3161         if (queue->valid_cnt == 0) {
3162                 printk("DCAM: q under flow \n");
3163                 return -1;
3164         }
3165
3166         //*frame  = queue->frm_array[0];
3167         memcpy(frame, &queue->frm_array[0], sizeof(struct dcam_frame));
3168         queue->valid_cnt--;
3169         for (i = 0; i < queue->valid_cnt; i++) {
3170                 //queue->frm_array[i] = queue->frm_array[i+1];
3171                 memcpy(&queue->frm_array[i], &queue->frm_array[i+1], sizeof(struct dcam_frame));
3172         }
3173         DCAM_TRACE("DCAM: de queue, %d, %d \n",
3174                 (0xF & (frame)->fid),
3175                 queue->valid_cnt);
3176         return 0;
3177 }
3178
3179 LOCAL void _dcam_frm_clear(enum dcam_path_index path_index)
3180 {
3181         uint32_t                i = 0;
3182
3183         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3184
3185         if (DCAM_PATH_IDX_0 & path_index) {
3186                 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path0.frame_queue);
3187                 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path0.buf_queue);
3188         }
3189
3190         if (DCAM_PATH_IDX_1 & path_index) {
3191                 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path1.frame_queue);
3192                 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path1.buf_queue);
3193         }
3194
3195         if (DCAM_PATH_IDX_2 & path_index) {
3196                 _dcam_frm_queue_clear(&s_p_dcam_mod->dcam_path2.frame_queue);
3197                 _dcam_buf_queue_init(&s_p_dcam_mod->dcam_path2.buf_queue);
3198         }
3199
3200         return;
3201 }
3202
3203 LOCAL void _dcam_frm_pop(enum dcam_path_index path_index)
3204 {
3205         uint32_t                i = 0;
3206         struct dcam_frame       *frame = NULL;
3207         uint32_t                *frame_count;
3208
3209         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3210
3211         if (DCAM_PATH_IDX_0 & path_index) {
3212                 frame = &s_p_dcam_mod->path0_frame[0];
3213                 frame_count = &s_p_dcam_mod->dcam_path0.output_frame_count;
3214         }
3215         if (DCAM_PATH_IDX_1 & path_index) {
3216                 frame = &s_p_dcam_mod->path1_frame[0];
3217                 frame_count = &s_p_dcam_mod->dcam_path1.output_frame_count;
3218         }
3219         if (DCAM_PATH_IDX_2 & path_index) {
3220                 frame = &s_p_dcam_mod->path2_frame[0];
3221                 frame_count = &s_p_dcam_mod->dcam_path2.output_frame_count;
3222         }
3223         printk("DCAM: frame pop index %d frame_count %d addr 0x%x \n", path_index, *frame_count, frame->yaddr);
3224         if (0 == *frame_count) {
3225                 return;
3226         }
3227
3228         for (i = 0; i < *frame_count - 1; i++) {
3229                 memcpy(frame+i, frame+i+1, sizeof(struct dcam_frame));
3230         }
3231         (*frame_count)--;
3232         //memset(frame+(*frame_count), 0, sizeof(struct dcam_frame));
3233         (frame+(*frame_count))->yaddr = 0;
3234         (frame+(*frame_count))->uaddr = 0;
3235         (frame+(*frame_count))->vaddr = 0;
3236
3237         if (0 == *frame_count) {
3238                 //_dcam_wait_for_quickstop(path_index);
3239         }
3240         DCAM_TRACE("DCAM: frame pop done \n");
3241         
3242         return;
3243 }
3244
3245
3246 LOCAL void _dcam_link_frm(uint32_t base_id)
3247 {
3248 /*      uint32_t                i = 0;
3249         struct dcam_frame       *path0_frame = NULL;
3250         struct dcam_frame       *path1_frame = NULL;
3251         struct dcam_frame       *path2_frame = NULL;
3252
3253         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3254
3255         path0_frame = &s_p_dcam_mod->path0_frame[0];
3256         path1_frame = &s_p_dcam_mod->path1_frame[0];
3257         path2_frame = &s_p_dcam_mod->path2_frame[0];
3258         for (i = 0; i < DCAM_PATH_0_FRM_CNT_MAX; i++) {
3259                 DCAM_CLEAR(path0_frame + i);
3260                 //(path0_frame+i)->next = path0_frame + (i + 1) % DCAM_PATH_0_FRM_CNT_MAX;
3261                 //(path0_frame+i)->prev = path0_frame + (i - 1 + DCAM_PATH_0_FRM_CNT_MAX) % DCAM_PATH_0_FRM_CNT_MAX;
3262                 (path0_frame+i)->fid  = base_id + i;
3263         }
3264
3265         for (i = 0; i < DCAM_PATH_1_FRM_CNT_MAX; i++) {
3266                 DCAM_CLEAR(path1_frame + i);
3267                 //(path1_frame+i)->next = path1_frame + (i + 1) % DCAM_PATH_1_FRM_CNT_MAX;
3268                 //(path1_frame+i)->prev = path1_frame + (i - 1 + DCAM_PATH_1_FRM_CNT_MAX) % DCAM_PATH_1_FRM_CNT_MAX;
3269                 (path1_frame+i)->fid  = base_id + i;
3270         }
3271
3272         for (i = 0; i < DCAM_PATH_2_FRM_CNT_MAX; i++) {
3273                 DCAM_CLEAR(path2_frame + i);
3274                 //(path2_frame+i)->next = path2_frame+(i + 1) % DCAM_PATH_2_FRM_CNT_MAX;
3275                 //(path2_frame+i)->prev = path2_frame+(i - 1 + DCAM_PATH_2_FRM_CNT_MAX) % DCAM_PATH_2_FRM_CNT_MAX;
3276                 (path2_frame+i)->fid  = base_id + i;
3277         }
3278
3279         //s_p_dcam_mod->dcam_path0.output_frame_head = path0_frame;
3280         //s_p_dcam_mod->dcam_path1.output_frame_head = path1_frame;
3281         //s_p_dcam_mod->dcam_path2.output_frame_head = path2_frame;
3282         //s_p_dcam_mod->dcam_path0.output_frame_cur = path0_frame;
3283         //s_p_dcam_mod->dcam_path1.output_frame_cur = path1_frame;
3284         //s_p_dcam_mod->dcam_path2.output_frame_cur = path2_frame;
3285 */
3286         return;
3287 }
3288
3289 LOCAL int32_t _dcam_path_set_next_frm(enum dcam_path_index path_index, uint32_t is_1st_frm)
3290 {
3291         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3292         struct dcam_frame       frame;
3293         struct dcam_frame       *reserved_frame = NULL;
3294         struct dcam_frame       *orig_frame = NULL;
3295         struct dcam_path_desc   *path = NULL;
3296         uint32_t                yuv_reg[3] = {0};
3297         uint32_t                path_max_frm_cnt;
3298         uint32_t                flag = 0;
3299         struct dcam_frm_queue   *p_heap = NULL;
3300         struct dcam_buf_queue   *p_buf_queue = NULL;
3301
3302         DCAM_CHECK_ZERO(s_p_dcam_mod);
3303
3304         if (DCAM_PATH_IDX_0 == path_index) {
3305                 //frame = &s_p_dcam_mod->path0_frame[0];
3306                 reserved_frame = &s_p_dcam_mod->path0_reserved_frame;
3307                 path = &s_p_dcam_mod->dcam_path0;
3308                 yuv_reg[0] = DCAM_FRM_ADDR0;
3309                 yuv_reg[1] = DCAM_FRM_ADDR12;
3310                 path_max_frm_cnt = DCAM_PATH_0_FRM_CNT_MAX;
3311                 p_heap = &s_p_dcam_mod->dcam_path0.frame_queue;
3312                 p_buf_queue = &s_p_dcam_mod->dcam_path0.buf_queue;
3313         } else if (DCAM_PATH_IDX_1 == path_index) {
3314                 //frame = &s_p_dcam_mod->path1_frame[0];
3315                 reserved_frame = &s_p_dcam_mod->path1_reserved_frame;
3316                 path = &s_p_dcam_mod->dcam_path1;
3317                 yuv_reg[0] = DCAM_FRM_ADDR1;
3318                 yuv_reg[1] = DCAM_FRM_ADDR2;
3319                 yuv_reg[2] = DCAM_FRM_ADDR3;
3320                 path_max_frm_cnt = DCAM_PATH_1_FRM_CNT_MAX;
3321                 p_heap = &s_p_dcam_mod->dcam_path1.frame_queue;
3322                 p_buf_queue = &s_p_dcam_mod->dcam_path1.buf_queue;
3323         } else /*if(DCAM_PATH_IDX_2 == path_index)*/ {
3324                 //frame = &s_p_dcam_mod->path2_frame[0];
3325                 reserved_frame = &s_p_dcam_mod->path2_reserved_frame;
3326                 path = &s_p_dcam_mod->dcam_path2;
3327                 yuv_reg[0] = DCAM_FRM_ADDR4;
3328                 yuv_reg[1] = DCAM_FRM_ADDR5;
3329                 yuv_reg[2] = DCAM_FRM_ADDR6;
3330                 path_max_frm_cnt = DCAM_PATH_2_FRM_CNT_MAX;
3331                 p_heap = &s_p_dcam_mod->dcam_path2.frame_queue;
3332                 p_buf_queue = &s_p_dcam_mod->dcam_path2.buf_queue;
3333         }
3334
3335         if (0 != _dcam_buf_queue_read(p_buf_queue, &frame)) {
3336                 DCAM_TRACE("DCAM: No freed frame id %d \n", frame.fid);
3337                 memcpy(&frame, reserved_frame, sizeof(struct dcam_frame));
3338         }
3339
3340         DCAM_TRACE("DCAM: next %d y 0x%x uv 0x%x \n", path->output_frame_count, frame.yaddr, frame.uaddr);
3341         REG_WR(yuv_reg[0], frame.yaddr);
3342         if (((DCAM_YUV400 > path->output_format) && (DCAM_PATH_IDX_0 != path_index)) ||
3343                         ((DCAM_OUTPUT_YUV420 == path->output_format) && (DCAM_PATH_IDX_0 == path_index))) {
3344                 REG_WR(yuv_reg[1], frame.uaddr);
3345                 if (DCAM_YUV420_3FRAME == path->output_format) {
3346                         REG_WR(yuv_reg[2], frame.vaddr);
3347                 }
3348         }
3349         dcam_frame_lock(&frame);
3350         if (0 == _dcam_frame_enqueue(p_heap, &frame)) {
3351         } else {
3352                 dcam_frame_unlock(&frame);
3353                 rtn = DCAM_RTN_PATH_FRAME_LOCKED;
3354         }
3355
3356         return -rtn;
3357 }
3358
3359 #if 0
3360 LOCAL int32_t _dcam_path_trim(enum dcam_path_index path_index)
3361 {
3362         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3363         struct dcam_path_desc   *path;
3364         uint32_t                cfg_reg, ctrl_bit;
3365
3366         DCAM_CHECK_ZERO(s_p_dcam_mod);
3367
3368         if (DCAM_PATH_IDX_1 == path_index) {
3369                 path = &s_p_dcam_mod->dcam_path1;
3370                 cfg_reg = DCAM_PATH1_CFG;
3371                 ctrl_bit = 8;
3372         } else if (DCAM_PATH_IDX_2 == path_index) {
3373                 path = &s_p_dcam_mod->dcam_path2;
3374                 cfg_reg = DCAM_PATH2_CFG;
3375                 ctrl_bit = 1;
3376         } else {
3377                 printk("DCAM: _dcam_path_trim invalid path_index=%d \n", path_index);
3378                 return -1;
3379         }
3380
3381         if (path->input_size.w != path->input_rect.w ||
3382                 path->input_size.h != path->input_rect.h) {
3383                 /*REG_OWR(cfg_reg, 1 << ctrl_bit);*/
3384         } else {
3385                 /*REG_MWR(cfg_reg, 1 << ctrl_bit, 0 << ctrl_bit);*/
3386         }
3387
3388         return rtn;
3389
3390 }
3391 #endif
3392
3393 LOCAL int32_t _dcam_path_scaler(enum dcam_path_index path_index)
3394 {
3395         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3396         struct dcam_path_desc   *path = NULL;
3397         uint32_t                cfg_reg = 0;
3398
3399         DCAM_CHECK_ZERO(s_p_dcam_mod);
3400         DCAM_CHECK_ZERO(s_dcam_sc_array);
3401
3402         if (DCAM_PATH_IDX_0 == path_index) {
3403                 path = &s_p_dcam_mod->dcam_path0;
3404                 cfg_reg = DCAM_PATH0_CFG;
3405         } else if (DCAM_PATH_IDX_1 == path_index) {
3406                 path = &s_p_dcam_mod->dcam_path1;
3407                 cfg_reg = DCAM_PATH1_CFG;
3408         } else if (DCAM_PATH_IDX_2 == path_index){
3409                 path = &s_p_dcam_mod->dcam_path2;
3410                 cfg_reg = DCAM_PATH2_CFG;
3411         }
3412
3413         DCAM_CHECK_ZERO(path);
3414         if (DCAM_RAWRGB == path->output_format ||
3415                 DCAM_JPEG == path->output_format) {
3416                 DCAM_TRACE("DCAM: _dcam_path_scaler out format is %d, no need scaler \n", path->output_format);
3417                 return DCAM_RTN_SUCCESS;
3418         }
3419
3420         rtn = _dcam_calc_sc_size(path_index);
3421         if (DCAM_RTN_SUCCESS != rtn) {
3422                 return rtn;
3423         }
3424
3425         if (path->sc_input_size.w == path->output_size.w &&
3426                 path->sc_input_size.h == path->output_size.h &&
3427                 DCAM_YUV422 == path->output_format) {
3428                 REG_MWR(cfg_reg, BIT_20, 1 << 20);// bypass scaler if the output size equals input size for YUV422 format
3429         } else {
3430                 REG_MWR(cfg_reg, BIT_20, 0 << 20);
3431                 if (s_dcam_sc_array->is_smooth_zoom
3432                         && DCAM_PATH_IDX_1 == path_index
3433                         && DCAM_ST_START == path->status) {
3434                         rtn = _dcam_calc_sc_coeff(path_index);
3435                 } else {
3436                         rtn = _dcam_set_sc_coeff(path_index);
3437                 }
3438         }
3439
3440         return rtn;
3441 }
3442
3443 LOCAL int32_t _dcam_path_check_deci(enum dcam_path_index path_index, uint32_t *is_deci)
3444 {
3445         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3446         struct dcam_path_desc   *path = NULL;
3447         uint32_t                                w_deci = 0;
3448         uint32_t                                h_deci = 0;
3449
3450         DCAM_CHECK_ZERO(s_p_dcam_mod);
3451
3452         if (DCAM_PATH_IDX_0 == path_index) {
3453                 path = &s_p_dcam_mod->dcam_path1;
3454         } else if (DCAM_PATH_IDX_1 == path_index) {
3455                 path = &s_p_dcam_mod->dcam_path1;
3456         } else if (DCAM_PATH_IDX_2 == path_index) {
3457                 path = &s_p_dcam_mod->dcam_path2;
3458         } else {
3459                 rtn = DCAM_RTN_PATH_SC_ERR;
3460                 goto dcam_path_err;
3461         }
3462
3463         if (path->input_rect.w > (path->output_size.w * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3464                 path->input_rect.h > (path->output_size.h * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3465                 path->input_rect.w * DCAM_SC_COEFF_UP_MAX < path->output_size.w ||
3466                 path->input_rect.h * DCAM_SC_COEFF_UP_MAX < path->output_size.h) {
3467                 rtn = DCAM_RTN_PATH_SC_ERR;
3468         } else {
3469                 if (path->input_rect.w > path->output_size.w * DCAM_SC_COEFF_DOWN_MAX)
3470                         w_deci = 1;
3471                 if (path->input_rect.h > path->output_size.h * DCAM_SC_COEFF_DOWN_MAX)
3472                         h_deci = 1;
3473
3474                 if(w_deci || h_deci)
3475                         *is_deci = 1;
3476                 else
3477                         *is_deci = 0;
3478         }
3479
3480 dcam_path_err:
3481         DCAM_TRACE("DCAM: _dcam_path_check_deci: path_index=%d, is_deci=%d, rtn=%d \n", path_index, *is_deci, rtn);
3482
3483         return rtn;
3484 }
3485
3486 LOCAL uint32_t _dcam_get_path_deci_factor(uint32_t src_size, uint32_t dst_size)
3487 {
3488         uint32_t                 factor = 0;
3489
3490         if (0 == src_size || 0 == dst_size) {
3491                 return factor;
3492         }
3493
3494         /* factor: 0 - 1/2, 1 - 1/4, 2 - 1/8, 3 - 1/16 */
3495         for (factor = 0; factor < DCAM_PATH_DECI_FAC_MAX; factor ++) {
3496                 if (src_size < (uint32_t)(dst_size * (1 << (factor + 1)))) {
3497                         break;
3498                 }
3499         }
3500
3501         return factor;
3502 }
3503
3504 LOCAL int32_t _dcam_calc_sc_size(enum dcam_path_index path_index)
3505 {
3506         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3507         struct dcam_path_desc   *path = NULL;
3508         uint32_t                cfg_reg = 0;
3509         uint32_t                tmp_dstsize = 0;
3510         uint32_t                align_size = 0;
3511
3512         DCAM_CHECK_ZERO(s_p_dcam_mod);
3513
3514         if (DCAM_PATH_IDX_0 == path_index) {
3515                 path = &s_p_dcam_mod->dcam_path0;
3516                 cfg_reg = DCAM_PATH0_CFG;
3517         } else if (DCAM_PATH_IDX_1 == path_index) {
3518                 path = &s_p_dcam_mod->dcam_path1;
3519                 cfg_reg = DCAM_PATH1_CFG;
3520         } else if (DCAM_PATH_IDX_2 == path_index){
3521                 path = &s_p_dcam_mod->dcam_path2;
3522                 cfg_reg = DCAM_PATH2_CFG;
3523         }
3524
3525         DCAM_CHECK_ZERO(path);
3526         if (path->input_rect.w > (path->output_size.w * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3527                 path->input_rect.h > (path->output_size.h * DCAM_SC_COEFF_DOWN_MAX * (1<<DCAM_PATH_DECI_FAC_MAX)) ||
3528                 path->input_rect.w * DCAM_SC_COEFF_UP_MAX < path->output_size.w ||
3529                 path->input_rect.h * DCAM_SC_COEFF_UP_MAX < path->output_size.h) {
3530                 rtn = DCAM_RTN_PATH_SC_ERR;
3531         } else {
3532                 path->sc_input_size.w = path->input_rect.w;
3533                 path->sc_input_size.h = path->input_rect.h;
3534                 if (path->input_rect.w > path->output_size.w * DCAM_SC_COEFF_DOWN_MAX) {
3535                         tmp_dstsize = path->output_size.w * DCAM_SC_COEFF_DOWN_MAX;
3536                         path->deci_val.deci_x = _dcam_get_path_deci_factor(path->input_rect.w, tmp_dstsize);
3537                         path->deci_val.deci_x_en = 1;
3538                         path->valid_param.v_deci = 1;
3539                         align_size = (1 << (path->deci_val.deci_x+1))*DCAM_PIXEL_ALIGN_WIDTH;
3540                         path->input_rect.w = (path->input_rect.w) & ~(align_size-1);
3541                         path->input_rect.x = (path->input_rect.x) & ~(align_size-1);
3542                         path->sc_input_size.w = path->input_rect.w >> (path->deci_val.deci_x+1);
3543                 } else {
3544                         path->deci_val.deci_x = 0;
3545                         path->deci_val.deci_x_en = 0;
3546                         path->valid_param.v_deci = 1;
3547                 }
3548
3549                 if (path->input_rect.h > path->output_size.h * DCAM_SC_COEFF_DOWN_MAX) {
3550                         tmp_dstsize = path->output_size.h * DCAM_SC_COEFF_DOWN_MAX;
3551                         path->deci_val.deci_y = _dcam_get_path_deci_factor(path->input_rect.h, tmp_dstsize);
3552                         path->deci_val.deci_y_en = 1;
3553                         path->valid_param.v_deci = 1;
3554                         align_size = (1 << (path->deci_val.deci_y+1))*DCAM_PIXEL_ALIGN_HEIGHT;
3555                         path->input_rect.h = (path->input_rect.h) & ~(align_size-1);
3556                         path->input_rect.y = (path->input_rect.y) & ~(align_size-1);
3557                         path->sc_input_size.h = path->input_rect.h >> (path->deci_val.deci_y+1);
3558                 } else {
3559                         path->deci_val.deci_y = 0;
3560                         path->deci_val.deci_y_en = 0;
3561                         path->valid_param.v_deci = 1;
3562                 }
3563
3564         }
3565
3566         DCAM_TRACE("DCAM: _dcam_calc_sc_size, path=%d, x_en=%d, deci_x=%d, y_en=%d, deci_y=%d \n",
3567                 path_index, path->deci_val.deci_x_en,
3568                 path->deci_val.deci_x, path->deci_val.deci_y_en,
3569                 path->deci_val.deci_y);
3570
3571         return -rtn;
3572 }
3573
3574 LOCAL int32_t _dcam_set_sc_coeff(enum dcam_path_index path_index)
3575 {
3576         struct dcam_path_desc   *path = NULL;
3577         uint32_t                i = 0;
3578         uint32_t                h_coeff_addr = DCAM_BASE;
3579         uint32_t                v_coeff_addr  = DCAM_BASE;
3580         uint32_t                v_chroma_coeff_addr  = DCAM_BASE;
3581         uint32_t                *tmp_buf = NULL;
3582         uint32_t                *h_coeff = NULL;
3583         uint32_t                *v_coeff = NULL;
3584         uint32_t                *v_chroma_coeff = NULL;
3585         uint32_t                clk_switch_bit = 0;
3586         uint32_t                clk_switch_shift_bit = 0;
3587         uint32_t                clk_status_bit = 0;
3588         uint32_t                ver_tap_reg = 0;
3589         uint32_t                scale2yuv420 = 0;
3590         uint8_t                 y_tap = 0;
3591         uint8_t                 uv_tap = 0;
3592         uint32_t                index = 0;
3593
3594         DCAM_CHECK_ZERO(s_p_dcam_mod);
3595
3596         if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
3597                 return -DCAM_RTN_PARA_ERR;
3598
3599         if (DCAM_PATH_IDX_1 == path_index) {
3600                 path = &s_p_dcam_mod->dcam_path1;
3601                 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
3602                 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
3603                 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
3604                 clk_switch_bit = BIT_3;
3605                 clk_switch_shift_bit = 3;
3606                 clk_status_bit = BIT_5;
3607                 ver_tap_reg = DCAM_PATH1_CFG;
3608         } else if (DCAM_PATH_IDX_2 == path_index) {
3609                 path = &s_p_dcam_mod->dcam_path2;
3610                 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
3611                 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
3612                 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
3613                 clk_switch_bit = BIT_4;
3614                 clk_switch_shift_bit = 4;
3615                 clk_status_bit = BIT_6;
3616                 ver_tap_reg = DCAM_PATH2_CFG;
3617         }
3618
3619         if (DCAM_YUV420 == path->output_format) {
3620             scale2yuv420 = 1;
3621         }
3622
3623         DCAM_TRACE("DCAM: _dcam_set_sc_coeff {%d %d %d %d}, 420=%d \n",
3624                 path->sc_input_size.w,
3625                 path->sc_input_size.h,
3626                 path->output_size.w,
3627                 path->output_size.h, scale2yuv420);
3628
3629
3630         tmp_buf = dcam_get_scale_coeff_addr(&index);
3631
3632         if (NULL == tmp_buf) {
3633                 return -DCAM_RTN_PATH_NO_MEM;
3634         }
3635
3636         h_coeff = tmp_buf;
3637         v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
3638         v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
3639
3640         down(&s_p_dcam_mod->scale_coeff_mem_sema);
3641
3642         if (!(Dcam_GenScaleCoeff((int16_t)path->sc_input_size.w,
3643                 (int16_t)path->sc_input_size.h,
3644                 (int16_t)path->output_size.w,
3645                 (int16_t)path->output_size.h,
3646                 h_coeff,
3647                 v_coeff,
3648                 v_chroma_coeff,
3649                 scale2yuv420,
3650                 &y_tap,
3651                 &uv_tap,
3652                 tmp_buf + (DCAM_SC_COEFF_COEF_SIZE*3/4),
3653                 DCAM_SC_COEFF_TMP_SIZE))) {
3654                 printk("DCAM: _dcam_set_sc_coeff Dcam_GenScaleCoeff error! \n");
3655                 up(&s_p_dcam_mod->scale_coeff_mem_sema);
3656                 return -DCAM_RTN_PATH_GEN_COEFF_ERR;
3657         }
3658
3659         for (i = 0; i < DCAM_SC_COEFF_H_NUM; i++) {
3660                 REG_WR(h_coeff_addr, *h_coeff);
3661                 h_coeff_addr += 4;
3662                 h_coeff++;
3663         }
3664
3665         for (i = 0; i < DCAM_SC_COEFF_V_NUM; i++) {
3666                 REG_WR(v_coeff_addr, *v_coeff);
3667                 v_coeff_addr += 4;
3668                 v_coeff++;
3669         }
3670
3671         for (i = 0; i < DCAM_SC_COEFF_V_CHROMA_NUM; i++) {
3672                 REG_WR(v_chroma_coeff_addr, *v_chroma_coeff);
3673                 v_chroma_coeff_addr += 4;
3674                 v_chroma_coeff++;
3675         }
3676
3677         path->scale_tap.y_tap = y_tap;
3678         path->scale_tap.uv_tap = uv_tap;
3679         path->valid_param.scale_tap = 1;
3680
3681         up(&s_p_dcam_mod->scale_coeff_mem_sema);
3682
3683         return DCAM_RTN_SUCCESS;
3684 }
3685
3686 LOCAL void _dcam_force_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy)
3687 {
3688         uint32_t         reg_val = 0;
3689
3690         if (DCAM_PATH_IDX_1 == path_index) {
3691                 if(path_copy)
3692                         reg_val |= BIT_10;
3693                 if(coef_copy)
3694                         reg_val |= BIT_14;
3695
3696                 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3697         } else if(DCAM_PATH_IDX_2 == path_index) {
3698                 if(path_copy)
3699                         reg_val |= BIT_12;
3700                 if(coef_copy)
3701                         reg_val |= BIT_16;
3702
3703                 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3704         } else {
3705                 DCAM_TRACE("DCAM: _dcam_force_copy_ext invalid path index: %d \n", path_index);
3706         }
3707 }
3708
3709 LOCAL void _dcam_auto_copy_ext(enum dcam_path_index path_index, uint32_t path_copy, uint32_t coef_copy)
3710 {
3711         uint32_t         reg_val = 0;
3712
3713         if (DCAM_PATH_IDX_0 == path_index) {
3714                 if (path_copy)
3715                         reg_val |= BIT_9;
3716                 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3717         } else if (DCAM_PATH_IDX_1 == path_index) {
3718                 if (path_copy)
3719                         reg_val |= BIT_11;
3720                 if (coef_copy)
3721                         reg_val |= BIT_15;
3722                 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3723         } else if (DCAM_PATH_IDX_2 == path_index) {
3724                 if (path_copy)
3725                         reg_val |= BIT_13;
3726                 if (coef_copy)
3727                         reg_val |= BIT_17;
3728                 dcam_glb_reg_mwr(DCAM_CONTROL, reg_val, reg_val, DCAM_CONTROL_REG);
3729         } else {
3730                 DCAM_TRACE("DCAM: _dcam_auto_copy_ext invalid path index: %d \n", path_index);
3731         }
3732
3733 }
3734
3735 LOCAL void _dcam_force_copy(enum dcam_path_index path_index)
3736 {
3737         if (DCAM_PATH_IDX_1 == path_index) {
3738                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_10, 1 << 10, DCAM_CONTROL_REG);
3739         } else if (DCAM_PATH_IDX_2 == path_index) {
3740                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_12, 1 << 12, DCAM_CONTROL_REG);
3741 #ifdef VERSION3D
3742         } else if (DCAM_PATH_IDX_0 == path_index) {
3743                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_8, 1 << 8, DCAM_CONTROL_REG);
3744 #endif
3745         } else {
3746                 DCAM_TRACE("DCAM: _dcam_force_copy invalid path index: %d \n", path_index);
3747         }
3748 }
3749
3750 LOCAL void _dcam_auto_copy(enum dcam_path_index path_index)
3751 {
3752         if (DCAM_PATH_IDX_0 == path_index) {
3753                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_9, 1 << 9, DCAM_CONTROL_REG);
3754         } else if(DCAM_PATH_IDX_1 == path_index) {
3755                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_11, 1 << 11, DCAM_CONTROL_REG);
3756         } else if(DCAM_PATH_IDX_2 == path_index) {
3757                 dcam_glb_reg_mwr(DCAM_CONTROL, BIT_13, 1 << 13, DCAM_CONTROL_REG);
3758         } else {
3759                 DCAM_TRACE("DCAM: _dcam_auto_copy invalid path index: %d \n", path_index);
3760         }
3761 }
3762
3763 LOCAL void _dcam_reg_trace(void)
3764 {
3765 #ifdef DCAM_DRV_DEBUG
3766         uint32_t                addr = 0;
3767
3768         printk("DCAM: Register list");
3769         for (addr = DCAM_CFG; addr <= CAP_SENSOR_CTRL; addr += 16) {
3770                 printk("\n 0x%x: 0x%x 0x%x 0x%x 0x%x",
3771                         addr,
3772                         REG_RD(addr),
3773                         REG_RD(addr + 4),
3774                         REG_RD(addr + 8),
3775                         REG_RD(addr + 12));
3776         }
3777
3778         printk("\n");
3779 #endif
3780 }
3781
3782 #if 0
3783 LOCAL void    _dcam_sensor_sof(void)
3784 {
3785         dcam_isr_func           user_func = s_user_func[DCAM_SN_SOF];
3786         void                    *data = s_user_data[DCAM_SN_SOF];
3787
3788         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3789
3790         DCAM_TRACE("DCAM: _sn_sof \n");
3791
3792         if (user_func) {
3793                 (*user_func)(NULL, data);
3794         }
3795
3796         return;
3797 }
3798 #endif
3799
3800 LOCAL void    _dcam_sensor_eof(void)
3801 {
3802         dcam_isr_func           user_func = s_user_func[DCAM_SN_EOF];
3803         void                    *data = s_user_data[DCAM_SN_EOF];
3804
3805         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3806
3807         DCAM_TRACE("DCAM: _sn_eof \n");
3808
3809         if (user_func) {
3810                 (*user_func)(NULL, data);
3811         }
3812
3813         return;
3814 }
3815
3816 LOCAL void    _dcam_cap_sof(void)
3817 {
3818         dcam_isr_func           user_func = s_user_func[DCAM_CAP_SOF];
3819         void                    *data = s_user_data[DCAM_CAP_SOF];
3820
3821         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3822
3823         DCAM_TRACE("DCAM: _cap_sof \n");
3824
3825         _dcam_stopped_notice();
3826
3827         if (user_func) {
3828                 (*user_func)(NULL, data);
3829         }
3830
3831         return;
3832 }
3833
3834 LOCAL void    _dcam_cap_eof(void)
3835 {
3836         dcam_isr_func           user_func = s_user_func[DCAM_CAP_EOF];
3837         void                    *data = s_user_data[DCAM_CAP_EOF];
3838
3839         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3840
3841         if (user_func) {
3842                 (*user_func)(NULL, data);
3843         }
3844
3845         return;
3846 }
3847
3848 LOCAL void    _dcam_path0_done(void)
3849 {
3850         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3851         dcam_isr_func           user_func = s_user_func[DCAM_PATH0_DONE];
3852         void                    *data = s_user_data[DCAM_PATH0_DONE];
3853         struct dcam_path_desc   *path;
3854         struct dcam_frame       frame;
3855
3856         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3857         path = &s_p_dcam_mod->dcam_path0;
3858         if (0 == path->valide) {
3859                 printk("DCAM: path0 not valid \n");
3860                 return;
3861         }
3862         if (path->need_stop) {
3863                 dcam_glb_reg_awr(DCAM_CFG, ~BIT_0, DCAM_CFG_REG);
3864                 path->need_stop = 0;
3865         }
3866         _dcam_path_done_notice(DCAM_PATH_IDX_0);
3867         //printk("DCAM 0 \n");
3868         if (path->sof_cnt < 1) {
3869                 printk("DCAM: path0 done cnt %d\n", path->sof_cnt);
3870                 path->need_wait = 0;
3871                 return;
3872         }
3873         path->sof_cnt = 0;
3874
3875         if (path->need_wait) {
3876                 path->need_wait = 0;
3877         } else {
3878         rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3879         if (0 == rtn && frame.yaddr != s_p_dcam_mod->path0_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3880                 frame.width = path->output_size.w;
3881                 frame.height = path->output_size.h;
3882                         DCAM_TRACE("DCAM: path0 frame 0x%x, y uv, 0x%x 0x%x \n",
3883                                 (int)&frame, frame.yaddr, frame.uaddr);
3884                 if (user_func) {
3885                         (*user_func)(&frame, data);
3886                 }
3887         } else {
3888                 DCAM_TRACE("DCAM: path0_reserved_frame \n");
3889         }
3890         }
3891
3892         return;
3893 }
3894
3895
3896 LOCAL void    _dcam_path0_overflow(void)
3897 {
3898         dcam_isr_func           user_func = s_user_func[DCAM_PATH0_OV];
3899         void                    *data = s_user_data[DCAM_PATH0_OV];
3900         struct dcam_path_desc   *path;
3901         struct dcam_frame       frame;
3902
3903         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3904
3905         printk("DCAM: _path0_overflow \n");
3906         path = &s_p_dcam_mod->dcam_path0;
3907         //frame = path->output_frame_cur->prev->prev;
3908         //frame = &s_p_dcam_mod->path0_frame[0];
3909         _dcam_frame_dequeue(&path->frame_queue, &frame);
3910
3911         if (user_func) {
3912                 (*user_func)(&frame, data);
3913         }
3914
3915         return;
3916 }
3917
3918 LOCAL void    _dcam_path1_done(void)
3919 {
3920         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
3921         dcam_isr_func           user_func = s_user_func[DCAM_PATH1_DONE];
3922         void                    *data = s_user_data[DCAM_PATH1_DONE];
3923         struct dcam_path_desc   *path;
3924         struct dcam_frame       frame;
3925
3926         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3927         path = &s_p_dcam_mod->dcam_path1;
3928         if (0 == path->valide) {
3929                 printk("DCAM: path1 not valid \n");
3930                 return;
3931         }
3932
3933         DCAM_TRACE("DCAM: 1\n");
3934
3935         if (path->need_stop) {
3936                 dcam_glb_reg_awr(DCAM_CFG, ~BIT_1, DCAM_CFG_REG);
3937                 path->need_stop = 0;
3938         }
3939         _dcam_path_done_notice(DCAM_PATH_IDX_1);
3940
3941         if (path->sof_cnt < 1) {
3942                 printk("DCAM: path1 done cnt %d\n", path->sof_cnt);
3943                 path->need_wait = 0;
3944                 return;
3945         }
3946         path->sof_cnt = 0;
3947
3948         if (path->need_wait) {
3949                 path->need_wait = 0;
3950         } else {
3951                 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
3952                 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path1_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
3953                         frame.width = path->output_size.w;
3954                         frame.height = path->output_size.h;
3955                         DCAM_TRACE("DCAM: path1 frame 0x%x, y uv, 0x%x 0x%x \n",
3956                                 (int)&frame, frame.yaddr, frame.uaddr);
3957                         if (user_func) {
3958                                 (*user_func)(&frame, data);
3959                         }
3960                 } else {
3961                         DCAM_TRACE("DCAM: path1_reserved_frame \n");
3962                 }
3963         }
3964         return;
3965 }
3966
3967 LOCAL void    _dcam_path1_overflow(void)
3968 {
3969         dcam_isr_func           user_func = s_user_func[DCAM_PATH1_OV];
3970         void                    *data = s_user_data[DCAM_PATH1_OV];
3971         struct dcam_path_desc   *path;
3972         struct dcam_frame       frame;
3973
3974         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3975
3976         printk("DCAM: _path1_overflow \n");
3977         path = &s_p_dcam_mod->dcam_path1;
3978         //frame = path->output_frame_cur->prev->prev;
3979         _dcam_frame_dequeue(&path->frame_queue, &frame);
3980
3981         if (user_func) {
3982                 (*user_func)(&frame, data);
3983         }
3984
3985         return;
3986 }
3987
3988 LOCAL void    _dcam_sensor_line_err(void)
3989 {
3990         dcam_isr_func           user_func = s_user_func[DCAM_SN_LINE_ERR];
3991         void                    *data = s_user_data[DCAM_SN_LINE_ERR];
3992
3993         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
3994
3995         printk("DCAM: _line_err \n");
3996
3997         if (user_func) {
3998                 (*user_func)(NULL, data);
3999         }
4000
4001         return;
4002 }
4003
4004 LOCAL void    _dcam_sensor_frame_err(void)
4005 {
4006         dcam_isr_func           user_func = s_user_func[DCAM_SN_FRAME_ERR];
4007         void                    *data = s_user_data[DCAM_SN_FRAME_ERR];
4008
4009         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4010
4011         printk("DCAM: _frame_err \n");
4012
4013         if (user_func) {
4014                 (*user_func)(NULL, data);
4015         }
4016
4017         return;
4018 }
4019
4020 LOCAL void    _dcam_jpeg_buf_ov(void)
4021 {
4022         dcam_isr_func           user_func = s_user_func[DCAM_JPEG_BUF_OV];
4023         void                    *data = s_user_data[DCAM_JPEG_BUF_OV];
4024         struct dcam_path_desc   *path;
4025         struct dcam_frame       frame;
4026
4027         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4028
4029         printk("DCAM: _jpeg_overflow \n");
4030         path = &s_p_dcam_mod->dcam_path0;
4031         //frame = path->output_frame_cur->prev->prev;
4032         //frame = &s_p_dcam_mod->path0_frame[0];
4033         _dcam_frame_dequeue(&path->frame_queue, &frame);
4034
4035         if (user_func) {
4036                 (*user_func)(&frame, data);
4037         }
4038
4039         return;
4040 }
4041
4042 LOCAL void    _dcam_path2_done(void)
4043 {
4044         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
4045         dcam_isr_func           user_func = s_user_func[DCAM_PATH2_DONE];
4046         void                    *data = s_user_data[DCAM_PATH2_DONE];
4047         struct dcam_path_desc   *path;
4048         struct dcam_frame       frame;
4049
4050         if (atomic_read(&s_resize_flag)) {
4051                 memset(&frame, 0, sizeof(struct dcam_frame));
4052                 if (user_func) {
4053                         (*user_func)(&frame, data);
4054                 }
4055         } else {
4056                 DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4057                 path = &s_p_dcam_mod->dcam_path2;
4058
4059                 DCAM_TRACE("DCAM: 2, %d %d \n", path->need_stop, path->need_wait);
4060                 if (path->status == DCAM_ST_START) {
4061
4062                         if (path->need_stop) {
4063                                 dcam_glb_reg_awr(DCAM_CFG, ~BIT_2, DCAM_CFG_REG);
4064                                 path->need_stop = 0;
4065                         }
4066                         _dcam_path_done_notice(DCAM_PATH_IDX_2);
4067
4068                         if (path->sof_cnt < 1) {
4069                                 printk("DCAM: path2 done cnt %d\n", path->sof_cnt);
4070                                 path->need_wait = 0;
4071                                 return;
4072                         }
4073                         path->sof_cnt = 0;
4074
4075                         if (path->need_wait) {
4076                                 path->need_wait = 0;
4077                         } else {
4078                                 rtn = _dcam_frame_dequeue(&path->frame_queue, &frame);
4079                                 if (0 == rtn && frame.yaddr != s_p_dcam_mod->path2_reserved_frame.yaddr && 0 != dcam_frame_is_locked(&frame)) {
4080                                         DCAM_TRACE("DCAM: path2 frame 0x%x, y uv, 0x%x 0x%x \n",
4081                                                 (int)&frame, frame.yaddr, frame.uaddr);
4082                                         frame.width = path->output_size.w;
4083                                         frame.height = path->output_size.h;
4084                                         if (user_func) {
4085                                                 (*user_func)(&frame, data);
4086                                         }
4087                                 } else {
4088                                         DCAM_TRACE("DCAM: path2_reserved_frame \n");
4089                                 }
4090                         }
4091                 }
4092         }
4093 }
4094
4095 LOCAL void    _dcam_path2_ov(void)
4096 {
4097         dcam_isr_func           user_func = s_user_func[DCAM_PATH2_OV];
4098         void                    *data = s_user_data[DCAM_PATH2_OV];
4099         struct dcam_path_desc   *path;
4100         struct dcam_frame       frame;
4101
4102         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4103
4104         printk("DCAM: _path2_overflow \n");
4105         path = &s_p_dcam_mod->dcam_path2;
4106         //frame = path->output_frame_cur->prev->prev;
4107         //frame = &s_p_dcam_mod->path2_frame[0];
4108         _dcam_frame_dequeue(&path->frame_queue, &frame);
4109
4110         if (user_func) {
4111                 (*user_func)(&frame, data);
4112         }
4113
4114         return;
4115 }
4116
4117 LOCAL void    _dcam_isp_ov(void)
4118 {
4119         dcam_isr_func           user_func = s_user_func[DCAM_ISP_OV];
4120         void                    *data = s_user_data[DCAM_ISP_OV];
4121
4122         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4123
4124         printk("DCAM: _isp_overflow \n");
4125
4126         if (user_func) {
4127                 (*user_func)(NULL, data);
4128         }
4129
4130         return;
4131 }
4132
4133 LOCAL void    _dcam_mipi_ov(void)
4134 {
4135         dcam_isr_func           user_func = s_user_func[DCAM_MIPI_OV];
4136         void                    *data = s_user_data[DCAM_MIPI_OV];
4137
4138         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4139
4140
4141         if (user_func) {
4142                 (*user_func)(NULL, data);
4143         }
4144
4145         printk("DCAM: _mipi_overflow \n");
4146         return;
4147 }
4148
4149 LOCAL void    _dcam_rot_done(void)
4150 {
4151         dcam_isr_func           user_func = s_user_func[DCAM_ROT_DONE];
4152         void                    *data = s_user_data[DCAM_ROT_DONE];
4153
4154         DCAM_TRACE("DCAM: rot_done \n");
4155
4156         if (user_func) {
4157                 (*user_func)(NULL, data);
4158         }
4159
4160         return;
4161 }
4162
4163 LOCAL void    _dcam_path1_slice_done(void)
4164 {
4165         dcam_isr_func           user_func = s_user_func[DCAM_PATH1_SLICE_DONE];
4166         void                    *data = s_user_data[DCAM_PATH1_SLICE_DONE];
4167
4168         DCAM_TRACE("DCAM: 1 slice done \n");
4169
4170         if (user_func) {
4171                 (*user_func)(NULL, data);
4172         }
4173
4174         return;
4175 }
4176
4177 LOCAL void    _dcam_path2_slice_done(void)
4178 {
4179         dcam_isr_func           user_func = s_user_func[DCAM_PATH2_SLICE_DONE];
4180         void                    *data = s_user_data[DCAM_PATH2_SLICE_DONE];
4181
4182         DCAM_TRACE("DCAM: 2 slice done \n");
4183
4184         if (user_func) {
4185                 (*user_func)(NULL, data);
4186         }
4187
4188         return;
4189 }
4190
4191 LOCAL void    _dcam_raw_slice_done(void)
4192 {
4193         dcam_isr_func           user_func = s_user_func[DCAM_RAW_SLICE_DONE];
4194         void                    *data = s_user_data[DCAM_RAW_SLICE_DONE];
4195
4196         DCAM_TRACE("DCAM: 0 slice done \n");
4197
4198         if (user_func) {
4199                 (*user_func)(NULL, data);
4200         }
4201
4202         return;
4203 }
4204
4205 LOCAL void    _dcam_path0_sof(void)
4206 {
4207         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
4208         dcam_isr_func           user_func = s_user_func[DCAM_PATH0_SOF];
4209         void                    *data = s_user_data[DCAM_PATH0_SOF];
4210         struct dcam_path_desc   *path;
4211         struct dcam_sc_coeff    *sc_coeff;
4212
4213         DCAM_TRACE("DCAM: 0 sof 1 \n");
4214
4215         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4216         DCAM_CHECK_ZERO_VOID(s_dcam_sc_array);
4217
4218         if(s_p_dcam_mod->dcam_path0.status == DCAM_ST_START){
4219                 DCAM_TRACE("DCAM: 0 sof 2 \n");
4220                 path = &s_p_dcam_mod->dcam_path0;
4221                 if (0 == path->valide) {
4222                         printk("DCAM: path0 not valid \n");
4223                         return;
4224                 }
4225
4226                 if (path->sof_cnt > 0) {
4227                         printk("DCAM: path0 sof %d \n", path->sof_cnt);
4228                         return;
4229                 } else {
4230                         path->sof_cnt++;
4231                 }
4232
4233                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_0, false);
4234
4235                 if (rtn) {
4236                         DCAM_TRACE("DCAM: path0 updated \n");
4237                 } else {
4238                         _dcam_auto_copy(DCAM_PATH_IDX_0);
4239                 }
4240
4241                 _dcam_path_updated_notice(DCAM_PATH_IDX_0);
4242
4243                 if (rtn) {
4244                         path->need_wait = 1;
4245                         printk("DCAM: 0 w\n");
4246                         return;
4247                 }
4248
4249                 if (user_func) {
4250                         (*user_func)(NULL, data);
4251                 }
4252         }
4253
4254         return;
4255 }
4256
4257 LOCAL void    _dcam_path1_sof(void)
4258 {
4259         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
4260         dcam_isr_func           user_func = s_user_func[DCAM_PATH1_SOF];
4261         void                    *data = s_user_data[DCAM_PATH1_SOF];
4262         struct dcam_path_desc   *path;
4263         struct dcam_sc_coeff    *sc_coeff;
4264         int32_t                 ret = 0;
4265
4266         DCAM_TRACE("DCAM: 1 sof done \n");
4267
4268         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4269         DCAM_CHECK_ZERO_VOID(s_dcam_sc_array);
4270
4271         if(s_p_dcam_mod->dcam_path1.status == DCAM_ST_START){
4272
4273                 path = &s_p_dcam_mod->dcam_path1;
4274                 if (0 == path->valide) {
4275                         printk("DCAM: path1 not valid \n");
4276                         return;
4277                 }
4278
4279                 if (path->sof_cnt > 0) {
4280                         printk("DCAM: path1 sof %d \n", path->sof_cnt);
4281                         return;
4282                 } else {
4283                         path->sof_cnt++;
4284                 }
4285
4286                 rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_1, false);
4287                 if (path->is_update) {
4288                         if (s_dcam_sc_array->is_smooth_zoom) {
4289 #ifndef CONFIG_MACH_Z3
4290                                 _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
4291                                 _dcam_write_sc_coeff(DCAM_PATH_IDX_1);
4292 #else /* possible fix for smooth zoom kernel panic */
4293                                 ret = 0;
4294                                 ret = _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
4295                                 if (ret) {
4296                                         printk("DCAM: get sc coeff ret %d \n", ret);
4297                                         return;
4298                                 }
4299                                 ret = _dcam_write_sc_coeff(DCAM_PATH_IDX_1);
4300                                 if (ret) {
4301                                         printk("DCAM: write sc coeff ret %d \n", ret);
4302                                         return;
4303                                 }
4304 #endif
4305                                 _dcam_path1_set(&sc_coeff->dcam_path1);
4306                                 _dcam_pop_sc_buf(s_dcam_sc_array, &sc_coeff);
4307                         } else {
4308                                 _dcam_path1_set(path);
4309                         }
4310                         path->is_update = 0;
4311                         DCAM_TRACE("DCAM: path1 updated \n");
4312                         _dcam_auto_copy_ext(DCAM_PATH_IDX_1, true, true);
4313                 } else {
4314                         if (rtn) {
4315                                 DCAM_TRACE("DCAM: path1 updated \n");
4316                         } else {
4317                                 _dcam_auto_copy(DCAM_PATH_IDX_1);
4318                         }
4319                 }
4320
4321                 _dcam_path_updated_notice(DCAM_PATH_IDX_1);
4322
4323                 if (rtn) {
4324                         path->need_wait = 1;
4325                         printk("DCAM: 1 w\n");
4326                         return;
4327                 }
4328         }
4329
4330         if (user_func) {
4331                 (*user_func)(NULL, data);
4332         }
4333
4334         return;
4335 }
4336
4337 LOCAL void    _dcam_path2_sof(void)
4338 {
4339         enum dcam_drv_rtn       rtn = DCAM_RTN_SUCCESS;
4340         dcam_isr_func           user_func = s_user_func[DCAM_PATH2_SOF];
4341         void                    *data = s_user_data[DCAM_PATH2_SOF];
4342         struct dcam_path_desc   *path;
4343
4344         DCAM_TRACE("DCAM: 2 sof done \n");
4345
4346         if (atomic_read(&s_resize_flag)) {
4347                 printk("DCAM: path 2  sof, review now \n");
4348         } else {
4349                 if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
4350                         return;
4351                 }
4352
4353                 if(s_p_dcam_mod->dcam_path2.status == DCAM_ST_START){
4354
4355                         path = &s_p_dcam_mod->dcam_path2;
4356                         if (0 == path->valide) {
4357                                 printk("DCAM: path2 not valid \n");
4358                                 return;
4359                         }
4360
4361                         if (path->sof_cnt > 0) {
4362                                 printk("DCAM: path2 sof %d \n", path->sof_cnt);
4363                                 return;
4364                         } else {
4365                                 path->sof_cnt++;
4366                         }
4367
4368                         rtn = _dcam_path_set_next_frm(DCAM_PATH_IDX_2, false);
4369                         if (path->is_update) {
4370                                 _dcam_path2_set();
4371                                 path->is_update = 0;
4372                                 DCAM_TRACE("DCAM: path2 updated \n");
4373                                 _dcam_auto_copy_ext(DCAM_PATH_IDX_2, true, true);
4374                         } else {
4375                                 if (rtn) {
4376                                         DCAM_TRACE("DCAM: path2 updated \n");
4377                                 } else {
4378                                         _dcam_auto_copy(DCAM_PATH_IDX_2);
4379                                 }
4380                         }
4381
4382                         _dcam_path_updated_notice(DCAM_PATH_IDX_2);
4383
4384                         if (rtn) {
4385                                 path->need_wait = 1;
4386                                 printk("DCAM:2 w \n");
4387                                 return;
4388                         }
4389                 }
4390         }
4391
4392         if (user_func) {
4393                 (*user_func)(NULL, data);
4394         }
4395
4396         return;
4397 }
4398
4399 LOCAL int32_t    _dcam_err_pre_proc(void)
4400 {
4401         DCAM_CHECK_ZERO(s_p_dcam_mod);
4402
4403         DCAM_TRACE("DCAM: state in err_pre_proc  0x%x,",s_p_dcam_mod->state);
4404         if (s_p_dcam_mod->state & DCAM_STATE_QUICKQUIT)
4405                 return -1;
4406
4407         s_p_dcam_mod->err_happened = 1;
4408         printk("DCAM: err, 0x%x, ISP int 0x%x \n",
4409                 REG_RD(DCAM_INT_STS),
4410                 REG_RD(SPRD_ISP_BASE + 0x2080));
4411
4412         _dcam_reg_trace();
4413         dcam_glb_reg_mwr(DCAM_CONTROL, BIT_2, 0, DCAM_CONTROL_REG); /* Cap Disable */
4414         _dcam_stopped();
4415         if (0 == atomic_read(&s_resize_flag) &&
4416                 0 == atomic_read(&s_rotation_flag)) {
4417                         dcam_reset(DCAM_RST_ALL, 1);
4418         }
4419         return 0;
4420 }
4421
4422 LOCAL void    _dcam_stopped(void)
4423 {
4424         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4425
4426         DCAM_TRACE("DCAM: stopped, %d \n", s_p_dcam_mod->wait_stop);
4427
4428         _dcam_path_done_notice(DCAM_PATH_IDX_0);
4429         _dcam_path_done_notice(DCAM_PATH_IDX_1);
4430         _dcam_path_done_notice(DCAM_PATH_IDX_2);
4431         _dcam_stopped_notice();
4432         return;
4433 }
4434
4435 LOCAL int  _dcam_internal_init(void)
4436 {
4437         int                     ret = 0;
4438
4439         s_p_dcam_mod = (struct dcam_module*)vzalloc(sizeof(struct dcam_module));
4440
4441         DCAM_CHECK_ZERO(s_p_dcam_mod);
4442
4443         sema_init(&s_p_dcam_mod->stop_sema, 0);
4444         sema_init(&s_p_dcam_mod->dcam_path0.tx_done_sema, 0);
4445         sema_init(&s_p_dcam_mod->dcam_path1.tx_done_sema, 0);
4446         sema_init(&s_p_dcam_mod->dcam_path2.tx_done_sema, 0);
4447         sema_init(&s_p_dcam_mod->dcam_path0.sof_sema, 0);
4448         sema_init(&s_p_dcam_mod->dcam_path1.sof_sema, 0);
4449         sema_init(&s_p_dcam_mod->dcam_path2.sof_sema, 0);
4450         sema_init(&s_p_dcam_mod->resize_done_sema, 0);
4451         sema_init(&s_p_dcam_mod->rotation_done_sema, 0);
4452         sema_init(&s_p_dcam_mod->scale_coeff_mem_sema, 1);
4453
4454         memset((void*)s_dcam_sc_array, 0, sizeof(struct dcam_sc_array));
4455         return ret;
4456 }
4457 LOCAL void _dcam_internal_deinit(void)
4458 {
4459         unsigned long flag;
4460
4461         spin_lock_irqsave(&dcam_mod_lock, flag);
4462         if (DCAM_ADDR_INVALID(s_p_dcam_mod)) {
4463                 printk("DCAM: Invalid addr, 0x%x", (uint32_t)s_p_dcam_mod);
4464         } else {
4465                 vfree(s_p_dcam_mod);
4466                 s_p_dcam_mod = NULL;
4467         }
4468         spin_unlock_irqrestore(&dcam_mod_lock, flag);
4469         return;
4470 }
4471
4472 LOCAL void _dcam_wait_path_done(enum dcam_path_index path_index, uint32_t *p_flag)
4473 {
4474         int                     ret = 0;
4475         struct dcam_path_desc   *p_path = NULL;
4476         unsigned long           flag;
4477
4478         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4479
4480         if (s_p_dcam_mod->err_happened) {
4481                 return;
4482         }
4483         if (DCAM_CAPTURE_MODE_SINGLE == s_p_dcam_mod->dcam_mode) {
4484                 return;
4485         }
4486         if (DCAM_PATH_IDX_0 == path_index) {
4487                 p_path = &s_p_dcam_mod->dcam_path0;
4488         } else if (DCAM_PATH_IDX_1 == path_index) {
4489                 p_path = &s_p_dcam_mod->dcam_path1;
4490         } else if (DCAM_PATH_IDX_2 == path_index) {
4491                 p_path = &s_p_dcam_mod->dcam_path2;
4492         } else {
4493                 printk("DCAM: Wrong index 0x%x \n", path_index);
4494                 return;
4495         }
4496         DCAM_TRACE("DCAM: path done wait %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4497
4498         spin_lock_irqsave(&dcam_lock, flag);
4499         if (p_flag) {
4500                 *p_flag = 1;
4501         }
4502         p_path->wait_for_done = 1;
4503         spin_unlock_irqrestore(&dcam_lock, flag);
4504         ret = down_timeout(&p_path->tx_done_sema, DCAM_PATH_TIMEOUT);
4505         if (ret) {
4506                 _dcam_reg_trace();
4507                 printk("DCAM: Failed to wait path 0x%x done \n", path_index);
4508         }
4509
4510         return;
4511 }
4512
4513 LOCAL void _dcam_path_done_notice(enum dcam_path_index path_index)
4514 {
4515         struct dcam_path_desc   *p_path = NULL;
4516
4517         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4518
4519         if (DCAM_PATH_IDX_0 == path_index) {
4520                 p_path = &s_p_dcam_mod->dcam_path0;
4521         } else if(DCAM_PATH_IDX_1 == path_index) {
4522                 p_path = &s_p_dcam_mod->dcam_path1;
4523         } else if(DCAM_PATH_IDX_2 == path_index) {
4524                 p_path = &s_p_dcam_mod->dcam_path2;
4525         } else {
4526                 printk("DCAM: Wrong index 0x%x \n", path_index);
4527                 return;
4528         }
4529         DCAM_TRACE("DCAM: path done notice %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4530         if (p_path->wait_for_done) {
4531                 up(&p_path->tx_done_sema);
4532                 p_path->wait_for_done = 0;
4533         }
4534
4535         return;
4536 }
4537
4538 LOCAL void _dcam_wait_update_done(enum dcam_path_index path_index, uint32_t *p_flag)
4539 {
4540         int                     ret = 0;
4541         struct dcam_path_desc   *p_path = NULL;
4542         unsigned long           flag;
4543
4544         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4545
4546         if (s_p_dcam_mod->err_happened) {
4547                 printk("DCAM: err happened \n");
4548                 return;
4549         }
4550         if (DCAM_CAPTURE_MODE_SINGLE == s_p_dcam_mod->dcam_mode) {
4551                 return;
4552         }
4553         if (DCAM_PATH_IDX_0 == path_index) {
4554                 p_path = &s_p_dcam_mod->dcam_path0;
4555         } else if (DCAM_PATH_IDX_1 == path_index) {
4556                 p_path = &s_p_dcam_mod->dcam_path1;
4557         } else if (DCAM_PATH_IDX_2 == path_index) {
4558                 p_path = &s_p_dcam_mod->dcam_path2;
4559         } else {
4560                 printk("DCAM: Wrong index 0x%x \n", path_index);
4561                 return;
4562         }
4563         DCAM_TRACE("DCAM: path done wait %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4564
4565         spin_lock_irqsave(&dcam_lock, flag);
4566         if (p_flag) {
4567                 *p_flag = 1;
4568         }
4569         p_path->wait_for_sof = 1;
4570         spin_unlock_irqrestore(&dcam_lock, flag);
4571         ret = down_timeout(&p_path->sof_sema, DCAM_PATH_TIMEOUT);
4572         if (ret) {
4573                 _dcam_reg_trace();
4574                 printk("DCAM: Failed to wait update path 0x%x done \n", path_index);
4575         }
4576
4577         return;
4578 }
4579
4580 LOCAL void _dcam_path_updated_notice(enum dcam_path_index path_index)
4581 {
4582         struct dcam_path_desc   *p_path = NULL;
4583
4584         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4585
4586         if (DCAM_PATH_IDX_0 == path_index) {
4587                 p_path = &s_p_dcam_mod->dcam_path0;
4588         } else if(DCAM_PATH_IDX_1 == path_index) {
4589                 p_path = &s_p_dcam_mod->dcam_path1;
4590         } else if(DCAM_PATH_IDX_2 == path_index) {
4591                 p_path = &s_p_dcam_mod->dcam_path2;
4592         } else {
4593                 printk("DCAM: Wrong index 0x%x \n", path_index);
4594                 return;
4595         }
4596         DCAM_TRACE("DCAM: path done notice %d, %d \n", p_path->wait_for_done, p_path->tx_done_sema.count);
4597         if (p_path->wait_for_sof) {
4598                 up(&p_path->sof_sema);
4599                 p_path->wait_for_sof = 0;
4600         }
4601
4602         return;
4603 }
4604
4605
4606 LOCAL void _dcam_stopped_notice(void)
4607 {
4608         DCAM_CHECK_ZERO_VOID(s_p_dcam_mod);
4609
4610         if (s_p_dcam_mod->wait_stop) {
4611                 up(&s_p_dcam_mod->stop_sema);
4612                 s_p_dcam_mod->wait_stop = 0;
4613         }
4614 }
4615
4616 void mm_clk_register_trace(void)
4617 {
4618    uint32_t i = 0;
4619    printk("REG_AON_APB_APB_EB0 = 0x%x \n",REG_RD(REG_AON_APB_APB_EB0));
4620    printk("REG_PMU_APB_PD_MM_TOP_CFG = 0x%x \n",REG_RD(REG_PMU_APB_PD_MM_TOP_CFG));
4621    printk("REG_PMU_APB_CP_SOFT_RST = 0x%x \n",REG_RD(REG_PMU_APB_CP_SOFT_RST));
4622         if(!(REG_RD(REG_AON_APB_APB_EB0)&BIT_MM_EB) ) return ;
4623         if(REG_RD(REG_PMU_APB_PD_MM_TOP_CFG)&BIT_PD_MM_TOP_FORCE_SHUTDOWN) return ;
4624
4625    printk("mm_clk_reg, part 1 \n");
4626    for (i = 0 ; i <= 0x10; i += 4 ) {
4627                 printk("MMAHB: %x val:%x \b\n",
4628                         (SPRD_MMAHB_BASE + i),
4629                         REG_RD(SPRD_MMAHB_BASE + i));
4630    }
4631
4632    printk("mm_clk_reg, part 2 \n");
4633    for (i = 0x20 ; i <= 0x38; i += 4 ) {
4634                 printk("MMCKG: %x val:%x \b\n",
4635                         (SPRD_MMCKG_BASE + i),
4636                         REG_RD(SPRD_MMCKG_BASE + i));
4637    }
4638 }
4639
4640 int32_t dcam_stop_sc_coeff(void)
4641 {
4642         uint32_t zoom_mode;
4643
4644         DCAM_CHECK_ZERO(s_dcam_sc_array);
4645
4646         zoom_mode = s_dcam_sc_array->is_smooth_zoom;
4647         /*memset((void*)s_dcam_sc_array, 0, sizeof(struct dcam_sc_array));*/
4648         s_dcam_sc_array->is_smooth_zoom = zoom_mode;
4649         s_dcam_sc_array->valid_cnt = 0;
4650         memset(&s_dcam_sc_array->scaling_coeff_queue, 0, DCAM_SC_COEFF_BUF_COUNT*sizeof(struct dcam_sc_coeff *));
4651
4652         return 0;
4653 }
4654
4655 LOCAL int32_t _dcam_get_valid_sc_coeff(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff)
4656 {
4657         if (DCAM_ADDR_INVALID(sc) || DCAM_ADDR_INVALID(sc_coeff)) {
4658                 printk("DCAM: get valid sc, invalid param 0x%x, 0x%x \n",
4659                         (uint32_t)sc,
4660                         (uint32_t)sc_coeff);
4661                 return -1;
4662         }
4663         if (sc->valid_cnt == 0) {
4664                 printk("DCAM: valid cnt 0 \n");
4665                 return -1;
4666         }
4667
4668         *sc_coeff  = sc->scaling_coeff_queue[0];
4669         DCAM_TRACE("DCAM: get valid sc, %d \n", sc->valid_cnt);
4670         return 0;
4671 }
4672
4673
4674 LOCAL int32_t _dcam_push_sc_buf(struct dcam_sc_array *sc, uint32_t index)
4675 {
4676         if (DCAM_ADDR_INVALID(sc)) {
4677                 printk("DCAM: push sc, invalid param 0x%x \n",
4678                         (uint32_t)sc);
4679                 return -1;
4680         }
4681         if (sc->valid_cnt >= DCAM_SC_COEFF_BUF_COUNT) {
4682                 printk("DCAM: valid cnt %d \n", sc->valid_cnt);
4683                 return -1;
4684         }
4685
4686         sc->scaling_coeff[index].flag = 1;
4687         sc->scaling_coeff_queue[sc->valid_cnt] = &sc->scaling_coeff[index];
4688         sc->valid_cnt ++;
4689
4690         DCAM_TRACE("DCAM: push sc, %d \n", sc->valid_cnt);
4691
4692         return 0;
4693 }
4694
4695 LOCAL int32_t _dcam_pop_sc_buf(struct dcam_sc_array *sc, struct dcam_sc_coeff **sc_coeff)
4696 {
4697         uint32_t                i = 0;
4698
4699         if (DCAM_ADDR_INVALID(sc) || DCAM_ADDR_INVALID(sc_coeff)) {
4700                 printk("DCAM: pop sc, invalid param 0x%x, 0x%x \n",
4701                         (uint32_t)sc,
4702                         (uint32_t)sc_coeff);
4703                 return -1;
4704         }
4705         if (sc->valid_cnt == 0) {
4706                 printk("DCAM: valid cnt 0 \n");
4707                 return -1;
4708         }
4709         sc->scaling_coeff_queue[0]->flag = 0;
4710         *sc_coeff  = sc->scaling_coeff_queue[0];
4711         sc->valid_cnt--;
4712         for (i = 0; i < sc->valid_cnt; i++) {
4713                 sc->scaling_coeff_queue[i] = sc->scaling_coeff_queue[i+1];
4714         }
4715         DCAM_TRACE("DCAM: pop sc, %d \n", sc->valid_cnt);
4716         return 0;
4717 }
4718
4719 LOCAL int32_t _dcam_write_sc_coeff(enum dcam_path_index path_index)
4720 {
4721         int32_t                 ret = 0;
4722         struct dcam_path_desc   *path = NULL;
4723         uint32_t                i = 0;
4724         uint32_t                h_coeff_addr = DCAM_BASE;
4725         uint32_t                v_coeff_addr  = DCAM_BASE;
4726         uint32_t                v_chroma_coeff_addr  = DCAM_BASE;
4727         uint32_t                *tmp_buf = NULL;
4728         uint32_t                *h_coeff = NULL;
4729         uint32_t                *v_coeff = NULL;
4730         uint32_t                *v_chroma_coeff = NULL;
4731         uint32_t                clk_switch_bit = 0;
4732         uint32_t                clk_switch_shift_bit = 0;
4733         uint32_t                clk_status_bit = 0;
4734         uint32_t                ver_tap_reg = 0;
4735         uint32_t                scale2yuv420 = 0;
4736         struct dcam_sc_coeff    *sc_coeff;
4737
4738         DCAM_CHECK_ZERO(s_p_dcam_mod);
4739         DCAM_CHECK_ZERO(s_dcam_sc_array);
4740
4741         if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
4742                 return -DCAM_RTN_PARA_ERR;
4743
4744         ret = _dcam_get_valid_sc_coeff(s_dcam_sc_array, &sc_coeff);
4745         if (ret) {
4746                 return -DCAM_RTN_PATH_NO_MEM;
4747         }
4748         tmp_buf = sc_coeff->buf;
4749         if (NULL == tmp_buf) {
4750                 return -DCAM_RTN_PATH_NO_MEM;
4751         }
4752
4753         h_coeff = tmp_buf;
4754         v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
4755         v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
4756
4757         if (DCAM_PATH_IDX_1 == path_index) {
4758                 path = &sc_coeff->dcam_path1;
4759                 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
4760                 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
4761                 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
4762                 clk_switch_bit = BIT_3;
4763                 clk_switch_shift_bit = 3;
4764                 clk_status_bit = BIT_5;
4765                 ver_tap_reg = DCAM_PATH1_CFG;
4766         } else if (DCAM_PATH_IDX_2 == path_index) {
4767                 path = &s_p_dcam_mod->dcam_path2;
4768                 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
4769                 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
4770                 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
4771                 clk_switch_bit = BIT_4;
4772                 clk_switch_shift_bit = 4;
4773                 clk_status_bit = BIT_6;
4774                 ver_tap_reg = DCAM_PATH2_CFG;
4775         }
4776
4777         if (DCAM_YUV420 == path->output_format) {
4778             scale2yuv420 = 1;
4779         }
4780
4781         DCAM_TRACE("DCAM: _dcam_write_sc_coeff {%d %d %d %d}, 420=%d \n",
4782                 path->sc_input_size.w,
4783                 path->sc_input_size.h,
4784                 path->output_size.w,
4785                 path->output_size.h, scale2yuv420);
4786
4787         for (i = 0; i < DCAM_SC_COEFF_H_NUM; i++) {
4788                 REG_WR(h_coeff_addr, *h_coeff);
4789                 h_coeff_addr += 4;
4790                 h_coeff++;
4791         }
4792
4793         for (i = 0; i < DCAM_SC_COEFF_V_NUM; i++) {
4794                 REG_WR(v_coeff_addr, *v_coeff);
4795                 v_coeff_addr += 4;
4796                 v_coeff++;
4797         }
4798
4799         for (i = 0; i < DCAM_SC_COEFF_V_CHROMA_NUM; i++) {
4800                 REG_WR(v_chroma_coeff_addr, *v_chroma_coeff);
4801                 v_chroma_coeff_addr += 4;
4802                 v_chroma_coeff++;
4803         }
4804
4805         DCAM_TRACE("DCAM: _dcam_write_sc_coeff E \n");
4806
4807         return ret;
4808 }
4809
4810 LOCAL int32_t _dcam_calc_sc_coeff(enum dcam_path_index path_index)
4811 {
4812         unsigned long           flag;
4813         struct dcam_path_desc   *path = NULL;
4814         uint32_t                h_coeff_addr = DCAM_BASE;
4815         uint32_t                v_coeff_addr  = DCAM_BASE;
4816         uint32_t                v_chroma_coeff_addr  = DCAM_BASE;
4817         uint32_t                *tmp_buf = NULL;
4818         uint32_t                *h_coeff = NULL;
4819         uint32_t                *v_coeff = NULL;
4820         uint32_t                *v_chroma_coeff = NULL;
4821         uint32_t                clk_switch_bit = 0;
4822         uint32_t                clk_switch_shift_bit = 0;
4823         uint32_t                clk_status_bit = 0;
4824         uint32_t                ver_tap_reg = 0;
4825         uint32_t                scale2yuv420 = 0;
4826         uint8_t                 y_tap = 0;
4827         uint8_t                 uv_tap = 0;
4828         uint32_t                index = 0;
4829         struct dcam_sc_coeff    *sc_coeff;
4830
4831         DCAM_CHECK_ZERO(s_p_dcam_mod);
4832         DCAM_CHECK_ZERO(s_dcam_sc_array);
4833
4834         if (DCAM_PATH_IDX_1 != path_index && DCAM_PATH_IDX_2 != path_index)
4835                 return -DCAM_RTN_PARA_ERR;
4836
4837         if (DCAM_PATH_IDX_1 == path_index) {
4838                 path = &s_p_dcam_mod->dcam_path1;
4839                 h_coeff_addr += DCAM_SC1_H_TAB_OFFSET;
4840                 v_coeff_addr += DCAM_SC1_V_TAB_OFFSET;
4841                 v_chroma_coeff_addr += DCAM_SC1_V_CHROMA_TAB_OFFSET;
4842                 clk_switch_bit = BIT_3;
4843                 clk_switch_shift_bit = 3;
4844                 clk_status_bit = BIT_5;
4845                 ver_tap_reg = DCAM_PATH1_CFG;
4846         } else if (DCAM_PATH_IDX_2 == path_index) {
4847                 path = &s_p_dcam_mod->dcam_path2;
4848                 h_coeff_addr += DCAM_SC2_H_TAB_OFFSET;
4849                 v_coeff_addr += DCAM_SC2_V_TAB_OFFSET;
4850                 v_chroma_coeff_addr += DCAM_SC2_V_CHROMA_TAB_OFFSET;
4851                 clk_switch_bit = BIT_4;
4852                 clk_switch_shift_bit = 4;
4853                 clk_status_bit = BIT_6;
4854                 ver_tap_reg = DCAM_PATH2_CFG;
4855         }
4856
4857         if (DCAM_YUV420 == path->output_format) {
4858             scale2yuv420 = 1;
4859         }
4860
4861         DCAM_TRACE("DCAM: _dcam_calc_sc_coeff {%d %d %d %d}, 420=%d \n",
4862                 path->sc_input_size.w,
4863                 path->sc_input_size.h,
4864                 path->output_size.w,
4865                 path->output_size.h, scale2yuv420);
4866
4867         down(&s_p_dcam_mod->scale_coeff_mem_sema);
4868
4869         spin_lock_irqsave(&dcam_lock,flag);
4870         tmp_buf = dcam_get_scale_coeff_addr(&index);
4871         if (NULL == tmp_buf) {
4872                 _dcam_pop_sc_buf(s_dcam_sc_array, &sc_coeff);
4873                 tmp_buf = dcam_get_scale_coeff_addr(&index);
4874         }
4875         spin_unlock_irqrestore(&dcam_lock,flag);
4876
4877         if (NULL == tmp_buf) {
4878                 return -DCAM_RTN_PATH_NO_MEM;
4879         }
4880
4881         h_coeff = tmp_buf;
4882         v_coeff = tmp_buf + (DCAM_SC_COEFF_COEF_SIZE/4);
4883         v_chroma_coeff = v_coeff + (DCAM_SC_COEFF_COEF_SIZE/4);
4884
4885         if (!(Dcam_GenScaleCoeff((int16_t)path->sc_input_size.w,
4886                 (int16_t)path->sc_input_size.h,
4887                 (int16_t)path->output_size.w,
4888                 (int16_t)path->output_size.h,
4889                 h_coeff,
4890                 v_coeff,
4891                 v_chroma_coeff,
4892                 scale2yuv420,
4893                 &y_tap,
4894                 &uv_tap,
4895                 tmp_buf + (DCAM_SC_COEFF_COEF_SIZE*3/4),
4896                 DCAM_SC_COEFF_TMP_SIZE))) {
4897                 printk("DCAM: _dcam_calc_sc_coeff Dcam_GenScaleCoeff error! \n");
4898                 up(&s_p_dcam_mod->scale_coeff_mem_sema);
4899                 return -DCAM_RTN_PATH_GEN_COEFF_ERR;
4900         }
4901         path->scale_tap.y_tap = y_tap;
4902         path->scale_tap.uv_tap = uv_tap;
4903         path->valid_param.scale_tap = 1;
4904         memcpy(&s_dcam_sc_array->scaling_coeff[index].dcam_path1, path, sizeof(struct dcam_path_desc));
4905         spin_lock_irqsave(&dcam_lock,flag);
4906         _dcam_push_sc_buf(s_dcam_sc_array, index);
4907         spin_unlock_irqrestore(&dcam_lock,flag);
4908
4909         up(&s_p_dcam_mod->scale_coeff_mem_sema);
4910         DCAM_TRACE("DCAM: _dcam_calc_sc_coeff E \n");
4911
4912         return DCAM_RTN_SUCCESS;
4913 }