arch/arm/plat-omap/include/mach/isp_user.h | 676 +++++++ drivers/media/video/Makefile | 2 drivers/media/video/isp/Makefile | 12 drivers/media/video/isp/bluegamma_table.h | 1040 +++++++++++ drivers/media/video/isp/cfa_coef_table.h | 603 ++++++ drivers/media/video/isp/greengamma_table.h | 1040 +++++++++++ drivers/media/video/isp/isp.c | 2547 +++++++++++++++++++++++++++ drivers/media/video/isp/isp.h | 318 +++ drivers/media/video/isp/isp_af.c | 784 ++++++++ drivers/media/video/isp/isp_af.h | 125 + drivers/media/video/isp/ispccdc.c | 1638 +++++++++++++++++ drivers/media/video/isp/ispccdc.h | 209 ++ drivers/media/video/isp/ispcsi2.c | 2124 ++++++++++++++++++++++ drivers/media/video/isp/ispcsi2.h | 232 ++ drivers/media/video/isp/isph3a.c | 932 +++++++++ drivers/media/video/isp/isph3a.h | 127 + drivers/media/video/isp/isphist.c | 608 ++++++ drivers/media/video/isp/isphist.h | 105 + drivers/media/video/isp/ispmmu.c | 141 + drivers/media/video/isp/ispmmu.h | 36 drivers/media/video/isp/isppreview.c | 1929 ++++++++++++++++++++ drivers/media/video/isp/isppreview.h | 354 +++ drivers/media/video/isp/ispreg.h | 1674 +++++++++++++++++ drivers/media/video/isp/ispresizer.c | 928 +++++++++ drivers/media/video/isp/ispresizer.h | 158 + drivers/media/video/isp/luma_enhance_table.h | 144 + drivers/media/video/isp/noise_filter_table.h | 79 drivers/media/video/isp/redgamma_table.h | 1040 +++++++++++ 28 files changed, 19605 insertions(+) diff --git a/arch/arm/plat-omap/include/mach/isp_user.h b/arch/arm/plat-omap/include/mach/isp_user.h new file mode 100644 index 0000000..b819e26 --- /dev/null +++ b/arch/arm/plat-omap/include/mach/isp_user.h @@ -0,0 +1,676 @@ +/* + * isp_user.h + * + * Include file for OMAP ISP module in TI's OMAP3. + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * Contributors: + * Mohit Jalori + * Sergio Aguirre + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef OMAP_ISP_USER_H +#define OMAP_ISP_USER_H + +/* ISP Private IOCTLs */ +#define VIDIOC_PRIVATE_ISP_CCDC_CFG \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct ispccdc_update_config) +#define VIDIOC_PRIVATE_ISP_PRV_CFG \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct ispprv_update_config) +#define VIDIOC_PRIVATE_ISP_AEWB_CFG \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct isph3a_aewb_config) +#define VIDIOC_PRIVATE_ISP_AEWB_REQ \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct isph3a_aewb_data) +#define VIDIOC_PRIVATE_ISP_HIST_CFG \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct isp_hist_config) +#define VIDIOC_PRIVATE_ISP_HIST_REQ \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct isp_hist_data) +#define VIDIOC_PRIVATE_ISP_AF_CFG \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct af_configuration) +#define VIDIOC_PRIVATE_ISP_AF_REQ \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 9, struct isp_af_data) + +/* AE/AWB related structures and flags*/ + +/* Flags for update field */ +#define REQUEST_STATISTICS (1 << 0) +#define SET_COLOR_GAINS (1 << 1) +#define SET_DIGITAL_GAIN (1 << 2) +#define SET_EXPOSURE (1 << 3) +#define SET_ANALOG_GAIN (1 << 4) + +#define MAX_FRAME_COUNT 0x0FFF +#define MAX_FUTURE_FRAMES 10 + +#define MAX_SATURATION_LIM 1023 +#define MIN_WIN_H 2 +#define MAX_WIN_H 256 +#define MIN_WIN_W 6 +#define MAX_WIN_W 256 +#define MAX_WINVC 128 +#define MAX_WINHC 36 +#define MAX_WINSTART 4095 +#define MIN_SUB_INC 2 +#define MAX_SUB_INC 32 + +/* Range Constants */ +#define AF_IIRSH_MIN 0 +#define AF_IIRSH_MAX 4094 +#define AF_PAXEL_HORIZONTAL_COUNT_MIN 0 +#define AF_PAXEL_HORIZONTAL_COUNT_MAX 35 +#define AF_PAXEL_VERTICAL_COUNT_MIN 0 +#define AF_PAXEL_VERTICAL_COUNT_MAX 127 +#define AF_PAXEL_INCREMENT_MIN 0 +#define AF_PAXEL_INCREMENT_MAX 14 +#define AF_PAXEL_HEIGHT_MIN 0 +#define AF_PAXEL_HEIGHT_MAX 127 +#define AF_PAXEL_WIDTH_MIN 0 +#define AF_PAXEL_WIDTH_MAX 127 +#define AF_PAXEL_HZSTART_MIN 2 +#define AF_PAXEL_HZSTART_MAX 4094 + +#define AF_PAXEL_VTSTART_MIN 0 +#define AF_PAXEL_VTSTART_MAX 4095 +#define AF_THRESHOLD_MAX 255 +#define AF_COEF_MAX 4095 +#define AF_PAXEL_SIZE 48 + +/** + * struct isph3a_aewb_config - AE AWB configuration reset values. + * saturation_limit: Saturation limit. + * @win_height: Window Height. Range 2 - 256, even values only. + * @win_width: Window Width. Range 6 - 256, even values only. + * @ver_win_count: Vertical Window Count. Range 1 - 128. + * @hor_win_count: Horizontal Window Count. Range 1 - 36. + * @ver_win_start: Vertical Window Start. Range 0 - 4095. + * @hor_win_start: Horizontal Window Start. Range 0 - 4095. + * @blk_ver_win_start: Black Vertical Windows Start. Range 0 - 4095. + * @blk_win_height: Black Window Height. Range 2 - 256, even values only. + * @subsample_ver_inc: Subsample Vertical points increment Range 2 - 32, even + * values only. + * @subsample_hor_inc: Subsample Horizontal points increment Range 2 - 32, even + * values only. + * @alaw_enable: AEW ALAW EN flag. + * @aewb_enable: AE AWB stats generation EN flag. + */ +struct isph3a_aewb_config { + __u16 saturation_limit; + __u16 win_height; + __u16 win_width; + __u16 ver_win_count; + __u16 hor_win_count; + __u16 ver_win_start; + __u16 hor_win_start; + __u16 blk_ver_win_start; + __u16 blk_win_height; + __u16 subsample_ver_inc; + __u16 subsample_hor_inc; + __u8 alaw_enable; + __u8 aewb_enable; +}; + +/** + * struct isph3a_aewb_data - Structure of data sent to or received from user + * @h3a_aewb_statistics_buf: Pointer to pass to user. + * @shutter: Shutter speed. + * @gain: Sensor analog Gain. + * @shutter_cap: Shutter speed for capture. + * @gain_cap: Sensor Gain for capture. + * @dgain: White balance digital gain. + * @wb_gain_b: White balance color gain blue. + * @wb_gain_r: White balance color gain red. + * @wb_gain_gb: White balance color gain green blue. + * @wb_gain_gr: White balance color gain green red. + * @frame_number: Frame number of requested stats. + * @curr_frame: Current frame number being processed. + * @update: Bitwise flags to update parameters. + * @ts: Timestamp of returned framestats. + * @field_count: Sequence number of returned framestats. + */ +struct isph3a_aewb_data { + void *h3a_aewb_statistics_buf; + __u32 shutter; + __u16 gain; + __u32 shutter_cap; + __u16 gain_cap; + __u16 dgain; + __u16 wb_gain_b; + __u16 wb_gain_r; + __u16 wb_gain_gb; + __u16 wb_gain_gr; + __u16 frame_number; + __u16 curr_frame; + __u8 update; + struct timeval ts; + __u32 config_counter; + unsigned long field_count; +}; + + +/* Histogram related structs */ +/* Flags for number of bins */ +#define BINS_32 0x0 +#define BINS_64 0x1 +#define BINS_128 0x2 +#define BINS_256 0x3 + +struct isp_hist_config { + __u8 hist_source; /* CCDC or Memory */ + __u8 input_bit_width; /* Needed o know the size per pixel */ + __u8 hist_frames; /* Num of frames to be processed and + * accumulated + */ + __u8 hist_h_v_info; /* frame-input width and height if source is + * memory + */ + __u16 hist_radd; /* frame-input address in memory */ + __u16 hist_radd_off; /* line-offset for frame-input */ + __u16 hist_bins; /* number of bins: 32, 64, 128, or 256 */ + __u16 wb_gain_R; /* White Balance Field-to-Pattern Assignments */ + __u16 wb_gain_RG; /* White Balance Field-to-Pattern Assignments */ + __u16 wb_gain_B; /* White Balance Field-to-Pattern Assignments */ + __u16 wb_gain_BG; /* White Balance Field-to-Pattern Assignments */ + __u8 num_regions; /* number of regions to be configured */ + __u16 reg0_hor; /* Region 0 size and position */ + __u16 reg0_ver; /* Region 0 size and position */ + __u16 reg1_hor; /* Region 1 size and position */ + __u16 reg1_ver; /* Region 1 size and position */ + __u16 reg2_hor; /* Region 2 size and position */ + __u16 reg2_ver; /* Region 2 size and position */ + __u16 reg3_hor; /* Region 3 size and position */ + __u16 reg3_ver; /* Region 3 size and position */ +}; + +struct isp_hist_data { + __u32 *hist_statistics_buf; /* Pointer to pass to user */ +}; + +/* Auto Focus related structs */ + +#define AF_NUMBER_OF_COEF 11 + +/* Flags for update field */ +#define REQUEST_STATISTICS (1 << 0) +#define LENS_DESIRED_POSITION (1 << 1) +#define LENS_CURRENT_POSITION (1 << 2) + +/** + * struct isp_af_xtrastats - Extra statistics related to AF generated stats. + * @ts: Timestamp when the frame gets delivered to the user. + * @field_count: Field count of the frame delivered to the user. + * @lens_position: Lens position when the stats are being generated. + */ +struct isp_af_xtrastats { + struct timeval ts; + unsigned long field_count; + __u16 lens_position; /* deprecated */ +}; + +/** + * struct isp_af_data - AF statistics data to transfer between driver and user. + * @af_statistics_buf: Pointer to pass to user. + * @lens_current_position: Read value of lens absolute position. + * @desired_lens_direction: Lens desired location. + * @update: Bitwise flags to update parameters. + * @frame_number: Data for which frame is desired/given. + * @curr_frame: Current frame number being processed by AF module. + * @xtrastats: Extra statistics structure. + */ +struct isp_af_data { + void *af_statistics_buf; + __u16 lens_current_position; /* deprecated */ + __u16 desired_lens_direction; /* deprecated */ + __u16 update; + __u16 frame_number; + __u16 curr_frame; + __u32 config_counter; + struct isp_af_xtrastats xtrastats; +}; + +/* enum used for status of specific feature */ +enum af_alaw_enable { + H3A_AF_ALAW_DISABLE = 0, + H3A_AF_ALAW_ENABLE = 1 +}; + +enum af_hmf_enable { + H3A_AF_HMF_DISABLE = 0, + H3A_AF_HMF_ENABLE = 1 +}; + +enum af_config_flag { + H3A_AF_CFG_DISABLE = 0, + H3A_AF_CFG_ENABLE = 1 +}; + +enum af_mode { + ACCUMULATOR_SUMMED = 0, + ACCUMULATOR_PEAK = 1 +}; + +/* Red, Green, and blue pixel location in the AF windows */ +enum rgbpos { + GR_GB_BAYER = 0, /* GR and GB as Bayer pattern */ + RG_GB_BAYER = 1, /* RG and GB as Bayer pattern */ + GR_BG_BAYER = 2, /* GR and BG as Bayer pattern */ + RG_BG_BAYER = 3, /* RG and BG as Bayer pattern */ + GG_RB_CUSTOM = 4, /* GG and RB as custom pattern */ + RB_GG_CUSTOM = 5 /* RB and GG as custom pattern */ +}; + +/* Contains the information regarding the Horizontal Median Filter */ +struct af_hmf { + enum af_hmf_enable enable; /* Status of Horizontal Median Filter */ + unsigned int threshold; /* Threshhold Value for Horizontal Median + * Filter + */ +}; + +/* Contains the information regarding the IIR Filters */ +struct af_iir { + unsigned int hz_start_pos; /* IIR Start Register Value */ + int coeff_set0[AF_NUMBER_OF_COEF]; /* + * IIR Filter Coefficient for + * Set 0 + */ + int coeff_set1[AF_NUMBER_OF_COEF]; /* + * IIR Filter Coefficient for + * Set 1 + */ +}; + +/* Contains the information regarding the Paxels Structure in AF Engine */ +struct af_paxel { + unsigned int width; /* Width of the Paxel */ + unsigned int height; /* Height of the Paxel */ + unsigned int hz_start; /* Horizontal Start Position */ + unsigned int vt_start; /* Vertical Start Position */ + unsigned int hz_cnt; /* Horizontal Count */ + unsigned int vt_cnt; /* vertical Count */ + unsigned int line_incr; /* Line Increment */ +}; +/* Contains the parameters required for hardware set up of AF Engine */ +struct af_configuration { + enum af_alaw_enable alaw_enable; /*ALWAW status */ + struct af_hmf hmf_config; /*HMF configurations */ + enum rgbpos rgb_pos; /*RGB Positions */ + struct af_iir iir_config; /*IIR filter configurations */ + struct af_paxel paxel_config; /*Paxel parameters */ + enum af_mode mode; /*Accumulator mode */ + enum af_config_flag af_config; /*Flag indicates Engine is configured */ +}; + +/* ISP CCDC structs */ + +/* Abstraction layer CCDC configurations */ +#define ISP_ABS_CCDC_ALAW (1 << 0) +#define ISP_ABS_CCDC_LPF (1 << 1) +#define ISP_ABS_CCDC_BLCLAMP (1 << 2) +#define ISP_ABS_CCDC_BCOMP (1 << 3) +#define ISP_ABS_CCDC_FPC (1 << 4) +#define ISP_ABS_CCDC_CULL (1 << 5) +#define ISP_ABS_CCDC_COLPTN (1 << 6) +#define ISP_ABS_CCDC_CONFIG_LSC (1 << 7) +#define ISP_ABS_TBL_LSC (1 << 8) + +#define RGB_MAX 3 + +/* Enumeration constants for Alaw input width */ +enum alaw_ipwidth { + ALAW_BIT12_3 = 0x3, + ALAW_BIT11_2 = 0x4, + ALAW_BIT10_1 = 0x5, + ALAW_BIT9_0 = 0x6 +}; + +/* Enumeration constants for Video Port */ +enum vpin { + BIT12_3 = 3, + BIT11_2 = 4, + BIT10_1 = 5, + BIT9_0 = 6 +}; + +enum vpif_freq { + PIXCLKBY2, + PIXCLKBY3_5, + PIXCLKBY4_5, + PIXCLKBY5_5, + PIXCLKBY6_5 +}; + +/** + * struct ispccdc_lsc_config - Structure for LSC configuration. + * @offset: Table Offset of the gain table. + * @gain_mode_n: Vertical dimension of a paxel in LSC configuration. + * @gain_mode_m: Horizontal dimension of a paxel in LSC configuration. + * @gain_format: Gain table format. + * @fmtsph: Start pixel horizontal from start of the HS sync pulse. + * @fmtlnh: Number of pixels in horizontal direction to use for the data + * reformatter. + * @fmtslv: Start line from start of VS sync pulse for the data reformatter. + * @fmtlnv: Number of lines in vertical direction for the data reformatter. + * @initial_x: X position, in pixels, of the first active pixel in reference + * to the first active paxel. Must be an even number. + * @initial_y: Y position, in pixels, of the first active pixel in reference + * to the first active paxel. Must be an even number. + * @size: Size of LSC gain table. Filled when loaded from userspace. + */ +struct ispccdc_lsc_config { + __u16 offset; + __u8 gain_mode_n; + __u8 gain_mode_m; + __u8 gain_format; + __u16 fmtsph; + __u16 fmtlnh; + __u16 fmtslv; + __u16 fmtlnv; + __u8 initial_x; + __u8 initial_y; + __u32 size; +}; + +/** + * struct ispccdc_bclamp - Structure for Optical & Digital black clamp subtract + * @obgain: Optical black average gain. + * @obstpixel: Start Pixel w.r.t. HS pulse in Optical black sample. + * @oblines: Optical Black Sample lines. + * @oblen: Optical Black Sample Length. + * @dcsubval: Digital Black Clamp subtract value. + */ +struct ispccdc_bclamp { + __u8 obgain; + __u8 obstpixel; + __u8 oblines; + __u8 oblen; + __u16 dcsubval; +}; + +/** + * ispccdc_fpc - Structure for FPC + * @fpnum: Number of faulty pixels to be corrected in the frame. + * @fpcaddr: Memory address of the FPC Table + */ +struct ispccdc_fpc { + __u16 fpnum; + __u32 fpcaddr; +}; + +/** + * ispccdc_blcomp - Structure for Black Level Compensation parameters. + * @b_mg: B/Mg pixels. 2's complement. -128 to +127. + * @gb_g: Gb/G pixels. 2's complement. -128 to +127. + * @gr_cy: Gr/Cy pixels. 2's complement. -128 to +127. + * @r_ye: R/Ye pixels. 2's complement. -128 to +127. + */ +struct ispccdc_blcomp { + __u8 b_mg; + __u8 gb_g; + __u8 gr_cy; + __u8 r_ye; +}; + +/** + * struct ispccdc_vp - Structure for Video Port parameters + * @bitshift_sel: Video port input select. 3 - bits 12-3, 4 - bits 11-2, + * 5 - bits 10-1, 6 - bits 9-0. + * @freq_sel: Video port data ready frequency. 1 - 1/3.5, 2 - 1/4.5, + * 3 - 1/5.5, 4 - 1/6.5. + */ +struct ispccdc_vp { + enum vpin bitshift_sel; + enum vpif_freq freq_sel; +}; + +/** + * ispccdc_culling - Structure for Culling parameters. + * @v_pattern: Vertical culling pattern. + * @h_odd: Horizontal Culling pattern for odd lines. + * @h_even: Horizontal Culling pattern for even lines. + */ +struct ispccdc_culling { + __u8 v_pattern; + __u16 h_odd; + __u16 h_even; +}; + +/** + * ispccdc_update_config - Structure for CCDC configuration. + * @update: Specifies which CCDC registers should be updated. + * @flag: Specifies which CCDC functions should be enabled. + * @alawip: Enable/Disable A-Law compression. + * @bclamp: Black clamp control register. + * @blcomp: Black level compensation value for RGrGbB Pixels. 2's complement. + * @fpc: Number of faulty pixels corrected in the frame, address of FPC table. + * @cull: Cull control register. + * @colptn: Color pattern of the sensor. + * @lsc: Pointer to LSC gain table. + */ +struct ispccdc_update_config { + __u16 update; + __u16 flag; + enum alaw_ipwidth alawip; + struct ispccdc_bclamp *bclamp; + struct ispccdc_blcomp *blcomp; + struct ispccdc_fpc *fpc; + struct ispccdc_lsc_config *lsc_cfg; + struct ispccdc_culling *cull; + __u32 colptn; + __u8 *lsc; +}; + +/* Preview configuration */ + +/*Abstraction layer preview configurations*/ +#define ISP_ABS_PREV_LUMAENH (1 << 0) +#define ISP_ABS_PREV_INVALAW (1 << 1) +#define ISP_ABS_PREV_HRZ_MED (1 << 2) +#define ISP_ABS_PREV_CFA (1 << 3) +#define ISP_ABS_PREV_CHROMA_SUPP (1 << 4) +#define ISP_ABS_PREV_WB (1 << 5) +#define ISP_ABS_PREV_BLKADJ (1 << 6) +#define ISP_ABS_PREV_RGB2RGB (1 << 7) +#define ISP_ABS_PREV_COLOR_CONV (1 << 8) +#define ISP_ABS_PREV_YC_LIMIT (1 << 9) +#define ISP_ABS_PREV_DEFECT_COR (1 << 10) +#define ISP_ABS_PREV_GAMMABYPASS (1 << 11) +#define ISP_ABS_TBL_NF (1 << 12) +#define ISP_ABS_TBL_REDGAMMA (1 << 13) +#define ISP_ABS_TBL_GREENGAMMA (1 << 14) +#define ISP_ABS_TBL_BLUEGAMMA (1 << 15) + +#define ISPPRV_NF_TBL_SIZE 64 +#define ISPPRV_CFA_TBL_SIZE 576 +#define ISPPRV_GAMMA_TBL_SIZE 1024 +#define ISPPRV_YENH_TBL_SIZE 128 + +/** + * struct ispprev_hmed - Structure for Horizontal Median Filter. + * @odddist: Distance between consecutive pixels of same color in the odd line. + * @evendist: Distance between consecutive pixels of same color in the even + * line. + * @thres: Horizontal median filter threshold. + */ +struct ispprev_hmed { + __u8 odddist; + __u8 evendist; + __u8 thres; +}; + +/* + * Enumeration for CFA Formats supported by preview + */ +enum cfa_fmt { + CFAFMT_BAYER, CFAFMT_SONYVGA, CFAFMT_RGBFOVEON, + CFAFMT_DNSPL, CFAFMT_HONEYCOMB, CFAFMT_RRGGBBFOVEON +}; + +/** + * struct ispprev_cfa - Structure for CFA Inpterpolation. + * @cfafmt: CFA Format Enum value supported by preview. + * @cfa_gradthrs_vert: CFA Gradient Threshold - Vertical. + * @cfa_gradthrs_horz: CFA Gradient Threshold - Horizontal. + * @cfa_table: Pointer to the CFA table. + */ +struct ispprev_cfa { + enum cfa_fmt cfafmt; + __u8 cfa_gradthrs_vert; + __u8 cfa_gradthrs_horz; + __u32 *cfa_table; +}; + +/** + * struct ispprev_csup - Structure for Chrominance Suppression. + * @gain: Gain. + * @thres: Threshold. + * @hypf_en: Flag to enable/disable the High Pass Filter. + */ +struct ispprev_csup { + __u8 gain; + __u8 thres; + __u8 hypf_en; +}; + +/** + * struct ispprev_wbal - Structure for White Balance. + * @dgain: Digital gain (U10Q8). + * @coef3: White balance gain - COEF 3 (U8Q5). + * @coef2: White balance gain - COEF 2 (U8Q5). + * @coef1: White balance gain - COEF 1 (U8Q5). + * @coef0: White balance gain - COEF 0 (U8Q5). + */ +struct ispprev_wbal { + __u16 dgain; + __u8 coef3; + __u8 coef2; + __u8 coef1; + __u8 coef0; +}; + +/** + * struct ispprev_blkadj - Structure for Black Adjustment. + * @red: Black level offset adjustment for Red in 2's complement format + * @green: Black level offset adjustment for Green in 2's complement format + * @blue: Black level offset adjustment for Blue in 2's complement format + */ +struct ispprev_blkadj { + /*Black level offset adjustment for Red in 2's complement format */ + __u8 red; + /*Black level offset adjustment for Green in 2's complement format */ + __u8 green; + /* Black level offset adjustment for Blue in 2's complement format */ + __u8 blue; +}; + +/** + * struct ispprev_rgbtorgb - Structure for RGB to RGB Blending. + * @matrix: Blending values(S12Q8 format) + * [RR] [GR] [BR] + * [RG] [GG] [BG] + * [RB] [GB] [BB] + * @offset: Blending offset value for R,G,B in 2's complement integer format. + */ +struct ispprev_rgbtorgb { + __u16 matrix[3][3]; + __u16 offset[3]; +}; + +/** + * struct ispprev_csc - Structure for Color Space Conversion from RGB-YCbYCr + * @matrix: Color space conversion coefficients(S10Q8) + * [CSCRY] [CSCGY] [CSCBY] + * [CSCRCB] [CSCGCB] [CSCBCB] + * [CSCRCR] [CSCGCR] [CSCBCR] + * @offset: CSC offset values for Y offset, CB offset and CR offset respectively + */ +struct ispprev_csc { + __u16 matrix[RGB_MAX][RGB_MAX]; + __s16 offset[RGB_MAX]; +}; + +/** + * struct ispprev_yclimit - Structure for Y, C Value Limit. + * @minC: Minimum C value + * @maxC: Maximum C value + * @minY: Minimum Y value + * @maxY: Maximum Y value + */ +struct ispprev_yclimit { + __u8 minC; + __u8 maxC; + __u8 minY; + __u8 maxY; +}; + +/** + * struct ispprev_dcor - Structure for Defect correction. + * @couplet_mode_en: Flag to enable or disable the couplet dc Correction in NF + * @detect_correct: Thresholds for correction bit 0:10 detect 16:25 correct + */ +struct ispprev_dcor { + __u8 couplet_mode_en; + __u32 detect_correct[4]; +}; + +/** + * struct ispprev_nf - Structure for Noise Filter + * @spread: Spread value to be used in Noise Filter + * @table: Pointer to the Noise Filter table + */ +struct ispprev_nf { + __u8 spread; + __u32 table[ISPPRV_NF_TBL_SIZE]; +}; + +/** + * struct ispprv_update_config - Structure for Preview Configuration (user). + * @update: Specifies which ISP Preview registers should be updated. + * @flag: Specifies which ISP Preview functions should be enabled. + * @yen: Pointer to luma enhancement table. + * @shading_shift: 3bit value of shift used in shading compensation. + * @prev_hmed: Pointer to structure containing the odd and even distance. + * between the pixels in the image along with the filter threshold. + * @prev_cfa: Pointer to structure containing the CFA interpolation table, CFA. + * format in the image, vertical and horizontal gradient threshold. + * @csup: Pointer to Structure for Chrominance Suppression coefficients. + * @prev_wbal: Pointer to structure for White Balance. + * @prev_blkadj: Pointer to structure for Black Adjustment. + * @rgb2rgb: Pointer to structure for RGB to RGB Blending. + * @prev_csc: Pointer to structure for Color Space Conversion from RGB-YCbYCr. + * @yclimit: Pointer to structure for Y, C Value Limit. + * @prev_dcor: Pointer to structure for defect correction. + * @prev_nf: Pointer to structure for Noise Filter + * @red_gamma: Pointer to red gamma correction table. + * @green_gamma: Pointer to green gamma correction table. + * @blue_gamma: Pointer to blue gamma correction table. + */ +struct ispprv_update_config { + __u16 update; + __u16 flag; + void *yen; + __u32 shading_shift; + struct ispprev_hmed *prev_hmed; + struct ispprev_cfa *prev_cfa; + struct ispprev_csup *csup; + struct ispprev_wbal *prev_wbal; + struct ispprev_blkadj *prev_blkadj; + struct ispprev_rgbtorgb *rgb2rgb; + struct ispprev_csc *prev_csc; + struct ispprev_yclimit *yclimit; + struct ispprev_dcor *prev_dcor; + struct ispprev_nf *prev_nf; + __u32 *red_gamma; + __u32 *green_gamma; + __u32 *blue_gamma; +}; + +#endif /* OMAP_ISP_USER_H */ diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 72f6d03..e654270 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -106,6 +106,8 @@ obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o obj-$(CONFIG_VIDEO_OV7670) += ov7670.o +obj-y += isp/ + obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o obj-$(CONFIG_USB_DABUSB) += dabusb.o diff --git a/drivers/media/video/isp/Makefile b/drivers/media/video/isp/Makefile new file mode 100644 index 0000000..f14d617 --- /dev/null +++ b/drivers/media/video/isp/Makefile @@ -0,0 +1,12 @@ +# Makefile for OMAP3 ISP driver + +ifdef CONFIG_ARCH_OMAP3410 +isp-mod-objs += \ + isp.o ispccdc.o +else +isp-mod-objs += \ + isp.o ispccdc.o ispmmu.o \ + isppreview.o ispresizer.o isph3a.o isphist.o isp_af.o ispcsi2.o +endif + +obj-$(CONFIG_VIDEO_OMAP3) += isp-mod.o diff --git a/drivers/media/video/isp/bluegamma_table.h b/drivers/media/video/isp/bluegamma_table.h new file mode 100644 index 0000000..301382a --- /dev/null +++ b/drivers/media/video/isp/bluegamma_table.h @@ -0,0 +1,1040 @@ +/* + * bluegamma_table.h + * + * Gamma Table values for BLUE for TI's OMAP3 Camera ISP + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +0, +0, +1, +2, +3, +3, +4, +5, +6, +8, +10, +12, +14, +16, +18, +20, +22, +23, +25, +26, +28, +29, +31, +32, +34, +35, +36, +37, +39, +40, +41, +42, +43, +44, +45, +46, +47, +48, +49, +50, +51, +52, +52, +53, +54, +55, +56, +57, +58, +59, +60, +61, +62, +63, +63, +64, +65, +66, +66, +67, +68, +69, +69, +70, +71, +72, +72, +73, +74, +75, +75, +76, +77, +78, +78, +79, +80, +81, +81, +82, +83, +84, +84, +85, +86, +87, +88, +88, +89, +90, +91, +91, +92, +93, +94, +94, +95, +96, +97, +97, +98, +98, +99, +99, +100, +100, +101, +101, +102, +103, +104, +104, +105, +106, +107, +108, +108, +109, +110, +111, +111, +112, +113, +114, +114, +115, +116, +117, +117, +118, +119, +119, +120, +120, +121, +121, +122, +122, +123, +123, +124, +124, +125, +125, +126, +126, +127, +127, +128, +128, +129, +129, +130, +130, +131, +131, +132, +132, +133, +133, +134, +134, +135, +135, +136, +136, +137, +137, +138, +138, +139, +139, +140, +140, +141, +141, +142, +142, +143, +143, +144, +144, +145, +145, +146, +146, +147, +147, +148, +148, +149, +149, +150, +150, +151, +151, +152, +152, +153, +153, +153, +153, +154, +154, +154, +154, +155, +155, +156, +156, +157, +157, +158, +158, +158, +159, +159, +159, +160, +160, +160, +161, +161, +162, +162, +163, +163, +164, +164, +164, +164, +165, +165, +165, +165, +166, +166, +167, +167, +168, +168, +169, +169, +170, +170, +170, +170, +171, +171, +171, +171, +172, +172, +173, +173, +174, +174, +175, +175, +176, +176, +176, +176, +177, +177, +177, +177, +178, +178, +178, +178, +179, +179, +179, +179, +180, +180, +180, +180, +181, +181, +181, +181, +182, +182, +182, +182, +183, +183, +183, +183, +184, +184, +184, +184, +185, +185, +185, +185, +186, +186, +186, +186, +187, +187, +187, +187, +188, +188, +188, +188, +189, +189, +189, +189, +190, +190, +190, +190, +191, +191, +191, +191, +192, +192, +192, +192, +193, +193, +193, +193, +194, +194, +194, +194, +195, +195, +195, +195, +196, +196, +196, +196, +197, +197, +197, +197, +198, +198, +198, +198, +199, +199, +199, +199, +200, +200, +200, +200, +201, +201, +201, +201, +202, +202, +202, +203, +203, +203, +203, +204, +204, +204, +204, +205, +205, +205, +205, +206, +206, +206, +206, +207, +207, +207, +207, +208, +208, +208, +208, +209, +209, +209, +209, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +211, +211, +211, +211, +211, +211, +211, +211, +211, +211, +211, +212, +212, +212, +212, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +214, +214, +214, +214, +215, +215, +215, +215, +215, +215, +215, +215, +215, +215, +215, +216, +216, +216, +216, +217, +217, +217, +217, +218, +218, +218, +218, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +220, +220, +220, +220, +221, +221, +221, +221, +221, +221, +221, +221, +221, +221, +221, +222, +222, +222, +222, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +224, +224, +224, +224, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +226, +226, +226, +226, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +228, +228, +228, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +230, +230, +230, +230, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +233, +233, +233, +233, +234, +234, +234, +234, +234, +234, +234, +234, +234, +234, +234, +235, +235, +235, +235, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +237, +237, +237, +237, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +239, +239, +239, +239, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +241, +241, +241, +241, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +243, +243, +243, +243, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +245, +245, +245, +245, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +247, +247, +247, +247, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +249, +249, +249, +249, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +251, +251, +251, +251, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +254, +254, +254, +254, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255 diff --git a/drivers/media/video/isp/cfa_coef_table.h b/drivers/media/video/isp/cfa_coef_table.h new file mode 100644 index 0000000..8cafa1f --- /dev/null +++ b/drivers/media/video/isp/cfa_coef_table.h @@ -0,0 +1,603 @@ +/* + * cfa_coef_table.h + * + * Copyright (C) 2009 Nokia Corporation + * + * Contact: Sakari Ailus + * Tuukka Toivonen + * + * Written by Gjorgji Rosikopulos + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +0, +0, +40, +0, +0, +0, +0, +248, +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +0, +0, +40, +0, +0, +0, +0, +248, +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +0, +0, +40, +0, +0, +0, +0, +248, +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +0, +0, +248, +0, +0, +40, +0, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +40, +0, +0, +248, +0, +0, +0, +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +0, +0, +248, +0, +0, +40, +0, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +40, +0, +0, +248, +0, +0, +0, +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +0, +0, +248, +0, +0, +40, +0, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +40, +0, +0, +248, +0, +0, +0, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +0, +0, +248, +0, +0, +40, +0, +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +40, +0, +0, +248, +0, +0, +0, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +0, +0, +248, +0, +0, +40, +0, +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +40, +0, +0, +248, +0, +0, +0, +4, +250, +12, +244, +250, +0, +27, +0, +12, +27, +36, +247, +244, +0, +247, +0, +0, +0, +0, +248, +0, +0, +40, +0, +0, +247, +0, +244, +247, +36, +27, +12, +0, +27, +0, +250, +244, +12, +250, +4, +0, +40, +0, +0, +248, +0, +0, +0, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +0, +0, +40, +0, +0, +0, +0, +248, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +0, +0, +40, +0, +0, +0, +0, +248, +244, +12, +250, +4, +0, +27, +0, +250, +247, +36, +27, +12, +0, +247, +0, +244, +248, +0, +0, +0, +0, +40, +0, +0, +244, +0, +247, +0, +12, +27, +36, +247, +250, +0, +27, +0, +4, +250, +12, +244, +0, +0, +40, +0, +0, +0, +0, +248 + diff --git a/drivers/media/video/isp/greengamma_table.h b/drivers/media/video/isp/greengamma_table.h new file mode 100644 index 0000000..0f5c5e4 --- /dev/null +++ b/drivers/media/video/isp/greengamma_table.h @@ -0,0 +1,1040 @@ +/* + * greengamma_table.h + * + * Gamma Table values for GREEN for TI's OMAP3 Camera ISP + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +0, +0, +1, +2, +3, +3, +4, +5, +6, +8, +10, +12, +14, +16, +18, +20, +22, +23, +25, +26, +28, +29, +31, +32, +34, +35, +36, +37, +39, +40, +41, +42, +43, +44, +45, +46, +47, +48, +49, +50, +51, +52, +52, +53, +54, +55, +56, +57, +58, +59, +60, +61, +62, +63, +63, +64, +65, +66, +66, +67, +68, +69, +69, +70, +71, +72, +72, +73, +74, +75, +75, +76, +77, +78, +78, +79, +80, +81, +81, +82, +83, +84, +84, +85, +86, +87, +88, +88, +89, +90, +91, +91, +92, +93, +94, +94, +95, +96, +97, +97, +98, +98, +99, +99, +100, +100, +101, +101, +102, +103, +104, +104, +105, +106, +107, +108, +108, +109, +110, +111, +111, +112, +113, +114, +114, +115, +116, +117, +117, +118, +119, +119, +120, +120, +121, +121, +122, +122, +123, +123, +124, +124, +125, +125, +126, +126, +127, +127, +128, +128, +129, +129, +130, +130, +131, +131, +132, +132, +133, +133, +134, +134, +135, +135, +136, +136, +137, +137, +138, +138, +139, +139, +140, +140, +141, +141, +142, +142, +143, +143, +144, +144, +145, +145, +146, +146, +147, +147, +148, +148, +149, +149, +150, +150, +151, +151, +152, +152, +153, +153, +153, +153, +154, +154, +154, +154, +155, +155, +156, +156, +157, +157, +158, +158, +158, +159, +159, +159, +160, +160, +160, +161, +161, +162, +162, +163, +163, +164, +164, +164, +164, +165, +165, +165, +165, +166, +166, +167, +167, +168, +168, +169, +169, +170, +170, +170, +170, +171, +171, +171, +171, +172, +172, +173, +173, +174, +174, +175, +175, +176, +176, +176, +176, +177, +177, +177, +177, +178, +178, +178, +178, +179, +179, +179, +179, +180, +180, +180, +180, +181, +181, +181, +181, +182, +182, +182, +182, +183, +183, +183, +183, +184, +184, +184, +184, +185, +185, +185, +185, +186, +186, +186, +186, +187, +187, +187, +187, +188, +188, +188, +188, +189, +189, +189, +189, +190, +190, +190, +190, +191, +191, +191, +191, +192, +192, +192, +192, +193, +193, +193, +193, +194, +194, +194, +194, +195, +195, +195, +195, +196, +196, +196, +196, +197, +197, +197, +197, +198, +198, +198, +198, +199, +199, +199, +199, +200, +200, +200, +200, +201, +201, +201, +201, +202, +202, +202, +203, +203, +203, +203, +204, +204, +204, +204, +205, +205, +205, +205, +206, +206, +206, +206, +207, +207, +207, +207, +208, +208, +208, +208, +209, +209, +209, +209, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +210, +211, +211, +211, +211, +211, +211, +211, +211, +211, +211, +211, +212, +212, +212, +212, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +213, +214, +214, +214, +214, +215, +215, +215, +215, +215, +215, +215, +215, +215, +215, +215, +216, +216, +216, +216, +217, +217, +217, +217, +218, +218, +218, +218, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +219, +220, +220, +220, +220, +221, +221, +221, +221, +221, +221, +221, +221, +221, +221, +221, +222, +222, +222, +222, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +223, +224, +224, +224, +224, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +225, +226, +226, +226, +226, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +227, +228, +228, +228, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +229, +230, +230, +230, +230, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +231, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +232, +233, +233, +233, +233, +234, +234, +234, +234, +234, +234, +234, +234, +234, +234, +234, +235, +235, +235, +235, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +236, +237, +237, +237, +237, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +238, +239, +239, +239, +239, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +240, +241, +241, +241, +241, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +242, +243, +243, +243, +243, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +244, +245, +245, +245, +245, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +246, +247, +247, +247, +247, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +248, +249, +249, +249, +249, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +250, +251, +251, +251, +251, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +252, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +253, +254, +254, +254, +254, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255, +255 diff --git a/drivers/media/video/isp/isp.c b/drivers/media/video/isp/isp.c new file mode 100644 index 0000000..54c839b --- /dev/null +++ b/drivers/media/video/isp/isp.c @@ -0,0 +1,2547 @@ +/* + * isp.c + * + * Driver Library for ISP Control module in TI's OMAP3 Camera ISP + * ISP interface and IRQ related APIs are defined here. + * + * Copyright (C) 2009 Texas Instruments. + * Copyright (C) 2009 Nokia. + * + * Contributors: + * Sameer Venkatraman + * Mohit Jalori + * Sergio Aguirre + * Sakari Ailus + * Tuukka Toivonen + * Toni Leinonen + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "isp.h" +#include "ispmmu.h" +#include "ispreg.h" +#include "ispccdc.h" +#include "isph3a.h" +#include "isphist.h" +#include "isp_af.h" +#include "isppreview.h" +#include "ispresizer.h" +#include "ispcsi2.h" + +static struct isp_device *omap3isp; + +static int isp_try_size(struct v4l2_pix_format *pix_input, + struct v4l2_pix_format *pix_output); + +static void isp_save_ctx(void); + +static void isp_restore_ctx(void); + +static void isp_buf_init(void); + +/* List of image formats supported via OMAP ISP */ +const static struct v4l2_fmtdesc isp_formats[] = { + { + .description = "UYVY, packed", + .pixelformat = V4L2_PIX_FMT_UYVY, + }, + { + .description = "YUYV (YUV 4:2:2), packed", + .pixelformat = V4L2_PIX_FMT_YUYV, + }, + { + .description = "Bayer10 (GrR/BGb)", + .pixelformat = V4L2_PIX_FMT_SGRBG10, + }, +}; + +/* ISP Crop capabilities */ +static struct v4l2_rect ispcroprect; +static struct v4l2_rect cur_rect; + +/** + * struct vcontrol - Video control structure. + * @qc: V4L2 Query control structure. + * @current_value: Current value of the control. + */ +static struct vcontrol { + struct v4l2_queryctrl qc; + int current_value; +} video_control[] = { + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = ISPPRV_BRIGHT_LOW, + .maximum = ISPPRV_BRIGHT_HIGH, + .step = ISPPRV_BRIGHT_STEP, + .default_value = ISPPRV_BRIGHT_DEF, + }, + .current_value = ISPPRV_BRIGHT_DEF, + }, + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = ISPPRV_CONTRAST_LOW, + .maximum = ISPPRV_CONTRAST_HIGH, + .step = ISPPRV_CONTRAST_STEP, + .default_value = ISPPRV_CONTRAST_DEF, + }, + .current_value = ISPPRV_CONTRAST_DEF, + }, + { + { + .id = V4L2_CID_COLORFX, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Color Effects", + .minimum = V4L2_COLORFX_NONE, + .maximum = V4L2_COLORFX_SEPIA, + .step = 1, + .default_value = V4L2_COLORFX_NONE, + }, + .current_value = V4L2_COLORFX_NONE, + } +}; + +static struct v4l2_querymenu video_menu[] = { + { + .id = V4L2_CID_COLORFX, + .index = 0, + .name = "None", + }, + { + .id = V4L2_CID_COLORFX, + .index = 1, + .name = "B&W", + }, + { + .id = V4L2_CID_COLORFX, + .index = 2, + .name = "Sepia", + }, +}; + +struct isp_buf { + dma_addr_t isp_addr; + void (*complete)(struct videobuf_buffer *vb, void *priv); + struct videobuf_buffer *vb; + void *priv; + u32 vb_state; +}; + +#define ISP_BUFS_IS_FULL(bufs) \ + (((bufs)->queue + 1) % NUM_BUFS == (bufs)->done) +#define ISP_BUFS_IS_EMPTY(bufs) ((bufs)->queue == (bufs)->done) +#define ISP_BUFS_IS_LAST(bufs) \ + ((bufs)->queue == ((bufs)->done + 1) % NUM_BUFS) +#define ISP_BUFS_QUEUED(bufs) \ + ((((bufs)->done - (bufs)->queue + NUM_BUFS)) % NUM_BUFS) +#define ISP_BUF_DONE(bufs) ((bufs)->buf + (bufs)->done) +#define ISP_BUF_NEXT_DONE(bufs) \ + ((bufs)->buf + ((bufs)->done + 1) % NUM_BUFS) +#define ISP_BUF_QUEUE(bufs) ((bufs)->buf + (bufs)->queue) +#define ISP_BUF_MARK_DONE(bufs) \ + (bufs)->done = ((bufs)->done + 1) % NUM_BUFS; +#define ISP_BUF_MARK_QUEUED(bufs) \ + (bufs)->queue = ((bufs)->queue + 1) % NUM_BUFS; + +struct isp_bufs { + dma_addr_t isp_addr_capture[VIDEO_MAX_FRAME]; + spinlock_t lock; /* For handling current buffer */ + /* queue full: (ispsg.queue + 1) % NUM_BUFS == ispsg.done + queue empty: ispsg.queue == ispsg.done */ + struct isp_buf buf[NUM_BUFS]; + /* Next slot to queue a buffer. */ + int queue; + /* Buffer that is being processed. */ + int done; + /* Wait for this many hs_vs before anything else. */ + int wait_hs_vs; +}; + +/** + * struct ispirq - Structure for containing callbacks to be called in ISP ISR. + * @isp_callbk: Array which stores callback functions, indexed by the type of + * callback (8 possible types). + * @isp_callbk_arg1: Pointer to array containing pointers to the first argument + * to be passed to the requested callback function. + * @isp_callbk_arg2: Pointer to array containing pointers to the second + * argument to be passed to the requested callback function. + * + * This structure is used to contain all the callback functions related for + * each callback type (CBK_CCDC_VD0, CBK_CCDC_VD1, CBK_PREV_DONE, + * CBK_RESZ_DONE, CBK_MMU_ERR, CBK_H3A_AWB_DONE, CBK_HIST_DONE, CBK_HS_VS, + * CBK_LSC_ISR). + */ +struct isp_irq { + isp_callback_t isp_callbk[CBK_END]; + isp_vbq_callback_ptr isp_callbk_arg1[CBK_END]; + void *isp_callbk_arg2[CBK_END]; +}; + +/** + * struct ispmodule - Structure for storing ISP sub-module information. + * @isp_pipeline: Bit mask for submodules enabled within the ISP. + * @applyCrop: Flag to do a crop operation when video buffer queue ISR is done + * @pix: Structure containing the format and layout of the output image. + * @ccdc_input_width: ISP CCDC module input image width. + * @ccdc_input_height: ISP CCDC module input image height. + * @ccdc_output_width: ISP CCDC module output image width. + * @ccdc_output_height: ISP CCDC module output image height. + * @preview_input_width: ISP Preview module input image width. + * @preview_input_height: ISP Preview module input image height. + * @preview_output_width: ISP Preview module output image width. + * @preview_output_height: ISP Preview module output image height. + * @resizer_input_width: ISP Resizer module input image width. + * @resizer_input_height: ISP Resizer module input image height. + * @resizer_output_width: ISP Resizer module output image width. + * @resizer_output_height: ISP Resizer module output image height. + */ +struct isp_module { + unsigned int isp_pipeline; + int applyCrop; + struct v4l2_pix_format pix; + unsigned int ccdc_input_width; + unsigned int ccdc_input_height; + unsigned int ccdc_output_width; + unsigned int ccdc_output_height; + unsigned int preview_input_width; + unsigned int preview_input_height; + unsigned int preview_output_width; + unsigned int preview_output_height; + unsigned int resizer_input_width; + unsigned int resizer_input_height; + unsigned int resizer_output_width; + unsigned int resizer_output_height; +}; + +#define RAW_CAPTURE(isp) \ + (!((isp)->module.isp_pipeline & OMAP_ISP_PREVIEW)) + +/** + * struct isp - Structure for storing ISP Control module information + * @lock: Spinlock to sync between isr and processes. + * @isp_mutex: Semaphore used to get access to the ISP. + * @ref_count: Reference counter. + * @cam_ick: Pointer to ISP Interface clock. + * @cam_fck: Pointer to ISP Functional clock. + * + * This structure is used to store the OMAP ISP Control Information. + */ +static struct isp { + spinlock_t lock; /* For handling registered ISP callbacks */ + struct mutex isp_mutex; /* For handling ref_count field */ + int ref_count; + struct clk *cam_ick; + struct clk *cam_mclk; + struct clk *csi2_fck; + struct isp_interface_config *config; + dma_addr_t tmp_buf; + size_t tmp_buf_size; + unsigned long tmp_buf_offset; + struct isp_bufs bufs; + struct isp_irq irq; + struct isp_module module; +} isp_obj; + +/* Structure for saving/restoring ISP module registers */ +static struct isp_reg isp_reg_list[] = { + {OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG, 0}, + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_GRESET_LENGTH, 0}, + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_PSTRB_REPLAY, 0}, + {OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, 0}, + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, 0}, + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_FRAME, 0}, + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_PSTRB_DELAY, 0}, + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_STRB_DELAY, 0}, + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_SHUT_DELAY, 0}, + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_PSTRB_LENGTH, 0}, + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_STRB_LENGTH, 0}, + {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_SHUT_LENGTH, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF_SYSCONFIG, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF_IRQENABLE, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF0_CTRL, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF1_CTRL, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF0_START, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF1_START, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF0_END, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF1_END, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF0_WINDOWSIZE, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF1_WINDOWSIZE, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF0_THRESHOLD, 0}, + {OMAP3_ISP_IOMEM_CBUFF, ISP_CBUFF1_THRESHOLD, 0}, + {0, ISP_TOK_TERM, 0} +}; + +u32 isp_reg_readl(enum isp_mem_resources isp_mmio_range, u32 reg_offset) +{ + return __raw_readl(omap3isp->mmio_base[isp_mmio_range] + reg_offset); +} +EXPORT_SYMBOL(isp_reg_readl); + +void isp_reg_writel(u32 reg_value, enum isp_mem_resources isp_mmio_range, + u32 reg_offset) +{ + __raw_writel(reg_value, + omap3isp->mmio_base[isp_mmio_range] + reg_offset); +} +EXPORT_SYMBOL(isp_reg_writel); + +/* + * + * V4L2 Handling + * + */ + +/** + * find_vctrl - Returns the index of the ctrl array of the requested ctrl ID. + * @id: Requested control ID. + * + * Returns 0 if successful, -EINVAL if not found, or -EDOM if its out of + * domain. + **/ +static int find_vctrl(int id) +{ + int i; + + if (id < V4L2_CID_BASE) + return -EDOM; + + for (i = (ARRAY_SIZE(video_control) - 1); i >= 0; i--) + if (video_control[i].qc.id == id) + break; + + if (i < 0) + i = -EINVAL; + + return i; +} + +static int find_next_vctrl(int id) +{ + int i; + u32 best = (u32)-1; + + for (i = 0; i < ARRAY_SIZE(video_control); i++) { + if (video_control[i].qc.id > id && + (best == (u32)-1 || + video_control[i].qc.id < + video_control[best].qc.id)) { + best = i; + } + } + + if (best == (u32)-1) + return -EINVAL; + + return best; +} + +/** + * find_vmenu - Returns index of the menu array of the requested ctrl option. + * @id: Requested control ID. + * @index: Requested menu option index. + * + * Returns 0 if successful, -EINVAL if not found, or -EDOM if its out of + * domain. + **/ +static int find_vmenu(int id, int index) +{ + int i; + + if (id < V4L2_CID_BASE) + return -EDOM; + + for (i = (ARRAY_SIZE(video_menu) - 1); i >= 0; i--) { + if (video_menu[i].id != id || video_menu[i].index != index) + continue; + return i; + } + + return -EINVAL; +} + +/** + * isp_release_resources - Free ISP submodules + **/ +static void isp_release_resources(void) +{ + if (isp_obj.module.isp_pipeline & OMAP_ISP_CCDC) + ispccdc_free(); + + if (isp_obj.module.isp_pipeline & OMAP_ISP_PREVIEW) + isppreview_free(); + + if (isp_obj.module.isp_pipeline & OMAP_ISP_RESIZER) + ispresizer_free(); + return; +} + +static int isp_wait(int (*busy)(void), int wait_for_busy, int max_wait) +{ + int wait = 0; + + if (max_wait == 0) + max_wait = 10000; /* 10 ms */ + + while ((wait_for_busy && !busy()) + || (!wait_for_busy && busy())) { + rmb(); + udelay(1); + wait++; + if (wait > max_wait) { + printk(KERN_ALERT "%s: wait is too much\n", __func__); + return -EBUSY; + } + } + DPRINTK_ISPCTRL(KERN_ALERT "%s: wait %d\n", __func__, wait); + + return 0; +} + +static int ispccdc_sbl_wait_idle(int max_wait) +{ + return isp_wait(ispccdc_sbl_busy, 0, max_wait); +} + +static void isp_enable_interrupts(int is_raw) +{ + isp_reg_writel(-1, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ | + IRQ0ENABLE_HS_VS_IRQ | + IRQ0ENABLE_CCDC_VD0_IRQ | + IRQ0ENABLE_CCDC_VD1_IRQ); + + if (is_raw) + return; + + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + IRQ0ENABLE_PRV_DONE_IRQ | + IRQ0ENABLE_RSZ_DONE_IRQ); + + return; +} + +static void isp_disable_interrupts(void) +{ + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + ~(IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ | + IRQ0ENABLE_HS_VS_IRQ | + IRQ0ENABLE_CCDC_VD0_IRQ | + IRQ0ENABLE_CCDC_VD1_IRQ | + IRQ0ENABLE_PRV_DONE_IRQ | + IRQ0ENABLE_RSZ_DONE_IRQ)); +} + +/** + * isp_set_callback - Sets the callback for the ISP module done events. + * @type: Type of the event for which callback is requested. + * @callback: Method to be called as callback in the ISR context. + * @arg1: First argument to be passed when callback is called in ISR. + * @arg2: Second argument to be passed when callback is called in ISR. + * + * This function sets a callback function for a done event in the ISP + * module, and enables the corresponding interrupt. + **/ +int isp_set_callback(enum isp_callback_type type, isp_callback_t callback, + isp_vbq_callback_ptr arg1, + void *arg2) +{ + unsigned long irqflags = 0; + + if (callback == NULL) { + DPRINTK_ISPCTRL("ISP_ERR : Null Callback\n"); + return -EINVAL; + } + + spin_lock_irqsave(&isp_obj.lock, irqflags); + isp_obj.irq.isp_callbk[type] = callback; + isp_obj.irq.isp_callbk_arg1[type] = arg1; + isp_obj.irq.isp_callbk_arg2[type] = arg2; + spin_unlock_irqrestore(&isp_obj.lock, irqflags); + + switch (type) { + case CBK_H3A_AWB_DONE: + isp_reg_writel(IRQ0ENABLE_H3A_AWB_DONE_IRQ, + OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + IRQ0ENABLE_H3A_AWB_DONE_IRQ); + break; + case CBK_H3A_AF_DONE: + isp_reg_writel(IRQ0ENABLE_H3A_AF_DONE_IRQ, + OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + IRQ0ENABLE_H3A_AF_DONE_IRQ); + break; + case CBK_HIST_DONE: + isp_reg_writel(IRQ0ENABLE_HIST_DONE_IRQ, + OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + IRQ0ENABLE_HIST_DONE_IRQ); + break; + case CBK_PREV_DONE: + isp_reg_writel(IRQ0ENABLE_PRV_DONE_IRQ, + OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS); + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + IRQ0ENABLE_PRV_DONE_IRQ); + break; + default: + break; + } + + return 0; +} +EXPORT_SYMBOL(isp_set_callback); + +/** + * isp_unset_callback - Clears the callback for the ISP module done events. + * @type: Type of the event for which callback to be cleared. + * + * This function clears a callback function for a done event in the ISP + * module, and disables the corresponding interrupt. + **/ +int isp_unset_callback(enum isp_callback_type type) +{ + unsigned long irqflags = 0; + + spin_lock_irqsave(&isp_obj.lock, irqflags); + isp_obj.irq.isp_callbk[type] = NULL; + isp_obj.irq.isp_callbk_arg1[type] = NULL; + isp_obj.irq.isp_callbk_arg2[type] = NULL; + spin_unlock_irqrestore(&isp_obj.lock, irqflags); + + switch (type) { + case CBK_H3A_AWB_DONE: + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + ~IRQ0ENABLE_H3A_AWB_DONE_IRQ); + break; + case CBK_H3A_AF_DONE: + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + ~IRQ0ENABLE_H3A_AF_DONE_IRQ); + break; + case CBK_HIST_DONE: + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + ~IRQ0ENABLE_HIST_DONE_IRQ); + break; + case CBK_CSIA: + isp_csi2_irq_set(0); + break; + case CBK_CSIB: + isp_reg_writel(IRQ0ENABLE_CSIB_IRQ, OMAP3_ISP_IOMEM_MAIN, + ISP_IRQ0STATUS); + isp_reg_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + IRQ0ENABLE_CSIB_IRQ); + break; + case CBK_PREV_DONE: + isp_reg_and(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, + ~IRQ0ENABLE_PRV_DONE_IRQ); + break; + default: + break; + } + + return 0; +} +EXPORT_SYMBOL(isp_unset_callback); + +/** + * isp_set_xclk - Configures the specified cam_xclk to the desired frequency. + * @xclk: Desired frequency of the clock in Hz. + * @xclksel: XCLK to configure (0 = A, 1 = B). + * + * Configures the specified MCLK divisor in the ISP timing control register + * (TCTRL_CTRL) to generate the desired xclk clock value. + * + * Divisor = CM_CAM_MCLK_HZ / xclk + * + * Returns the final frequency that is actually being generated + **/ +u32 isp_set_xclk(u32 xclk, u8 xclksel) +{ + u32 divisor; + u32 currentxclk; + + if (xclk >= CM_CAM_MCLK_HZ) { + divisor = ISPTCTRL_CTRL_DIV_BYPASS; + currentxclk = CM_CAM_MCLK_HZ; + } else if (xclk >= 2) { + divisor = CM_CAM_MCLK_HZ / xclk; + if (divisor >= ISPTCTRL_CTRL_DIV_BYPASS) + divisor = ISPTCTRL_CTRL_DIV_BYPASS - 1; + currentxclk = CM_CAM_MCLK_HZ / divisor; + } else { + divisor = xclk; + currentxclk = 0; + } + + switch (xclksel) { + case 0: + isp_reg_and_or(OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, + ~ISPTCTRL_CTRL_DIVA_MASK, + divisor << ISPTCTRL_CTRL_DIVA_SHIFT); + DPRINTK_ISPCTRL("isp_set_xclk(): cam_xclka set to %d Hz\n", + currentxclk); + break; + case 1: + isp_reg_and_or(OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, + ~ISPTCTRL_CTRL_DIVB_MASK, + divisor << ISPTCTRL_CTRL_DIVB_SHIFT); + DPRINTK_ISPCTRL("isp_set_xclk(): cam_xclkb set to %d Hz\n", + currentxclk); + break; + default: + DPRINTK_ISPCTRL("ISP_ERR: isp_set_xclk(): Invalid requested " + "xclk. Must be 0 (A) or 1 (B)." + "\n"); + return -EINVAL; + } + + return currentxclk; +} +EXPORT_SYMBOL(isp_set_xclk); + +/** + * isp_power_settings - Sysconfig settings, for Power Management. + * @isp_sysconfig: Structure containing the power settings for ISP to configure + * + * Sets the power settings for the ISP, and SBL bus. + **/ +static void isp_power_settings(int idle) +{ + if (idle) { + isp_reg_writel(ISP_SYSCONFIG_AUTOIDLE | + (ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY << + ISP_SYSCONFIG_MIDLEMODE_SHIFT), + OMAP3_ISP_IOMEM_MAIN, + ISP_SYSCONFIG); + if (omap_rev() == OMAP3430_REV_ES1_0) { + isp_reg_writel(ISPCSI1_AUTOIDLE | + (ISPCSI1_MIDLEMODE_SMARTSTANDBY << + ISPCSI1_MIDLEMODE_SHIFT), + OMAP3_ISP_IOMEM_CSI2A, + ISP_CSIA_SYSCONFIG); + isp_reg_writel(ISPCSI1_AUTOIDLE | + (ISPCSI1_MIDLEMODE_SMARTSTANDBY << + ISPCSI1_MIDLEMODE_SHIFT), + OMAP3_ISP_IOMEM_CCP2, + ISP_CSIB_SYSCONFIG); + } + isp_reg_writel(ISPCTRL_SBL_AUTOIDLE, OMAP3_ISP_IOMEM_MAIN, + ISP_CTRL); + + } else { + isp_reg_writel(ISP_SYSCONFIG_AUTOIDLE | + (ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY << + ISP_SYSCONFIG_MIDLEMODE_SHIFT), + OMAP3_ISP_IOMEM_MAIN, + ISP_SYSCONFIG); + if (omap_rev() == OMAP3430_REV_ES1_0) { + isp_reg_writel(ISPCSI1_AUTOIDLE | + (ISPCSI1_MIDLEMODE_FORCESTANDBY << + ISPCSI1_MIDLEMODE_SHIFT), + OMAP3_ISP_IOMEM_CSI2A, + ISP_CSIA_SYSCONFIG); + + isp_reg_writel(ISPCSI1_AUTOIDLE | + (ISPCSI1_MIDLEMODE_FORCESTANDBY << + ISPCSI1_MIDLEMODE_SHIFT), + OMAP3_ISP_IOMEM_CCP2, + ISP_CSIB_SYSCONFIG); + } + + isp_reg_writel(ISPCTRL_SBL_AUTOIDLE, OMAP3_ISP_IOMEM_MAIN, + ISP_CTRL); + } +} + +#define BIT_SET(var, shift, mask, val) \ + do { \ + var = (var & ~(mask << shift)) \ + | (val << shift); \ + } while (0) + +static int isp_init_csi(struct isp_interface_config *config) +{ + u32 i = 0, val, reg; + int format; + + switch (config->u.csi.format) { + case V4L2_PIX_FMT_SGRBG10: + format = 0x16; /* RAW10+VP */ + break; + case V4L2_PIX_FMT_SGRBG10DPCM8: + format = 0x12; /* RAW8+DPCM10+VP */ + break; + default: + printk(KERN_ERR "isp_init_csi: bad csi format\n"); + return -EINVAL; + } + + /* Reset the CSI and wait for reset to complete */ + isp_reg_writel(isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_SYSCONFIG) | + BIT(1), + OMAP3_ISP_IOMEM_CCP2, + ISPCSI1_SYSCONFIG); + while (!(isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_SYSSTATUS) & + BIT(0))) { + udelay(10); + if (i++ > 10) + break; + } + if (!(isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_SYSSTATUS) & + BIT(0))) { + printk(KERN_WARNING + "omap3_isp: timeout waiting for csi reset\n"); + } + + /* ISPCSI1_CTRL */ + val = isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_CTRL); + val &= ~BIT(11); /* Enable VP only off -> + extract embedded data to interconnect */ + BIT_SET(val, 8, 0x3, config->u.csi.vpclk); /* Video port clock */ +/* val |= BIT(3); */ /* Wait for FEC before disabling interface */ + val |= BIT(2); /* I/O cell output is parallel + (no effect, but errata says should be enabled + for class 1/2) */ + val |= BIT(12); /* VP clock polarity to falling edge + (needed or bad picture!) */ + + /* Data/strobe physical layer */ + BIT_SET(val, 1, 1, config->u.csi.signalling); + BIT_SET(val, 10, 1, config->u.csi.strobe_clock_inv); + val |= BIT(4); /* Magic bit to enable CSI1 and strobe mode */ + isp_reg_writel(val, OMAP3_ISP_IOMEM_CCP2, ISPCSI1_CTRL); + + /* ISPCSI1_LCx_CTRL logical channel #0 */ + reg = ISPCSI1_LCx_CTRL(0); /* reg = ISPCSI1_CTRL1; */ + val = isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, reg); + /* Format = RAW10+VP or RAW8+DPCM10+VP*/ + BIT_SET(val, 3, 0x1f, format); + /* Enable setting of frame regions of interest */ + BIT_SET(val, 1, 1, 1); + BIT_SET(val, 2, 1, config->u.csi.crc); + isp_reg_writel(val, OMAP3_ISP_IOMEM_CCP2, reg); + + /* ISPCSI1_DAT_START for logical channel #0 */ + reg = ISPCSI1_LCx_DAT_START(0); /* reg = ISPCSI1_DAT_START; */ + val = isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, reg); + BIT_SET(val, 16, 0xfff, config->u.csi.data_start); + isp_reg_writel(val, OMAP3_ISP_IOMEM_CCP2, reg); + + /* ISPCSI1_DAT_SIZE for logical channel #0 */ + reg = ISPCSI1_LCx_DAT_SIZE(0); /* reg = ISPCSI1_DAT_SIZE; */ + val = isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, reg); + BIT_SET(val, 16, 0xfff, config->u.csi.data_size); + isp_reg_writel(val, OMAP3_ISP_IOMEM_CCP2, reg); + + /* Clear status bits for logical channel #0 */ + isp_reg_writel(0xFFF & ~BIT(6), OMAP3_ISP_IOMEM_CCP2, + ISPCSI1_LC01_IRQSTATUS); + + /* Enable CSI1 */ + val = isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_CTRL); + val |= BIT(0) | BIT(4); + isp_reg_writel(val, OMAP3_ISP_IOMEM_CCP2, ISPCSI1_CTRL); + + if (!(isp_reg_readl(OMAP3_ISP_IOMEM_CCP2, ISPCSI1_CTRL) & BIT(4))) { + printk(KERN_WARNING "OMAP3 CSI1 bus not available\n"); + if (config->u.csi.signalling) /* Strobe mode requires CSI1 */ + return -EIO; + } + + return 0; +} + +/** + * isp_configure_interface - Configures ISP Control I/F related parameters. + * @config: Pointer to structure containing the desired c