39 #include <linux/videodev2.h>
43 #include <linux/module.h>
55 static struct ccdc_oper_config {
58 enum vpfe_hw_if_type if_type;
60 struct ccdc_params_raw bayer;
62 struct ccdc_params_ycbcr ycbcr;
75 .fid_pol = VPFE_PINPOL_POSITIVE,
76 .vd_pol = VPFE_PINPOL_POSITIVE,
77 .hd_pol = VPFE_PINPOL_POSITIVE,
86 .fid_pol = VPFE_PINPOL_POSITIVE,
87 .vd_pol = VPFE_PINPOL_POSITIVE,
88 .hd_pol = VPFE_PINPOL_POSITIVE,
95 #define CCDC_MAX_RAW_YUV_FORMATS 2
98 static u32 ccdc_raw_bayer_pix_formats[] =
102 static u32 ccdc_raw_yuv_pix_formats[] =
119 static void ccdc_enable(
int flag)
124 static void ccdc_enable_vport(
int flag)
142 int horz_start, horz_nr_pixels;
143 int vert_start, vert_nr_lines;
144 int val = 0, mid_img = 0;
146 dev_dbg(ccdc_cfg.dev,
"\nStarting ccdc_setwin...");
152 horz_start = image_win->
left << (ppc - 1);
153 horz_nr_pixels = (image_win->
width << (ppc - 1)) - 1;
157 vert_start = image_win->
top;
160 vert_nr_lines = (image_win->
height >> 1) - 1;
171 vert_nr_lines = image_win->
height - 1;
176 mid_img = vert_start + (image_win->
height / 2);
185 dev_dbg(ccdc_cfg.dev,
"\nEnd of ccdc_setwin...");
188 static void ccdc_readregs(
void)
190 unsigned int val = 0;
193 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to ALAW...\n", val);
195 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to CLAMP...\n", val);
197 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to DCSUB...\n", val);
199 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to BLKCMP...\n", val);
201 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to FPC_ADDR...\n", val);
203 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to FPC...\n", val);
205 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to FMTCFG...\n", val);
207 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to COLPTN...\n", val);
209 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to FMT_HORZ...\n", val);
211 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to FMT_VERT...\n", val);
213 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to HSIZE_OFF...\n", val);
215 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to SDOFST...\n", val);
217 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to VP_OUT...\n", val);
219 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to SYN_MODE...\n", val);
221 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to HORZ_INFO...\n", val);
223 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to VERT_START...\n", val);
225 dev_notice(ccdc_cfg.dev,
"\nReading 0x%x to VERT_LINES...\n", val);
230 if (ccdcparam->
alaw.enable) {
234 dev_dbg(ccdc_cfg.dev,
"\nInvalid data line select");
244 &ccdc_cfg.bayer.config_params;
245 unsigned int *fpc_virtaddr =
NULL;
246 unsigned int *fpc_physaddr =
NULL;
248 memcpy(config_params, raw_params,
sizeof(*raw_params));
256 fpc_physaddr = (
unsigned int *)config_params->
fault_pxl.fpc_table_addr;
258 (
unsigned long)fpc_physaddr);
265 if (fpc_physaddr !=
NULL) {
279 if (fpc_virtaddr ==
NULL) {
281 "\nUnable to allocate memory for FPC");
291 (
void __user *)raw_params->
fault_pxl.fpc_table_addr,
292 config_params->
fault_pxl.fp_num * FP_NUM_BYTES)) {
293 dev_dbg(ccdc_cfg.dev,
"\n copy_from_user failed");
296 config_params->
fault_pxl.fpc_table_addr = (
unsigned int)fpc_physaddr;
300 static int ccdc_close(
struct device *
dev)
303 &ccdc_cfg.bayer.config_params;
304 unsigned int *fpc_physaddr =
NULL, *fpc_virtaddr =
NULL;
306 fpc_physaddr = (
unsigned int *)config_params->
fault_pxl.fpc_table_addr;
308 if (fpc_physaddr !=
NULL) {
309 fpc_virtaddr = (
unsigned int *)
322 static void ccdc_restore_defaults(
void)
329 for (i = 4; i <= 0x94; i += 4)
337 ccdc_restore_defaults();
338 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
339 ccdc_enable_vport(1);
343 static void ccdc_sbl_reset(
void)
349 static int ccdc_set_params(
void __user *
params)
354 if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
357 x =
copy_from_user(&ccdc_raw_params, params,
sizeof(ccdc_raw_params));
359 dev_dbg(ccdc_cfg.dev,
"ccdc_set_params: error in copying"
360 "ccdc params, %d\n", x);
364 if (!validate_ccdc_param(&ccdc_raw_params)) {
365 if (!ccdc_update_raw_params(&ccdc_raw_params))
377 struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
380 dev_dbg(ccdc_cfg.dev,
"\nStarting ccdc_config_ycbcr...");
386 ccdc_restore_defaults();
400 if (params->bt656_enable) {
408 if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
430 if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
450 dev_dbg(ccdc_cfg.dev,
"\nEnd of ccdc_config_ycbcr...\n");
461 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to DCSUB...\n", val);
463 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x0000 to CLAMP...\n");
478 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to CLAMP...\n", val);
481 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x00000000 to DCSUB...\n");
511 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to FPC_ADDR...\n",
517 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to FPC...\n", val);
521 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to FPC...\n", val);
530 struct ccdc_params_raw *params = &ccdc_cfg.bayer;
532 &ccdc_cfg.bayer.config_params;
533 unsigned int syn_mode = 0;
536 dev_dbg(ccdc_cfg.dev,
"\nStarting ccdc_config_raw...");
539 ccdc_restore_defaults();
562 if (config_params->
alaw.enable) {
563 val = ((config_params->
alaw.gama_wd &
566 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to ALAW...\n", val);
573 ccdc_config_black_clamp(&config_params->
blk_clamp);
576 ccdc_config_black_compense(&config_params->
blk_comp);
579 ccdc_config_fpc(&config_params->
fault_pxl);
583 config_params->
alaw.enable)
586 #ifdef CONFIG_DM644X_VIDEO_PORT_ENABLE
603 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to FMTCFG...\n", val);
607 dev_dbg(ccdc_cfg.dev,
"\nWriting 0xBB11BB11 to COLPTN...\n");
617 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to FMT_HORZ...\n", val);
625 dev_dbg(ccdc_cfg.dev,
"\nparams->win.height 0x%x ...\n",
629 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to FMT_VERT...\n", val);
631 dev_dbg(ccdc_cfg.dev,
"\nbelow regw(val, FMT_VERT)...");
638 config_params->
alaw.enable)
649 if (params->image_invert_enable) {
652 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x4B6D to SDOFST..\n");
658 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x0249 to SDOFST..\n");
662 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x0000 to SDOFST...\n");
683 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to VP_OUT...\n", val);
685 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to SYN_MODE...\n", syn_mode);
688 dev_dbg(ccdc_cfg.dev,
"\nend of ccdc_config_raw...");
692 static int ccdc_configure(
void)
694 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
703 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
704 ccdc_cfg.bayer.buf_type = buf_type;
706 ccdc_cfg.ycbcr.buf_type = buf_type;
712 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
713 return ccdc_cfg.bayer.buf_type;
714 return ccdc_cfg.ycbcr.buf_type;
717 static int ccdc_enum_pix(
u32 *pix,
int i)
720 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
721 if (i <
ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
722 *pix = ccdc_raw_bayer_pix_formats[
i];
726 if (i <
ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
727 *pix = ccdc_raw_yuv_pix_formats[
i];
734 static int ccdc_set_pixel_format(
u32 pixfmt)
736 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
739 ccdc_cfg.bayer.config_params.alaw.enable = 1;
753 static u32 ccdc_get_pixel_format(
void)
755 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
758 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
774 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
775 ccdc_cfg.bayer.win = *
win;
777 ccdc_cfg.ycbcr.win = *
win;
781 static void ccdc_get_image_window(
struct v4l2_rect *win)
783 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
784 *win = ccdc_cfg.bayer.win;
786 *win = ccdc_cfg.ycbcr.win;
789 static unsigned int ccdc_get_line_length(
void)
792 &ccdc_cfg.bayer.config_params;
795 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
796 if ((config_params->
alaw.enable) ||
798 len = ccdc_cfg.bayer.win.width;
800 len = ccdc_cfg.bayer.win.width * 2;
802 len = ccdc_cfg.ycbcr.win.width * 2;
803 return ALIGN(len, 32);
806 static int ccdc_set_frame_format(
enum ccdc_frmfmt frm_fmt)
808 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
809 ccdc_cfg.bayer.frm_fmt = frm_fmt;
811 ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
815 static enum ccdc_frmfmt ccdc_get_frame_format(
void)
817 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
818 return ccdc_cfg.bayer.frm_fmt;
820 return ccdc_cfg.ycbcr.frm_fmt;
823 static int ccdc_getfid(
void)
829 static inline void ccdc_setfbaddr(
unsigned long addr)
834 static int ccdc_set_hw_if_params(
struct vpfe_hw_if_param *params)
836 ccdc_cfg.if_type = params->if_type;
838 switch (params->if_type) {
840 case VPFE_YCBCR_SYNC_16:
841 case VPFE_YCBCR_SYNC_8:
842 case VPFE_BT656_10BIT:
843 ccdc_cfg.ycbcr.vd_pol = params->vdpol;
844 ccdc_cfg.ycbcr.hd_pol = params->hdpol;
853 static void ccdc_save_context(
void)
894 static void ccdc_restore_context(
void)
934 static struct ccdc_hw_device ccdc_hw_dev = {
935 .name =
"DM6446 CCDC",
940 .reset = ccdc_sbl_reset,
941 .enable = ccdc_enable,
942 .set_hw_if_params = ccdc_set_hw_if_params,
943 .set_params = ccdc_set_params,
944 .configure = ccdc_configure,
945 .set_buftype = ccdc_set_buftype,
946 .get_buftype = ccdc_get_buftype,
947 .enum_pix = ccdc_enum_pix,
948 .set_pixel_format = ccdc_set_pixel_format,
949 .get_pixel_format = ccdc_get_pixel_format,
950 .set_frame_format = ccdc_set_frame_format,
951 .get_frame_format = ccdc_get_frame_format,
952 .set_image_window = ccdc_set_image_window,
953 .get_image_window = ccdc_get_image_window,
954 .get_line_length = ccdc_get_line_length,
955 .setfbaddr = ccdc_setfbaddr,
956 .getfid = ccdc_getfid,
986 if (!ccdc_cfg.base_addr) {
992 ccdc_cfg.mclk =
clk_get(&pdev->
dev,
"master");
993 if (IS_ERR(ccdc_cfg.mclk)) {
994 status = PTR_ERR(ccdc_cfg.mclk);
1003 ccdc_cfg.sclk =
clk_get(&pdev->
dev,
"slave");
1004 if (IS_ERR(ccdc_cfg.sclk)) {
1005 status = PTR_ERR(ccdc_cfg.sclk);
1012 ccdc_cfg.dev = &pdev->
dev;
1042 static int dm644x_ccdc_suspend(
struct device *dev)
1045 ccdc_save_context();
1055 static int dm644x_ccdc_resume(
struct device *dev)
1061 ccdc_restore_context();
1066 static const struct dev_pm_ops dm644x_ccdc_pm_ops = {
1067 .suspend = dm644x_ccdc_suspend,
1068 .resume = dm644x_ccdc_resume,
1073 .name =
"dm644x_ccdc",
1075 .pm = &dm644x_ccdc_pm_ops,
1078 .probe = dm644x_ccdc_probe,