39 #include <linux/videodev2.h>
42 #include <linux/module.h>
54 static struct ccdc_oper_config {
57 enum vpfe_hw_if_type if_type;
59 struct ccdc_params_raw bayer;
61 struct ccdc_params_ycbcr ycbcr;
74 .fid_pol = VPFE_PINPOL_POSITIVE,
75 .vd_pol = VPFE_PINPOL_POSITIVE,
76 .hd_pol = VPFE_PINPOL_POSITIVE,
113 .fid_pol = VPFE_PINPOL_POSITIVE,
114 .vd_pol = VPFE_PINPOL_POSITIVE,
115 .hd_pol = VPFE_PINPOL_POSITIVE,
124 static u32 ccdc_raw_bayer_pix_formats[] =
128 static u32 ccdc_raw_yuv_pix_formats[] =
142 static void ccdc_enable(
int en)
151 static void ccdc_enable_output_to_sdram(
int en)
160 static void ccdc_config_gain_offset(
void)
175 static int ccdc_restore_defaults(
void)
179 dev_dbg(ccdc_cfg.dev,
"\nstarting ccdc_restore_defaults...");
194 ccdc_config_gain_offset();
199 dev_dbg(ccdc_cfg.dev,
"\ncouldn't select ccdc input source");
204 dev_dbg(ccdc_cfg.dev,
"\ncouldn't enable ccdc clock");
207 dev_dbg(ccdc_cfg.dev,
"\nEnd of ccdc_restore_defaults...");
213 return ccdc_restore_defaults();
231 int horz_start, horz_nr_pixels;
232 int vert_start, vert_nr_lines;
235 dev_dbg(ccdc_cfg.dev,
"\nStarting ccdc_setwin...");
242 horz_start = image_win->
left << (ppc - 1);
243 horz_nr_pixels = ((image_win->
width) << (ppc - 1)) - 1;
248 vert_start = image_win->
top;
251 vert_nr_lines = (image_win->
height >> 1) - 1;
260 vert_nr_lines = image_win->
height - 1;
262 mid_img = vert_start + (image_win->
height / 2);
269 dev_dbg(ccdc_cfg.dev,
"\nEnd of ccdc_setwin...");
276 dev_dbg(ccdc_cfg.dev,
"Invalid value of data shift\n");
282 dev_dbg(ccdc_cfg.dev,
"Invalid value of median filter1\n");
288 dev_dbg(ccdc_cfg.dev,
"Invalid value of median filter2\n");
295 "Invalid value of median filter threshold\n");
301 dev_dbg(ccdc_cfg.dev,
"Invalid value of data size\n");
305 if (ccdcparam->
alaw.enable) {
308 dev_dbg(ccdc_cfg.dev,
"Invalid value of ALAW\n");
313 if (ccdcparam->
blk_clamp.b_clamp_enable) {
317 "Invalid value of sample pixel\n");
323 "Invalid value of sample lines\n");
331 static int ccdc_set_params(
void __user *
params)
337 if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
340 x =
copy_from_user(&ccdc_raw_params, params,
sizeof(ccdc_raw_params));
342 dev_dbg(ccdc_cfg.dev,
"ccdc_set_params: error in copying ccdc"
347 if (!validate_ccdc_param(&ccdc_raw_params)) {
348 memcpy(&ccdc_cfg.bayer.config_params,
350 sizeof(ccdc_raw_params));
359 struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
363 dev_dbg(ccdc_cfg.dev,
"\nStarting ccdc_config_ycbcr...");
364 ccdc_restore_defaults();
373 if (params->bt656_enable) {
407 regw(((params->win.width * 2 + 31) >> 5),
HSIZE);
415 dev_dbg(ccdc_cfg.dev,
"\nEnd of ccdc_config_ycbcr...\n");
471 #define DFC_WRITE_WAIT_COUNT 1000
495 dev_err(ccdc_cfg.dev,
"defect table write timeout !!!\n");
558 static void ccdc_config_csc(
struct ccdc_csc *csc)
573 val1 = (csc->
coeff[
i].integer &
580 val1 |= (((csc->
coeff[
i].decimal &
586 val2 = (csc->
coeff[
i].integer &
589 val2 |= (((csc->
coeff[
i].decimal &
603 static void ccdc_config_color_patterns(
struct ccdc_col_pat *pat0,
608 val = (pat0->
olop | (pat0->
olep << 2) | (pat0->
elop << 4) |
609 (pat0->
elep << 6) | (pat1->
olop << 8) | (pat1->
olep << 10) |
610 (pat1->
elop << 12) | (pat1->
elep << 14));
617 struct ccdc_params_raw *params = &ccdc_cfg.bayer;
619 &ccdc_cfg.bayer.config_params;
622 dev_dbg(ccdc_cfg.dev,
"\nStarting ccdc_config_raw...");
625 ccdc_restore_defaults();
659 config_params->
alaw.enable)
671 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to MODESET...\n", val);
681 if (config_params->
alaw.enable) {
683 ((config_params->
alaw.gama_wd &
693 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to GAMMAWD...\n", val);
699 ccdc_config_black_clamp(&config_params->
blk_clamp);
702 ccdc_config_black_compense(&config_params->
blk_comp);
709 ccdc_config_csc(&config_params->
csc);
716 ccdc_config_gain_offset();
718 dev_dbg(ccdc_cfg.dev,
"\nWriting %x to COLPTN...\n", val);
733 config_params->
alaw.enable) {
734 val |= (((params->win.width) + 31) >> 5) &
738 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to HSIZE...\n",
739 (((params->win.width) + 31) >> 5) &
743 val |= (((params->win.width * 2) + 31) >> 5) &
746 dev_dbg(ccdc_cfg.dev,
"\nWriting 0x%x to HSIZE...\n",
747 (((params->win.width * 2) + 31) >> 5) &
754 if (params->image_invert_enable) {
757 dev_dbg(ccdc_cfg.dev,
"\nWriting %x to SDOFST...\n",
762 dev_dbg(ccdc_cfg.dev,
"\nWriting %x to SDOFST...\n",
766 if (params->image_invert_enable) {
769 dev_dbg(ccdc_cfg.dev,
"\nWriting %x to SDOFST...\n",
774 dev_dbg(ccdc_cfg.dev,
"\nWriting %x to SDOFST...\n",
778 dev_dbg(ccdc_cfg.dev,
"\nend of ccdc_config_raw...");
782 static int ccdc_configure(
void)
784 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
793 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
794 ccdc_cfg.bayer.buf_type = buf_type;
796 ccdc_cfg.ycbcr.buf_type = buf_type;
801 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
802 return ccdc_cfg.bayer.buf_type;
803 return ccdc_cfg.ycbcr.buf_type;
806 static int ccdc_enum_pix(
u32 *pix,
int i)
809 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
810 if (i <
ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
811 *pix = ccdc_raw_bayer_pix_formats[
i];
815 if (i <
ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
816 *pix = ccdc_raw_yuv_pix_formats[
i];
823 static int ccdc_set_pixel_format(
u32 pixfmt)
825 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
827 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
843 static u32 ccdc_get_pixel_format(
void)
845 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
848 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
863 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
864 ccdc_cfg.bayer.win = *
win;
866 ccdc_cfg.ycbcr.win = *
win;
870 static void ccdc_get_image_window(
struct v4l2_rect *win)
872 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
873 *win = ccdc_cfg.bayer.win;
875 *win = ccdc_cfg.ycbcr.win;
878 static unsigned int ccdc_get_line_length(
void)
881 &ccdc_cfg.bayer.config_params;
884 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
885 if ((config_params->
alaw.enable) ||
887 len = ccdc_cfg.bayer.win.width;
889 len = ccdc_cfg.bayer.win.width * 2;
891 len = ccdc_cfg.ycbcr.win.width * 2;
892 return ALIGN(len, 32);
895 static int ccdc_set_frame_format(
enum ccdc_frmfmt frm_fmt)
897 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
898 ccdc_cfg.bayer.frm_fmt = frm_fmt;
900 ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
904 static enum ccdc_frmfmt ccdc_get_frame_format(
void)
906 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
907 return ccdc_cfg.bayer.frm_fmt;
909 return ccdc_cfg.ycbcr.frm_fmt;
912 static int ccdc_getfid(
void)
918 static inline void ccdc_setfbaddr(
unsigned long addr)
924 static int ccdc_set_hw_if_params(
struct vpfe_hw_if_param *params)
926 ccdc_cfg.if_type = params->if_type;
928 switch (params->if_type) {
930 case VPFE_YCBCR_SYNC_16:
931 case VPFE_YCBCR_SYNC_8:
932 ccdc_cfg.ycbcr.vd_pol = params->vdpol;
933 ccdc_cfg.ycbcr.hd_pol = params->hdpol;
942 static struct ccdc_hw_device ccdc_hw_dev = {
943 .name =
"DM355 CCDC",
948 .enable = ccdc_enable,
949 .enable_out_to_sdram = ccdc_enable_output_to_sdram,
950 .set_hw_if_params = ccdc_set_hw_if_params,
951 .set_params = ccdc_set_params,
952 .configure = ccdc_configure,
953 .set_buftype = ccdc_set_buftype,
954 .get_buftype = ccdc_get_buftype,
955 .enum_pix = ccdc_enum_pix,
956 .set_pixel_format = ccdc_set_pixel_format,
957 .get_pixel_format = ccdc_get_pixel_format,
958 .set_frame_format = ccdc_set_frame_format,
959 .get_frame_format = ccdc_get_frame_format,
960 .set_image_window = ccdc_set_image_window,
961 .get_image_window = ccdc_get_image_window,
962 .get_line_length = ccdc_get_line_length,
963 .setfbaddr = ccdc_setfbaddr,
964 .getfid = ccdc_getfid,
995 if (!ccdc_cfg.base_addr) {
1001 ccdc_cfg.mclk =
clk_get(&pdev->
dev,
"master");
1002 if (IS_ERR(ccdc_cfg.mclk)) {
1003 status = PTR_ERR(ccdc_cfg.mclk);
1012 ccdc_cfg.sclk =
clk_get(&pdev->
dev,
"slave");
1013 if (IS_ERR(ccdc_cfg.sclk)) {
1014 status = PTR_ERR(ccdc_cfg.sclk);
1023 if (
NULL == pdev->
dev.platform_data) {
1027 setup_pinmux = pdev->
dev.platform_data;
1033 ccdc_cfg.dev = &pdev->
dev;
1065 .name =
"dm355_ccdc",
1069 .probe = dm355_ccdc_probe,