aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/omap3isp/ispccdc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-24 13:21:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-24 13:21:51 -0400
commitab11ca34eea8fda7a1a9302d86f6ef6108ffd68f (patch)
tree987ec6c263f3dfa4a7a6f9ce4d5ece47cbc12e29 /drivers/media/video/omap3isp/ispccdc.c
parentf9369910a6225b8d4892c3f20ae740a711cd5ace (diff)
parent71006fb22b0f5a2045605b3887ee99a0e9adafe4 (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - some V4L2 API updates needed by embedded devices - DVB API extensions for ATSC-MH delivery system, used in US for mobile TV - new tuners for fc0011/0012/0013 and tua9001 - a new dvb driver for af9033/9035 - a new ATSC-MH frontend (lg2160) - new remote controller keymaps - Removal of a few legacy webcam driver that got replaced by gspca on several kernel versions ago - a new driver for Exynos 4/5 webcams(s5pp fimc-lite) - a new webcam sensor driver (smiapp) - a new video input driver for embedded (sta2x1xx) - several improvements, fixes, cleanups, etc inside the drivers. Manually fix up conflicts due to err() -> dev_err() conversion in drivers/staging/media/easycap/easycap_main.c * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (484 commits) [media] saa7134-cards: Remove a PCI entry added by mistake [media] radio-sf16fmi: add support for SF16-FMD [media] rc-loopback: remove duplicate line [media] patch for Asus My Cinema PS3-100 (1043:48cd) [media] au0828: Move the Kconfig knob under V4L_USB_DRIVERS [media] em28xx: simple comment fix [media] [resend] radio-sf16fmr2: add PnP support for SF16-FMD2 [media] smiapp: Use v4l2_ctrl_new_int_menu() instead of v4l2_ctrl_new_custom() [media] smiapp: Add support for 8-bit uncompressed formats [media] smiapp: Allow generic quirk registers [media] smiapp: Use non-binning limits if the binning limit is zero [media] smiapp: Initialise rval in smiapp_read_nvm() [media] smiapp: Round minimum pre_pll up rather than down in ip_clk_freq check [media] smiapp: Use 8-bit reads only before identifying the sensor [media] smiapp: Quirk for sensors that only do 8-bit reads [media] smiapp: Pass struct sensor to register writing commands instead of i2c_client [media] smiapp: Allow using external clock from the clock framework [media] zl10353: change .read_snr() to report SNR as a 0.1 dB [media] media: add support to gspca/pac7302.c for 093a:2627 (Genius FaceCam 300) [media] m88rs2000 - only flip bit 2 on reg 0x70 on 16th try ...
Diffstat (limited to 'drivers/media/video/omap3isp/ispccdc.c')
-rw-r--r--drivers/media/video/omap3isp/ispccdc.c256
1 files changed, 238 insertions, 18 deletions
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
index eaabc27f0fa2..7e32331b60fb 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -38,6 +38,9 @@
38#include "ispreg.h" 38#include "ispreg.h"
39#include "ispccdc.h" 39#include "ispccdc.h"
40 40
41#define CCDC_MIN_WIDTH 32
42#define CCDC_MIN_HEIGHT 32
43
41static struct v4l2_mbus_framefmt * 44static struct v4l2_mbus_framefmt *
42__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, 45__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
43 unsigned int pad, enum v4l2_subdev_format_whence which); 46 unsigned int pad, enum v4l2_subdev_format_whence which);
@@ -836,8 +839,8 @@ static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
836 839
837 if (pipe->input) 840 if (pipe->input)
838 div = DIV_ROUND_UP(l3_ick, pipe->max_rate); 841 div = DIV_ROUND_UP(l3_ick, pipe->max_rate);
839 else if (ccdc->vpcfg.pixelclk) 842 else if (pipe->external_rate)
840 div = l3_ick / ccdc->vpcfg.pixelclk; 843 div = l3_ick / pipe->external_rate;
841 844
842 div = clamp(div, 2U, max_div); 845 div = clamp(div, 2U, max_div);
843 fmtcfg_vp |= (div - 2) << ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT; 846 fmtcfg_vp |= (div - 2) << ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT;
@@ -1118,6 +1121,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
1118 struct isp_parallel_platform_data *pdata = NULL; 1121 struct isp_parallel_platform_data *pdata = NULL;
1119 struct v4l2_subdev *sensor; 1122 struct v4l2_subdev *sensor;
1120 struct v4l2_mbus_framefmt *format; 1123 struct v4l2_mbus_framefmt *format;
1124 const struct v4l2_rect *crop;
1121 const struct isp_format_info *fmt_info; 1125 const struct isp_format_info *fmt_info;
1122 struct v4l2_subdev_format fmt_src; 1126 struct v4l2_subdev_format fmt_src;
1123 unsigned int depth_out; 1127 unsigned int depth_out;
@@ -1211,14 +1215,14 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
1211 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT); 1215 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT);
1212 1216
1213 /* CCDC_PAD_SOURCE_OF */ 1217 /* CCDC_PAD_SOURCE_OF */
1214 format = &ccdc->formats[CCDC_PAD_SOURCE_OF]; 1218 crop = &ccdc->crop;
1215 1219
1216 isp_reg_writel(isp, (0 << ISPCCDC_HORZ_INFO_SPH_SHIFT) | 1220 isp_reg_writel(isp, (crop->left << ISPCCDC_HORZ_INFO_SPH_SHIFT) |
1217 ((format->width - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT), 1221 ((crop->width - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT),
1218 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO); 1222 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO);
1219 isp_reg_writel(isp, 0 << ISPCCDC_VERT_START_SLV0_SHIFT, 1223 isp_reg_writel(isp, crop->top << ISPCCDC_VERT_START_SLV0_SHIFT,
1220 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START); 1224 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START);
1221 isp_reg_writel(isp, (format->height - 1) 1225 isp_reg_writel(isp, (crop->height - 1)
1222 << ISPCCDC_VERT_LINES_NLV_SHIFT, 1226 << ISPCCDC_VERT_LINES_NLV_SHIFT,
1223 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES); 1227 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES);
1224 1228
@@ -1410,6 +1414,9 @@ static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
1410 struct video_device *vdev = ccdc->subdev.devnode; 1414 struct video_device *vdev = ccdc->subdev.devnode;
1411 struct v4l2_event event; 1415 struct v4l2_event event;
1412 1416
1417 /* Frame number propagation */
1418 atomic_inc(&pipe->frame_number);
1419
1413 memset(&event, 0, sizeof(event)); 1420 memset(&event, 0, sizeof(event));
1414 event.type = V4L2_EVENT_FRAME_SYNC; 1421 event.type = V4L2_EVENT_FRAME_SYNC;
1415 event.u.frame_sync.frame_sequence = atomic_read(&pipe->frame_number); 1422 event.u.frame_sync.frame_sequence = atomic_read(&pipe->frame_number);
@@ -1703,7 +1710,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1703 if (sub->id != 0) 1710 if (sub->id != 0)
1704 return -EINVAL; 1711 return -EINVAL;
1705 1712
1706 return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS); 1713 return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
1707} 1714}
1708 1715
1709static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, 1716static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
@@ -1790,6 +1797,16 @@ __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1790 return &ccdc->formats[pad]; 1797 return &ccdc->formats[pad];
1791} 1798}
1792 1799
1800static struct v4l2_rect *
1801__ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1802 enum v4l2_subdev_format_whence which)
1803{
1804 if (which == V4L2_SUBDEV_FORMAT_TRY)
1805 return v4l2_subdev_get_try_crop(fh, CCDC_PAD_SOURCE_OF);
1806 else
1807 return &ccdc->crop;
1808}
1809
1793/* 1810/*
1794 * ccdc_try_format - Try video format on a pad 1811 * ccdc_try_format - Try video format on a pad
1795 * @ccdc: ISP CCDC device 1812 * @ccdc: ISP CCDC device
@@ -1806,6 +1823,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1806 const struct isp_format_info *info; 1823 const struct isp_format_info *info;
1807 unsigned int width = fmt->width; 1824 unsigned int width = fmt->width;
1808 unsigned int height = fmt->height; 1825 unsigned int height = fmt->height;
1826 struct v4l2_rect *crop;
1809 unsigned int i; 1827 unsigned int i;
1810 1828
1811 switch (pad) { 1829 switch (pad) {
@@ -1831,14 +1849,10 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1831 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which); 1849 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
1832 memcpy(fmt, format, sizeof(*fmt)); 1850 memcpy(fmt, format, sizeof(*fmt));
1833 1851
1834 /* The data formatter truncates the number of horizontal output 1852 /* Hardcode the output size to the crop rectangle size. */
1835 * pixels to a multiple of 16. To avoid clipping data, allow 1853 crop = __ccdc_get_crop(ccdc, fh, which);
1836 * callers to request an output size bigger than the input size 1854 fmt->width = crop->width;
1837 * up to the nearest multiple of 16. 1855 fmt->height = crop->height;
1838 */
1839 fmt->width = clamp_t(u32, width, 32, fmt->width + 15);
1840 fmt->width &= ~15;
1841 fmt->height = clamp_t(u32, height, 32, fmt->height);
1842 break; 1856 break;
1843 1857
1844 case CCDC_PAD_SOURCE_VP: 1858 case CCDC_PAD_SOURCE_VP:
@@ -1866,6 +1880,49 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1866} 1880}
1867 1881
1868/* 1882/*
1883 * ccdc_try_crop - Validate a crop rectangle
1884 * @ccdc: ISP CCDC device
1885 * @sink: format on the sink pad
1886 * @crop: crop rectangle to be validated
1887 */
1888static void ccdc_try_crop(struct isp_ccdc_device *ccdc,
1889 const struct v4l2_mbus_framefmt *sink,
1890 struct v4l2_rect *crop)
1891{
1892 const struct isp_format_info *info;
1893 unsigned int max_width;
1894
1895 /* For Bayer formats, restrict left/top and width/height to even values
1896 * to keep the Bayer pattern.
1897 */
1898 info = omap3isp_video_format_info(sink->code);
1899 if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) {
1900 crop->left &= ~1;
1901 crop->top &= ~1;
1902 }
1903
1904 crop->left = clamp_t(u32, crop->left, 0, sink->width - CCDC_MIN_WIDTH);
1905 crop->top = clamp_t(u32, crop->top, 0, sink->height - CCDC_MIN_HEIGHT);
1906
1907 /* The data formatter truncates the number of horizontal output pixels
1908 * to a multiple of 16. To avoid clipping data, allow callers to request
1909 * an output size bigger than the input size up to the nearest multiple
1910 * of 16.
1911 */
1912 max_width = (sink->width - crop->left + 15) & ~15;
1913 crop->width = clamp_t(u32, crop->width, CCDC_MIN_WIDTH, max_width)
1914 & ~15;
1915 crop->height = clamp_t(u32, crop->height, CCDC_MIN_HEIGHT,
1916 sink->height - crop->top);
1917
1918 /* Odd width/height values don't make sense for Bayer formats. */
1919 if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) {
1920 crop->width &= ~1;
1921 crop->height &= ~1;
1922 }
1923}
1924
1925/*
1869 * ccdc_enum_mbus_code - Handle pixel format enumeration 1926 * ccdc_enum_mbus_code - Handle pixel format enumeration
1870 * @sd : pointer to v4l2 subdev structure 1927 * @sd : pointer to v4l2 subdev structure
1871 * @fh : V4L2 subdev file handle 1928 * @fh : V4L2 subdev file handle
@@ -1937,6 +1994,93 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
1937} 1994}
1938 1995
1939/* 1996/*
1997 * ccdc_get_selection - Retrieve a selection rectangle on a pad
1998 * @sd: ISP CCDC V4L2 subdevice
1999 * @fh: V4L2 subdev file handle
2000 * @sel: Selection rectangle
2001 *
2002 * The only supported rectangles are the crop rectangles on the output formatter
2003 * source pad.
2004 *
2005 * Return 0 on success or a negative error code otherwise.
2006 */
2007static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2008 struct v4l2_subdev_selection *sel)
2009{
2010 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2011 struct v4l2_mbus_framefmt *format;
2012
2013 if (sel->pad != CCDC_PAD_SOURCE_OF)
2014 return -EINVAL;
2015
2016 switch (sel->target) {
2017 case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
2018 sel->r.left = 0;
2019 sel->r.top = 0;
2020 sel->r.width = INT_MAX;
2021 sel->r.height = INT_MAX;
2022
2023 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which);
2024 ccdc_try_crop(ccdc, format, &sel->r);
2025 break;
2026
2027 case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
2028 sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
2029 break;
2030
2031 default:
2032 return -EINVAL;
2033 }
2034
2035 return 0;
2036}
2037
2038/*
2039 * ccdc_set_selection - Set a selection rectangle on a pad
2040 * @sd: ISP CCDC V4L2 subdevice
2041 * @fh: V4L2 subdev file handle
2042 * @sel: Selection rectangle
2043 *
2044 * The only supported rectangle is the actual crop rectangle on the output
2045 * formatter source pad.
2046 *
2047 * Return 0 on success or a negative error code otherwise.
2048 */
2049static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2050 struct v4l2_subdev_selection *sel)
2051{
2052 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2053 struct v4l2_mbus_framefmt *format;
2054
2055 if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL ||
2056 sel->pad != CCDC_PAD_SOURCE_OF)
2057 return -EINVAL;
2058
2059 /* The crop rectangle can't be changed while streaming. */
2060 if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED)
2061 return -EBUSY;
2062
2063 /* Modifying the crop rectangle always changes the format on the source
2064 * pad. If the KEEP_CONFIG flag is set, just return the current crop
2065 * rectangle.
2066 */
2067 if (sel->flags & V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG) {
2068 sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
2069 return 0;
2070 }
2071
2072 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which);
2073 ccdc_try_crop(ccdc, format, &sel->r);
2074 *__ccdc_get_crop(ccdc, fh, sel->which) = sel->r;
2075
2076 /* Update the source format. */
2077 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF, sel->which);
2078 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format, sel->which);
2079
2080 return 0;
2081}
2082
2083/*
1940 * ccdc_get_format - Retrieve the video format on a pad 2084 * ccdc_get_format - Retrieve the video format on a pad
1941 * @sd : ISP CCDC V4L2 subdevice 2085 * @sd : ISP CCDC V4L2 subdevice
1942 * @fh : V4L2 subdev file handle 2086 * @fh : V4L2 subdev file handle
@@ -1973,6 +2117,7 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1973{ 2117{
1974 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); 2118 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1975 struct v4l2_mbus_framefmt *format; 2119 struct v4l2_mbus_framefmt *format;
2120 struct v4l2_rect *crop;
1976 2121
1977 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which); 2122 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
1978 if (format == NULL) 2123 if (format == NULL)
@@ -1983,6 +2128,16 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1983 2128
1984 /* Propagate the format from sink to source */ 2129 /* Propagate the format from sink to source */
1985 if (fmt->pad == CCDC_PAD_SINK) { 2130 if (fmt->pad == CCDC_PAD_SINK) {
2131 /* Reset the crop rectangle. */
2132 crop = __ccdc_get_crop(ccdc, fh, fmt->which);
2133 crop->left = 0;
2134 crop->top = 0;
2135 crop->width = fmt->format.width;
2136 crop->height = fmt->format.height;
2137
2138 ccdc_try_crop(ccdc, &fmt->format, crop);
2139
2140 /* Update the source formats. */
1986 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF, 2141 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF,
1987 fmt->which); 2142 fmt->which);
1988 *format = fmt->format; 2143 *format = fmt->format;
@@ -2000,6 +2155,69 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2000} 2155}
2001 2156
2002/* 2157/*
2158 * Decide whether desired output pixel code can be obtained with
2159 * the lane shifter by shifting the input pixel code.
2160 * @in: input pixelcode to shifter
2161 * @out: output pixelcode from shifter
2162 * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0]
2163 *
2164 * return true if the combination is possible
2165 * return false otherwise
2166 */
2167static bool ccdc_is_shiftable(enum v4l2_mbus_pixelcode in,
2168 enum v4l2_mbus_pixelcode out,
2169 unsigned int additional_shift)
2170{
2171 const struct isp_format_info *in_info, *out_info;
2172
2173 if (in == out)
2174 return true;
2175
2176 in_info = omap3isp_video_format_info(in);
2177 out_info = omap3isp_video_format_info(out);
2178
2179 if ((in_info->flavor == 0) || (out_info->flavor == 0))
2180 return false;
2181
2182 if (in_info->flavor != out_info->flavor)
2183 return false;
2184
2185 return in_info->bpp - out_info->bpp + additional_shift <= 6;
2186}
2187
2188static int ccdc_link_validate(struct v4l2_subdev *sd,
2189 struct media_link *link,
2190 struct v4l2_subdev_format *source_fmt,
2191 struct v4l2_subdev_format *sink_fmt)
2192{
2193 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2194 unsigned long parallel_shift;
2195
2196 /* Check if the two ends match */
2197 if (source_fmt->format.width != sink_fmt->format.width ||
2198 source_fmt->format.height != sink_fmt->format.height)
2199 return -EPIPE;
2200
2201 /* We've got a parallel sensor here. */
2202 if (ccdc->input == CCDC_INPUT_PARALLEL) {
2203 struct isp_parallel_platform_data *pdata =
2204 &((struct isp_v4l2_subdevs_group *)
2205 media_entity_to_v4l2_subdev(link->source->entity)
2206 ->host_priv)->bus.parallel;
2207 parallel_shift = pdata->data_lane_shift * 2;
2208 } else {
2209 parallel_shift = 0;
2210 }
2211
2212 /* Lane shifter may be used to drop bits on CCDC sink pad */
2213 if (!ccdc_is_shiftable(source_fmt->format.code,
2214 sink_fmt->format.code, parallel_shift))
2215 return -EPIPE;
2216
2217 return 0;
2218}
2219
2220/*
2003 * ccdc_init_formats - Initialize formats on all pads 2221 * ccdc_init_formats - Initialize formats on all pads
2004 * @sd: ISP CCDC V4L2 subdevice 2222 * @sd: ISP CCDC V4L2 subdevice
2005 * @fh: V4L2 subdev file handle 2223 * @fh: V4L2 subdev file handle
@@ -2041,6 +2259,9 @@ static const struct v4l2_subdev_pad_ops ccdc_v4l2_pad_ops = {
2041 .enum_frame_size = ccdc_enum_frame_size, 2259 .enum_frame_size = ccdc_enum_frame_size,
2042 .get_fmt = ccdc_get_format, 2260 .get_fmt = ccdc_get_format,
2043 .set_fmt = ccdc_set_format, 2261 .set_fmt = ccdc_set_format,
2262 .get_selection = ccdc_get_selection,
2263 .set_selection = ccdc_set_selection,
2264 .link_validate = ccdc_link_validate,
2044}; 2265};
2045 2266
2046/* V4L2 subdev operations */ 2267/* V4L2 subdev operations */
@@ -2150,6 +2371,7 @@ static int ccdc_link_setup(struct media_entity *entity,
2150/* media operations */ 2371/* media operations */
2151static const struct media_entity_operations ccdc_media_ops = { 2372static const struct media_entity_operations ccdc_media_ops = {
2152 .link_setup = ccdc_link_setup, 2373 .link_setup = ccdc_link_setup,
2374 .link_validate = v4l2_subdev_link_validate,
2153}; 2375};
2154 2376
2155void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc) 2377void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
@@ -2276,8 +2498,6 @@ int omap3isp_ccdc_init(struct isp_device *isp)
2276 ccdc->clamp.oblen = 0; 2498 ccdc->clamp.oblen = 0;
2277 ccdc->clamp.dcsubval = 0; 2499 ccdc->clamp.dcsubval = 0;
2278 2500
2279 ccdc->vpcfg.pixelclk = 0;
2280
2281 ccdc->update = OMAP3ISP_CCDC_BLCLAMP; 2501 ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
2282 ccdc_apply_controls(ccdc); 2502 ccdc_apply_controls(ccdc);
2283 2503