Lines Matching +full:v +full:- +full:blanking
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2013-2015 Ideas on Board
6 * Copyright (C) 2013-2015 Xilinx, Inc.
18 #include <linux/xilinx-v4l2-controls.h>
20 #include <media/v4l2-async.h>
21 #include <media/v4l2-ctrls.h>
22 #include <media/v4l2-subdev.h>
24 #include "xilinx-vip.h"
25 #include "xilinx-vtc.h"
63 * The minimum blanking value is one clock cycle for the front porch, one clock
67 #define XTPG_MAX_HBLANK (XVTC_MAX_HSIZE - XVIP_MIN_WIDTH)
69 #define XTPG_MAX_VBLANK (XVTC_MAX_VSIZE - XVIP_MIN_HEIGHT)
72 * struct xtpg_device - Xilinx Test Pattern Generator device structure
82 * @hblank: horizontal blanking control
83 * @vblank: vertical blanking control
135 u32 pattern_mask = (1 << (xtpg->pattern->maximum + 1)) - 1; in __xtpg_update_pattern_control()
141 if (xtpg->npads == 1 || !xtpg->has_input) in __xtpg_update_pattern_control()
152 __v4l2_ctrl_modify_range(xtpg->pattern, 0, xtpg->pattern->maximum, in __xtpg_update_pattern_control()
159 mutex_lock(xtpg->ctrl_handler.lock); in xtpg_update_pattern_control()
161 mutex_unlock(xtpg->ctrl_handler.lock); in xtpg_update_pattern_control()
164 /* -----------------------------------------------------------------------------
171 unsigned int width = xtpg->formats[0].width; in xtpg_s_stream()
172 unsigned int height = xtpg->formats[0].height; in xtpg_s_stream()
177 xvip_stop(&xtpg->xvip); in xtpg_s_stream()
178 if (xtpg->vtc) in xtpg_s_stream()
179 xvtc_generator_stop(xtpg->vtc); in xtpg_s_stream()
182 xtpg->streaming = false; in xtpg_s_stream()
186 xvip_set_frame_size(&xtpg->xvip, &xtpg->formats[0]); in xtpg_s_stream()
188 if (xtpg->vtc) { in xtpg_s_stream()
199 v4l2_ctrl_g_ctrl(xtpg->hblank) + width); in xtpg_s_stream()
201 v4l2_ctrl_g_ctrl(xtpg->vblank) + height); in xtpg_s_stream()
203 config.hsync_end = htotal - 1; in xtpg_s_stream()
205 config.vsync_end = vtotal - 1; in xtpg_s_stream()
208 xvtc_generator_start(xtpg->vtc, &config); in xtpg_s_stream()
217 mutex_lock(xtpg->ctrl_handler.lock); in xtpg_s_stream()
219 xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, in xtpg_s_stream()
220 XTPG_PATTERN_MASK, xtpg->pattern->cur.val); in xtpg_s_stream()
226 passthrough = xtpg->pattern->cur.val == 0; in xtpg_s_stream()
229 xtpg->streaming = true; in xtpg_s_stream()
231 mutex_unlock(xtpg->ctrl_handler.lock); in xtpg_s_stream()
238 : xtpg_get_bayer_phase(xtpg->formats[0].code); in xtpg_s_stream()
239 xvip_write(&xtpg->xvip, XTPG_BAYER_PHASE, bayer_phase); in xtpg_s_stream()
241 if (xtpg->vtmux_gpio) in xtpg_s_stream()
242 gpiod_set_value_cansleep(xtpg->vtmux_gpio, !passthrough); in xtpg_s_stream()
244 xvip_start(&xtpg->xvip); in xtpg_s_stream()
249 /* -----------------------------------------------------------------------------
262 return &xtpg->formats[pad]; in __xtpg_get_pad_format()
274 fmt->format = *__xtpg_get_pad_format(xtpg, sd_state, fmt->pad, in xtpg_get_format()
275 fmt->which); in xtpg_get_format()
288 __format = __xtpg_get_pad_format(xtpg, sd_state, fmt->pad, fmt->which); in xtpg_set_format()
293 if (xtpg->npads == 2 && fmt->pad == 1) { in xtpg_set_format()
294 fmt->format = *__format; in xtpg_set_format()
299 if (xtpg->bayer) { in xtpg_set_format()
300 bayer_phase = xtpg_get_bayer_phase(fmt->format.code); in xtpg_set_format()
302 __format->code = fmt->format.code; in xtpg_set_format()
307 fmt->format = *__format; in xtpg_set_format()
310 if (xtpg->npads == 2) { in xtpg_set_format()
312 fmt->which); in xtpg_set_format()
313 *__format = fmt->format; in xtpg_set_format()
319 /* -----------------------------------------------------------------------------
329 format = v4l2_subdev_state_get_format(sd_state, fse->pad); in xtpg_enum_frame_size()
331 if (fse->index || fse->code != format->code) in xtpg_enum_frame_size()
332 return -EINVAL; in xtpg_enum_frame_size()
337 if (fse->pad == 0) { in xtpg_enum_frame_size()
338 fse->min_width = XVIP_MIN_WIDTH; in xtpg_enum_frame_size()
339 fse->max_width = XVIP_MAX_WIDTH; in xtpg_enum_frame_size()
340 fse->min_height = XVIP_MIN_HEIGHT; in xtpg_enum_frame_size()
341 fse->max_height = XVIP_MAX_HEIGHT; in xtpg_enum_frame_size()
343 fse->min_width = format->width; in xtpg_enum_frame_size()
344 fse->max_width = format->width; in xtpg_enum_frame_size()
345 fse->min_height = format->height; in xtpg_enum_frame_size()
346 fse->max_height = format->height; in xtpg_enum_frame_size()
357 format = v4l2_subdev_state_get_format(fh->state, 0); in xtpg_open()
358 *format = xtpg->default_format; in xtpg_open()
360 if (xtpg->npads == 2) { in xtpg_open()
361 format = v4l2_subdev_state_get_format(fh->state, 1); in xtpg_open()
362 *format = xtpg->default_format; in xtpg_open()
375 struct xtpg_device *xtpg = container_of(ctrl->handler, in xtpg_s_ctrl()
378 switch (ctrl->id) { in xtpg_s_ctrl()
380 xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, in xtpg_s_ctrl()
381 XTPG_PATTERN_MASK, ctrl->val); in xtpg_s_ctrl()
384 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, in xtpg_s_ctrl()
385 XTPG_PATTERN_CONTROL_CROSS_HAIRS, ctrl->val); in xtpg_s_ctrl()
388 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, in xtpg_s_ctrl()
389 XTPG_PATTERN_CONTROL_MOVING_BOX, ctrl->val); in xtpg_s_ctrl()
392 xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, in xtpg_s_ctrl()
394 ctrl->val << in xtpg_s_ctrl()
398 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, in xtpg_s_ctrl()
399 XTPG_PATTERN_CONTROL_STUCK_PIXEL, ctrl->val); in xtpg_s_ctrl()
402 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, in xtpg_s_ctrl()
403 XTPG_PATTERN_CONTROL_NOISE, ctrl->val); in xtpg_s_ctrl()
406 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL, in xtpg_s_ctrl()
407 XTPG_PATTERN_CONTROL_MOTION, ctrl->val); in xtpg_s_ctrl()
410 xvip_write(&xtpg->xvip, XTPG_MOTION_SPEED, ctrl->val); in xtpg_s_ctrl()
413 xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS, in xtpg_s_ctrl()
415 ctrl->val << XTPG_CROSS_HAIRS_ROW_SHIFT); in xtpg_s_ctrl()
418 xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS, in xtpg_s_ctrl()
420 ctrl->val << XTPG_CROSS_HAIRS_COLUMN_SHIFT); in xtpg_s_ctrl()
423 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL, in xtpg_s_ctrl()
425 ctrl->val << XTPG_ZPLATE_START_SHIFT); in xtpg_s_ctrl()
428 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL, in xtpg_s_ctrl()
430 ctrl->val << XTPG_ZPLATE_SPEED_SHIFT); in xtpg_s_ctrl()
433 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL, in xtpg_s_ctrl()
435 ctrl->val << XTPG_ZPLATE_START_SHIFT); in xtpg_s_ctrl()
438 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL, in xtpg_s_ctrl()
440 ctrl->val << XTPG_ZPLATE_SPEED_SHIFT); in xtpg_s_ctrl()
443 xvip_write(&xtpg->xvip, XTPG_BOX_SIZE, ctrl->val); in xtpg_s_ctrl()
446 xvip_write(&xtpg->xvip, XTPG_BOX_COLOR, ctrl->val); in xtpg_s_ctrl()
449 xvip_write(&xtpg->xvip, XTPG_STUCK_PIXEL_THRESH, ctrl->val); in xtpg_s_ctrl()
452 xvip_write(&xtpg->xvip, XTPG_NOISE_GAIN, ctrl->val); in xtpg_s_ctrl()
571 .max = (1 << 8) - 1,
581 .max = (1 << 12) - 1,
591 .max = (1 << 12) - 1,
601 .max = (1 << 16) - 1,
611 .max = (1 << 16) - 1,
621 .max = (1 << 16) - 1,
631 .max = (1 << 16) - 1,
641 .max = (1 << 12) - 1,
651 .max = (1 << 24) - 1,
660 .max = (1 << 16) - 1,
670 .max = (1 << 8) - 1,
677 /* -----------------------------------------------------------------------------
685 /* -----------------------------------------------------------------------------
693 xvip_suspend(&xtpg->xvip); in xtpg_pm_suspend()
702 xvip_resume(&xtpg->xvip); in xtpg_pm_resume()
707 /* -----------------------------------------------------------------------------
713 struct device *dev = xtpg->xvip.dev; in xtpg_parse_of()
714 struct device_node *node = xtpg->xvip.dev->of_node; in xtpg_parse_of()
729 if (!xtpg->vip_format) { in xtpg_parse_of()
730 xtpg->vip_format = format; in xtpg_parse_of()
731 } else if (xtpg->vip_format != format) { in xtpg_parse_of()
733 return -EINVAL; in xtpg_parse_of()
749 return -EINVAL; in xtpg_parse_of()
752 xtpg->npads = nports; in xtpg_parse_of()
754 xtpg->has_input = true; in xtpg_parse_of()
766 xtpg = devm_kzalloc(&pdev->dev, sizeof(*xtpg), GFP_KERNEL); in xtpg_probe()
768 return -ENOMEM; in xtpg_probe()
770 xtpg->xvip.dev = &pdev->dev; in xtpg_probe()
776 ret = xvip_init_resources(&xtpg->xvip); in xtpg_probe()
780 xtpg->vtmux_gpio = devm_gpiod_get_optional(&pdev->dev, "timing", in xtpg_probe()
782 if (IS_ERR(xtpg->vtmux_gpio)) { in xtpg_probe()
783 ret = PTR_ERR(xtpg->vtmux_gpio); in xtpg_probe()
787 xtpg->vtc = xvtc_of_get(pdev->dev.of_node); in xtpg_probe()
788 if (IS_ERR(xtpg->vtc)) { in xtpg_probe()
789 ret = PTR_ERR(xtpg->vtc); in xtpg_probe()
794 xvip_reset(&xtpg->xvip); in xtpg_probe()
799 if (xtpg->npads == 2) { in xtpg_probe()
800 xtpg->pads[0].flags = MEDIA_PAD_FL_SINK; in xtpg_probe()
801 xtpg->pads[1].flags = MEDIA_PAD_FL_SOURCE; in xtpg_probe()
803 xtpg->pads[0].flags = MEDIA_PAD_FL_SOURCE; in xtpg_probe()
807 xtpg->default_format.code = xtpg->vip_format->code; in xtpg_probe()
808 xtpg->default_format.field = V4L2_FIELD_NONE; in xtpg_probe()
809 xtpg->default_format.colorspace = V4L2_COLORSPACE_SRGB; in xtpg_probe()
810 xvip_get_frame_size(&xtpg->xvip, &xtpg->default_format); in xtpg_probe()
812 bayer_phase = xtpg_get_bayer_phase(xtpg->vip_format->code); in xtpg_probe()
814 xtpg->bayer = true; in xtpg_probe()
816 xtpg->formats[0] = xtpg->default_format; in xtpg_probe()
817 if (xtpg->npads == 2) in xtpg_probe()
818 xtpg->formats[1] = xtpg->default_format; in xtpg_probe()
821 subdev = &xtpg->xvip.subdev; in xtpg_probe()
823 subdev->dev = &pdev->dev; in xtpg_probe()
824 subdev->internal_ops = &xtpg_internal_ops; in xtpg_probe()
825 strscpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name)); in xtpg_probe()
827 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in xtpg_probe()
828 subdev->entity.ops = &xtpg_media_ops; in xtpg_probe()
830 ret = media_entity_pads_init(&subdev->entity, xtpg->npads, xtpg->pads); in xtpg_probe()
834 v4l2_ctrl_handler_init(&xtpg->ctrl_handler, 3 + ARRAY_SIZE(xtpg_ctrls)); in xtpg_probe()
836 xtpg->vblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops, in xtpg_probe()
839 xtpg->hblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops, in xtpg_probe()
842 xtpg->pattern = v4l2_ctrl_new_std_menu_items(&xtpg->ctrl_handler, in xtpg_probe()
844 ARRAY_SIZE(xtpg_pattern_strings) - 1, in xtpg_probe()
848 v4l2_ctrl_new_custom(&xtpg->ctrl_handler, &xtpg_ctrls[i], NULL); in xtpg_probe()
850 if (xtpg->ctrl_handler.error) { in xtpg_probe()
851 dev_err(&pdev->dev, "failed to add controls\n"); in xtpg_probe()
852 ret = xtpg->ctrl_handler.error; in xtpg_probe()
855 subdev->ctrl_handler = &xtpg->ctrl_handler; in xtpg_probe()
859 ret = v4l2_ctrl_handler_setup(&xtpg->ctrl_handler); in xtpg_probe()
861 dev_err(&pdev->dev, "failed to set controls\n"); in xtpg_probe()
867 xvip_print_version(&xtpg->xvip); in xtpg_probe()
871 dev_err(&pdev->dev, "failed to register subdev\n"); in xtpg_probe()
878 v4l2_ctrl_handler_free(&xtpg->ctrl_handler); in xtpg_probe()
879 media_entity_cleanup(&subdev->entity); in xtpg_probe()
880 xvtc_put(xtpg->vtc); in xtpg_probe()
882 xvip_cleanup_resources(&xtpg->xvip); in xtpg_probe()
889 struct v4l2_subdev *subdev = &xtpg->xvip.subdev; in xtpg_remove()
892 v4l2_ctrl_handler_free(&xtpg->ctrl_handler); in xtpg_remove()
893 media_entity_cleanup(&subdev->entity); in xtpg_remove()
895 xvip_cleanup_resources(&xtpg->xvip); in xtpg_remove()
901 { .compatible = "xlnx,v-tpg-5.0" },
908 .name = "xilinx-tpg",