27 #include <linux/module.h>
30 #include <linux/device.h>
33 #include <linux/sched.h>
34 #include <linux/slab.h>
41 #define CCDC_MIN_WIDTH 32
42 #define CCDC_MIN_HEIGHT 32
44 static struct v4l2_mbus_framefmt *
48 static const unsigned int ccdc_fmts[] = {
74 #define CCDC_PRINT_REGISTER(isp, name)\
75 dev_dbg(isp->dev, "###CCDC " #name "=0x%08x\n", \
76 isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_##name))
82 dev_dbg(isp->
dev,
"-------------CCDC Register dump-------------\n");
118 dev_dbg(isp->
dev,
"--------------------------------------------\n");
148 struct v4l2_mbus_framefmt *
format;
149 unsigned int paxel_width, paxel_height;
150 unsigned int paxel_shift_x, paxel_shift_y;
152 unsigned int input_width, input_height;
157 if ((paxel_shift_x < 2) || (paxel_shift_x > 6) ||
158 (paxel_shift_y < 2) || (paxel_shift_y > 6)) {
159 dev_dbg(isp->
dev,
"CCDC: LSC: Invalid paxel size\n");
163 if (lsc_cfg->
offset & 3) {
164 dev_dbg(isp->
dev,
"CCDC: LSC: Offset must be a multiple of "
170 dev_dbg(isp->
dev,
"CCDC: LSC: initial_x and y must be even\n");
176 input_width = format->width;
177 input_height = format->height;
180 paxel_width = 1 << paxel_shift_x;
181 min_width = ((input_width + lsc_cfg->
initial_x + paxel_width - 1)
182 >> paxel_shift_x) + 1;
184 paxel_height = 1 << paxel_shift_y;
185 min_height = ((input_height + lsc_cfg->
initial_y + paxel_height - 1)
186 >> paxel_shift_y) + 1;
189 if (min_size > lsc_cfg->
size) {
190 dev_dbg(isp->
dev,
"CCDC: LSC: too small table\n");
193 if (lsc_cfg->
offset < (min_width * 4)) {
194 dev_dbg(isp->
dev,
"CCDC: LSC: Offset is too small\n");
197 if ((lsc_cfg->
size / lsc_cfg->
offset) < min_height) {
198 dev_dbg(isp->
dev,
"CCDC: LSC: Wrong size/offset combination\n");
251 for (wait = 0; wait < 1000; wait++) {
254 isp_reg_writel(isp, IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ,
274 const struct v4l2_mbus_framefmt *format =
291 if (ccdc_lsc_wait_prefetch(ccdc) < 0) {
326 if (ccdc_lsc_validate_config(ccdc, &req->
config) < 0) {
331 if (ccdc_lsc_busy(ccdc))
334 ccdc_lsc_setup_regs(ccdc, &req->
config);
335 ccdc_lsc_program_table(ccdc, req->
table);
387 spin_unlock_irqrestore(&ccdc->
lsc.req_lock, flags);
388 ccdc_lsc_free_request(ccdc, req);
391 spin_unlock_irqrestore(&ccdc->
lsc.req_lock, flags);
429 "need to be supplied\n", __func__);
481 if (ccdc->
lsc.request) {
486 spin_unlock_irqrestore(&ccdc->
lsc.req_lock, flags);
492 ccdc_lsc_free_request(ccdc, req);
502 if (ccdc->
lsc.active) {
503 spin_unlock_irqrestore(&ccdc->
lsc.req_lock, flags);
506 spin_unlock_irqrestore(&ccdc->
lsc.req_lock, flags);
522 if (__ccdc_lsc_configure(ccdc, lsc->
request) < 0) {
532 __ccdc_lsc_enable(ccdc, 1);
564 isp_reg_writel(isp, ccdc->
clamp.dcsubval,
637 switch (info->
width) {
690 spin_unlock_irqrestore(&ccdc->
lock, flags);
704 sizeof(ccdc->
clamp))) {
744 size = ccdc->
fpc.fpnum * 4;
752 ccdc->
fpc.fpcaddr, size)) {
758 table_old = ccdc->
fpc.fpcaddr;
759 ccdc->
fpc.fpcaddr = table_new;
762 ccdc_configure_fpc(ccdc);
767 return ccdc_lsc_config(ccdc, ccdc_struct);
773 ccdc_configure_alaw(ccdc);
778 ccdc_configure_lpf(ccdc);
783 ccdc_configure_clamp(ccdc);
788 ccdc_configure_black_comp(ccdc);
805 ccdc_apply_controls(ccdc);
806 ccdc_configure_fpc(ccdc);
822 unsigned long l3_ick = pipe->
l3_ick;
824 unsigned int div = 0;
832 switch (info->
width) {
853 div =
clamp(div, 2
U, max_div);
894 isp_reg_writel(isp, offset & 0xffff,
947 unsigned int *max_rate)
960 rate = pipe->
l3_ick / 2 * 9 / 10;
964 *max_rate =
min(*max_rate, rate);
978 const struct v4l2_mbus_framefmt *
format;
1009 if (pdata && pdata->
hs_pol)
1012 if (pdata && pdata->
vs_pol)
1032 static const u32 ccdc_sgrbg_pattern =
1050 static const u32 ccdc_srggb_pattern =
1068 static const u32 ccdc_sbggr_pattern =
1086 static const u32 ccdc_sgbrg_pattern =
1109 struct v4l2_mbus_framefmt *
format;
1113 unsigned int depth_out;
1114 unsigned int depth_in = 0;
1116 unsigned long flags;
1131 fmt_src.pad = pad->
index;
1135 depth_in = fmt_info->
width;
1140 depth_out = fmt_info->
width;
1141 shift = depth_in - depth_out;
1152 ccdc_config_sync_if(ccdc, pdata, depth_out);
1175 switch (format->code) {
1178 ccdc_pattern = ccdc_srggb_pattern;
1182 ccdc_pattern = ccdc_sbggr_pattern;
1186 ccdc_pattern = ccdc_sgbrg_pattern;
1190 ccdc_pattern = ccdc_sgrbg_pattern;
1193 ccdc_config_imgattr(ccdc, ccdc_pattern);
1211 isp_reg_writel(isp, (crop->
height - 1)
1215 ccdc_config_outlineoffset(ccdc, ccdc->
video_out.bpl_value, 0, 0);
1251 if (ccdc->
lsc.request ==
NULL)
1259 if (ccdc->
lsc.active ==
NULL &&
1260 __ccdc_lsc_configure(ccdc, ccdc->
lsc.request) == 0) {
1261 ccdc->
lsc.active = ccdc->
lsc.request;
1270 spin_unlock_irqrestore(&ccdc->
lsc.req_lock, flags);
1272 ccdc_apply_controls(ccdc);
1285 unsigned long flags;
1291 spin_unlock_irqrestore(&ccdc->
lock, flags);
1304 ccdc_lsc_free_request(ccdc, ccdc->
lsc.request);
1305 ccdc->
lsc.request = ccdc->
lsc.active;
1308 ccdc_lsc_free_queue(ccdc, &ccdc->
lsc.free_queue);
1313 return ret > 0 ? 0 :
ret;
1318 if (ccdc_lsc_is_configured(ccdc))
1319 __ccdc_lsc_enable(ccdc, 1);
1320 __ccdc_enable(ccdc, 1);
1355 unsigned int max_wait)
1357 unsigned int wait = 0;
1362 for (wait = 0; wait <= max_wait; wait++) {
1363 if (!ccdc_sbl_busy(ccdc))
1384 switch ((ccdc->
stopping & 3) | event) {
1387 __ccdc_lsc_enable(ccdc, 0);
1388 __ccdc_enable(ccdc, 0);
1425 memset(&event, 0,
sizeof(event));
1439 unsigned long flags;
1443 to_isp_pipeline(&ccdc->
subdev.entity);
1445 ccdc_lsc_error_handler(ccdc);
1481 if (ccdc->
lsc.request ==
NULL)
1484 ccdc_lsc_enable(ccdc);
1487 spin_unlock_irqrestore(&ccdc->
lsc.req_lock, flags);
1503 if (list_empty(&ccdc->
video_out.dmaqueue))
1516 if (ccdc_sbl_wait_idle(ccdc, 1000)) {
1522 if (buffer !=
NULL) {
1523 ccdc_set_outaddr(ccdc, buffer->
isp_addr);
1530 isp_pipeline_ready(pipe))
1546 unsigned long flags;
1550 restart = ccdc_isr_buffer(ccdc);
1554 spin_unlock_irqrestore(&ccdc->
lock, flags);
1559 ccdc_apply_controls(ccdc);
1560 spin_unlock_irqrestore(&ccdc->
lock, flags);
1572 unsigned long flags;
1586 switch (ccdc->
state) {
1594 __ccdc_lsc_enable(ccdc, 0);
1595 __ccdc_enable(ccdc, 0);
1606 if (ccdc->
lsc.request ==
NULL)
1614 __ccdc_lsc_enable(ccdc, 0);
1621 ccdc_lsc_enable(ccdc);
1624 spin_unlock_irqrestore(&ccdc->
lsc.req_lock, flags);
1640 ccdc_lsc_isr(ccdc, events);
1645 if (events & IRQ0STATUS_HS_VS_IRQ)
1646 ccdc_hs_vs_isr(ccdc);
1662 ccdc_set_outaddr(ccdc, buffer->
isp_addr);
1674 .queue = ccdc_video_queue,
1739 static int ccdc_set_stream(
struct v4l2_subdev *sd,
int enable)
1753 ccdc_configure(ccdc);
1758 ccdc_config_vp(ccdc);
1759 ccdc_enable_vp(ccdc, 1);
1760 ccdc_print_status(ccdc);
1783 ret = ccdc_disable(ccdc);
1795 static struct v4l2_mbus_framefmt *
1800 return v4l2_subdev_get_try_format(fh, pad);
1824 unsigned int pad,
struct v4l2_mbus_framefmt *
fmt,
1829 unsigned int width = fmt->width;
1830 unsigned int height = fmt->height;
1836 for (i = 0; i <
ARRAY_SIZE(ccdc_fmts); i++) {
1837 if (fmt->code == ccdc_fmts[i])
1847 fmt->height =
clamp_t(
u32, height, 32, 4096);
1851 pixelcode = fmt->code;
1864 fmt->code = pixelcode;
1873 crop = __ccdc_get_crop(ccdc, fh, which);
1874 fmt->width = crop->
width;
1875 fmt->height = crop->
height;
1894 fmt->width =
clamp_t(
u32, width, 32, fmt->width);
1895 fmt->height =
clamp_t(
u32, height, 32, fmt->height - 1);
1913 const struct v4l2_mbus_framefmt *
sink,
1936 max_width = (sink->width - crop->
left + 15) & ~15;
1940 sink->height - crop->
top);
1956 static int ccdc_enum_mbus_code(
struct v4l2_subdev *sd,
1958 struct v4l2_subdev_mbus_code_enum *
code)
1961 struct v4l2_mbus_framefmt *
format;
1963 switch (code->pad) {
1968 code->code = ccdc_fmts[code->index];
1972 format = __ccdc_get_format(ccdc, fh, code->pad,
1978 if (code->index == 0)
1980 else if (code->index == 1)
1988 if (code->index == 0)
1989 code->code = format->code;
2000 if (code->index != 0)
2003 format = __ccdc_get_format(ccdc, fh, code->pad,
2009 if (format->code == 0)
2012 code->code = format->code;
2022 static int ccdc_enum_frame_size(
struct v4l2_subdev *sd,
2024 struct v4l2_subdev_frame_size_enum *fse)
2027 struct v4l2_mbus_framefmt format;
2029 if (fse->index != 0)
2032 format.code = fse->code;
2036 fse->min_width = format.width;
2037 fse->min_height = format.height;
2039 if (format.code != fse->code)
2042 format.code = fse->code;
2046 fse->max_width = format.width;
2047 fse->max_height = format.height;
2064 struct v4l2_subdev_selection *
sel)
2067 struct v4l2_mbus_framefmt *
format;
2072 switch (sel->target) {
2079 format = __ccdc_get_format(ccdc, fh,
CCDC_PAD_SINK, sel->which);
2080 ccdc_try_crop(ccdc, format, &sel->r);
2084 sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
2106 struct v4l2_subdev_selection *sel)
2109 struct v4l2_mbus_framefmt *
format;
2124 sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
2128 format = __ccdc_get_format(ccdc, fh,
CCDC_PAD_SINK, sel->which);
2129 ccdc_try_crop(ccdc, format, &sel->r);
2130 *__ccdc_get_crop(ccdc, fh, sel->which) = sel->r;
2152 struct v4l2_mbus_framefmt *
format;
2154 format = __ccdc_get_format(ccdc, fh, fmt->
pad, fmt->
which);
2175 struct v4l2_mbus_framefmt *
format;
2178 format = __ccdc_get_format(ccdc, fh, fmt->
pad, fmt->
which);
2188 crop = __ccdc_get_crop(ccdc, fh, fmt->
which);
2194 ccdc_try_crop(ccdc, &fmt->
format, crop);
2225 unsigned int additional_shift)
2241 return in_info->
width - out_info->
width + additional_shift <= 6;
2244 static int ccdc_link_validate(
struct v4l2_subdev *sd,
2250 unsigned long parallel_shift;
2253 if (source_fmt->
format.width != sink_fmt->
format.width ||
2262 ->host_priv)->
bus.parallel;
2269 if (!ccdc_is_shiftable(source_fmt->
format.code,
2270 sink_fmt->
format.code, parallel_shift))
2289 memset(&format, 0,
sizeof(format));
2293 format.format.width = 4096;
2294 format.format.height = 4096;
2295 ccdc_set_format(sd, fh, &format);
2302 .ioctl = ccdc_ioctl,
2303 .subscribe_event = ccdc_subscribe_event,
2304 .unsubscribe_event = ccdc_unsubscribe_event,
2309 .s_stream = ccdc_set_stream,
2314 .enum_mbus_code = ccdc_enum_mbus_code,
2315 .enum_frame_size = ccdc_enum_frame_size,
2316 .get_fmt = ccdc_get_format,
2317 .set_fmt = ccdc_set_format,
2318 .get_selection = ccdc_get_selection,
2319 .set_selection = ccdc_set_selection,
2320 .link_validate = ccdc_link_validate,
2325 .core = &ccdc_v4l2_core_ops,
2326 .video = &ccdc_v4l2_video_ops,
2327 .pad = &ccdc_v4l2_pad_ops,
2332 .open = ccdc_init_formats,
2348 static int ccdc_link_setup(
struct media_entity *entity,
2356 switch (local->
index | media_entity_type(remote->
entity)) {
2389 if (flags & MEDIA_LNK_FL_ENABLED) {
2400 if (flags & MEDIA_LNK_FL_ENABLED) {
2411 if (flags & MEDIA_LNK_FL_ENABLED) {
2429 .link_setup = ccdc_link_setup,
2430 .link_validate = v4l2_subdev_link_validate,
2483 v4l2_set_subdevdata(sd, ccdc);
2490 me->
ops = &ccdc_media_ops;
2495 ccdc_init_formats(sd,
NULL);
2541 INIT_WORK(&ccdc->
lsc.table_work, ccdc_lsc_free_table_work);
2543 INIT_LIST_HEAD(&ccdc->
lsc.free_queue);
2546 ccdc->
clamp.oblen = 0;
2547 ccdc->
clamp.dcsubval = 0;
2550 ccdc_apply_controls(ccdc);
2552 ret = ccdc_init_entities(ccdc);
2575 ccdc_lsc_free_request(ccdc, ccdc->
lsc.request);
2577 ccdc_lsc_free_queue(ccdc, &ccdc->
lsc.free_queue);
2579 if (ccdc->
fpc.fpcaddr != 0)