34 #include <linux/videodev2.h>
37 #include <linux/module.h>
85 static struct isif_oper_config {
87 enum vpfe_hw_if_type if_type;
88 struct isif_ycbcr_config ycbcr;
89 struct isif_params_raw bayer;
90 enum isif_data_pack data_pack;
103 .win = ISIF_WIN_NTSC,
104 .fid_pol = VPFE_PINPOL_POSITIVE,
105 .vd_pol = VPFE_PINPOL_POSITIVE,
106 .hd_pol = VPFE_PINPOL_POSITIVE,
114 .fid_pol = VPFE_PINPOL_POSITIVE,
115 .vd_pol = VPFE_PINPOL_POSITIVE,
116 .hd_pol = VPFE_PINPOL_POSITIVE,
123 .cfa_pat = ISIF_CFA_PAT_MOSAIC,
124 .data_msb = ISIF_BIT_MSB_11,
146 static const u32 isif_raw_bayer_pix_formats[] = {
150 static const u32 isif_raw_yuv_pix_formats[] = {
167 u32 new_val = (
regr(offset) & ~mask) | (val & mask);
169 regw(new_val, offset);
173 static inline void regw_lin_tbl(
u32 val,
u32 offset,
int i)
181 static void isif_disable_all_modules(
void)
194 static void isif_enable(
int en)
198 isif_disable_all_modules();
208 static void isif_enable_output_to_sdram(
int en)
213 static void isif_config_culling(
struct isif_cul *cul)
229 static void isif_config_gain_offset(
void)
232 &isif_cfg.bayer.config_params.gain_offset;
245 gain_off_p->
gain.r_ye.decimal;
249 gain_off_p->
gain.gr_cy.decimal;
253 gain_off_p->
gain.gb_g.decimal;
257 gain_off_p->
gain.b_mg.decimal;
263 static void isif_restore_defaults(
void)
267 dev_dbg(isif_cfg.dev,
"\nstarting isif_restore_defaults...");
268 isif_cfg.bayer.config_params = isif_config_defaults;
274 isif_config_gain_offset();
276 dev_dbg(isif_cfg.dev,
"\nEnd of isif_restore_defaults...");
281 isif_restore_defaults();
286 static void isif_setwin(
struct v4l2_rect *image_win,
289 int horz_start, horz_nr_pixels;
290 int vert_start, vert_nr_lines;
293 dev_dbg(isif_cfg.dev,
"\nStarting isif_setwin...");
299 horz_start = image_win->
left << (ppc - 1);
300 horz_nr_pixels = ((image_win->
width) << (ppc - 1)) - 1;
305 vert_start = image_win->
top;
308 vert_nr_lines = (image_win->
height >> 1) - 1;
315 vert_nr_lines = image_win->
height - 1;
317 mid_img = vert_start + (image_win->
height / 2);
355 val = bc->
horz.win_count_calc |
356 ((!!bc->
horz.base_win_sel_calc) <<
358 ((!!bc->
horz.clamp_pix_limit) <<
360 (bc->
horz.win_h_sz_calc <<
362 (bc->
horz.win_v_sz_calc <<
389 static void isif_config_linearization(
struct isif_linearize *linearize)
393 if (!linearize->
en) {
410 regw_lin_tbl(linearize->
table[i], ((i >> 1) << 2), 1);
412 regw_lin_tbl(linearize->
table[i], ((i >> 1) << 2), 0);
416 static int isif_config_dfc(
struct isif_dfc *vdfc)
458 dev_dbg(isif_cfg.dev,
"defect table write timeout !!!\n");
483 "defect table write timeout !!!\n");
500 static void isif_config_csc(
struct isif_df_csc *df_csc)
502 u32 val1 = 0, val2 = 0,
i;
504 if (!df_csc->
csc.en) {
511 val1 = (df_csc->
csc.coeff[
i].integer <<
513 df_csc->
csc.coeff[i].decimal;
517 val2 = (df_csc->
csc.coeff[
i].integer <<
519 df_csc->
csc.coeff[i].decimal;
546 static int isif_config_raw(
void)
548 struct isif_params_raw *
params = &isif_cfg.bayer;
550 &isif_cfg.bayer.config_params;
555 dev_dbg(isif_cfg.dev,
"\nStarting isif_config_raw..\n");
571 dev_dbg(isif_cfg.dev,
"Writing 0x%x to ...CCDCFG \n", val);
595 dev_dbg(isif_cfg.dev,
"Writing 0x%x to MODESET...\n", val);
620 isif_config_gain_offset();
623 val = (params->config_params.col_pat_field0.olop) |
624 (params->config_params.col_pat_field0.olep << 2) |
625 (params->config_params.col_pat_field0.elop << 4) |
626 (params->config_params.col_pat_field0.elep << 6) |
627 (params->config_params.col_pat_field1.olop << 8) |
628 (params->config_params.col_pat_field1.olep << 10) |
629 (params->config_params.col_pat_field1.elop << 12) |
630 (params->config_params.col_pat_field1.elep << 14);
632 dev_dbg(isif_cfg.dev,
"Writing %x to CCOLP ...\n", val);
638 if (isif_cfg.data_pack == ISIF_PACK_8BIT)
639 val |= ((params->win.width + 31) >> 5);
640 else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
641 val |= (((params->win.width +
642 (params->win.width >> 2)) + 31) >> 5);
644 val |= (((params->win.width * 2) + 31) >> 5);
649 if (params->image_invert_en) {
652 dev_dbg(isif_cfg.dev,
"Writing 0x4B6D to SDOFST...\n");
656 dev_dbg(isif_cfg.dev,
"Writing 0x0B6D to SDOFST...\n");
659 if (params->image_invert_en) {
662 dev_dbg(isif_cfg.dev,
"Writing 0x4000 to SDOFST...\n");
666 dev_dbg(isif_cfg.dev,
"Writing 0x0000 to SDOFST...\n");
671 isif_setwin(¶ms->win, params->frm_fmt, 1);
674 isif_config_bclamp(&module_params->
bclamp);
677 if (isif_config_dfc(&module_params->
dfc) < 0)
680 if (!module_params->
df_csc.df_or_csc)
682 isif_config_csc(&module_params->
df_csc);
684 isif_config_linearization(&module_params->
linearize);
687 isif_config_culling(&module_params->
culling);
694 if (params->config_params.test_pat_gen) {
696 sync.ccdpg_hdpol = params->hd_pol;
697 sync.ccdpg_vdpol = params->vd_pol;
699 frame_size.hlpfr = isif_cfg.bayer.win.width;
700 frame_size.pplen = isif_cfg.bayer.win.height;
705 dev_dbg(isif_cfg.dev,
"\nEnd of isif_config_ycbcr...\n");
711 if (isif_cfg.if_type == VPFE_RAW_BAYER)
712 isif_cfg.bayer.buf_type = buf_type;
714 isif_cfg.ycbcr.buf_type = buf_type;
721 if (isif_cfg.if_type == VPFE_RAW_BAYER)
722 return isif_cfg.bayer.buf_type;
724 return isif_cfg.ycbcr.buf_type;
727 static int isif_enum_pix(
u32 *pix,
int i)
731 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
732 if (i <
ARRAY_SIZE(isif_raw_bayer_pix_formats)) {
733 *pix = isif_raw_bayer_pix_formats[
i];
737 if (i <
ARRAY_SIZE(isif_raw_yuv_pix_formats)) {
738 *pix = isif_raw_yuv_pix_formats[
i];
746 static int isif_set_pixel_format(
unsigned int pixfmt)
748 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
750 if ((isif_cfg.bayer.config_params.compress.alg !=
752 (isif_cfg.bayer.config_params.compress.alg !=
755 "Either configure A-Law or DPCM\n");
758 isif_cfg.data_pack = ISIF_PACK_8BIT;
760 isif_cfg.bayer.config_params.compress.alg =
762 isif_cfg.data_pack = ISIF_PACK_16BIT;
773 isif_cfg.data_pack = ISIF_PACK_8BIT;
778 static u32 isif_get_pixel_format(
void)
782 if (isif_cfg.if_type == VPFE_RAW_BAYER)
783 if (isif_cfg.bayer.config_params.compress.alg ==
ISIF_ALAW ||
784 isif_cfg.bayer.config_params.compress.alg ==
ISIF_DPCM)
799 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
800 isif_cfg.bayer.win.top = win->
top;
801 isif_cfg.bayer.win.left = win->
left;
802 isif_cfg.bayer.win.width = win->
width;
803 isif_cfg.bayer.win.height = win->
height;
805 isif_cfg.ycbcr.win.top = win->
top;
806 isif_cfg.ycbcr.win.left = win->
left;
807 isif_cfg.ycbcr.win.width = win->
width;
808 isif_cfg.ycbcr.win.height = win->
height;
813 static void isif_get_image_window(
struct v4l2_rect *win)
815 if (isif_cfg.if_type == VPFE_RAW_BAYER)
816 *win = isif_cfg.bayer.win;
818 *win = isif_cfg.ycbcr.win;
821 static unsigned int isif_get_line_length(
void)
825 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
826 if (isif_cfg.data_pack == ISIF_PACK_8BIT)
827 len = ((isif_cfg.bayer.win.width));
828 else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
829 len = (((isif_cfg.bayer.win.width * 2) +
830 (isif_cfg.bayer.win.width >> 2)));
832 len = (((isif_cfg.bayer.win.width * 2)));
834 len = (((isif_cfg.ycbcr.win.width * 2)));
835 return ALIGN(len, 32);
838 static int isif_set_frame_format(
enum ccdc_frmfmt frm_fmt)
840 if (isif_cfg.if_type == VPFE_RAW_BAYER)
841 isif_cfg.bayer.frm_fmt = frm_fmt;
843 isif_cfg.ycbcr.frm_fmt = frm_fmt;
846 static enum ccdc_frmfmt isif_get_frame_format(
void)
848 if (isif_cfg.if_type == VPFE_RAW_BAYER)
849 return isif_cfg.bayer.frm_fmt;
850 return isif_cfg.ycbcr.frm_fmt;
853 static int isif_getfid(
void)
859 static void isif_setfbaddr(
unsigned long addr)
865 static int isif_set_hw_if_params(
struct vpfe_hw_if_param *params)
867 isif_cfg.if_type = params->if_type;
869 switch (params->if_type) {
871 case VPFE_BT656_10BIT:
872 case VPFE_YCBCR_SYNC_8:
877 case VPFE_YCBCR_SYNC_16:
885 dev_dbg(isif_cfg.dev,
"Invalid interface type\n");
893 static int isif_config_ycbcr(
void)
895 struct isif_ycbcr_config *params = &isif_cfg.ycbcr;
897 u32 modeset = 0, ccdcfg = 0;
900 dev_dbg(isif_cfg.dev,
"\nStarting isif_config_ycbcr...");
910 switch (isif_cfg.if_type) {
913 dev_dbg(isif_cfg.dev,
"Invalid pix_fmt(input mode)\n");
920 case VPFE_BT656_10BIT:
922 dev_dbg(isif_cfg.dev,
"Invalid pix_fmt(input mode)\n");
933 dev_dbg(isif_cfg.dev,
"Invalid pix_fmt(input mode)\n");
939 case VPFE_YCBCR_SYNC_8:
943 dev_dbg(isif_cfg.dev,
"Invalid pix_fmt(input mode)\n");
947 case VPFE_YCBCR_SYNC_16:
949 dev_dbg(isif_cfg.dev,
"Invalid pix_fmt(input mode)\n");
955 dev_dbg(isif_cfg.dev,
"Invalid interface type\n");
967 if ((isif_cfg.if_type == VPFE_BT1120) ||
968 (isif_cfg.if_type == VPFE_YCBCR_SYNC_16))
969 isif_setwin(¶ms->win, params->frm_fmt, 1);
971 isif_setwin(¶ms->win, params->frm_fmt, 2);
978 regw(((((params->win.width * 2) + 31) & 0xffffffe0) >> 5),
HSIZE);
987 if (isif_cfg.bayer.config_params.test_pat_gen) {
988 sync.ccdpg_hdpol = params->hd_pol;
989 sync.ccdpg_vdpol = params->vd_pol;
996 static int isif_configure(
void)
998 if (isif_cfg.if_type == VPFE_RAW_BAYER)
999 return isif_config_raw();
1000 return isif_config_ycbcr();
1006 isif_cfg.bayer.config_params = isif_config_defaults;
1010 static struct ccdc_hw_device isif_hw_dev = {
1015 .close = isif_close,
1016 .enable = isif_enable,
1017 .enable_out_to_sdram = isif_enable_output_to_sdram,
1018 .set_hw_if_params = isif_set_hw_if_params,
1019 .configure = isif_configure,
1020 .set_buftype = isif_set_buftype,
1021 .get_buftype = isif_get_buftype,
1022 .enum_pix = isif_enum_pix,
1023 .set_pixel_format = isif_set_pixel_format,
1024 .get_pixel_format = isif_get_pixel_format,
1025 .set_frame_format = isif_set_frame_format,
1026 .get_frame_format = isif_get_frame_format,
1027 .set_image_window = isif_set_image_window,
1028 .get_image_window = isif_get_image_window,
1029 .get_line_length = isif_get_line_length,
1030 .setfbaddr = isif_setfbaddr,
1031 .getfid = isif_getfid,
1051 isif_cfg.mclk =
clk_get(&pdev->
dev,
"master");
1052 if (IS_ERR(isif_cfg.mclk)) {
1053 status = PTR_ERR(isif_cfg.mclk);
1062 if (
NULL == pdev->
dev.platform_data) {
1066 setup_pinmux = pdev->
dev.platform_data;
1079 goto fail_nobase_res;
1085 goto fail_nobase_res;
1090 goto fail_base_iomap;
1095 isif_cfg.base_addr =
addr;
1099 isif_cfg.linear_tbl0_addr =
addr;
1103 isif_cfg.linear_tbl1_addr =
addr;
1108 isif_cfg.dev = &pdev->
dev;
1117 if (isif_cfg.base_addr)
1119 if (isif_cfg.linear_tbl0_addr)
1120 iounmap(isif_cfg.linear_tbl0_addr);
1139 iounmap(isif_cfg.linear_tbl0_addr);
1140 iounmap(isif_cfg.linear_tbl1_addr);
1157 .probe = isif_probe,