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