2 * Copyright (C) 2012 Spreadtrum Communications Inc.
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.
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.
13 #include <linux/module.h>
14 #include <linux/delay.h>
15 #include <linux/errno.h>
17 #include <linux/kernel.h>
19 #include <linux/ioport.h>
20 #include <linux/init.h>
21 #include <linux/sched.h>
22 #include <linux/version.h>
23 #include <linux/mutex.h>
24 #include <linux/interrupt.h>
25 #include <linux/kthread.h>
26 #include <linux/highmem.h>
27 #include <linux/freezer.h>
28 #include <linux/platform_device.h>
29 #include <linux/miscdevice.h>
31 #include <soc/sprd/board.h>
32 #include <soc/sprd/hardware.h>
33 #include <soc/sprd/adi.h>
35 #include <linux/module.h>
36 #include <linux/slab.h>
37 #include <linux/proc_fs.h>
39 #include <linux/of_device.h>
41 #include <linux/vmalloc.h>
47 #include <../flash/flash.h>
48 #include <video/sprd_img.h>
50 #include "../../sprd_sensor/csi2/csi_api.h"
52 //#define LOCAL static
55 #define IMG_DEVICE_NAME "sprd_image"
56 #define IMAGE_MINOR MISC_DYNAMIC_MINOR
57 #define DCAM_INVALID_FOURCC 0xFFFFFFFF
58 #define DCAM_MAJOR_VERSION 1
59 #define DCAM_MINOR_VERSION 0
60 #define DCAM_RELEASE 0
61 #define DCAM_QUEUE_LENGTH 16
62 #define DCAM_TIMING_LEN 16
64 #define DCAM_TIMEOUT (2000*100)
66 #define DCAM_TIMEOUT 1500
69 #define DCAM_ZOOM_LEVEL_MAX 4
70 #define DCAM_ZOOM_STEP(x, y) (((x) - (y)) / DCAM_ZOOM_LEVEL_MAX)
71 #define DCAM_PIXEL_ALIGNED 4
72 #define DCAM_WIDTH(w) ((w)& ~(DCAM_PIXEL_ALIGNED - 1))
73 #define DCAM_HEIGHT(h) ((h)& ~(DCAM_PIXEL_ALIGNED - 1))
75 #define DEBUG_STR "Error L %d, %s: \n"
76 #define DEBUG_ARGS __LINE__,__FUNCTION__
77 #define IMG_RTN_IF_ERR(n) \
80 printk(DEBUG_STR,DEBUG_ARGS); \
85 #define IMG_PRINT_IF_ERR(n) \
88 printk(DEBUG_STR,DEBUG_ARGS); \
92 #define DCAM_VERSION \
93 KERNEL_VERSION(DCAM_MAJOR_VERSION, DCAM_MINOR_VERSION, DCAM_RELEASE)
95 typedef int (*path_cfg_func)(enum dcam_cfg_id, void *);
120 uint32_t invalid_flag;
125 struct dcam_node node[DCAM_QUEUE_LENGTH];
126 struct dcam_node *write;
127 struct dcam_node *read;
132 struct dcam_img_buf_addr {
133 struct dcam_addr frm_addr;
134 struct dcam_addr frm_addr_vir;
137 struct dcam_img_buf_queue {
138 struct dcam_img_buf_addr buf_addr[DCAM_FRM_CNT_MAX];
139 struct dcam_img_buf_addr *write;
140 struct dcam_img_buf_addr *read;
145 struct dcam_path_spec {
147 uint32_t is_from_isp;
150 struct dcam_size in_size;
151 struct dcam_path_dec img_deci;
152 struct dcam_rect in_rect;
153 struct dcam_rect in_rect_current;
154 struct dcam_rect in_rect_backup;
155 struct dcam_size out_size;
156 enum dcam_fmt out_fmt;
157 struct dcam_endian_sel end_sel;
159 uint32_t pixel_depth;
160 uint32_t frm_id_base;
162 uint32_t index[DCAM_FRM_CNT_MAX];
163 //struct dcam_addr frm_addr[DCAM_FRM_CNT_MAX];
164 //struct dcam_addr frm_addr_vir[DCAM_FRM_CNT_MAX];
165 struct dcam_img_buf_queue buf_queue;
166 struct dcam_addr frm_reserved_addr;
167 struct dcam_addr frm_reserved_addr_vir;
168 struct dcam_frame *frm_ptr[DCAM_FRM_CNT_MAX];
169 uint32_t frm_cnt_act;
170 uint32_t path_frm_deci;
182 struct dcam_cap_sync_pol sync_pol;
184 struct dcam_cap_dec img_deci;
185 struct dcam_size cap_in_size;
186 struct dcam_rect cap_in_rect;
187 struct dcam_size cap_out_size;
188 struct dcam_size dst_size;
190 uint32_t need_isp_tool;
192 uint32_t need_shrink;
193 struct dcam_rect path_input_rect;
195 struct dcam_path_spec dcam_path[DCAM_PATH_NUM];
197 uint32_t capture_mode;
198 uint32_t skip_number;
199 uint32_t flash_status;
201 uint32_t is_smooth_zoom;
202 struct timeval timestamp;
203 struct timeval frame_last_timestamp;
208 struct mutex dcam_mutex;
209 struct semaphore irq_sem;
211 struct dcam_info dcam_cxt;
213 uint32_t stream_mode;
214 struct dcam_queue queue;
215 struct timer_list dcam_timer;
217 uint32_t got_resizer;
218 struct proc_dir_entry* proc_file;
219 struct semaphore flash_thread_sem;
220 struct task_struct* flash_thread;
221 uint32_t is_flash_thread_stop;
222 uint32_t frame_skipped;
223 struct semaphore zoom_thread_sem;
224 struct task_struct* zoom_thread;
225 uint32_t is_zoom_thread_stop;
231 #ifndef __SIMULATOR__
232 LOCAL int sprd_img_tx_done(struct dcam_frame *frame, void* param);
233 LOCAL int sprd_img_tx_error(struct dcam_frame *frame, void* param);
234 LOCAL int sprd_img_no_mem(struct dcam_frame *frame, void* param);
235 LOCAL int sprd_img_queue_write(struct dcam_queue *queue, struct dcam_node *node);
236 LOCAL int sprd_img_queue_read(struct dcam_queue *queue, struct dcam_node *node);
237 LOCAL int sprd_img_queue_disable(struct dcam_queue *queue, uint32_t channel_id);
238 LOCAL int sprd_img_queue_enable(struct dcam_queue *queue, uint32_t channel_id);
239 LOCAL int sprd_img_buf_queue_init(struct dcam_img_buf_queue *queue);
240 LOCAL int sprd_img_queue_init(struct dcam_queue *queue);
241 LOCAL int sprd_img_buf_queue_write(struct dcam_img_buf_queue *queue, struct dcam_img_buf_addr *buf_addr);
242 LOCAL int sprd_img_buf_queue_read(struct dcam_img_buf_queue *queue, struct dcam_img_buf_addr *buf_addr);
243 LOCAL int sprd_start_timer(struct timer_list *dcam_timer, uint32_t time_val);
244 LOCAL int sprd_stop_timer(struct timer_list *dcam_timer);
245 LOCAL int sprd_img_streampause(struct file *file, uint32_t channel_id, uint32_t reconfig_flag);
246 LOCAL int sprd_img_streamresume(struct file *file, uint32_t channel_id);
247 LOCAL int sprd_img_reg_isr(struct dcam_dev* param);
248 LOCAL int sprd_img_reg_path2_isr(struct dcam_dev* param);
249 LOCAL int sprd_img_unreg_isr(struct dcam_dev* param);
250 LOCAL int sprd_img_unreg_path2_isr(struct dcam_dev* param);
251 /*LOCAL int sprd_img_proc_read(char *page, char **start,off_t off, int count, int *eof, void *data);*/
252 LOCAL void sprd_img_print_reg(void);
253 LOCAL int sprd_img_start_zoom(struct dcam_frame *frame, void* param);
254 LOCAL int sprd_img_path_cfg_output_addr(path_cfg_func path_cfg, struct dcam_path_spec* path_spec);
255 LOCAL int sprd_img_local_clear_path_buffer(struct dcam_dev *dev, int path_id);
257 LOCAL struct dcam_format dcam_img_fmt[] = {
259 .name = "4:2:2, packed, YUYV",
260 .fourcc = IMG_PIX_FMT_YUYV,
264 .name = "4:2:2, packed, YVYU",
265 .fourcc = IMG_PIX_FMT_YVYU,
269 .name = "4:2:2, packed, UYVY",
270 .fourcc = IMG_PIX_FMT_UYVY,
274 .name = "4:2:2, packed, VYUY",
275 .fourcc = IMG_PIX_FMT_VYUY,
279 .name = "YUV 4:2:2, planar, (Y-Cb-Cr)",
280 .fourcc = IMG_PIX_FMT_YUV422P,
284 .name = "YUV 4:2:0 planar (Y-CbCr)",
285 .fourcc = IMG_PIX_FMT_NV12,
289 .name = "YVU 4:2:0 planar (Y-CrCb)",
290 .fourcc = IMG_PIX_FMT_NV21,
295 .name = "YUV 4:2:0 planar (Y-Cb-Cr)",
296 .fourcc = IMG_PIX_FMT_YUV420,
300 .name = "YVU 4:2:0 planar (Y-Cr-Cb)",
301 .fourcc = IMG_PIX_FMT_YVU420,
305 .name = "RGB565 (LE)",
306 .fourcc = IMG_PIX_FMT_RGB565,
310 .name = "RGB565 (BE)",
311 .fourcc = IMG_PIX_FMT_RGB565X,
316 .fourcc = IMG_PIX_FMT_GREY,
321 .fourcc = IMG_PIX_FMT_JPEG,
326 LOCAL struct dcam_format dcam_img_fmt[] = {
327 {"4:2:2, packed, YUYV", IMG_PIX_FMT_YUYV, 16},
328 {"4:2:2, packed, YVYU", IMG_PIX_FMT_YVYU, 16},
329 {"4:2:2, packed, UYVY", IMG_PIX_FMT_UYVY, 16},
330 {"4:2:2, packed, VYUY", IMG_PIX_FMT_VYUY, 16},
331 {"YUV 4:2:2, planar, (Y-Cb-Cr)", IMG_PIX_FMT_YUV422P, 16},
332 {"YUV 4:2:0 planar (Y-CbCr)", IMG_PIX_FMT_NV12, 12},
333 {"YVU 4:2:0 planar (Y-CrCb)", IMG_PIX_FMT_NV21, 12},
334 {"YUV 4:2:0 planar (Y-Cb-Cr)", IMG_PIX_FMT_YUV420, 12},
335 {"YVU 4:2:0 planar (Y-Cr-Cb)", IMG_PIX_FMT_YVU420, 12},
336 {"RGB565 (LE)", IMG_PIX_FMT_RGB565, 16},
337 {"RGB565 (BE)", IMG_PIX_FMT_RGB565X, 16},
338 {"RawRGB", IMG_PIX_FMT_GREY, 8},
339 {"JPEG", IMG_PIX_FMT_JPEG, 8}
343 enum cmr_flash_status {
346 FLASH_TORCH = 0x2, /*user only set flash to close/open/torch state */
348 FLASH_CLOSE_AFTER_OPEN = 0x10, /* following is set to sensor */
349 FLASH_HIGH_LIGHT = 0x11,
350 FLASH_OPEN_ON_RECORDING = 0x22,
351 FLASH_CLOSE_AFTER_AUTOFOCUS = 0x30,
355 #define DISCARD_FRAME_TIME (10000)
357 LOCAL int img_get_timestamp(struct timeval *tv)
362 tv->tv_sec = ts.tv_sec;
363 tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
366 extern int flash_torch_status;
367 LOCAL int sprd_img_setflash(uint32_t flash_mode)
369 if(flash_torch_status==1)
371 switch (flash_mode) {
372 case FLASH_OPEN: /*flash on */
373 case FLASH_TORCH: /*for torch */
377 case FLASH_HIGH_LIGHT:
379 sprd_flash_high_light();
381 case FLASH_CLOSE_AFTER_OPEN: /*close flash */
382 case FLASH_CLOSE_AFTER_AUTOFOCUS:
388 printk("sprd_img_setflash unknow mode:flash_mode 0x%x \n", flash_mode);
392 DCAM_TRACE("sprd_img_setflash: flash_mode 0x%x \n", flash_mode);
397 LOCAL int sprd_img_opt_flash(struct dcam_frame *frame, void* param)
399 struct dcam_dev *dev = (struct dcam_dev*)param;
400 struct dcam_info *info = NULL;
403 DCAM_TRACE("SPRD_IMG: sprd_img_opt_flash, dev is NULL \n");
407 info = &dev->dcam_cxt;
408 if (info->flash_status < FLASH_STATUS_MAX) {
409 DCAM_TRACE("SPRD_IMG: sprd_img_opt_flash, status %d \n", info->flash_status);
410 if(info->flash_status == FLASH_CLOSE_AFTER_AUTOFOCUS) {
411 img_get_timestamp(&info->timestamp);
413 DCAM_TRACE("SPRD_IMG: sprd_img_opt_flash, time, %d %d \n",
414 (int)info->timestamp.tv_sec, (int)info->timestamp.tv_usec);
416 sprd_img_setflash(info->flash_status);
417 info->flash_status = FLASH_STATUS_MAX;
423 LOCAL int sprd_img_start_flash(struct dcam_frame *frame, void* param)
425 struct dcam_dev *dev = (struct dcam_dev*)param;
426 struct dcam_info *info = NULL;
427 uint32_t need_light = 1;
430 DCAM_TRACE("SPRD_IMG: sprd_img_start_flash, dev is NULL \n");
434 info = &dev->dcam_cxt;
435 if (info->flash_status < FLASH_STATUS_MAX) {
436 if (FLASH_HIGH_LIGHT == info->flash_status) {
437 dev->frame_skipped ++;
438 if (dev->frame_skipped >= info->skip_number) {
439 //flash lighted at the last SOF before the right capture frame
440 DCAM_TRACE("V4L2: waiting finished \n");
443 DCAM_TRACE("V4L2: wait for the next SOF, %d ,%d \n",
444 dev->frame_skipped, info->skip_number);
448 up(&dev->flash_thread_sem);
455 int flash_thread_loop(void *arg)
457 struct dcam_dev *dev = (struct dcam_dev*)arg;
460 DCAM_TRACE("SPRD_IMG: flash_thread_loop, dev is NULL \n");
464 if (0 == down_interruptible(&dev->flash_thread_sem)) {
465 if (dev->is_flash_thread_stop) {
466 sprd_img_setflash(0);
467 DCAM_TRACE("SPRD_IMG: flash_thread_loop stop \n");
470 sprd_img_opt_flash(NULL, arg);
472 DCAM_TRACE("SPRD_IMG: flash int!");
476 dev->is_flash_thread_stop = 0;
481 int dcam_create_flash_thread(void* param)
483 struct dcam_dev *dev = (struct dcam_dev*)param;
486 DCAM_TRACE("SPRD_IMG: dcam_create_flash_thread, dev is NULL \n");
489 dev->is_flash_thread_stop = 0;
490 sema_init(&dev->flash_thread_sem, 0);
491 dev->flash_thread = kthread_run(flash_thread_loop, param, "dcam_flash_thread");
492 if (IS_ERR(dev->flash_thread)) {
493 printk("SPRD_IMG: dcam_create_flash_thread error!\n");
499 int dcam_stop_flash_thread(void* param)
501 struct dcam_dev *dev = (struct dcam_dev*)param;
505 DCAM_TRACE("SPRD_IMG: sprd_img_opt_flash, dev is NULL \n");
508 if (dev->flash_thread) {
509 dev->is_flash_thread_stop = 1;
510 up(&dev->flash_thread_sem);
511 if (0 != dev->is_flash_thread_stop) {
514 if (0 == dev->is_flash_thread_stop)
519 dev->flash_thread = NULL;
525 LOCAL int sprd_img_discard_frame(struct dcam_frame *frame, void* param)
527 int ret = DCAM_RTN_PARA_ERR;
528 struct dcam_dev *dev = (struct dcam_dev*)param;
529 struct dcam_info *info = NULL;
530 struct timeval timestamp;
533 info = &dev->dcam_cxt;
534 img_get_timestamp(×tamp);
535 DCAM_TRACE("SPRD_IMG: sprd_img_discard_frame, time, %d %d \n",
536 (int)timestamp.tv_sec, (int)timestamp.tv_usec);
537 if ((timestamp.tv_sec == info->timestamp.tv_sec)
538 && (timestamp.tv_usec -info->timestamp.tv_usec >= DISCARD_FRAME_TIME)){
540 } else if (timestamp.tv_sec > info->timestamp.tv_sec) {
541 if ((1000000 -info->timestamp.tv_sec) + timestamp.tv_sec >= DISCARD_FRAME_TIME) {
547 DCAM_TRACE("SPRD_IMG: sprd_img_discard_frame,unlock frame %p \n", frame);
548 //dcam_frame_unlock(frame);
549 ret = DCAM_RTN_SUCCESS;
554 LOCAL struct dcam_format *sprd_img_get_format(uint32_t fourcc)
556 struct dcam_format *fmt;
559 for (i = 0; i < ARRAY_SIZE(dcam_img_fmt); i++) {
560 fmt = &dcam_img_fmt[i];
561 if (fmt->fourcc == fourcc)
565 if (unlikely(i == ARRAY_SIZE(dcam_img_fmt)))
568 return &dcam_img_fmt[i];
571 LOCAL uint32_t sprd_img_get_fourcc(struct dcam_path_spec *path)
573 uint32_t fourcc = DCAM_INVALID_FOURCC;
575 switch (path->out_fmt) {
577 fourcc = IMG_PIX_FMT_YUV422P;
580 if (likely(DCAM_ENDIAN_LITTLE == path->end_sel.uv_endian))
581 fourcc = IMG_PIX_FMT_NV12;
583 fourcc = IMG_PIX_FMT_NV21;
585 case DCAM_YUV420_3FRAME:
586 fourcc = IMG_PIX_FMT_YUV420;
589 if (likely(DCAM_ENDIAN_HALFBIG == path->end_sel.uv_endian))
590 fourcc = IMG_PIX_FMT_RGB565;
592 fourcc = IMG_PIX_FMT_RGB565X;
595 fourcc = IMG_PIX_FMT_GREY;
598 fourcc = IMG_PIX_FMT_JPEG;
606 LOCAL uint32_t sprd_img_get_deci_factor(uint32_t src_size, uint32_t dst_size)
610 if (0 == src_size || 0 == dst_size) {
614 for (factor = 0; factor < DCAM_CAP_X_DECI_FAC_MAX; factor ++) {
615 if (src_size < (uint32_t)(dst_size * (1 << factor))) {
623 LOCAL uint32_t sprd_img_endian_sel(uint32_t fourcc, struct dcam_path_spec *path)
627 if (IMG_PIX_FMT_YUV422P == fourcc ||
628 IMG_PIX_FMT_RGB565 == fourcc ||
629 IMG_PIX_FMT_RGB565X == fourcc) {
631 if (IMG_PIX_FMT_YUV422P == fourcc) {
632 path->out_fmt = DCAM_YUV422;
634 path->out_fmt = DCAM_RGB565;
635 if (IMG_PIX_FMT_RGB565 == fourcc) {
636 path->end_sel.y_endian = DCAM_ENDIAN_HALFBIG;
638 path->end_sel.y_endian = DCAM_ENDIAN_BIG;
643 if (IMG_PIX_FMT_YUV420 == fourcc ||
644 IMG_PIX_FMT_YVU420 == fourcc) {
645 path->out_fmt = DCAM_YUV420_3FRAME;
647 path->out_fmt = DCAM_YUV420;
648 if (IMG_PIX_FMT_NV12 == fourcc) {
649 path->end_sel.uv_endian = DCAM_ENDIAN_LITTLE;
651 path->end_sel.uv_endian = DCAM_ENDIAN_HALFBIG;
659 LOCAL int sprd_img_check_path0_cap(uint32_t fourcc,
660 struct sprd_img_format *f,
661 struct dcam_info *info)
663 struct dcam_path_spec *path = &info->dcam_path[DCAM_PATH0];
665 DCAM_TRACE("SPRD_IMG: check format for path0\n");
667 path->is_from_isp = f->need_isp;
668 path->rot_mode = f->reserved[0];
670 path->frm_type = f->channel_id;
672 DCAM_TRACE("zcf sprd_img_check_path0_cap rot_mode:%d\n",path->rot_mode);
675 case IMG_PIX_FMT_GREY:
676 path->out_fmt = info->is_loose; // 0 - word/packet, 1 - half word
679 case IMG_PIX_FMT_JPEG:
680 path->out_fmt = 0; // 0 - word, 1 - half word
681 path->end_sel.y_endian = DCAM_ENDIAN_LITTLE;
684 case IMG_PIX_FMT_YUYV:
685 path->out_fmt = DCAM_OUTPUT_YVYU_1FRAME;
686 path->end_sel.y_endian = DCAM_ENDIAN_LITTLE;
689 case IMG_PIX_FMT_NV21:
690 case IMG_PIX_FMT_NV12:
691 path->out_fmt = DCAM_OUTPUT_YUV420;
692 path->end_sel.y_endian = DCAM_ENDIAN_LITTLE;
693 if (IMG_PIX_FMT_NV12 == fourcc) {
694 path->end_sel.uv_endian = DCAM_ENDIAN_LITTLE;
696 path->end_sel.uv_endian = DCAM_ENDIAN_HALFBIG;
698 DCAM_TRACE("SPRD_IMG: path->end_sel.uv_endian=%d \n", path->end_sel.uv_endian);
702 printk("SPRD_IMG: unsupported image format for path0 0x%x \n", fourcc);
705 path->fourcc = fourcc;
707 DCAM_TRACE("SPRD_IMG: check format for path0: out_fmt=%d, is_loose=%d \n", path->out_fmt, info->is_loose);
708 path->out_size.w = f->width;
709 path->out_size.h = f->height;
716 LOCAL int sprd_img_check_path1_cap(uint32_t fourcc,
717 struct sprd_img_format *f,
718 struct dcam_info *info)
720 uint32_t maxw, maxh, tempw,temph;
721 uint32_t depth_pixel = 0;
722 struct dcam_path_spec *path = &info->dcam_path[DCAM_PATH1];
723 uint32_t need_recal = 0;
725 DCAM_TRACE("SPRD_IMG: check format for path1 \n");
727 path->frm_type = f->channel_id;
728 path->is_from_isp = f->need_isp;
729 path->rot_mode = f->reserved[0];
730 path->end_sel.y_endian = DCAM_ENDIAN_LITTLE;
731 path->end_sel.uv_endian = DCAM_ENDIAN_LITTLE;
733 path->pixel_depth = 0;
734 path->img_deci.x_factor = 0;
735 path->img_deci.y_factor = 0;
736 tempw = path->in_rect.w;
737 temph = path->in_rect.h;
738 info->img_deci.x_factor = 0;
740 DCAM_TRACE("zcf sprd_img_check_path1_cap rot_mode:%d\n",path->rot_mode);
741 /*app should fill in this field(fmt.pix.priv) to set the base index of frame buffer,
742 and lately this field will return the flag whether ISP is needed for this work path*/
745 case IMG_PIX_FMT_GREY:
746 case IMG_PIX_FMT_JPEG:
747 case IMG_PIX_FMT_YUYV:
748 case IMG_PIX_FMT_YVYU:
749 case IMG_PIX_FMT_UYVY:
750 case IMG_PIX_FMT_VYUY:
751 if (unlikely(f->width != tempw ||
752 f->height != temph)) {
753 /*need need scaling or triming*/
754 printk("SPRD_IMG: Can not scaling for this image fmt src %d %d, dst %d %d \n",
762 if (unlikely(DCAM_CAP_MODE_JPEG != info->sn_mode &&
763 IMG_PIX_FMT_JPEG == fourcc)) {
764 /* the output of sensor is not JPEG which is needed by app*/
765 printk("SPRD_IMG: It's not JPEG sensor \n");
769 if (unlikely(DCAM_CAP_MODE_RAWRGB != info->sn_mode &&
770 IMG_PIX_FMT_GREY == fourcc)) {
771 /* the output of sensor is not RawRGB which is needed by app*/
772 printk("SPRD_IMG: It's not RawRGB sensor \n");
776 if (IMG_PIX_FMT_GREY == fourcc) {
777 if (DCAM_CAP_IF_CSI2 == info->if_mode && 0 == info->is_loose) {
782 DCAM_TRACE("SPRD_IMG: RawRGB sensor, %d %d \n", info->is_loose, depth_pixel);
783 } else if (IMG_PIX_FMT_JPEG == fourcc) {
789 if (IMG_PIX_FMT_GREY == fourcc) {
790 path->out_fmt = DCAM_RAWRGB;
791 path->end_sel.y_endian = DCAM_ENDIAN_BIG;
793 path->out_fmt = DCAM_JPEG;
796 case IMG_PIX_FMT_YUV422P:
797 case IMG_PIX_FMT_YUV420:
798 case IMG_PIX_FMT_YVU420:
799 case IMG_PIX_FMT_NV12:
800 case IMG_PIX_FMT_NV21:
801 case IMG_PIX_FMT_RGB565:
802 case IMG_PIX_FMT_RGB565X:
803 if (DCAM_CAP_MODE_RAWRGB == info->sn_mode &&
805 if (unlikely(info->cap_out_size.w > DCAM_ISP_LINE_BUF_LENGTH)) {
806 if (0 == info->if_mode) {
807 /*CCIR CAP, no bining*/
808 printk("SPRD_IMG: CCIR CAP, no bining for this path, %d %d \n",
813 /*MIPI CAP, support 1/2 bining*/
814 DCAM_TRACE("Need Binning \n");
816 if (unlikely(tempw > DCAM_ISP_LINE_BUF_LENGTH)) {
817 printk("SPRD_IMG: the width is out of ISP line buffer, %d %d \n",
819 DCAM_ISP_LINE_BUF_LENGTH);
822 info->img_deci.x_factor = 1;
824 DCAM_TRACE("x_factor, %d \n", info->img_deci.x_factor);
825 path->in_size.w = path->in_size.w >> 1;
826 path->in_rect.x = path->in_rect.x >> 1;
827 path->in_rect.w = path->in_rect.w >> 1;
828 path->in_rect.w = path->in_rect.w & (~3);
832 if (DCAM_CAP_MODE_YUV == info->sn_mode ||
833 DCAM_CAP_MODE_SPI == info->sn_mode) {
834 if (tempw != f->width || temph != f->height) {
836 if (unlikely(f->width > DCAM_PATH1_LINE_BUF_LENGTH)) {
837 /*out of scaling capbility*/
838 printk("SPRD_IMG: the output width %d can not be more than %d \n",
840 DCAM_PATH1_LINE_BUF_LENGTH);
844 /* To check whether the output size is too lager*/
845 maxw = tempw * DCAM_SC_COEFF_UP_MAX;
846 maxh = temph * DCAM_SC_COEFF_UP_MAX;
847 if (unlikely(f->width > maxw || f->height > maxh)) {
848 /*out of scaling capbility*/
849 printk("SPRD_IMG: the output size is too large, %d %d \n",
855 /* To check whether the output size is too small*/
856 maxw = f->width * DCAM_SC_COEFF_DOWN_MAX;
857 if (unlikely( tempw > maxw)) {
858 path->img_deci.x_factor = sprd_img_get_deci_factor(tempw, maxw);
859 if (path->img_deci.x_factor > DCAM_PATH_DECI_FAC_MAX) {
860 printk("SPRD_IMG: the output size is too small, %d %d \n",
867 maxh = f->height * DCAM_SC_COEFF_DOWN_MAX;
868 if (unlikely(temph > maxh)) {
869 path->img_deci.y_factor = sprd_img_get_deci_factor(temph, maxh);
870 if (path->img_deci.y_factor > DCAM_PATH_DECI_FAC_MAX) {
871 printk("SPRD_IMG: the output size is too small, %d %d \n",
878 if (path->img_deci.x_factor) {
879 tempw = path->in_rect.w >> 1;
883 if (path->img_deci.y_factor) {
884 temph = path->in_rect.h >> 1;
888 if (need_recal && (tempw != f->width || temph != f->height)) {
890 if (unlikely(f->width > DCAM_PATH1_LINE_BUF_LENGTH)) {
891 /*out of scaling capbility*/
892 printk("SPRD_IMG: the output width %d can not be more than %d \n",
894 DCAM_PATH1_LINE_BUF_LENGTH);
899 } else if (DCAM_CAP_MODE_RAWRGB == info->sn_mode) {
900 if (path->is_from_isp) {
902 if (tempw != f->width ||
903 temph != f->height) {
905 maxw = f->width * DCAM_SC_COEFF_DOWN_MAX;
906 maxw = maxw * (1 << DCAM_PATH_DECI_FAC_MAX);
907 maxh = f->height * DCAM_SC_COEFF_DOWN_MAX;
908 maxh = maxh * (1 << DCAM_PATH_DECI_FAC_MAX);
909 if (unlikely(tempw > maxw || temph > maxh)) {
910 /*out of scaling capbility*/
911 printk("SPRD_IMG: the output size is too small, %d %d \n",
917 if (unlikely(f->width > DCAM_PATH1_LINE_BUF_LENGTH)) {
918 /*out of scaling capbility*/
919 printk("SPRD_IMG: the output width %d can not be more than %d \n",
921 DCAM_PATH1_LINE_BUF_LENGTH);
925 maxw = tempw * DCAM_SC_COEFF_UP_MAX;
926 maxh = temph * DCAM_SC_COEFF_UP_MAX;
927 if (unlikely(f->width > maxw || f->height > maxh)) {
928 /*out of scaling capbility*/
929 printk("SPRD_IMG: the output size is too large, %d %d \n",
936 /*no ISP ,only RawRGB data can be sampled*/
937 printk("SPRD_IMG: RawRGB sensor, no ISP, format 0x%x can't be supported \n",
943 depth_pixel = sprd_img_endian_sel(fourcc, path);
946 printk("SPRD_IMG: unsupported image format for path2 0x%x \n", fourcc);
950 path->fourcc = fourcc;
951 path->pixel_depth = depth_pixel;
952 f->bytesperline = (f->width * depth_pixel) >> 3;
953 path->out_size.w = f->width;
954 path->out_size.h = f->height;
959 LOCAL int sprd_img_check_path2_cap(uint32_t fourcc,
960 struct sprd_img_format *f,
961 struct dcam_info *info)
963 uint32_t maxw, maxh, tempw,temph;
964 uint32_t depth_pixel = 0;
965 struct dcam_path_spec *path = &info->dcam_path[DCAM_PATH2];
966 uint32_t need_recal = 0;
970 DCAM_TRACE("SPRD_IMG: check format for path2 \n");
972 path->frm_type = f->channel_id;
973 path->is_from_isp = f->need_isp;
974 path->rot_mode= f->reserved[0];
975 path->end_sel.y_endian = DCAM_ENDIAN_LITTLE;
976 path->end_sel.uv_endian = DCAM_ENDIAN_LITTLE;
978 path->pixel_depth = 0;
979 DCAM_TRACE("zcf sprd_img_check_path2_cap rot:%d\n",path->rot_mode);
980 if (info->img_deci.x_factor) {
981 tempw = path->in_rect.w >> 1;
982 path->in_size.w = path->in_size.w >> 1;
983 path->in_rect.w = path->in_rect.w >> 1;
984 path->in_rect.x = path->in_rect.x >> 1;
986 tempw = path->in_rect.w;
988 temph = path->in_rect.h;
990 case IMG_PIX_FMT_YUV422P:
991 case IMG_PIX_FMT_YUV420:
992 case IMG_PIX_FMT_YVU420:
993 case IMG_PIX_FMT_NV12:
994 case IMG_PIX_FMT_NV21:
996 if (DCAM_CAP_MODE_JPEG == info->sn_mode ||
997 info->sn_mode >= DCAM_CAP_MODE_MAX) {
1001 if (DCAM_CAP_MODE_RAWRGB == info->sn_mode) {
1002 path->is_from_isp = 1;
1005 if (DCAM_CAP_MODE_YUV == info->sn_mode ||
1006 DCAM_CAP_MODE_SPI == info->sn_mode) {
1007 if (tempw != f->width || temph != f->height) {
1009 if (unlikely(f->width > DCAM_PATH2_LINE_BUF_LENGTH)) {
1010 /*out of scaling capbility*/
1011 printk("SPRD_IMG: the output width %d can not be more than %d \n",
1013 DCAM_PATH2_LINE_BUF_LENGTH);
1017 /* To check whether the output size is too lager*/
1018 maxw = tempw * DCAM_SC_COEFF_UP_MAX;
1019 maxh = temph * DCAM_SC_COEFF_UP_MAX;
1020 if (unlikely(f->width > maxw || f->height > maxh)) {
1021 /*out of scaling capbility*/
1022 printk("SPRD_IMG: the output size is too large, %d %d \n",
1028 /* To check whether the output size is too small*/
1029 maxw = f->width * DCAM_SC_COEFF_DOWN_MAX;
1030 if (unlikely( tempw > maxw)) {
1031 path->img_deci.x_factor = sprd_img_get_deci_factor(tempw, maxw);
1032 if (path->img_deci.x_factor > DCAM_PATH_DECI_FAC_MAX) {
1033 printk("SPRD_IMG: the output size is too small, %d %d \n",
1040 maxh = f->height * DCAM_SC_COEFF_DOWN_MAX;
1041 if (unlikely(temph > maxh)) {
1042 path->img_deci.y_factor = sprd_img_get_deci_factor(temph, maxh);
1043 if (path->img_deci.y_factor > DCAM_PATH_DECI_FAC_MAX) {
1044 printk("SPRD_IMG: the output size is too small, %d %d \n",
1051 if (path->img_deci.x_factor) {
1052 tempw = path->in_rect.w >> 1;
1056 if (path->img_deci.y_factor) {
1057 temph = path->in_rect.h >> 1;
1061 if (need_recal && (tempw != f->width || temph != f->height)) {
1063 if (unlikely(f->width > DCAM_PATH2_LINE_BUF_LENGTH)) {
1064 /*out of scaling capbility*/
1065 printk("SPRD_IMG: the output width %d can not be more than %d \n",
1067 DCAM_PATH2_LINE_BUF_LENGTH);
1072 } else if (DCAM_CAP_MODE_RAWRGB == info->sn_mode) {
1073 if (path->is_from_isp) {
1075 if (tempw != f->width ||
1076 temph != f->height) {
1078 maxw = f->width * DCAM_SC_COEFF_DOWN_MAX;
1079 maxw = maxw * (1 << DCAM_PATH_DECI_FAC_MAX);
1080 maxh = f->height * DCAM_SC_COEFF_DOWN_MAX;
1081 maxh = maxh * (1 << DCAM_PATH_DECI_FAC_MAX);
1082 if (unlikely(tempw > maxw || temph > maxh)) {
1083 /*out of scaling capbility*/
1084 printk("SPRD_IMG: the output size is too small, %d %d \n",
1090 if (unlikely(f->width > DCAM_PATH2_LINE_BUF_LENGTH)) {
1091 /*out of scaling capbility*/
1092 printk("SPRD_IMG: the output width %d can not be more than %d \n",
1094 DCAM_PATH2_LINE_BUF_LENGTH);
1098 maxw = tempw * DCAM_SC_COEFF_UP_MAX;
1099 maxh = temph * DCAM_SC_COEFF_UP_MAX;
1100 if (unlikely(f->width > maxw || f->height > maxh)) {
1101 /*out of scaling capbility*/
1102 printk("SPRD_IMG: the output size is too large, %d %d \n",
1109 /*no ISP ,only RawRGB data can be sampled*/
1110 printk("SPRD_IMG: RawRGB sensor, no ISP, format 0x%x can't be supported \n",
1117 depth_pixel = sprd_img_endian_sel(fourcc, path);
1118 //path->end_sel.uv_endian = DCAM_ENDIAN_LITTLE; // tmp fix: output is vu, jpeg only support vu
1121 printk("SPRD_IMG: unsupported image format for path2 0x%x \n", fourcc);
1125 path->fourcc = fourcc;
1126 f->need_isp = path->is_from_isp;
1127 path->pixel_depth = depth_pixel;
1128 f->bytesperline = (f->width * depth_pixel) >> 3;
1129 path->out_size.w = f->width;
1130 path->out_size.h = f->height;
1136 LOCAL int sprd_img_cap_cfg(struct dcam_info* info)
1138 int ret = DCAM_RTN_SUCCESS;
1144 ret = dcam_cap_cfg(DCAM_CAP_SYNC_POL, &info->sync_pol);
1145 IMG_RTN_IF_ERR(ret);
1147 if ((info->dcam_path[DCAM_PATH0].is_work && info->dcam_path[DCAM_PATH0].is_from_isp) ||
1148 (info->dcam_path[DCAM_PATH1].is_work && info->dcam_path[DCAM_PATH1].is_from_isp) ||
1149 (info->dcam_path[DCAM_PATH2].is_work && info->dcam_path[DCAM_PATH2].is_from_isp)) {
1154 ret = dcam_cap_cfg(DCAM_CAP_TO_ISP, ¶m);
1155 IMG_RTN_IF_ERR(ret);
1157 ret = dcam_cap_cfg(DCAM_CAP_YUV_TYPE, &info->yuv_ptn);
1158 IMG_RTN_IF_ERR(ret);
1160 ret = dcam_cap_cfg(DCAM_CAP_DATA_BITS, &info->data_bits);
1161 IMG_RTN_IF_ERR(ret);
1163 if (DCAM_CAP_MODE_RAWRGB == info->sn_mode &&
1164 DCAM_CAP_IF_CSI2 == info->if_mode)
1166 ret = dcam_cap_cfg(DCAM_CAP_DATA_PACKET, &info->is_loose);
1167 IMG_RTN_IF_ERR(ret);
1170 ret = dcam_cap_cfg(DCAM_CAP_FRM_DECI, &info->frm_deci);
1171 IMG_RTN_IF_ERR(ret);
1173 ret = dcam_cap_cfg(DCAM_CAP_INPUT_RECT, &info->cap_in_rect);
1174 IMG_RTN_IF_ERR(ret);
1176 ret = dcam_cap_cfg(DCAM_CAP_FRM_COUNT_CLR, NULL);
1177 IMG_RTN_IF_ERR(ret);
1179 ret = dcam_cap_cfg(DCAM_CAP_PRE_SKIP_CNT, &info->skip_number);
1180 IMG_RTN_IF_ERR(ret);
1182 ret = dcam_cap_cfg(DCAM_CAP_SAMPLE_MODE, &info->capture_mode);
1183 IMG_RTN_IF_ERR(ret);
1185 ret = dcam_cap_cfg(DCAM_CAP_ZOOM_MODE, &info->is_smooth_zoom);
1187 ret = dcam_cap_cfg(DCAM_CAP_IMAGE_XY_DECI, &info->img_deci);
1193 LOCAL void sprd_img_frm_pop(struct dcam_frame *frame, void* param)
1197 uint32_t frame_count = 0;
1198 struct dcam_path_spec *path = NULL;
1199 struct dcam_dev *dev = (struct dcam_dev*)param;
1200 struct dcam_info *info = NULL;
1202 info = &dev->dcam_cxt;
1204 switch (frame->type) {
1206 path = &info->dcam_path[DCAM_PATH0];
1209 path = &info->dcam_path[DCAM_PATH1];
1212 path = &info->dcam_path[DCAM_PATH2];
1215 printk("SPRD_IMG error: sprd_img_frm_pop, path 0x%x \n", frame->type);
1218 DCAM_TRACE("SPRD_IMG: sprd_img_frm_pop start, path 0x%x \n", frame->type);
1219 DCAM_TRACE("SPRD_IMG: sprd_img_frm_pop, yaddr 0x%x 0x%x \n", frame->yaddr, path->frm_addr[0].yaddr);
1220 if (frame->yaddr == path->frm_addr[0].yaddr) {
1221 for (i = 0; i < path->frm_cnt_act - 1; i++) {
1222 path->frm_addr[i] = path->frm_addr[i+1];
1223 path->frm_addr_vir[i] = path->frm_addr_vir[i+1];
1225 path->frm_cnt_act--;
1226 memset(&path->frm_addr[path->frm_cnt_act], 0, sizeof(struct dcam_addr));
1227 memset(&path->frm_addr_vir[path->frm_cnt_act], 0, sizeof(struct dcam_addr));
1229 printk("SPRD_IMG error: sprd_img_frm_pop, yaddr 0x%x 0x%x \n", frame->yaddr, path->frm_addr[0].yaddr);
1231 DCAM_TRACE("SPRD_IMG: sprd_img_frm_pop end, path 0x%x yaddr 0x%x \n", frame->type, frame->yaddr);
1236 LOCAL int sprd_img_tx_done(struct dcam_frame *frame, void* param)
1238 int ret = DCAM_RTN_SUCCESS;
1239 struct dcam_dev *dev = (struct dcam_dev*)param;
1240 struct dcam_path_spec *path;
1241 struct dcam_node node;
1243 struct dcam_img_buf_addr buf_addr;
1245 if (NULL == frame || NULL == param || 0 == atomic_read(&dev->stream_on))
1247 path = &dev->dcam_cxt.dcam_path[frame->type];
1248 if (PATH_IDLE == path->status) {
1252 atomic_set(&dev->run_flag, 1);
1254 memset((void*)&node, 0, sizeof(struct dcam_node));
1255 node.irq_flag = IMG_TX_DONE;
1256 node.f_type = frame->type;
1257 node.index = frame->fid;
1258 node.height = frame->height;
1259 node.yaddr = frame->yaddr;
1260 node.uaddr = frame->uaddr;
1261 node.vaddr = frame->vaddr;
1262 node.yaddr_vir = frame->yaddr_vir;
1263 node.uaddr_vir = frame->uaddr_vir;
1264 node.vaddr_vir = frame->vaddr_vir;
1266 DCAM_TRACE("SPRD_IMG: flag 0x%x type 0x%x index 0x%x \n",
1267 node.irq_flag, node.f_type, node.index);
1269 /* path = &dev->dcam_cxt.dcam_path[frame->type];
1270 ret = sprd_img_buf_queue_read(&path->buf_queue, &buf_addr);
1274 node.yaddr_vir = buf_addr.frm_addr_vir.yaddr;
1275 node.uaddr_vir = buf_addr.frm_addr_vir.uaddr;
1276 node.vaddr_vir = buf_addr.frm_addr_vir.vaddr;
1279 //printk("SPRD_IMG: DCAM_PATH = %d\n", frame->type);
1281 if (DCAM_PATH0 == frame->type && DCAM_CAP_MODE_JPEG == dev->dcam_cxt.sn_mode) {
1282 dcam_cap_get_info(DCAM_CAP_JPEG_GET_LENGTH, &node.reserved);
1283 printk("SPRD_IMG: JPEG length 0x%x \n", node.reserved);
1284 if (node.reserved < DCAM_JPEG_LENGTH_MIN) {
1285 return sprd_img_tx_error(frame, param);
1289 #if defined(CONFIG_MACH_GRANDPRIME3G_VE) || defined(CONFIG_MACH_Z3)
1290 if (dev->dcam_cxt.after_af && DCAM_PATH1 == frame->type) {
1291 ret = sprd_img_discard_frame(frame, param);
1292 if (DCAM_RTN_SUCCESS == ret) {
1293 dev->dcam_cxt.after_af = 0;
1294 node.irq_flag = IMG_CANCELED_BUF;
1298 if (DCAM_PATH1 == frame->type) {
1299 ret = sprd_img_discard_frame(frame, param);
1300 if (DCAM_RTN_PARA_ERR == ret) {
1301 dev->dcam_cxt.after_af = 0;
1302 node.irq_flag = IMG_CANCELED_BUF;
1307 ret = sprd_img_queue_write(&dev->queue, &node);
1315 LOCAL int sprd_img_tx_error(struct dcam_frame *frame, void* param)
1317 int ret = DCAM_RTN_SUCCESS;
1318 struct dcam_dev *dev = (struct dcam_dev*)param;
1319 struct dcam_path_spec *path;
1320 struct dcam_node node;
1321 struct dcam_img_buf_addr buf_addr;
1323 if (NULL == param || 0 == atomic_read(&dev->stream_on))
1326 memset((void*)&node, 0, sizeof(struct dcam_node));
1327 atomic_set(&dev->run_flag, 1);//to avoid time out processing
1328 node.irq_flag = IMG_TX_ERR;
1329 if (NULL != frame) {
1330 node.f_type = frame->type;
1331 node.index = frame->fid;
1332 node.height = frame->height;
1333 node.yaddr = frame->yaddr;
1334 node.uaddr = frame->uaddr;
1335 node.vaddr = frame->vaddr;
1336 node.yaddr_vir = frame->yaddr_vir;
1337 node.uaddr_vir = frame->uaddr_vir;
1338 node.vaddr_vir = frame->vaddr_vir;
1340 /* path = &dev->dcam_cxt.dcam_path[frame->type];
1341 ret = sprd_img_buf_queue_read(&path->buf_queue, &buf_addr);
1345 node.yaddr_vir = buf_addr.frm_addr_vir.yaddr;
1346 node.uaddr_vir = buf_addr.frm_addr_vir.uaddr;
1347 node.vaddr_vir = buf_addr.frm_addr_vir.vaddr;*/
1349 ret = sprd_img_queue_write(&dev->queue, &node);
1355 printk("SPRD_IMG: tx_error \n");
1356 //mm_clk_register_trace();
1360 LOCAL int sprd_img_no_mem(struct dcam_frame *frame, void* param)
1362 int ret = DCAM_RTN_SUCCESS;
1363 struct dcam_dev *dev = (struct dcam_dev*)param;
1364 struct dcam_path_spec *path;
1365 struct dcam_node node;
1366 struct dcam_img_buf_addr buf_addr;
1368 if (NULL == param || 0 == atomic_read(&dev->stream_on))
1370 atomic_set(&dev->run_flag, 1);//to avoid time out processing
1372 memset((void*)&node, 0, sizeof(struct dcam_node));
1373 node.irq_flag = IMG_NO_MEM;
1374 node.f_type = frame->type;
1375 node.index = frame->fid;
1376 node.height = frame->height;
1377 node.yaddr = frame->yaddr;
1378 node.uaddr = frame->uaddr;
1379 node.vaddr = frame->vaddr;
1380 node.yaddr_vir = frame->yaddr_vir;
1381 node.uaddr_vir = frame->uaddr_vir;
1382 node.vaddr_vir = frame->vaddr_vir;
1385 /* path = &dev->dcam_cxt.dcam_path[frame->type];
1386 ret = sprd_img_buf_queue_read(&path->buf_queue, &buf_addr);
1390 node.yaddr_vir = buf_addr.frm_addr_vir.yaddr;
1391 node.uaddr_vir = buf_addr.frm_addr_vir.uaddr;
1392 node.vaddr_vir = buf_addr.frm_addr_vir.vaddr;*/
1393 ret = sprd_img_queue_write(&dev->queue, &node);
1398 printk("SPRD_IMG: no mem \n");
1402 LOCAL int sprd_img_tx_stop(void* param)
1404 int ret = DCAM_RTN_SUCCESS;
1405 struct dcam_dev *dev = (struct dcam_dev*)param;
1406 struct dcam_node node;
1408 memset((void*)&node, 0, sizeof(struct dcam_node));
1409 node.irq_flag = IMG_TX_STOP;
1410 ret = sprd_img_queue_write(&dev->queue, &node);
1419 LOCAL int sprd_img_reg_isr(struct dcam_dev* param)
1421 dcam_reg_isr(DCAM_PATH0_DONE, sprd_img_tx_done, param);
1422 dcam_reg_isr(DCAM_PATH1_DONE, sprd_img_tx_done, param);
1423 dcam_reg_isr(DCAM_PATH0_OV, sprd_img_tx_error, param);
1424 dcam_reg_isr(DCAM_PATH1_OV, sprd_img_tx_error, param);
1425 dcam_reg_isr(DCAM_ISP_OV, sprd_img_tx_error, param);
1426 dcam_reg_isr(DCAM_MIPI_OV, sprd_img_tx_error, param);
1427 dcam_reg_isr(DCAM_SN_LINE_ERR, sprd_img_tx_error, param);
1428 dcam_reg_isr(DCAM_SN_FRAME_ERR, sprd_img_tx_error, param);
1429 dcam_reg_isr(DCAM_JPEG_BUF_OV, sprd_img_no_mem, param);
1430 dcam_reg_isr(DCAM_SN_EOF, sprd_img_start_flash, param);
1431 dcam_reg_isr(DCAM_PATH1_SOF, sprd_img_start_zoom, param);
1436 LOCAL int sprd_img_reg_path2_isr(struct dcam_dev* param)
1438 dcam_reg_isr(DCAM_PATH2_DONE, sprd_img_tx_done, param);
1439 dcam_reg_isr(DCAM_PATH2_OV, sprd_img_tx_error, param);
1444 LOCAL int sprd_img_unreg_isr(struct dcam_dev* param)
1446 dcam_reg_isr(DCAM_PATH0_DONE, NULL, param);
1447 dcam_reg_isr(DCAM_PATH1_DONE, NULL, param);
1448 dcam_reg_isr(DCAM_PATH0_OV, NULL, param);
1449 dcam_reg_isr(DCAM_PATH1_OV, NULL, param);
1450 dcam_reg_isr(DCAM_ISP_OV, NULL, param);
1451 dcam_reg_isr(DCAM_MIPI_OV, NULL, param);
1452 dcam_reg_isr(DCAM_SN_LINE_ERR, NULL, param);
1453 dcam_reg_isr(DCAM_SN_FRAME_ERR, NULL, param);
1454 dcam_reg_isr(DCAM_JPEG_BUF_OV, NULL, param);
1455 dcam_reg_isr(DCAM_SN_EOF, NULL, param);
1456 dcam_reg_isr(DCAM_PATH1_SOF, NULL, param);
1461 LOCAL int sprd_img_unreg_path2_isr(struct dcam_dev* param)
1463 dcam_reg_isr(DCAM_PATH2_DONE, NULL, NULL);
1464 dcam_reg_isr(DCAM_PATH2_OV, NULL, NULL);
1469 LOCAL int sprd_img_path0_cfg(path_cfg_func path_cfg,
1470 struct dcam_path_spec* path_spec)
1472 int ret = DCAM_RTN_SUCCESS;
1475 if (NULL == path_cfg || NULL == path_spec)
1478 if (path_spec->is_from_isp) {
1483 ret = path_cfg(DCAM_PATH_SRC_SEL, ¶m);
1484 /*IMG_RTN_IF_ERR(ret);*/
1486 ret = path_cfg(DCAM_PATH_ROT_MODE, &path_spec->rot_mode);
1487 IMG_RTN_IF_ERR(ret);
1489 ret = path_cfg(DCAM_PATH_INPUT_SIZE, &path_spec->in_size);
1490 IMG_RTN_IF_ERR(ret);
1492 ret = path_cfg(DCAM_PATH_INPUT_RECT, &path_spec->in_rect);
1493 /*IMG_RTN_IF_ERR(ret);*/
1495 ret = path_cfg(DCAM_PATH_OUTPUT_FORMAT, &path_spec->out_fmt);
1496 IMG_RTN_IF_ERR(ret);
1498 ret = path_cfg(DCAM_PATH_FRAME_BASE_ID, &path_spec->frm_id_base);
1499 IMG_RTN_IF_ERR(ret);
1501 ret = path_cfg(DCAM_PATH_FRAME_TYPE, &path_spec->frm_type);
1502 IMG_RTN_IF_ERR(ret);
1504 ret = path_cfg(DCAM_PATH_DATA_ENDIAN, &path_spec->end_sel);
1505 IMG_RTN_IF_ERR(ret);
1507 ret = path_cfg(DCAM_PATH_FRM_DECI, &path_spec->path_frm_deci);
1508 IMG_RTN_IF_ERR(ret);
1510 ret = sprd_img_path_cfg_output_addr(path_cfg, path_spec);
1511 IMG_RTN_IF_ERR(ret);
1513 ret = path_cfg(DCAM_PATH_OUTPUT_RESERVED_ADDR, &path_spec->frm_reserved_addr);
1516 ret = path_cfg(DCAM_PATH_ENABLE, ¶m);
1522 LOCAL int sprd_img_path_cfg(path_cfg_func path_cfg,
1523 struct dcam_path_spec* path_spec)
1525 int ret = DCAM_RTN_SUCCESS;
1528 if (NULL == path_cfg || NULL == path_spec)
1531 if (path_spec->is_from_isp) {
1536 ret = path_cfg(DCAM_PATH_SRC_SEL, ¶m);
1537 IMG_RTN_IF_ERR(ret);
1539 ret = path_cfg(DCAM_PATH_ROT_MODE, &path_spec->rot_mode);
1540 IMG_RTN_IF_ERR(ret);
1542 ret = path_cfg(DCAM_PATH_INPUT_SIZE, &path_spec->in_size);
1543 IMG_RTN_IF_ERR(ret);
1545 ret = path_cfg(DCAM_PATH_INPUT_RECT, &path_spec->in_rect);
1546 IMG_RTN_IF_ERR(ret);
1548 ret = path_cfg(DCAM_PATH_OUTPUT_SIZE, &path_spec->out_size);
1549 IMG_RTN_IF_ERR(ret);
1551 ret = path_cfg(DCAM_PATH_OUTPUT_FORMAT, &path_spec->out_fmt);
1552 IMG_RTN_IF_ERR(ret);
1554 ret = path_cfg(DCAM_PATH_FRAME_BASE_ID, &path_spec->frm_id_base);
1555 IMG_RTN_IF_ERR(ret);
1557 ret = path_cfg(DCAM_PATH_FRAME_TYPE, &path_spec->frm_type);
1558 IMG_RTN_IF_ERR(ret);
1560 ret = path_cfg(DCAM_PATH_DATA_ENDIAN, &path_spec->end_sel);
1561 IMG_RTN_IF_ERR(ret);
1563 ret = path_cfg(DCAM_PATH_FRM_DECI, &path_spec->path_frm_deci);
1564 IMG_RTN_IF_ERR(ret);
1566 ret = sprd_img_path_cfg_output_addr(path_cfg, path_spec);
1567 IMG_RTN_IF_ERR(ret);
1569 ret = path_cfg(DCAM_PATH_OUTPUT_RESERVED_ADDR, &path_spec->frm_reserved_addr);
1571 ret = path_cfg(DCAM_PATH_SHRINK, &path_spec->shrink);
1574 ret = path_cfg(DCAM_PATH_ENABLE, ¶m);
1580 LOCAL int sprd_img_path_lightly_cfg(path_cfg_func path_cfg,
1581 struct dcam_path_spec* path_spec)
1583 int ret = DCAM_RTN_SUCCESS;
1586 if (NULL == path_cfg || NULL == path_spec)
1589 if (path_spec->is_from_isp) {
1594 ret = path_cfg(DCAM_PATH_SRC_SEL, ¶m);
1595 IMG_RTN_IF_ERR(ret);
1597 ret = path_cfg(DCAM_PATH_INPUT_SIZE, &path_spec->in_size);
1598 IMG_RTN_IF_ERR(ret);
1600 ret = path_cfg(DCAM_PATH_INPUT_RECT, &path_spec->in_rect);
1601 IMG_RTN_IF_ERR(ret);
1603 ret = path_cfg(DCAM_PATH_OUTPUT_SIZE, &path_spec->out_size);
1604 IMG_RTN_IF_ERR(ret);
1606 ret = path_cfg(DCAM_PATH_OUTPUT_FORMAT, &path_spec->out_fmt);
1607 IMG_RTN_IF_ERR(ret);
1609 ret = path_cfg(DCAM_PATH_FRAME_BASE_ID, &path_spec->frm_id_base);
1610 IMG_RTN_IF_ERR(ret);
1612 ret = path_cfg(DCAM_PATH_FRAME_TYPE, &path_spec->frm_type);
1613 IMG_RTN_IF_ERR(ret);
1615 ret = path_cfg(DCAM_PATH_DATA_ENDIAN, &path_spec->end_sel);
1616 IMG_RTN_IF_ERR(ret);
1622 LOCAL int sprd_img_local_clear_path_buffer(struct dcam_dev *dev, int path_id)
1625 struct dcam_path_spec *path = NULL;
1627 if (unlikely(NULL == dev)) {
1631 if (DCAM_PATH1 == path_id) {
1632 path = &dev->dcam_cxt.dcam_path[DCAM_PATH1];
1633 } else if (DCAM_PATH2 == path_id) {
1634 path = &dev->dcam_cxt.dcam_path[DCAM_PATH2];
1635 } else if (DCAM_PATH0 == path_id) {
1636 path = &dev->dcam_cxt.dcam_path[DCAM_PATH0];
1638 if (unlikely(NULL == path))
1642 path->frm_cnt_act = 0;
1643 sprd_img_buf_queue_init(&path->buf_queue);
1645 DCAM_TRACE("SPRD_IMG: clear path buffer, frm_cnt_act %d \n", path->frm_cnt_act);
1650 LOCAL int sprd_img_local_deinit(struct dcam_dev *dev)
1653 struct dcam_path_spec *path = &dev->dcam_cxt.dcam_path[DCAM_PATH1];
1654 DCAM_TRACE("SPRD_IMG: sprd_img_local_deinit, frm_cnt_act %d \n", path->frm_cnt_act);
1655 if (unlikely(NULL == dev || NULL == path)) {
1659 path->frm_cnt_act = 0;
1660 sprd_img_buf_queue_init(&path->buf_queue);
1662 path = &dev->dcam_cxt.dcam_path[DCAM_PATH2];
1663 if (unlikely(NULL == path))
1666 path->frm_cnt_act = 0;
1667 sprd_img_buf_queue_init(&path->buf_queue);
1669 path = &dev->dcam_cxt.dcam_path[DCAM_PATH0];
1670 if (unlikely(NULL == path))
1673 path->frm_cnt_act = 0;
1674 sprd_img_buf_queue_init(&path->buf_queue);
1676 ret = sprd_img_queue_init(&dev->queue);
1677 if (unlikely(ret != 0)) {
1678 printk("SPRD_IMG: Failed to init queue \n");
1682 printk("SPRD_IMG: sprd_img_local_deinit, frm_cnt_act %d \n", path->frm_cnt_act);
1687 LOCAL int sprd_img_queue_init(struct dcam_queue *queue)
1692 memset(queue, 0, sizeof(*queue));
1693 queue->write = &queue->node[0];
1694 queue->read = &queue->node[0];
1699 LOCAL int sprd_img_queue_write(struct dcam_queue *queue, struct dcam_node *node)
1701 struct dcam_node *ori_node;
1702 unsigned long lock_flag;
1704 if (NULL == queue || NULL == node)
1707 ori_node = queue->write;
1709 DCAM_TRACE("SPRD_IMG: sprd_img_queue_write \n");
1710 *queue->write++ = *node;
1711 if (queue->write > &queue->node[DCAM_QUEUE_LENGTH-1]) {
1712 queue->write = &queue->node[0];
1715 if (queue->write == queue->read) {
1716 queue->write = ori_node;
1717 printk("SPRD_IMG: warning, queue is full, cannot write, flag 0x%x type 0x%x index 0x%x wcht %d %d\n",
1718 node->irq_flag, node->f_type, node->index, queue->wcnt, queue->rcnt);
1724 LOCAL int sprd_img_queue_read(struct dcam_queue *queue, struct dcam_node *node)
1726 int ret = DCAM_RTN_SUCCESS;
1729 if (NULL == queue || NULL == node)
1732 DCAM_TRACE("SPRD_IMG: sprd_img_queue_read \n");
1734 if (queue->read != queue->write) {
1736 *node = *queue->read;
1737 queue->read->yaddr = 0;
1738 queue->read->yaddr_vir = 0;
1741 if (queue->read > &queue->node[DCAM_QUEUE_LENGTH-1]) {
1742 queue->read = &queue->node[0];
1748 DCAM_TRACE("SPRD_IMG: sprd_img_queue_read type %d \n", node->f_type);
1752 LOCAL int sprd_img_queue_disable(struct dcam_queue *queue, uint32_t channel_id)
1754 struct dcam_node *cur_node;
1759 cur_node = queue->read;
1760 while (cur_node != queue->write) {
1761 if (channel_id == cur_node->f_type) {
1762 cur_node->invalid_flag = 1;
1764 if (cur_node >= &queue->node[DCAM_QUEUE_LENGTH-1]) {
1765 cur_node = &queue->node[0];
1775 LOCAL int sprd_img_queue_enable(struct dcam_queue *queue, uint32_t channel_id)
1777 struct dcam_node *cur_node;
1783 for (i=0 ; i < DCAM_QUEUE_LENGTH ; i++) {
1784 queue->node[i].invalid_flag = 0;
1790 LOCAL int sprd_img_buf_queue_init(struct dcam_img_buf_queue *queue)
1795 DCAM_TRACE("SPRD_IMG: sprd_img_buf_queue_init \n");
1796 memset(queue, 0, sizeof(*queue));
1797 queue->write = &queue->buf_addr[0];
1798 queue->read = &queue->buf_addr[0];
1803 LOCAL int sprd_img_buf_queue_write(struct dcam_img_buf_queue *queue, struct dcam_img_buf_addr *buf_addr)
1805 struct dcam_img_buf_addr *ori_node;
1807 if (NULL == queue || NULL == buf_addr)
1810 ori_node = queue->write;
1811 DCAM_TRACE("SPRD_IMG: sprd_img_buf_queue_write \n");
1812 *queue->write++ = *buf_addr;
1814 if (queue->write > &queue->buf_addr[DCAM_FRM_CNT_MAX-1]) {
1815 queue->write = &queue->buf_addr[0];
1818 if (queue->write == queue->read) {
1819 queue->write = ori_node;
1820 printk("SPRD_IMG: warning, queue is full, cannot write %d %d", queue->wcnt, queue->rcnt);
1827 LOCAL int sprd_img_buf_queue_read(struct dcam_img_buf_queue *queue, struct dcam_img_buf_addr *buf_addr)
1829 int ret = DCAM_RTN_SUCCESS;
1831 if (NULL == queue || NULL == buf_addr)
1834 DCAM_TRACE("SPRD_IMG: sprd_img_buf_queue_read \n");
1835 if (queue->read != queue->write) {
1836 *buf_addr = *queue->read++;
1838 if (queue->read > &queue->buf_addr[DCAM_FRM_CNT_MAX-1]) {
1839 queue->read = &queue->buf_addr[0];
1842 printk("SPRD_IMG: buf_queue_read fail %d\n", queue->rcnt);
1846 DCAM_TRACE("SPRD_IMG: sprd_img_buf_queue_read \n");
1850 LOCAL int sprd_img_path_cfg_output_addr(path_cfg_func path_cfg, struct dcam_path_spec* path_spec)
1852 int ret = DCAM_RTN_SUCCESS;
1853 struct dcam_img_buf_addr *cur_node;
1854 struct dcam_img_buf_queue *queue;
1855 struct dcam_addr frm_addr;
1857 if (NULL == path_cfg || NULL == path_spec)
1860 queue = &path_spec->buf_queue;
1862 for (cur_node = queue->read; cur_node != queue->write; cur_node++) {
1863 if (cur_node > &queue->buf_addr[DCAM_FRM_CNT_MAX-1]) {
1864 cur_node = &queue->buf_addr[0];
1866 frm_addr.yaddr = cur_node->frm_addr.yaddr;
1867 frm_addr.uaddr = cur_node->frm_addr.uaddr;
1868 frm_addr.vaddr = cur_node->frm_addr.vaddr;
1869 frm_addr.yaddr_vir = cur_node->frm_addr_vir.yaddr;
1870 frm_addr.uaddr_vir = cur_node->frm_addr_vir.uaddr;
1871 frm_addr.vaddr_vir = cur_node->frm_addr_vir.vaddr;
1872 ret = path_cfg(DCAM_PATH_OUTPUT_ADDR, &frm_addr);
1873 IMG_RTN_IF_ERR(ret);
1881 LOCAL int sprd_img_get_path_index(uint32_t channel_id)
1885 switch (channel_id) {
1887 path_index = DCAM_PATH_IDX_0;
1890 path_index = DCAM_PATH_IDX_1;
1893 path_index = DCAM_PATH_IDX_2;
1896 path_index = DCAM_PATH_IDX_NONE;
1897 printk("SPRD_IMG: get path index error, invalid channel_id=0x%x \n", channel_id);
1902 LOCAL int img_get_zoom_rect(struct dcam_rect *src_rect, struct dcam_rect *dst_rect, struct dcam_rect *output_rect, uint32_t zoom_level)
1904 uint32_t trim_width = 0;
1905 uint32_t trim_height = 0;
1906 uint32_t zoom_step_w = 0, zoom_step_h = 0;
1908 if (NULL == src_rect || NULL == dst_rect || NULL == output_rect) {
1909 printk("SPRD_IMG: img_get_zoom_rect: %p, %p, %p\n", src_rect, dst_rect, output_rect);
1913 if (0 == dst_rect->w || 0 == dst_rect->h) {
1914 printk("SPRD_IMG: img_get_zoom_rect: dst0x%x, 0x%x\n", dst_rect->w, dst_rect->h);
1918 if (src_rect->w > dst_rect->w && src_rect->h > dst_rect->h) {
1919 zoom_step_w = DCAM_ZOOM_STEP(src_rect->w, dst_rect->w);
1921 zoom_step_w *= zoom_level;
1922 trim_width = src_rect->w - zoom_step_w;
1924 zoom_step_h = DCAM_ZOOM_STEP(src_rect->h, dst_rect->h);
1926 zoom_step_h *= zoom_level;
1927 trim_height = src_rect->h - zoom_step_h;
1929 output_rect->x = src_rect->x + ((src_rect->w - trim_width) >> 1);
1930 output_rect->y = src_rect->y + ((src_rect->h - trim_height) >> 1);
1931 } else if (src_rect->w < dst_rect->w && src_rect->h < dst_rect->h) {
1932 zoom_step_w = DCAM_ZOOM_STEP(dst_rect->w, src_rect->w);
1934 zoom_step_w *= zoom_level;
1935 trim_width = src_rect->w + zoom_step_w;
1937 zoom_step_h = DCAM_ZOOM_STEP(dst_rect->h, src_rect->h);
1939 zoom_step_h *= zoom_level;
1940 trim_height = src_rect->h + zoom_step_h;
1942 output_rect->x = src_rect->x - ((trim_width - src_rect->w) >> 1);
1943 output_rect->y = src_rect->y - ((trim_height - src_rect->h) >> 1);
1945 printk("SPRD_IMG: SPRD_IMG img_get_zoom_rect: param error\n");
1949 output_rect->x = DCAM_WIDTH(output_rect->x);
1950 output_rect->y = DCAM_HEIGHT(output_rect->y);
1951 output_rect->w = DCAM_WIDTH(trim_width);
1952 output_rect->h = DCAM_HEIGHT(trim_height);
1953 DCAM_TRACE("SPRD_IMG: zoom_level %d, trim rect, %d %d %d %d\n",
1963 LOCAL int sprd_img_start_zoom(struct dcam_frame *frame, void* param)
1965 struct dcam_dev *dev = (struct dcam_dev*)param;
1968 DCAM_TRACE("SPRD_IMG: sprd_img_start_zoom, dev is NULL \n");
1971 DCAM_TRACE("SPRD_IMG: start zoom level %d \n", dev->zoom_level);
1972 if (dev->zoom_level <= DCAM_ZOOM_LEVEL_MAX && dev->dcam_cxt.is_smooth_zoom) {
1973 up(&dev->zoom_thread_sem);
1975 dcam_stop_sc_coeff();
1981 int sprd_img_zoom_thread_loop(void *arg)
1983 struct dcam_dev *dev = (struct dcam_dev*)arg;
1984 int ret = DCAM_RTN_SUCCESS;
1985 struct dcam_rect zoom_rect = {0};
1986 struct dcam_path_spec *path = NULL;
1987 enum dcam_path_index path_index;
1990 printk("SPRD_IMG: zoom_thread_loop, dev is NULL \n");
1994 if (0 == down_interruptible(&dev->zoom_thread_sem)) {
1995 DCAM_TRACE("SPRD_IMG: zoom thread level %d \n", dev->zoom_level);
1996 if (dev->is_zoom_thread_stop) {
1997 DCAM_TRACE("SPRD_IMG: zoom_thread_loop stop \n");
2001 if (dev->zoom_level > DCAM_ZOOM_LEVEL_MAX) {
2004 mutex_lock(&dev->dcam_mutex);
2005 path = &dev->dcam_cxt.dcam_path[dev->channel_id];
2006 path_index = sprd_img_get_path_index(dev->channel_id);
2007 if (dev->zoom_level < DCAM_ZOOM_LEVEL_MAX) {
2008 ret = img_get_zoom_rect(&path->in_rect_backup, &path->in_rect, &zoom_rect, dev->zoom_level);
2010 memcpy((void*)&path->in_rect_current, (void*)&zoom_rect, sizeof(struct dcam_rect));
2011 dcam_update_path(path_index, &path->in_size, &zoom_rect, &path->out_size);
2014 dcam_update_path(path_index, &path->in_size, &path->in_rect, &path->out_size);
2015 memcpy((void*)&path->in_rect_backup, (void*)&path->in_rect, sizeof(struct dcam_rect));
2016 memcpy((void*)&path->in_rect_current, (void*)&path->in_rect_backup, sizeof(struct dcam_rect));
2019 mutex_unlock(&dev->dcam_mutex);
2020 DCAM_TRACE("SPRD_IMG: zoom thread level %d end \n", dev->zoom_level);
2023 printk("SPRD_IMG: zoom int!");
2027 dev->is_zoom_thread_stop = 0;
2032 int sprd_img_create_zoom_thread(void* param)
2034 struct dcam_dev *dev = (struct dcam_dev*)param;
2037 DCAM_TRACE("create_zoom_thread, dev is NULL \n");
2040 DCAM_TRACE("SPRD_IMG: create_zoom_thread E!\n");
2042 dev->is_zoom_thread_stop = 0;
2043 dev->zoom_level = DCAM_ZOOM_LEVEL_MAX + 1;
2044 sema_init(&dev->zoom_thread_sem, 0);
2045 dev->zoom_thread = kthread_run(sprd_img_zoom_thread_loop, param, "img_zoom_thread");
2046 if (IS_ERR(dev->zoom_thread)) {
2047 printk("SPRD_IMG: create_zoom_thread error!\n");
2053 int sprd_img_stop_zoom_thread(void* param)
2055 struct dcam_dev *dev = (struct dcam_dev*)param;
2059 DCAM_TRACE("stop_zoom_thread, dev is NULL \n");
2062 DCAM_TRACE("SPRD_IMG: stop_zoom_thread E!\n");
2063 if (dev->zoom_thread) {
2064 dev->is_zoom_thread_stop = 1;
2065 up(&dev->zoom_thread_sem);
2066 if (dev->is_zoom_thread_stop != 0) {
2069 if (0 == dev->is_zoom_thread_stop)
2074 dev->zoom_thread = NULL;
2080 LOCAL int sprd_img_update_video(struct file *file, uint32_t channel_id)
2082 struct dcam_dev *dev = file->private_data;
2083 int ret = DCAM_RTN_SUCCESS;
2084 struct dcam_path_spec *path = NULL;
2085 path_cfg_func path_cfg;
2086 enum dcam_path_index path_index;
2089 DCAM_TRACE("SPRD_IMG: sprd_img_update_video, channel=%d \n", channel_id);
2091 mutex_lock(&dev->dcam_mutex);
2093 path = &dev->dcam_cxt.dcam_path[channel_id];
2094 path_index = sprd_img_get_path_index(channel_id);
2096 if (DCAM_PATH0 == channel_id) {
2097 path_cfg = dcam_path0_cfg;
2098 } else if (DCAM_PATH1 == channel_id) {
2099 path_cfg = dcam_path1_cfg;
2100 }else if (DCAM_PATH2 == channel_id) {
2101 path_cfg = dcam_path2_cfg;
2104 if (dev->dcam_cxt.is_smooth_zoom && DCAM_PATH0 != channel_id) {
2105 dev->zoom_level = 1;
2106 dev->channel_id = channel_id;
2107 if (0 == path->in_rect_backup.w || 0 == path->in_rect_backup.h) {
2108 path->in_rect_backup.x = 0;
2109 path->in_rect_backup.y = 0;
2110 path->in_rect_backup.w = path->in_size.w;
2111 path->in_rect_backup.h = path->in_size.h;
2112 memcpy((void*)&path->in_rect_current, (void*)&path->in_rect_backup, sizeof(struct dcam_rect));
2114 memcpy((void*)&path->in_rect_backup, (void*)&path->in_rect_current, sizeof(struct dcam_rect));
2117 DCAM_TRACE("SPRD_IMG: in_size{%d %d}, in_rect{%d %d %d %d}, in_rect_backup{%d %d %d %d}, out_size{%d %d}\n",
2124 path->in_rect_backup.x,
2125 path->in_rect_backup.y,
2126 path->in_rect_backup.w,
2127 path->in_rect_backup.h,
2131 DCAM_TRACE("SPRD_IMG: in_size{%d %d}, in_rect{%d %d %d %d}, out_size{%d %d}\n",
2140 ret = dcam_update_path(path_index, &path->in_size, &path->in_rect, &path->out_size);
2143 mutex_unlock(&dev->dcam_mutex);
2144 DCAM_TRACE("SPRD_IMG: update video 0x%x \n", ret);
2146 printk("SPRD_IMG: Failed to update video 0x%x \n", ret);
2152 LOCAL int sprd_img_streampause(struct file *file, uint32_t channel_id, uint32_t reconfig_flag)
2154 struct dcam_dev *dev = file->private_data;
2155 struct dcam_path_spec *path = NULL;
2157 enum dcam_path_index path_index;
2159 printk("SPRD_IMG: pause, channel %d ,recfg flag %d\n", channel_id, reconfig_flag);
2161 path = &dev->dcam_cxt.dcam_path[channel_id];
2162 path_index = sprd_img_get_path_index(channel_id);
2164 if (PATH_RUN == path->status) {
2165 path->status = PATH_IDLE;
2166 ret = dcam_stop_path(path_index);
2167 IMG_PRINT_IF_ERR(ret);
2168 if ((reconfig_flag)/* && (DCAM_PATH2 == channel_id)*/) {
2169 //path->is_work = 0;
2170 path->frm_cnt_act = 0;
2171 sprd_img_buf_queue_init(&path->buf_queue);
2172 sprd_img_queue_disable(&dev->queue, channel_id);
2173 ret = sprd_img_unreg_path2_isr(dev);
2174 IMG_PRINT_IF_ERR(ret);
2177 if (DCAM_PATH2 == channel_id && dev->got_resizer) {
2179 dev->got_resizer = 0;
2181 printk("SPRD_IMG: pause, channel=%d done \n", channel_id);
2183 printk("SPRD_IMG: pause, path %d not running, status=%d \n",
2184 channel_id, path->status);
2190 LOCAL int sprd_img_streamresume(struct file *file, uint32_t channel_id)
2192 struct dcam_dev *dev = NULL;
2193 struct dcam_path_spec *path = NULL;
2194 enum dcam_path_index path_index;
2195 path_cfg_func path_cfg;
2199 DCAM_TRACE("SPRD_IMG: resume, channel=%d \n", channel_id);
2201 dev = file->private_data;
2203 printk("SPRD_IMG: dev is NULL \n");
2207 path = &dev->dcam_cxt.dcam_path[channel_id];
2208 path_index = sprd_img_get_path_index(channel_id);
2210 if (unlikely(0 == atomic_read(&dev->stream_on))) {
2211 printk("SPRD_IMG: resume stream not on\n");
2212 ret = sprd_img_local_deinit(dev);
2213 if (unlikely(ret)) {
2214 printk(DEBUG_STR,DEBUG_ARGS);
2218 if (PATH_IDLE == path->status && on_flag) {
2219 if (path->is_work) {
2220 if (DCAM_PATH0 == channel_id) {
2221 path_cfg = dcam_path0_cfg;
2222 } else if (DCAM_PATH1 == channel_id) {
2223 path_cfg = dcam_path1_cfg;
2224 } else if (DCAM_PATH2 == channel_id) {
2225 if (0 == dev->got_resizer) {
2226 /* if not owned resiezer, try to get it */
2227 if (unlikely(dcam_get_resizer(DCAM_WAIT_FOREVER))) {
2228 /*no wait to get the controller of resizer, failed*/
2229 printk("SPRD_IMG: resume, path2 has been occupied by other app \n");
2232 dev->got_resizer = 1;
2234 ret = sprd_img_reg_path2_isr(dev);
2235 IMG_PRINT_IF_ERR(ret);
2236 path_cfg = dcam_path2_cfg;
2238 printk("SPRD_IMG: resume, invalid channel_id=0x%x \n", channel_id);
2242 if (DCAM_PATH0 == channel_id) {
2243 ret = sprd_img_path0_cfg(path_cfg, path);
2245 ret = sprd_img_path_cfg(path_cfg, path);
2247 sprd_img_queue_enable(&dev->queue, channel_id);
2248 IMG_RTN_IF_ERR(ret);
2249 ret = dcam_start_path(path_index);
2250 IMG_PRINT_IF_ERR(ret);
2252 path->status = PATH_RUN;
2254 DCAM_TRACE("SPRD_IMG: resume, path %d no parameter, is_work=%d, cannot resume \n",
2255 channel_id, path->is_work);
2258 DCAM_TRACE("SPRD_IMG: resume, path %d not idle, status=%d, cannot resume \n",
2259 channel_id, path->status);
2263 DCAM_TRACE("SPRD_IMG: fail resume, path %d, ret = 0x%x\n", channel_id, ret);
2268 LOCAL void sprd_img_print_reg(void)
2270 uint32_t* reg_buf = NULL;
2271 uint32_t reg_buf_len = 0x400;
2273 uint32_t print_len = 0, print_cnt = 0;
2275 reg_buf = (uint32_t*)vzalloc(reg_buf_len);
2276 if (NULL == reg_buf)
2279 ret = dcam_read_registers(reg_buf, ®_buf_len);
2285 mm_clk_register_trace();
2286 printk("dcam registers \n");
2287 while (print_len < reg_buf_len) {
2288 printk("offset 0x%03x : 0x%08x, 0x%08x, 0x%08x, 0x%08x \n",
2291 reg_buf[print_cnt+1],
2292 reg_buf[print_cnt+2],
2293 reg_buf[print_cnt+3]);
2298 ret = csi_read_registers(reg_buf, ®_buf_len);
2306 printk("csi registers \n");
2307 while (print_len < reg_buf_len) {
2308 printk("offset 0x%3x : 0x%8x, 0x%8x, 0x%8x, 0x%8x \n",
2311 reg_buf[print_cnt+1],
2312 reg_buf[print_cnt+2],
2313 reg_buf[print_cnt+3]);
2324 LOCAL void sprd_timer_callback(unsigned long data)
2326 struct dcam_dev *dev = (struct dcam_dev*)data;
2327 struct dcam_node node;
2330 DCAM_TRACE("SPRD_IMG: sprd_timer_callback \n");
2332 if (0 == data || 0 == atomic_read(&dev->stream_on)) {
2333 printk("SPRD_IMG: timer cb error \n");
2337 if (0 == atomic_read(&dev->run_flag)) {
2338 printk("DCAM timeout.\n");
2339 node.irq_flag = IMG_TIMEOUT;
2340 node.invalid_flag = 0;
2341 ret = sprd_img_queue_write(&dev->queue, &node);
2343 printk("SPRD_IMG: timer cb write queue error \n");
2348 LOCAL int sprd_init_timer(struct timer_list *dcam_timer, unsigned long data)
2352 setup_timer(dcam_timer, sprd_timer_callback, data);
2355 LOCAL int sprd_start_timer(struct timer_list *dcam_timer, uint32_t time_val)
2359 DCAM_TRACE("SPRD_IMG: starting timer %ld \n",jiffies);
2360 ret = mod_timer(dcam_timer, jiffies + msecs_to_jiffies(time_val));
2362 printk("SPRD_IMG: Error in mod_timer %d \n",ret);
2367 LOCAL int sprd_stop_timer(struct timer_list *dcam_timer)
2371 DCAM_TRACE("SPRD_IMG: stop timer \n");
2372 del_timer_sync(dcam_timer);
2376 LOCAL int sprd_init_handle(struct dcam_dev *dev)
2378 struct dcam_info *info = &dev->dcam_cxt;
2379 struct dcam_path_spec *path;
2383 printk("SPRD_IMG: init handle fail \n");
2386 info->flash_status = FLASH_STATUS_MAX;
2388 for (i = 0; i < DCAM_PATH_MAX; i++) {
2389 path = &info->dcam_path[i];
2391 printk("SPRD_IMG: init path %d fail \n", i);
2394 memset((void*)path->frm_ptr,
2396 (uint32_t)(DCAM_FRM_CNT_MAX * sizeof(struct dcam_frame*)));
2397 path->frm_cnt_act = 0;
2398 sprd_img_buf_queue_init(&path->buf_queue);
2399 path->status = PATH_IDLE;
2401 atomic_set(&dev->stream_on, 0);
2402 dev->got_resizer = 0;
2406 LOCAL int sprd_img_k_open(struct inode *node, struct file *file)
2408 struct dcam_dev *dev = NULL;
2409 struct miscdevice *md = file->private_data;
2412 dev = vzalloc(sizeof(*dev));
2415 printk("sprd_img_k_open fail alloc \n");
2419 mutex_init(&dev->dcam_mutex);
2420 sema_init(&dev->irq_sem, 0);
2422 if (unlikely(atomic_inc_return(&dev->users) > 1)) {
2427 DCAM_TRACE("sprd_img_k_open \n");
2428 ret = dcam_module_en(md->this_device->of_node);
2429 if (unlikely(ret != 0)) {
2430 printk("SPRD_IMG: Failed to enable dcam module \n");
2435 ret = sprd_img_queue_init(&dev->queue);
2436 if (unlikely(ret != 0)) {
2437 printk("SPRD_IMG: Failed to init queue \n");
2442 ret = sprd_init_timer(&dev->dcam_timer,(unsigned long)dev);
2443 if (unlikely(ret != 0)) {
2444 printk("SPRD_IMG: Failed to init timer \n");
2449 ret = sprd_init_handle(dev);
2450 if (unlikely(ret != 0)) {
2451 printk("SPRD_IMG: Failed to init queue \n");
2456 ret = dcam_create_flash_thread(dev);
2457 if (unlikely(ret != 0)) {
2458 printk("SPRD_IMG: Failed to create flash thread \n");
2463 ret = sprd_img_create_zoom_thread(dev);
2464 if (unlikely(ret != 0)) {
2465 printk("SPRD_IMG: Failed to create zoom thread \n");
2470 dev->driver_data = (void*)md;
2471 file->private_data = (void*)dev;
2474 if (unlikely(ret)) {
2475 atomic_dec(&dev->users);
2478 dev->proc_file = create_proc_read_entry(DCAM_PROC_FILE_NAME,
2483 if (unlikely(NULL == dev->proc_file)) {
2484 printk("SPRD_IMG: Can't create an entry for video0 in /proc \n");
2490 printk("sprd_img_k_open %d \n", ret);
2494 static int sprd_img_k_release(struct inode *node, struct file *file)
2496 struct dcam_dev *dev = NULL;
2497 struct miscdevice *md = NULL;
2500 DCAM_TRACE("SPRD_IMG: Close start\n");
2502 if (dev->proc_file) {
2503 DCAM_TRACE("SPRD_IMG: sprd_img_k_release \n");
2504 remove_proc_entry(DCAM_PROC_FILE_NAME, NULL);
2505 dev->proc_file = NULL;
2509 dev = file->private_data;
2513 md = dev->driver_data;
2515 mutex_lock(&dev->dcam_mutex);
2516 dcam_reset(DCAM_RST_ALL, 0);
2517 if (dev->got_resizer) {
2519 dev->got_resizer = 0;
2520 sprd_img_unreg_path2_isr(dev);
2523 atomic_set(&dev->stream_on, 0);
2524 dcam_module_deinit(dev->dcam_cxt.if_mode, dev->dcam_cxt.sn_mode);
2525 sprd_img_local_deinit(dev);
2526 sema_init(&dev->irq_sem, 0);
2527 ret = dcam_module_dis(md->this_device->of_node);
2528 if (unlikely(0 != ret)) {
2529 printk("SPRD_IMG: Failed to enable dcam module \n");
2532 sprd_stop_timer(&dev->dcam_timer);
2533 atomic_dec(&dev->users);
2534 dcam_stop_flash_thread(dev);
2535 sprd_img_stop_zoom_thread(dev);
2536 mutex_unlock(&dev->dcam_mutex);
2540 file->private_data = NULL;
2543 DCAM_TRACE("SPRD_IMG: Close end.\n");
2547 static long sprd_img_k_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2549 struct dcam_dev *dev = NULL;
2550 struct dcam_info *info = NULL;
2552 uint32_t channel_id;
2555 uint32_t flash_status;
2557 struct sprd_img_parm parm;
2558 struct sprd_img_size size;
2559 struct sprd_img_rect rect;
2560 struct dcam_path_spec *path = NULL;
2561 struct dcam_rect *input_rect;
2562 struct dcam_size *input_size;
2563 path_cfg_func path_cfg;
2564 int ret = DCAM_RTN_SUCCESS;
2566 DCAM_TRACE("sprd_img_k_ioctl: cmd: 0x%x \n", cmd);
2568 dev = file->private_data;
2571 printk("sprd_img_k_ioctl: dev is NULL \n");
2575 info = &dev->dcam_cxt;
2578 case SPRD_IMG_IO_SET_MODE:
2579 mutex_lock(&dev->dcam_mutex);
2580 ret = copy_from_user(&mode, (uint32_t *)arg, sizeof(uint32_t));
2582 printk("sprd_img_k_ioctl: fail to get user info \n");
2583 mutex_unlock(&dev->dcam_mutex);
2586 dev->dcam_cxt.capture_mode = mode;
2587 mutex_unlock(&dev->dcam_mutex);
2588 DCAM_TRACE("SPRD_IMG: capture mode %d \n", dev->dcam_cxt.capture_mode);
2591 case SPRD_IMG_IO_SET_SKIP_NUM:
2592 mutex_lock(&dev->dcam_mutex);
2593 ret = copy_from_user(&skip_num, (uint32_t *)arg, sizeof(uint32_t));
2595 printk("sprd_img_k_ioctl: fail to get user info \n");
2596 mutex_unlock(&dev->dcam_mutex);
2599 dev->dcam_cxt.skip_number = skip_num;
2600 mutex_unlock(&dev->dcam_mutex);
2601 DCAM_TRACE("SPRD_IMG: cap skip number %d \n", dev->dcam_cxt.skip_number);
2604 case SPRD_IMG_IO_SET_SENSOR_SIZE:
2605 mutex_lock(&dev->dcam_mutex);
2606 ret = copy_from_user(&size, (struct sprd_img_size *)arg, sizeof(struct sprd_img_size));
2608 printk("sprd_img_k_ioctl: fail to get user info \n");
2609 mutex_unlock(&dev->dcam_mutex);
2612 dev->dcam_cxt.cap_in_size.w = size.w;
2613 dev->dcam_cxt.cap_in_size.h = size.h;
2614 mutex_unlock(&dev->dcam_mutex);
2615 DCAM_TRACE("SPRD_IMG: sensor size %d %d \n",
2616 dev->dcam_cxt.cap_in_size.w,
2617 dev->dcam_cxt.cap_in_size.h);
2620 case SPRD_IMG_IO_SET_SENSOR_TRIM:
2621 mutex_lock(&dev->dcam_mutex);
2622 ret = copy_from_user(&rect, (struct sprd_img_rect *)arg, sizeof(struct sprd_img_rect));
2624 printk("sprd_img_k_ioctl: fail to get user info \n");
2625 mutex_unlock(&dev->dcam_mutex);
2628 dev->dcam_cxt.cap_in_rect.x = rect.x;
2629 dev->dcam_cxt.cap_in_rect.y = rect.y;
2630 dev->dcam_cxt.cap_in_rect.w = rect.w;
2631 dev->dcam_cxt.cap_in_rect.h = rect.h;
2633 dev->dcam_cxt.cap_out_size.w = dev->dcam_cxt.cap_in_rect.w;
2634 dev->dcam_cxt.cap_out_size.h = dev->dcam_cxt.cap_in_rect.h;
2635 mutex_unlock(&dev->dcam_mutex);
2636 DCAM_TRACE("SPRD_IMG: sensor trim x y w h %d %d %d %d\n",
2637 dev->dcam_cxt.cap_in_rect.x,
2638 dev->dcam_cxt.cap_in_rect.y,
2639 dev->dcam_cxt.cap_in_rect.w,
2640 dev->dcam_cxt.cap_in_rect.h);
2643 case SPRD_IMG_IO_SET_FRM_ID_BASE:
2644 mutex_lock(&dev->dcam_mutex);
2645 ret = copy_from_user(&parm, (struct sprd_img_parm *)arg, sizeof(struct sprd_img_parm));
2647 printk("sprd_img_k_ioctl: fail to get user info \n");
2648 mutex_unlock(&dev->dcam_mutex);
2651 switch (parm.channel_id) {
2655 dev->dcam_cxt.dcam_path[parm.channel_id].frm_id_base = parm.frame_base_id;
2658 printk("SPRD_IMG: Wrong channel ID, %d \n", parm.channel_id);
2659 mutex_unlock(&dev->dcam_mutex);
2662 mutex_unlock(&dev->dcam_mutex);
2663 DCAM_TRACE("SPRD_IMG: channel %d, base id 0x%x \n",
2665 parm.frame_base_id);
2668 case SPRD_IMG_IO_SET_CROP:
2669 mutex_lock(&dev->dcam_mutex);
2670 ret = copy_from_user(&parm, (struct sprd_img_parm *)arg, sizeof(struct sprd_img_parm));
2672 printk("sprd_img_k_ioctl: fail to get user info \n");
2673 mutex_unlock(&dev->dcam_mutex);
2677 if (unlikely(parm.crop_rect.x + parm.crop_rect.w > dev->dcam_cxt.cap_in_size.w ||
2678 parm.crop_rect.y + parm.crop_rect.h > dev->dcam_cxt.cap_in_size.h)) {
2679 mutex_unlock(&dev->dcam_mutex);
2684 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_SET_CROP, window %d %d %d %d \n",
2690 switch (parm.channel_id) {
2694 input_size = &dev->dcam_cxt.dcam_path[parm.channel_id].in_size;
2695 input_rect = &dev->dcam_cxt.dcam_path[parm.channel_id].in_rect;
2698 printk("SPRD_IMG: Wrong channel ID, %d \n", parm.channel_id);
2699 mutex_unlock(&dev->dcam_mutex);
2703 input_size->w = dev->dcam_cxt.cap_out_size.w;
2704 input_size->h = dev->dcam_cxt.cap_out_size.h;
2705 input_rect->x = parm.crop_rect.x;
2706 input_rect->y = parm.crop_rect.y;
2707 input_rect->w = parm.crop_rect.w;
2708 input_rect->h = parm.crop_rect.h;
2710 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_SET_CROP, Path %d, cap crop: cap_rect %d %d %d %d, cap_out:%d %d \n",
2711 parm.channel_id, input_rect->x, input_rect->y,
2712 input_rect->w, input_rect->h,
2713 input_size->w, input_size->h);
2714 mutex_unlock(&dev->dcam_mutex);
2717 case SPRD_IMG_IO_SET_FLASH:
2718 mutex_lock(&dev->dcam_mutex);
2719 ret = copy_from_user(&flash_status, (uint32_t *)arg, sizeof(uint32_t));
2721 printk("sprd_img_k_ioctl: fail to get user info \n");
2722 mutex_unlock(&dev->dcam_mutex);
2725 dev->dcam_cxt.flash_status = flash_status;
2726 mutex_unlock(&dev->dcam_mutex);
2727 if ((dev->dcam_cxt.flash_status == FLASH_CLOSE_AFTER_OPEN)
2728 || (dev->dcam_cxt.flash_status == FLASH_CLOSE)
2729 || (dev->dcam_cxt.flash_status == FLASH_CLOSE_AFTER_AUTOFOCUS)) {
2730 up(&dev->flash_thread_sem);
2732 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_SET_FLASH, flash status %d \n", dev->dcam_cxt.flash_status);
2735 case SPRD_IMG_IO_SET_OUTPUT_SIZE:
2736 DCAM_TRACE("SPRD_IMG: set output size \n");
2737 mutex_lock(&dev->dcam_mutex);
2738 ret = copy_from_user(&parm, (struct sprd_img_parm *)arg, sizeof(struct sprd_img_parm));
2740 printk("sprd_img_k_ioctl: fail to get user info \n");
2741 mutex_unlock(&dev->dcam_mutex);
2744 dev->dcam_cxt.dst_size.w = parm.dst_size.w;
2745 dev->dcam_cxt.dst_size.h = parm.dst_size.h;
2746 dev->dcam_cxt.pxl_fmt = parm.pixel_fmt;
2747 dev->dcam_cxt.need_isp_tool = parm.need_isp_tool;
2748 dev->dcam_cxt.need_isp = parm.need_isp;
2749 dev->dcam_cxt.need_shrink = parm.shrink;
2750 dev->dcam_cxt.camera_id = parm.camera_id;
2751 dev->dcam_cxt.path_input_rect.x = parm.crop_rect.x;
2752 dev->dcam_cxt.path_input_rect.y = parm.crop_rect.y;
2753 dev->dcam_cxt.path_input_rect.w = parm.crop_rect.w;
2754 dev->dcam_cxt.path_input_rect.h = parm.crop_rect.h;
2755 mutex_unlock(&dev->dcam_mutex);
2758 case SPRD_IMG_IO_SET_ZOOM_MODE:
2759 mutex_lock(&dev->dcam_mutex);
2760 ret = copy_from_user(&zoom, (uint32_t *)arg, sizeof(uint32_t));
2762 printk("sprd_img_k_ioctl: fail to get user info \n");
2763 mutex_unlock(&dev->dcam_mutex);
2766 dev->dcam_cxt.is_smooth_zoom = zoom;
2767 mutex_unlock(&dev->dcam_mutex);
2768 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_SET_ZOOM_MODE, zoom mode %d \n", dev->dcam_cxt.is_smooth_zoom);
2771 case SPRD_IMG_IO_SET_SENSOR_IF:
2773 struct sprd_img_sensor_if sensor_if;
2775 DCAM_TRACE("SPRD_IMG: set sensor if \n");
2776 mutex_lock(&dev->dcam_mutex);
2777 ret = copy_from_user(&sensor_if, (struct sprd_img_sensor_if *)arg, sizeof(struct sprd_img_sensor_if));
2778 if (unlikely(ret)) {
2779 printk("sprd_img_k_ioctl: fail to get user info \n");
2780 mutex_unlock(&dev->dcam_mutex);
2784 if (IF_OPEN == sensor_if.res[0]) {
2785 dev->dcam_cxt.if_mode = sensor_if.if_type;
2786 dev->dcam_cxt.sn_mode = sensor_if.img_fmt;
2787 dev->dcam_cxt.yuv_ptn = sensor_if.img_ptn;
2788 dev->dcam_cxt.frm_deci = sensor_if.frm_deci;
2790 DCAM_TRACE("SPRD_IMG: interface %d, mode %d frm_deci %d \n",
2791 dev->dcam_cxt.if_mode,
2792 dev->dcam_cxt.sn_mode,
2793 dev->dcam_cxt.frm_deci);
2795 if (DCAM_CAP_IF_CCIR == dev->dcam_cxt.if_mode) {
2796 /* CCIR interface */
2797 dev->dcam_cxt.sync_pol.vsync_pol = sensor_if.if_spec.ccir.v_sync_pol;
2798 dev->dcam_cxt.sync_pol.hsync_pol = sensor_if.if_spec.ccir.h_sync_pol;
2799 dev->dcam_cxt.sync_pol.pclk_pol = sensor_if.if_spec.ccir.pclk_pol;
2800 dev->dcam_cxt.data_bits = 8;
2801 DCAM_TRACE("SPRD_IMG: CIR interface, vsync %d hsync %d pclk %d psrc %d bits %d \n",
2802 dev->dcam_cxt.sync_pol.vsync_pol,
2803 dev->dcam_cxt.sync_pol.hsync_pol,
2804 dev->dcam_cxt.sync_pol.pclk_pol,
2805 dev->dcam_cxt.sync_pol.pclk_src,
2806 dev->dcam_cxt.data_bits);
2808 dev->dcam_cxt.sync_pol.need_href = sensor_if.if_spec.mipi.use_href;
2809 dev->dcam_cxt.is_loose = sensor_if.if_spec.mipi.is_loose;
2810 dev->dcam_cxt.data_bits = sensor_if.if_spec.mipi.bits_per_pxl;
2811 dev->dcam_cxt.lane_num = sensor_if.if_spec.mipi.lane_num;
2812 dev->dcam_cxt.pclk = sensor_if.if_spec.mipi.pclk;
2813 DCAM_TRACE("SPRD_IMG: MIPI interface, ref %d is_loose %d bits %d lanes %d pclk %d\n",
2814 dev->dcam_cxt.sync_pol.need_href,
2815 dev->dcam_cxt.is_loose,
2816 dev->dcam_cxt.data_bits,
2817 dev->dcam_cxt.lane_num,
2818 dev->dcam_cxt.pclk);
2821 mutex_unlock(&dev->dcam_mutex);
2825 case SPRD_IMG_IO_SET_FRAME_ADDR:
2826 DCAM_TRACE("SPRD_IMG: set frame addr \n");
2827 mutex_lock(&dev->dcam_mutex);
2828 ret = copy_from_user(&parm, (struct sprd_img_parm *)arg, sizeof(struct sprd_img_parm));
2830 printk("sprd_img_k_ioctl: fail to get user info \n");
2831 mutex_unlock(&dev->dcam_mutex);
2834 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_SET_FRAME_ADDR = %d \n",parm.channel_id);
2836 switch (parm.channel_id) {
2838 path = &info->dcam_path[DCAM_PATH0];
2839 path_cnt = DCAM_PATH_0_FRM_CNT_MAX;
2840 path_cfg = dcam_path0_cfg;
2843 path = &info->dcam_path[DCAM_PATH1];
2844 path_cnt = DCAM_PATH_1_FRM_CNT_MAX;
2845 path_cfg = dcam_path1_cfg;
2848 path = &info->dcam_path[DCAM_PATH2];
2849 path_cnt = DCAM_PATH_2_FRM_CNT_MAX;
2850 path_cfg = dcam_path2_cfg;
2853 printk("SPRD_IMG error: SPRD_IMG_IO_SET_FRAME_ADDR, path 0x%x \n", parm.channel_id);
2854 mutex_unlock(&dev->dcam_mutex);
2859 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_SET_FRAME_ADDR, status %d, frm_cnt_act %d \n",
2860 path->status, path->frm_cnt_act);
2862 if (unlikely(0 == parm.frame_addr.y)) {
2863 printk("SPRD_IMG: No yaddr \n");
2864 mutex_unlock(&dev->dcam_mutex);
2867 if (1 == parm.is_reserved_buf) {
2868 path->frm_reserved_addr.yaddr = parm.frame_addr.y;
2869 path->frm_reserved_addr.uaddr = parm.frame_addr.u;
2870 path->frm_reserved_addr.vaddr = parm.frame_addr.v;
2871 path->frm_reserved_addr_vir.yaddr = parm.frame_addr_vir.y;
2872 path->frm_reserved_addr_vir.uaddr = parm.frame_addr_vir.u;
2873 path->frm_reserved_addr_vir.vaddr = parm.frame_addr_vir.v;
2875 struct dcam_addr frame_addr;
2876 struct dcam_img_buf_addr buf_addr;
2878 frame_addr.yaddr = parm.frame_addr.y;
2879 frame_addr.uaddr = parm.frame_addr.u;
2880 frame_addr.vaddr = parm.frame_addr.v;
2881 frame_addr.yaddr_vir = parm.frame_addr_vir.y;
2882 frame_addr.uaddr_vir = parm.frame_addr_vir.u;
2883 frame_addr.vaddr_vir = parm.frame_addr_vir.v;
2885 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_SET_FRAME_ADDR, yaddr: 0x%x, uaddr: 0x%x, vaddr: 0x%x\n",
2890 if (unlikely(1 == atomic_read(&dev->stream_on)) && path->status == PATH_RUN) {
2891 ret = path_cfg(DCAM_PATH_OUTPUT_ADDR, &frame_addr);
2893 buf_addr.frm_addr.yaddr = parm.frame_addr.y;
2894 buf_addr.frm_addr.uaddr = parm.frame_addr.u;
2895 buf_addr.frm_addr.vaddr = parm.frame_addr.v;
2896 buf_addr.frm_addr_vir.yaddr = parm.frame_addr_vir.y;
2897 buf_addr.frm_addr_vir.uaddr = parm.frame_addr_vir.u;
2898 buf_addr.frm_addr_vir.vaddr = parm.frame_addr_vir.v;
2899 ret = sprd_img_buf_queue_write(&path->buf_queue, &buf_addr);
2903 mutex_unlock(&dev->dcam_mutex);
2906 case SPRD_IMG_IO_PATH_FRM_DECI:
2907 mutex_lock(&dev->dcam_mutex);
2908 ret = copy_from_user(&parm, (struct sprd_img_parm *)arg, sizeof(struct sprd_img_parm));
2910 printk("sprd_img_k_ioctl: fail to get user info \n");
2911 mutex_unlock(&dev->dcam_mutex);
2914 path = &dev->dcam_cxt.dcam_path[parm.channel_id];
2915 path->path_frm_deci = 0;//parm.deci; // aiden tmp changes
2916 mutex_unlock(&dev->dcam_mutex);
2917 DCAM_TRACE("SPRD_IMG: channel %d, frm_deci=%d \n", parm.channel_id, path->path_frm_deci);
2920 case SPRD_IMG_IO_SET_SHRINK:
2921 mutex_lock(&dev->dcam_mutex);
2922 ret = copy_from_user(&parm, (struct sprd_img_parm *)arg, sizeof(struct sprd_img_parm));
2924 printk("sprd_img_k_ioctl: fail to get user info \n");
2925 mutex_unlock(&dev->dcam_mutex);
2928 path = &dev->dcam_cxt.dcam_path[parm.channel_id];
2929 path->shrink = parm.shrink;
2930 mutex_unlock(&dev->dcam_mutex);
2931 DCAM_TRACE("SPRD_IMG: channel %d, shrink=%d \n", parm.channel_id, path->shrink);
2934 case SPRD_IMG_IO_PATH_PAUSE:
2935 ret = copy_from_user(&parm, (struct sprd_img_parm *)arg, sizeof(struct sprd_img_parm));
2937 printk("sprd_img_k_ioctl: fail to get user info \n");
2940 sprd_img_streampause(file, parm.channel_id, parm.reserved[0]);
2943 case SPRD_IMG_IO_PATH_RESUME:
2944 ret = copy_from_user(&channel_id, (uint32_t *)arg, sizeof(uint32_t));
2946 printk("sprd_img_k_ioctl: fail to get user info \n");
2949 sprd_img_streamresume(file, channel_id);
2952 case SPRD_IMG_IO_STREAM_ON:
2954 struct dcam_path_spec *path_0 = NULL;
2955 struct dcam_path_spec *path_1 = NULL;
2956 struct dcam_path_spec *path_2 = NULL;
2958 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_STREAM_ON \n");
2960 mutex_lock(&dev->dcam_mutex);
2962 path_0 = &dev->dcam_cxt.dcam_path[DCAM_PATH0];
2963 path_1 = &dev->dcam_cxt.dcam_path[DCAM_PATH1];
2964 path_2 = &dev->dcam_cxt.dcam_path[DCAM_PATH2];
2965 memset((void*)path_0->frm_ptr,
2967 (uint32_t)(DCAM_FRM_CNT_MAX * sizeof(struct dcam_frame*)));
2968 memset((void*)path_1->frm_ptr,
2970 (uint32_t)(DCAM_FRM_CNT_MAX * sizeof(struct dcam_frame*)));
2971 memset((void*)path_2->frm_ptr,
2973 (uint32_t)(DCAM_FRM_CNT_MAX * sizeof(struct dcam_frame*)));
2975 DCAM_TRACE("SPRD_IMG: streamon, is_work: path_0 = %d, path_1 = %d, path_2 = %d, stream_on = %d \n",
2976 path_0->is_work, path_1->is_work, path_2->is_work, atomic_read(&dev->stream_on));
2978 memset((void*)&path_1->in_rect_backup, 0x00, sizeof(struct dcam_rect));
2979 memset((void*)&path_1->in_rect_current, 0x00, sizeof(struct dcam_rect));
2982 /* dcam driver module initialization */
2983 ret = dcam_module_init(dev->dcam_cxt.if_mode, dev->dcam_cxt.sn_mode);
2984 if (unlikely(ret)) {
2985 printk(DEBUG_STR,DEBUG_ARGS);
2989 ret = sprd_img_queue_init(&dev->queue);
2990 if (unlikely(ret != 0)) {
2991 printk("SPRD_IMG: Failed to init queue \n");
2995 ret = sprd_img_reg_isr(dev);
2996 if (unlikely(ret)) {
2997 printk(DEBUG_STR,DEBUG_ARGS);
3001 /* config cap sub-module */
3002 ret = sprd_img_cap_cfg(&dev->dcam_cxt);
3003 if (unlikely(ret)) {
3004 printk(DEBUG_STR,DEBUG_ARGS);
3008 /* config path1 sub-module if necessary*/
3009 if (path_1->is_work) {
3010 ret = sprd_img_path_cfg(dcam_path1_cfg, path_1);
3011 if (unlikely(ret)) {
3012 printk(DEBUG_STR,DEBUG_ARGS);
3015 path_1->status = PATH_RUN;
3017 ret = dcam_path1_cfg(DCAM_PATH_ENABLE, &path_1->is_work);
3018 if (unlikely(ret)) {
3019 printk(DEBUG_STR,DEBUG_ARGS);
3024 /* config path2 sub-module if necessary*/
3025 if (path_2->is_work) {
3026 ret = sprd_img_path_cfg(dcam_path2_cfg, path_2);
3027 if (unlikely(ret)) {
3028 printk(DEBUG_STR,DEBUG_ARGS);
3031 ret = sprd_img_reg_path2_isr(dev);
3032 if (unlikely(ret)) {
3033 printk(DEBUG_STR,DEBUG_ARGS);
3036 path_2->status = PATH_RUN;
3038 ret = dcam_path2_cfg(DCAM_PATH_ENABLE, &path_2->is_work);
3039 if (unlikely(ret)) {
3040 printk(DEBUG_STR,DEBUG_ARGS);
3045 if (path_0->is_work) {
3046 ret = sprd_img_path0_cfg(dcam_path0_cfg, path_0);
3047 if (unlikely(ret)) {
3048 printk(DEBUG_STR,DEBUG_ARGS);
3051 path_0->status = PATH_RUN;
3053 ret = dcam_path0_cfg(DCAM_PATH_ENABLE, &path_0->is_work);
3054 if (unlikely(ret)) {
3055 printk(DEBUG_STR,DEBUG_ARGS);
3060 dev->frame_skipped = 0;
3061 if (FLASH_HIGH_LIGHT == dev->dcam_cxt.flash_status) {
3062 if (0 == dev->dcam_cxt.skip_number) {
3063 sprd_img_start_flash(NULL, dev);
3068 atomic_set(&dev->stream_on, 1);
3071 sprd_img_unreg_path2_isr(dev);
3072 sprd_img_unreg_isr(dev);
3073 printk("SPRD_IMG: Failed to start stream 0x%x \n", ret);
3075 atomic_set(&dev->run_flag, 0);
3076 sprd_start_timer(&dev->dcam_timer, DCAM_TIMEOUT);
3079 mutex_unlock(&dev->dcam_mutex);
3083 case SPRD_IMG_IO_STREAM_OFF:
3085 struct dcam_path_spec *path_0 = NULL;
3086 struct dcam_path_spec *path_1 = NULL;
3087 struct dcam_path_spec *path_2 = NULL;
3089 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_STREAM_OFF \n");
3091 mutex_lock(&dev->dcam_mutex);
3093 path_0 = &dev->dcam_cxt.dcam_path[DCAM_PATH0];
3094 path_1 = &dev->dcam_cxt.dcam_path[DCAM_PATH1];
3095 path_2 = &dev->dcam_cxt.dcam_path[DCAM_PATH2];
3097 DCAM_TRACE("SPRD_IMG: streamoff, is_work: path_0 = %d, path_1 = %d, path_2 = %d, stream_on = %d \n",
3098 path_0->is_work, path_1->is_work, path_2->is_work, atomic_read(&dev->stream_on));
3100 if (unlikely(0 == atomic_read(&dev->stream_on))) {
3101 printk("SPRD_IMG: stream not on\n");
3102 ret = sprd_img_local_deinit(dev);
3103 if (unlikely(ret)) {
3104 printk(DEBUG_STR,DEBUG_ARGS);
3106 mutex_unlock(&dev->dcam_mutex);
3111 ret = sprd_stop_timer(&dev->dcam_timer);
3112 if (unlikely(ret)) {
3113 printk(DEBUG_STR,DEBUG_ARGS);
3116 if (dev->got_resizer) {
3118 dev->got_resizer = 0;
3122 if (unlikely(ret)) {
3123 printk(DEBUG_STR,DEBUG_ARGS);
3127 ret = dcam_stop_cap();
3128 if (unlikely(ret)) {
3129 printk(DEBUG_STR,DEBUG_ARGS);
3133 ret = sprd_img_unreg_isr(dev);
3134 if (unlikely(ret)) {
3135 printk(DEBUG_STR,DEBUG_ARGS);
3139 if (path_1->is_work) {
3140 path_1->status = PATH_IDLE;
3141 path_1->is_work = 0;
3144 if (path_2->is_work) {
3145 path_2->status = PATH_IDLE;
3147 ret = sprd_img_unreg_path2_isr(dev);
3148 if (unlikely(ret)) {
3149 printk(DEBUG_STR,DEBUG_ARGS);
3153 path_2->is_work = 0;
3156 if (path_0->is_work) {
3157 path_0->status = PATH_IDLE;
3158 path_0->is_work = 0;
3160 DCAM_TRACE("SPRD_IMG: off, path work %d %d %d \n", path_0->is_work, path_1->is_work, path_2->is_work);
3161 atomic_set(&dev->stream_on, 0);
3163 if (DCAM_CAP_IF_CSI2 == dev->dcam_cxt.if_mode) {
3164 ret = csi_api_close();
3165 if (unlikely(ret)) {
3166 printk(DEBUG_STR,DEBUG_ARGS);
3172 ret = dcam_module_deinit(dev->dcam_cxt.if_mode, dev->dcam_cxt.sn_mode);
3173 if (unlikely(ret)) {
3174 printk(DEBUG_STR,DEBUG_ARGS);
3178 ret = sprd_img_local_deinit(dev);
3179 if (unlikely(ret)) {
3180 printk(DEBUG_STR,DEBUG_ARGS);
3185 mutex_unlock(&dev->dcam_mutex);
3189 case SPRD_IMG_IO_GET_FMT:
3191 struct dcam_format *fmt;
3192 struct sprd_img_get_fmt fmt_desc;
3194 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_GET_FMT \n");
3195 ret = copy_from_user(&fmt_desc, (struct sprd_img_get_fmt *)arg, sizeof(struct sprd_img_get_fmt));
3197 printk("sprd_img_k_ioctl: fail to get user info \n");
3200 if (unlikely(fmt_desc.index >= ARRAY_SIZE(dcam_img_fmt)))
3203 fmt = &dcam_img_fmt[fmt_desc.index];
3204 fmt_desc.fmt = fmt->fourcc;
3206 ret = copy_to_user((struct sprd_img_get_fmt *)arg, &fmt_desc, sizeof(struct sprd_img_get_fmt));
3210 case SPRD_IMG_IO_GET_CH_ID:
3212 struct dcam_path_spec *path_0 = NULL;
3213 struct dcam_path_spec *path_1 = NULL;
3214 struct dcam_path_spec *path_2 = NULL;
3215 struct dcam_get_path_id path_id;
3217 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_GET_CH_ID \n");
3218 path_0 = &dev->dcam_cxt.dcam_path[DCAM_PATH0];
3219 path_1 = &dev->dcam_cxt.dcam_path[DCAM_PATH1];
3220 path_2 = &dev->dcam_cxt.dcam_path[DCAM_PATH2];
3222 memset((void*)&path_id, 0, sizeof(struct dcam_get_path_id));
3223 path_id.input_size.w = dev->dcam_cxt.cap_in_rect.w;
3224 path_id.input_size.h = dev->dcam_cxt.cap_in_rect.h;
3225 path_id.output_size.w = dev->dcam_cxt.dst_size.w;
3226 path_id.output_size.h = dev->dcam_cxt.dst_size.h;
3227 path_id.fourcc = dev->dcam_cxt.pxl_fmt;
3228 path_id.need_isp_tool = dev->dcam_cxt.need_isp_tool;
3229 path_id.need_isp = dev->dcam_cxt.need_isp;
3230 path_id.camera_id = dev->dcam_cxt.camera_id;
3231 path_id.need_shrink = dev->dcam_cxt.need_shrink;
3232 path_id.input_trim.x = dev->dcam_cxt.path_input_rect.x;
3233 path_id.input_trim.y = dev->dcam_cxt.path_input_rect.y;
3234 path_id.input_trim.w = dev->dcam_cxt.path_input_rect.w;
3235 path_id.input_trim.h = dev->dcam_cxt.path_input_rect.h;
3236 DCAM_TRACE("SPRD_IMG: get param, path work %d %d %d \n", path_0->is_work, path_1->is_work, path_2->is_work);
3237 path_id.is_path_work[DCAM_PATH0] = path_0->is_work;
3238 path_id.is_path_work[DCAM_PATH1] = path_1->is_work;
3239 path_id.is_path_work[DCAM_PATH2] = path_2->is_work;
3240 ret = dcam_get_path_id(&path_id, &channel_id);
3241 ret = copy_to_user((uint32_t *)arg, &channel_id, sizeof(uint32_t));
3242 sprd_img_local_clear_path_buffer(dev, channel_id);
3243 DCAM_TRACE("SPRD_IMG: get channel_id %d \n", channel_id);
3247 case SPRD_IMG_IO_GET_TIME:
3249 struct timeval time;
3250 struct sprd_img_time utime;
3252 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_GET_TIME \n");
3253 img_get_timestamp(&time);
3254 utime.sec = time.tv_sec;
3255 utime.usec = time.tv_usec;
3256 ret = copy_to_user((struct sprd_img_time *)arg, &utime, sizeof(struct sprd_img_time));
3260 case SPRD_IMG_IO_CHECK_FMT:
3262 struct dcam_format *fmt;
3263 struct sprd_img_format img_format;
3265 DCAM_TRACE("SPRD_IMG: SPRD_IMG_IO_CHECK_FMT \n");
3266 ret = copy_from_user(&img_format, (struct sprd_img_format *)arg, sizeof(struct sprd_img_format));
3268 printk("sprd_img_k_ioctl: fail to get user info \n");
3272 fmt = sprd_img_get_format(img_format.fourcc);
3273 if (unlikely(!fmt)) {
3274 printk("SPRD_IMG: Fourcc format (0x%08x) invalid. \n",
3279 if (DCAM_PATH1 == img_format.channel_id) {
3280 mutex_lock(&dev->dcam_mutex);
3281 ret = sprd_img_check_path1_cap(fmt->fourcc, &img_format, &dev->dcam_cxt);
3282 mutex_unlock(&dev->dcam_mutex);
3283 channel_id = DCAM_PATH1;
3284 } else if (DCAM_PATH2 == img_format.channel_id) {
3285 if (img_format.is_lightly) {
3286 mutex_lock(&dev->dcam_mutex);
3287 ret = sprd_img_check_path2_cap(fmt->fourcc, &img_format, &dev->dcam_cxt);
3288 mutex_unlock(&dev->dcam_mutex);
3290 if (unlikely(dcam_get_resizer(DCAM_WAIT_FOREVER))) {
3291 /*no wait to get the controller of resizer, failed*/
3292 printk("SPRD_IMG: path2 has been occupied by other app \n");
3295 dev->got_resizer = 1;
3296 mutex_lock(&dev->dcam_mutex);
3297 ret = sprd_img_check_path2_cap(fmt->fourcc, &img_format, &dev->dcam_cxt);
3298 mutex_unlock(&dev->dcam_mutex);
3300 /*failed to set path2, release the controller of resizer*/
3302 dev->got_resizer = 0;
3305 channel_id = DCAM_PATH2;
3306 } else if (DCAM_PATH0 == img_format.channel_id) {
3307 mutex_lock(&dev->dcam_mutex);
3308 ret = sprd_img_check_path0_cap(fmt->fourcc, &img_format, &dev->dcam_cxt);
3309 mutex_unlock(&dev->dcam_mutex);
3310 channel_id = DCAM_PATH0;
3312 printk("SPRD_IMG: Buf type invalid. \n");
3316 memcpy((void*)&img_format.reserved[0], (void*)&dev->dcam_cxt.dcam_path[channel_id].end_sel, sizeof(struct dcam_endian_sel));
3317 if ((0 == ret) && (0 != atomic_read(&dev->stream_on))) {
3318 if (DCAM_PATH0 == channel_id || DCAM_PATH1 == channel_id || DCAM_PATH2 == channel_id) {
3319 ret = sprd_img_update_video(file, channel_id);
3322 ret = copy_to_user((struct sprd_img_format *)arg, &img_format, sizeof(struct sprd_img_format));
3327 printk("sprd_img_k_ioctl: invalid cmd %d \n", cmd);
3336 LOCAL int sprd_img_check_frame_timestamp(struct dcam_dev* param, struct timeval *tv)
3338 int ret = DCAM_RTN_SUCCESS;
3339 struct dcam_dev *dev = (struct dcam_dev*)param;
3340 struct dcam_info *info = NULL;
3341 struct timeval timestamp;
3344 info = &dev->dcam_cxt;
3345 timestamp.tv_sec = tv->tv_sec;
3346 timestamp.tv_usec = tv->tv_usec;
3347 DCAM_TRACE("SPRD_IMG: check_frame_timestamp, time, %d %d \n",
3348 (int)timestamp.tv_sec, (int)timestamp.tv_usec);
3349 if ((timestamp.tv_sec == info->frame_last_timestamp.tv_sec)
3350 && (timestamp.tv_usec - info->frame_last_timestamp.tv_usec >= 1)){
3352 } else if (timestamp.tv_sec > info->frame_last_timestamp.tv_sec) {
3359 printk("SPRD_IMG: check_frame_timestamp, %d %d %d %d \n", (int)timestamp.tv_sec, (int)timestamp.tv_usec,
3360 (int)info->frame_last_timestamp.tv_sec, (int)info->frame_last_timestamp.tv_usec);
3361 ret = DCAM_RTN_PARA_ERR;
3364 info->frame_last_timestamp.tv_sec = timestamp.tv_sec;
3365 info->frame_last_timestamp.tv_usec = timestamp.tv_usec;
3371 ssize_t sprd_img_read(struct file *file, char __user *u_data, size_t cnt, loff_t *cnt_ret)
3373 struct dcam_dev *dev = file->private_data;
3374 struct dcam_node node;
3375 struct dcam_path_spec *path;
3376 struct sprd_img_read_op read_op;
3377 struct timeval time;
3378 struct dcam_path_capability path_capability;
3382 DCAM_TRACE("SPRD_IMG: sprd_img_read %ld, dev %p \n", cnt, dev);
3387 if (cnt < sizeof(struct sprd_img_read_op)) {
3388 printk("sprd_img_read: error, cnt %ld read_op %ld \n", cnt, sizeof(struct sprd_img_read_op));
3392 ret = copy_from_user(&read_op, (struct sprd_img_read_op *)u_data, sizeof(struct sprd_img_read_op));
3394 printk("sprd_img_read: fail to get user info \n");
3398 switch (read_op.cmd) {
3399 case SPRD_IMG_GET_SCALE_CAP:
3400 DCAM_TRACE("SPRD_IMG: get scale capbility \n");
3401 read_op.parm.reserved[0] = DCAM_PATH2_LINE_BUF_LENGTH;
3402 read_op.parm.reserved[1] = DCAM_SC_COEFF_UP_MAX;
3403 read_op.parm.reserved[2] = DCAM_SCALING_THRESHOLD;
3404 DCAM_TRACE("SPRD_IMG: sprd_img_read line threshold %d, sc factor %d, scaling %d.\n",
3405 read_op.parm.reserved[0],
3406 read_op.parm.reserved[1],
3407 read_op.parm.reserved[2]);
3410 case SPRD_IMG_GET_FRM_BUFFER:
3411 DCAM_TRACE("SPRD_IMG: read frame buffer \n");
3412 memset(&read_op, 0, sizeof(struct sprd_img_read_op));
3414 ret = down_interruptible(&dev->irq_sem);
3417 } else if (-EINTR == ret) {
3418 read_op.evt = IMG_SYS_BUSY;
3419 ret = DCAM_RTN_SUCCESS;
3422 printk("SPRD_IMG: read frame buffer, failed to down, %d \n", ret);
3427 if (sprd_img_queue_read(&dev->queue, &node)) {
3428 printk("SPRD_IMG: read frame buffer, queue is null \n");
3429 read_op.evt = IMG_SYS_BUSY;
3430 ret = DCAM_RTN_SUCCESS;
3433 if (node.invalid_flag) {
3434 printk("SPRD_IMG: read frame buffer, invalid node\n");
3435 read_op.evt = IMG_SYS_BUSY;
3436 ret = DCAM_RTN_SUCCESS;
3441 img_get_timestamp(&time);
3442 DCAM_TRACE("SPRD_IMG: time, %ld %ld \n", (unsigned long)time.tv_sec, (unsigned long)time.tv_usec);
3444 read_op.evt = node.irq_flag;
3445 if (IMG_TX_DONE == read_op.evt || IMG_CANCELED_BUF == read_op.evt) {
3446 read_op.parm.frame.channel_id = node.f_type;
3447 path = &dev->dcam_cxt.dcam_path[read_op.parm.frame.channel_id];
3448 DCAM_TRACE("SPRD_IMG: node, 0x%x %d %d \n", node, node.index, path->frm_id_base);
3449 read_op.parm.frame.index = path->frm_id_base;//node.index;
3450 read_op.parm.frame.height = node.height;
3451 read_op.parm.frame.length = node.reserved;
3452 read_op.parm.frame.sec = time.tv_sec;
3453 read_op.parm.frame.usec = time.tv_usec;
3454 //fmr_index = node.index - path->frm_id_base;
3455 //read_op.parm.frame.real_index = path->index[fmr_index];
3456 read_op.parm.frame.frm_base_id = path->frm_id_base;
3457 read_op.parm.frame.img_fmt = path->fourcc;
3458 read_op.parm.frame.yaddr = node.yaddr;
3459 read_op.parm.frame.uaddr = node.uaddr;
3460 read_op.parm.frame.vaddr = node.vaddr;
3461 read_op.parm.frame.yaddr_vir = node.yaddr_vir;
3462 read_op.parm.frame.uaddr_vir = node.uaddr_vir;
3463 read_op.parm.frame.vaddr_vir = node.vaddr_vir;
3464 DCAM_TRACE("index %d real_index %d frm_id_base %d fmr_index %d \n",
3465 read_op.parm.frame.index,
3466 read_op.parm.frame.real_index,
3467 read_op.parm.frame.frm_base_id,
3470 DCAM_TRACE("SPRD_IMG: read, %d %d %d \n", node.index, path->frm_id_base, node.index-path->frm_id_base);
3471 if (sprd_img_check_frame_timestamp(dev, &time)) {
3472 read_op.evt = IMG_CANCELED_BUF;
3473 ret = DCAM_RTN_SUCCESS;
3478 if (IMG_TIMEOUT == read_op.evt ||
3479 IMG_TX_ERR == read_op.evt)
3480 sprd_img_print_reg();
3482 DCAM_TRACE("SPRD_IMG: read frame buffer, evt 0x%x channel_id 0x%x index 0x%x \n",
3484 read_op.parm.frame.channel_id,
3485 read_op.parm.frame.index);
3488 case SPRD_IMG_GET_PATH_CAP:
3489 DCAM_TRACE("SPRD_IMG: get path capbility \n");
3490 dcam_get_path_capability(&path_capability);
3491 read_op.parm.capability.count = path_capability.count;
3492 for (i = 0; i< path_capability.count; i++) {
3493 read_op.parm.capability.path_info[i].line_buf = path_capability.path_info[i].line_buf;
3494 read_op.parm.capability.path_info[i].support_yuv = path_capability.path_info[i].support_yuv;
3495 read_op.parm.capability.path_info[i].support_raw = path_capability.path_info[i].support_raw;
3496 read_op.parm.capability.path_info[i].support_jpeg = path_capability.path_info[i].support_jpeg;
3497 read_op.parm.capability.path_info[i].support_scaling = path_capability.path_info[i].support_scaling;
3498 read_op.parm.capability.path_info[i].support_trim = path_capability.path_info[i].support_trim;
3499 read_op.parm.capability.path_info[i].is_scaleing_path = path_capability.path_info[i].is_scaleing_path;
3504 printk("SPRD_IMG: sprd_img_read, invalid cmd \n");
3508 return copy_to_user((struct sprd_img_read_op *)u_data, &read_op, sizeof(struct sprd_img_read_op));
3511 ssize_t sprd_img_write(struct file *file, const char __user * u_data, size_t cnt, loff_t *cnt_ret)
3513 struct dcam_dev *dev = file->private_data;
3514 struct dcam_info *info = &dev->dcam_cxt;
3515 struct dcam_path_spec *path;
3516 struct sprd_img_write_op write_op;
3520 DCAM_TRACE("SPRD_IMG: sprd_img_write %ld, dev %p \n", cnt, dev);
3525 if (cnt < sizeof(struct sprd_img_write_op)) {
3526 printk("sprd_img_write: error, cnt %ld read_op %ld \n", cnt, sizeof(struct sprd_img_write_op));
3530 ret = copy_from_user(&write_op, (struct sprd_img_write_op *)u_data, sizeof(struct sprd_img_write_op));
3532 printk("sprd_img_write: fail to get user info \n");
3536 switch (write_op.cmd) {
3537 case SPRD_IMG_STOP_DCAM:
3538 mutex_lock(&dev->dcam_mutex);
3539 ret = sprd_img_tx_stop(dev);
3544 mutex_unlock(&dev->dcam_mutex);
3547 case SPRD_IMG_FREE_FRAME:
3548 if (0 == atomic_read(&dev->stream_on)) {
3549 printk("SPRD_IMG: dev close, no need free!");
3552 switch (write_op.channel_id) {
3556 path = &info->dcam_path[write_op.channel_id];
3559 printk("SPRD_IMG: error free frame buffer, channel_id 0x%x \n", write_op.channel_id);
3563 if (PATH_IDLE == path->status) {
3564 DCAM_TRACE("SPRD_IMG: error free frame buffer, wrong status, channel_id 0x%x \n",
3565 write_op.channel_id);
3569 if (unlikely(write_op.index > path->frm_id_base + path->frm_cnt_act - 1)) {
3570 printk("SPRD_IMG: error, index %d, frm_id_base %d frm_cnt_act %d \n",
3571 write_op.index, path->frm_id_base, path->frm_cnt_act);
3573 } else if (write_op.index < path->frm_id_base) {
3574 printk("SPRD_IMG: error, index %d, frm_id_base %d \n",
3575 write_op.index, path->frm_id_base);
3578 index = write_op.index - path->frm_id_base;
3579 if (path->frm_ptr[index]) {
3580 dcam_frame_unlock(path->frm_ptr[index]);
3582 DCAM_TRACE("SPRD_IMG: free frame buffer, channel_id 0x%x, index 0x%x \n",
3583 write_op.channel_id, write_op.index);
3588 printk("SPRD_IMG: cmd error! \n");
3597 LOCAL int sprd_img_proc_read(char *page,
3605 struct dcam_dev *dev = (struct dcam_dev*)data;
3607 uint32_t reg_buf_len = 0x400;
3608 uint32_t print_len = 0, print_cnt = 0;
3610 (void)start; (void)off; (void)count; (void)eof;
3612 len += sprintf(page + len, "Context for DCAM device \n");
3613 len += sprintf(page + len, "*************************************************************** \n");
3614 len += sprintf(page + len, "SPRD_ION_MM_SIZE: 0x%x \n", SPRD_ION_MM_SIZE);
3615 len += sprintf(page + len, "the configuration of CAP \n");
3616 len += sprintf(page + len, " 1. interface mode, %d \n", dev->dcam_cxt.if_mode);
3617 len += sprintf(page + len, " 2. sensor mode, %d \n", dev->dcam_cxt.sn_mode);
3618 len += sprintf(page + len, " 3. YUV pattern, %d \n", dev->dcam_cxt.yuv_ptn);
3619 len += sprintf(page + len, " 4. sync polarities, v %d h %d p %d href %d \n",
3620 dev->dcam_cxt.sync_pol.vsync_pol,
3621 dev->dcam_cxt.sync_pol.hsync_pol,
3622 dev->dcam_cxt.sync_pol.pclk_pol,
3623 dev->dcam_cxt.sync_pol.need_href);
3624 len += sprintf(page + len, " 5. Data bit-width, %d \n", dev->dcam_cxt.data_bits);
3625 len += sprintf(page + len, " 6. need ISP, %d \n", dev->dcam_cxt.dcam_path[DCAM_PATH1].is_from_isp);
3626 len += sprintf(page + len, "*************************************************************** \n");
3627 len += sprintf(page + len, "the configuration of PATH1 \n");
3628 len += sprintf(page + len, " 1. input rect, %d %d %d %d \n",
3629 dev->dcam_cxt.dcam_path[DCAM_PATH1].in_rect.x,
3630 dev->dcam_cxt.dcam_path[DCAM_PATH1].in_rect.y,
3631 dev->dcam_cxt.dcam_path[DCAM_PATH1].in_rect.w,
3632 dev->dcam_cxt.dcam_path[DCAM_PATH1].in_rect.h);
3633 len += sprintf(page + len, " 2. output size, %d %d \n",
3634 dev->dcam_cxt.dcam_path[DCAM_PATH1].out_size.w,
3635 dev->dcam_cxt.dcam_path[DCAM_PATH1].out_size.h);
3636 len += sprintf(page + len, " 3. output format, %d \n",
3637 dev->dcam_cxt.dcam_path[DCAM_PATH1].out_fmt);
3638 len += sprintf(page + len, " 4. frame base index, 0x%x \n", dev->dcam_cxt.dcam_path[DCAM_PATH1].frm_id_base);
3639 len += sprintf(page + len, " 5. frame count, 0x%x \n", dev->dcam_cxt.dcam_path[DCAM_PATH1].frm_cnt_act);
3640 len += sprintf(page + len, " 6. frame type, 0x%x \n", dev->dcam_cxt.dcam_path[DCAM_PATH1].frm_type);
3641 for (print_cnt = 0; print_cnt < DCAM_PATH_1_FRM_CNT_MAX; print_cnt ++) {
3642 len += sprintf(page + len, "%2d. frame buffer%d, 0x%08x 0x%08x 0x%08x \n",
3645 dev->dcam_cxt.dcam_path[DCAM_PATH1].frm_addr[print_cnt].yaddr,
3646 dev->dcam_cxt.dcam_path[DCAM_PATH1].frm_addr[print_cnt].uaddr,
3647 dev->dcam_cxt.dcam_path[DCAM_PATH1].frm_addr[print_cnt].vaddr);
3650 if (dev->dcam_cxt.dcam_path[DCAM_PATH2].is_work) {
3651 len += sprintf(page + len, "*************************************************************** \n");
3652 len += sprintf(page + len, "the configuration of PATH2 \n");
3653 len += sprintf(page + len, " 1. input rect, %d %d %d %d \n",
3654 dev->dcam_cxt.dcam_path[DCAM_PATH2].in_rect.x,
3655 dev->dcam_cxt.dcam_path[DCAM_PATH2].in_rect.y,
3656 dev->dcam_cxt.dcam_path[DCAM_PATH2].in_rect.w,
3657 dev->dcam_cxt.dcam_path[DCAM_PATH2].in_rect.h);
3658 len += sprintf(page + len, " 2. output size, %d %d \n",
3659 dev->dcam_cxt.dcam_path[DCAM_PATH2].out_size.w,
3660 dev->dcam_cxt.dcam_path[DCAM_PATH2].out_size.h);
3661 len += sprintf(page + len, " 3. output format, %d \n",
3662 dev->dcam_cxt.dcam_path[DCAM_PATH2].out_fmt);
3663 len += sprintf(page + len, " 4. frame base index, 0x%x \n", dev->dcam_cxt.dcam_path[DCAM_PATH2].frm_id_base);
3664 len += sprintf(page + len, " 5. frame count, 0x%x \n", dev->dcam_cxt.dcam_path[DCAM_PATH2].frm_cnt_act);
3665 len += sprintf(page + len, " 6. frame type, 0x%x \n", dev->dcam_cxt.dcam_path[DCAM_PATH2].frm_type);
3666 for (print_cnt = 0; print_cnt < DCAM_PATH_2_FRM_CNT_MAX; print_cnt ++) {
3667 len += sprintf(page + len, "%2d. frame buffer%d, 0x%8x 0x%8x 0x%8x \n",
3670 dev->dcam_cxt.dcam_path[DCAM_PATH2].frm_addr[print_cnt].yaddr,
3671 dev->dcam_cxt.dcam_path[DCAM_PATH2].frm_addr[print_cnt].uaddr,
3672 dev->dcam_cxt.dcam_path[DCAM_PATH2].frm_addr[print_cnt].vaddr);
3677 reg_buf = (uint32_t*)vzalloc(reg_buf_len);
3678 ret = dcam_read_registers(reg_buf, ®_buf_len);
3684 len += sprintf(page + len, "*************************************************************** \n");
3685 len += sprintf(page + len, "dcam registers \n");
3687 while (print_len < reg_buf_len) {
3688 len += sprintf(page + len, "offset 0x%03x: 0x%08x, 0x%08x, 0x%08x, 0x%08x \n",
3691 reg_buf[print_cnt+1],
3692 reg_buf[print_cnt+2],
3693 reg_buf[print_cnt+3]);
3698 ret = csi_read_registers(reg_buf, ®_buf_len);
3704 len += sprintf(page + len, "*************************************************************** \n");
3705 len += sprintf(page + len, "csi host registers \n");
3708 while (print_len < reg_buf_len) {
3709 len += sprintf(page + len, "offset 0x%03x: 0x%08x, 0x%08x, 0x%08x, 0x%08x \n",
3712 reg_buf[print_cnt+1],
3713 reg_buf[print_cnt+2],
3714 reg_buf[print_cnt+3]);
3718 len += sprintf(page + len, "*************************************************************** \n");
3719 len += sprintf(page + len, "The end of DCAM device \n");
3727 static struct file_operations image_fops = {
3728 .owner = THIS_MODULE,
3729 .open = sprd_img_k_open,
3730 .unlocked_ioctl = sprd_img_k_ioctl,
3731 #ifdef CONFIG_COMPAT
3732 .compat_ioctl = sprd_img_k_ioctl,
3734 .release = sprd_img_k_release,
3735 .read = sprd_img_read,
3736 .write = sprd_img_write,
3739 static struct miscdevice image_dev = {
3740 .minor = IMAGE_MINOR,
3741 .name = IMG_DEVICE_NAME,
3742 .fops = &image_fops,
3746 int sprd_img_probe(struct platform_device *pdev)
3750 DCAM_TRACE(KERN_ALERT "sprd_img_probe called\n");
3752 ret = misc_register(&image_dev);
3754 printk(KERN_ERR "cannot register miscdev on minor=%d (%d)\n",
3759 image_dev.this_device->of_node = pdev->dev.of_node;
3760 parse_baseaddress(pdev->dev.of_node);
3762 printk(KERN_ALERT "sprd_img_probe Success\n");
3769 static int sprd_img_remove(struct platform_device *pdev)
3771 misc_deregister(&image_dev);
3775 static void sprd_img_shutdown(struct platform_device *pdev)
3780 LOCAL const struct of_device_id of_match_table_dcam[] = {
3781 { .compatible = "sprd,sprd_dcam", },
3784 LOCAL struct platform_driver sprd_img_driver = {
3785 .probe = sprd_img_probe,
3786 .remove = sprd_img_remove,
3787 .shutdown = sprd_img_shutdown,
3789 .owner = THIS_MODULE,
3790 .name = IMG_DEVICE_NAME,
3791 .of_match_table = of_match_ptr(of_match_table_dcam),
3795 int __init sprd_img_k_init(void)
3797 if (platform_driver_register(&sprd_img_driver) != 0) {
3798 printk("platform device register Failed \n");
3802 if (dcam_scale_coeff_alloc()) {
3803 printk("dcam_scale_coeff_alloc Failed \n");
3807 printk(KERN_INFO "Video Technology Magazine Virtual Video "
3808 "Capture Board ver %u.%u.%u successfully loaded.\n",
3809 (DCAM_VERSION >> 16) & 0xFF, (DCAM_VERSION >> 8) & 0xFF,
3810 DCAM_VERSION & 0xFF);
3814 void sprd_img_k_exit(void)
3816 dcam_scale_coeff_free();
3817 platform_driver_unregister(&sprd_img_driver);
3820 module_init(sprd_img_k_init);
3821 module_exit(sprd_img_k_exit);
3822 MODULE_DESCRIPTION("DCAM Driver");
3823 MODULE_AUTHOR("Multimedia_Camera@Spreadtrum");
3824 MODULE_LICENSE("GPL");