18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * v4l2-tpg.h - Test Pattern Generator
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef _V4L2_TPG_H_
98c2ecf20Sopenharmony_ci#define _V4L2_TPG_H_
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/types.h>
128c2ecf20Sopenharmony_ci#include <linux/errno.h>
138c2ecf20Sopenharmony_ci#include <linux/random.h>
148c2ecf20Sopenharmony_ci#include <linux/slab.h>
158c2ecf20Sopenharmony_ci#include <linux/vmalloc.h>
168c2ecf20Sopenharmony_ci#include <linux/videodev2.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistruct tpg_rbg_color8 {
198c2ecf20Sopenharmony_ci	unsigned char r, g, b;
208c2ecf20Sopenharmony_ci};
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistruct tpg_rbg_color16 {
238c2ecf20Sopenharmony_ci	__u16 r, g, b;
248c2ecf20Sopenharmony_ci};
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_cienum tpg_color {
278c2ecf20Sopenharmony_ci	TPG_COLOR_CSC_WHITE,
288c2ecf20Sopenharmony_ci	TPG_COLOR_CSC_YELLOW,
298c2ecf20Sopenharmony_ci	TPG_COLOR_CSC_CYAN,
308c2ecf20Sopenharmony_ci	TPG_COLOR_CSC_GREEN,
318c2ecf20Sopenharmony_ci	TPG_COLOR_CSC_MAGENTA,
328c2ecf20Sopenharmony_ci	TPG_COLOR_CSC_RED,
338c2ecf20Sopenharmony_ci	TPG_COLOR_CSC_BLUE,
348c2ecf20Sopenharmony_ci	TPG_COLOR_CSC_BLACK,
358c2ecf20Sopenharmony_ci	TPG_COLOR_75_YELLOW,
368c2ecf20Sopenharmony_ci	TPG_COLOR_75_CYAN,
378c2ecf20Sopenharmony_ci	TPG_COLOR_75_GREEN,
388c2ecf20Sopenharmony_ci	TPG_COLOR_75_MAGENTA,
398c2ecf20Sopenharmony_ci	TPG_COLOR_75_RED,
408c2ecf20Sopenharmony_ci	TPG_COLOR_75_BLUE,
418c2ecf20Sopenharmony_ci	TPG_COLOR_100_WHITE,
428c2ecf20Sopenharmony_ci	TPG_COLOR_100_YELLOW,
438c2ecf20Sopenharmony_ci	TPG_COLOR_100_CYAN,
448c2ecf20Sopenharmony_ci	TPG_COLOR_100_GREEN,
458c2ecf20Sopenharmony_ci	TPG_COLOR_100_MAGENTA,
468c2ecf20Sopenharmony_ci	TPG_COLOR_100_RED,
478c2ecf20Sopenharmony_ci	TPG_COLOR_100_BLUE,
488c2ecf20Sopenharmony_ci	TPG_COLOR_100_BLACK,
498c2ecf20Sopenharmony_ci	TPG_COLOR_TEXTFG,
508c2ecf20Sopenharmony_ci	TPG_COLOR_TEXTBG,
518c2ecf20Sopenharmony_ci	TPG_COLOR_RANDOM,
528c2ecf20Sopenharmony_ci	TPG_COLOR_RAMP,
538c2ecf20Sopenharmony_ci	TPG_COLOR_MAX = TPG_COLOR_RAMP + 256
548c2ecf20Sopenharmony_ci};
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ciextern const struct tpg_rbg_color8 tpg_colors[TPG_COLOR_MAX];
578c2ecf20Sopenharmony_ciextern const unsigned short tpg_rec709_to_linear[255 * 16 + 1];
588c2ecf20Sopenharmony_ciextern const unsigned short tpg_linear_to_rec709[255 * 16 + 1];
598c2ecf20Sopenharmony_ciextern const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1]
608c2ecf20Sopenharmony_ci					  [V4L2_XFER_FUNC_SMPTE2084 + 1]
618c2ecf20Sopenharmony_ci					  [TPG_COLOR_CSC_BLACK + 1];
628c2ecf20Sopenharmony_cienum tpg_pattern {
638c2ecf20Sopenharmony_ci	TPG_PAT_75_COLORBAR,
648c2ecf20Sopenharmony_ci	TPG_PAT_100_COLORBAR,
658c2ecf20Sopenharmony_ci	TPG_PAT_CSC_COLORBAR,
668c2ecf20Sopenharmony_ci	TPG_PAT_100_HCOLORBAR,
678c2ecf20Sopenharmony_ci	TPG_PAT_100_COLORSQUARES,
688c2ecf20Sopenharmony_ci	TPG_PAT_BLACK,
698c2ecf20Sopenharmony_ci	TPG_PAT_WHITE,
708c2ecf20Sopenharmony_ci	TPG_PAT_RED,
718c2ecf20Sopenharmony_ci	TPG_PAT_GREEN,
728c2ecf20Sopenharmony_ci	TPG_PAT_BLUE,
738c2ecf20Sopenharmony_ci	TPG_PAT_CHECKERS_16X16,
748c2ecf20Sopenharmony_ci	TPG_PAT_CHECKERS_2X2,
758c2ecf20Sopenharmony_ci	TPG_PAT_CHECKERS_1X1,
768c2ecf20Sopenharmony_ci	TPG_PAT_COLOR_CHECKERS_2X2,
778c2ecf20Sopenharmony_ci	TPG_PAT_COLOR_CHECKERS_1X1,
788c2ecf20Sopenharmony_ci	TPG_PAT_ALTERNATING_HLINES,
798c2ecf20Sopenharmony_ci	TPG_PAT_ALTERNATING_VLINES,
808c2ecf20Sopenharmony_ci	TPG_PAT_CROSS_1_PIXEL,
818c2ecf20Sopenharmony_ci	TPG_PAT_CROSS_2_PIXELS,
828c2ecf20Sopenharmony_ci	TPG_PAT_CROSS_10_PIXELS,
838c2ecf20Sopenharmony_ci	TPG_PAT_GRAY_RAMP,
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	/* Must be the last pattern */
868c2ecf20Sopenharmony_ci	TPG_PAT_NOISE,
878c2ecf20Sopenharmony_ci};
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ciextern const char * const tpg_pattern_strings[];
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_cienum tpg_quality {
928c2ecf20Sopenharmony_ci	TPG_QUAL_COLOR,
938c2ecf20Sopenharmony_ci	TPG_QUAL_GRAY,
948c2ecf20Sopenharmony_ci	TPG_QUAL_NOISE
958c2ecf20Sopenharmony_ci};
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cienum tpg_video_aspect {
988c2ecf20Sopenharmony_ci	TPG_VIDEO_ASPECT_IMAGE,
998c2ecf20Sopenharmony_ci	TPG_VIDEO_ASPECT_4X3,
1008c2ecf20Sopenharmony_ci	TPG_VIDEO_ASPECT_14X9_CENTRE,
1018c2ecf20Sopenharmony_ci	TPG_VIDEO_ASPECT_16X9_CENTRE,
1028c2ecf20Sopenharmony_ci	TPG_VIDEO_ASPECT_16X9_ANAMORPHIC,
1038c2ecf20Sopenharmony_ci};
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cienum tpg_pixel_aspect {
1068c2ecf20Sopenharmony_ci	TPG_PIXEL_ASPECT_SQUARE,
1078c2ecf20Sopenharmony_ci	TPG_PIXEL_ASPECT_NTSC,
1088c2ecf20Sopenharmony_ci	TPG_PIXEL_ASPECT_PAL,
1098c2ecf20Sopenharmony_ci};
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_cienum tpg_move_mode {
1128c2ecf20Sopenharmony_ci	TPG_MOVE_NEG_FAST,
1138c2ecf20Sopenharmony_ci	TPG_MOVE_NEG,
1148c2ecf20Sopenharmony_ci	TPG_MOVE_NEG_SLOW,
1158c2ecf20Sopenharmony_ci	TPG_MOVE_NONE,
1168c2ecf20Sopenharmony_ci	TPG_MOVE_POS_SLOW,
1178c2ecf20Sopenharmony_ci	TPG_MOVE_POS,
1188c2ecf20Sopenharmony_ci	TPG_MOVE_POS_FAST,
1198c2ecf20Sopenharmony_ci};
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_cienum tgp_color_enc {
1228c2ecf20Sopenharmony_ci	TGP_COLOR_ENC_RGB,
1238c2ecf20Sopenharmony_ci	TGP_COLOR_ENC_YCBCR,
1248c2ecf20Sopenharmony_ci	TGP_COLOR_ENC_HSV,
1258c2ecf20Sopenharmony_ci	TGP_COLOR_ENC_LUMA,
1268c2ecf20Sopenharmony_ci};
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ciextern const char * const tpg_aspect_strings[];
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci#define TPG_MAX_PLANES 3
1318c2ecf20Sopenharmony_ci#define TPG_MAX_PAT_LINES 8
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_cistruct tpg_data {
1348c2ecf20Sopenharmony_ci	/* Source frame size */
1358c2ecf20Sopenharmony_ci	unsigned			src_width, src_height;
1368c2ecf20Sopenharmony_ci	/* Buffer height */
1378c2ecf20Sopenharmony_ci	unsigned			buf_height;
1388c2ecf20Sopenharmony_ci	/* Scaled output frame size */
1398c2ecf20Sopenharmony_ci	unsigned			scaled_width;
1408c2ecf20Sopenharmony_ci	u32				field;
1418c2ecf20Sopenharmony_ci	bool				field_alternate;
1428c2ecf20Sopenharmony_ci	/* crop coordinates are frame-based */
1438c2ecf20Sopenharmony_ci	struct v4l2_rect		crop;
1448c2ecf20Sopenharmony_ci	/* compose coordinates are format-based */
1458c2ecf20Sopenharmony_ci	struct v4l2_rect		compose;
1468c2ecf20Sopenharmony_ci	/* border and square coordinates are frame-based */
1478c2ecf20Sopenharmony_ci	struct v4l2_rect		border;
1488c2ecf20Sopenharmony_ci	struct v4l2_rect		square;
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	/* Color-related fields */
1518c2ecf20Sopenharmony_ci	enum tpg_quality		qual;
1528c2ecf20Sopenharmony_ci	unsigned			qual_offset;
1538c2ecf20Sopenharmony_ci	u8				alpha_component;
1548c2ecf20Sopenharmony_ci	bool				alpha_red_only;
1558c2ecf20Sopenharmony_ci	u8				brightness;
1568c2ecf20Sopenharmony_ci	u8				contrast;
1578c2ecf20Sopenharmony_ci	u8				saturation;
1588c2ecf20Sopenharmony_ci	s16				hue;
1598c2ecf20Sopenharmony_ci	u32				fourcc;
1608c2ecf20Sopenharmony_ci	enum tgp_color_enc		color_enc;
1618c2ecf20Sopenharmony_ci	u32				colorspace;
1628c2ecf20Sopenharmony_ci	u32				xfer_func;
1638c2ecf20Sopenharmony_ci	u32				ycbcr_enc;
1648c2ecf20Sopenharmony_ci	u32				hsv_enc;
1658c2ecf20Sopenharmony_ci	/*
1668c2ecf20Sopenharmony_ci	 * Stores the actual transfer function, i.e. will never be
1678c2ecf20Sopenharmony_ci	 * V4L2_XFER_FUNC_DEFAULT.
1688c2ecf20Sopenharmony_ci	 */
1698c2ecf20Sopenharmony_ci	u32				real_xfer_func;
1708c2ecf20Sopenharmony_ci	/*
1718c2ecf20Sopenharmony_ci	 * Stores the actual Y'CbCr encoding, i.e. will never be
1728c2ecf20Sopenharmony_ci	 * V4L2_YCBCR_ENC_DEFAULT.
1738c2ecf20Sopenharmony_ci	 */
1748c2ecf20Sopenharmony_ci	u32				real_hsv_enc;
1758c2ecf20Sopenharmony_ci	u32				real_ycbcr_enc;
1768c2ecf20Sopenharmony_ci	u32				quantization;
1778c2ecf20Sopenharmony_ci	/*
1788c2ecf20Sopenharmony_ci	 * Stores the actual quantization, i.e. will never be
1798c2ecf20Sopenharmony_ci	 * V4L2_QUANTIZATION_DEFAULT.
1808c2ecf20Sopenharmony_ci	 */
1818c2ecf20Sopenharmony_ci	u32				real_quantization;
1828c2ecf20Sopenharmony_ci	enum tpg_video_aspect		vid_aspect;
1838c2ecf20Sopenharmony_ci	enum tpg_pixel_aspect		pix_aspect;
1848c2ecf20Sopenharmony_ci	unsigned			rgb_range;
1858c2ecf20Sopenharmony_ci	unsigned			real_rgb_range;
1868c2ecf20Sopenharmony_ci	unsigned			buffers;
1878c2ecf20Sopenharmony_ci	unsigned			planes;
1888c2ecf20Sopenharmony_ci	bool				interleaved;
1898c2ecf20Sopenharmony_ci	u8				vdownsampling[TPG_MAX_PLANES];
1908c2ecf20Sopenharmony_ci	u8				hdownsampling[TPG_MAX_PLANES];
1918c2ecf20Sopenharmony_ci	/*
1928c2ecf20Sopenharmony_ci	 * horizontal positions must be ANDed with this value to enforce
1938c2ecf20Sopenharmony_ci	 * correct boundaries for packed YUYV values.
1948c2ecf20Sopenharmony_ci	 */
1958c2ecf20Sopenharmony_ci	unsigned			hmask[TPG_MAX_PLANES];
1968c2ecf20Sopenharmony_ci	/* Used to store the colors in native format, either RGB or YUV */
1978c2ecf20Sopenharmony_ci	u8				colors[TPG_COLOR_MAX][3];
1988c2ecf20Sopenharmony_ci	u8				textfg[TPG_MAX_PLANES][8], textbg[TPG_MAX_PLANES][8];
1998c2ecf20Sopenharmony_ci	/* size in bytes for two pixels in each plane */
2008c2ecf20Sopenharmony_ci	unsigned			twopixelsize[TPG_MAX_PLANES];
2018c2ecf20Sopenharmony_ci	unsigned			bytesperline[TPG_MAX_PLANES];
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	/* Configuration */
2048c2ecf20Sopenharmony_ci	enum tpg_pattern		pattern;
2058c2ecf20Sopenharmony_ci	bool				hflip;
2068c2ecf20Sopenharmony_ci	bool				vflip;
2078c2ecf20Sopenharmony_ci	unsigned			perc_fill;
2088c2ecf20Sopenharmony_ci	bool				perc_fill_blank;
2098c2ecf20Sopenharmony_ci	bool				show_border;
2108c2ecf20Sopenharmony_ci	bool				show_square;
2118c2ecf20Sopenharmony_ci	bool				insert_sav;
2128c2ecf20Sopenharmony_ci	bool				insert_eav;
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	/* Test pattern movement */
2158c2ecf20Sopenharmony_ci	enum tpg_move_mode		mv_hor_mode;
2168c2ecf20Sopenharmony_ci	int				mv_hor_count;
2178c2ecf20Sopenharmony_ci	int				mv_hor_step;
2188c2ecf20Sopenharmony_ci	enum tpg_move_mode		mv_vert_mode;
2198c2ecf20Sopenharmony_ci	int				mv_vert_count;
2208c2ecf20Sopenharmony_ci	int				mv_vert_step;
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	bool				recalc_colors;
2238c2ecf20Sopenharmony_ci	bool				recalc_lines;
2248c2ecf20Sopenharmony_ci	bool				recalc_square_border;
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci	/* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */
2278c2ecf20Sopenharmony_ci	unsigned			max_line_width;
2288c2ecf20Sopenharmony_ci	u8				*lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
2298c2ecf20Sopenharmony_ci	u8				*downsampled_lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
2308c2ecf20Sopenharmony_ci	u8				*random_line[TPG_MAX_PLANES];
2318c2ecf20Sopenharmony_ci	u8				*contrast_line[TPG_MAX_PLANES];
2328c2ecf20Sopenharmony_ci	u8				*black_line[TPG_MAX_PLANES];
2338c2ecf20Sopenharmony_ci};
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_civoid tpg_init(struct tpg_data *tpg, unsigned w, unsigned h);
2368c2ecf20Sopenharmony_ciint tpg_alloc(struct tpg_data *tpg, unsigned max_w);
2378c2ecf20Sopenharmony_civoid tpg_free(struct tpg_data *tpg);
2388c2ecf20Sopenharmony_civoid tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
2398c2ecf20Sopenharmony_ci		       u32 field);
2408c2ecf20Sopenharmony_civoid tpg_log_status(struct tpg_data *tpg);
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_civoid tpg_set_font(const u8 *f);
2438c2ecf20Sopenharmony_civoid tpg_gen_text(const struct tpg_data *tpg,
2448c2ecf20Sopenharmony_ci		u8 *basep[TPG_MAX_PLANES][2], int y, int x, const char *text);
2458c2ecf20Sopenharmony_civoid tpg_calc_text_basep(struct tpg_data *tpg,
2468c2ecf20Sopenharmony_ci		u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf);
2478c2ecf20Sopenharmony_ciunsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line);
2488c2ecf20Sopenharmony_civoid tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
2498c2ecf20Sopenharmony_ci			   unsigned p, u8 *vbuf);
2508c2ecf20Sopenharmony_civoid tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std,
2518c2ecf20Sopenharmony_ci		    unsigned p, u8 *vbuf);
2528c2ecf20Sopenharmony_cibool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc);
2538c2ecf20Sopenharmony_civoid tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
2548c2ecf20Sopenharmony_ci		const struct v4l2_rect *compose);
2558c2ecf20Sopenharmony_ciconst char *tpg_g_color_order(const struct tpg_data *tpg);
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_cistatic inline void tpg_s_pattern(struct tpg_data *tpg, enum tpg_pattern pattern)
2588c2ecf20Sopenharmony_ci{
2598c2ecf20Sopenharmony_ci	if (tpg->pattern == pattern)
2608c2ecf20Sopenharmony_ci		return;
2618c2ecf20Sopenharmony_ci	tpg->pattern = pattern;
2628c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
2638c2ecf20Sopenharmony_ci}
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_cistatic inline void tpg_s_quality(struct tpg_data *tpg,
2668c2ecf20Sopenharmony_ci				    enum tpg_quality qual, unsigned qual_offset)
2678c2ecf20Sopenharmony_ci{
2688c2ecf20Sopenharmony_ci	if (tpg->qual == qual && tpg->qual_offset == qual_offset)
2698c2ecf20Sopenharmony_ci		return;
2708c2ecf20Sopenharmony_ci	tpg->qual = qual;
2718c2ecf20Sopenharmony_ci	tpg->qual_offset = qual_offset;
2728c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
2738c2ecf20Sopenharmony_ci}
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_cistatic inline enum tpg_quality tpg_g_quality(const struct tpg_data *tpg)
2768c2ecf20Sopenharmony_ci{
2778c2ecf20Sopenharmony_ci	return tpg->qual;
2788c2ecf20Sopenharmony_ci}
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_cistatic inline void tpg_s_alpha_component(struct tpg_data *tpg,
2818c2ecf20Sopenharmony_ci					    u8 alpha_component)
2828c2ecf20Sopenharmony_ci{
2838c2ecf20Sopenharmony_ci	if (tpg->alpha_component == alpha_component)
2848c2ecf20Sopenharmony_ci		return;
2858c2ecf20Sopenharmony_ci	tpg->alpha_component = alpha_component;
2868c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
2878c2ecf20Sopenharmony_ci}
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_cistatic inline void tpg_s_alpha_mode(struct tpg_data *tpg,
2908c2ecf20Sopenharmony_ci					    bool red_only)
2918c2ecf20Sopenharmony_ci{
2928c2ecf20Sopenharmony_ci	if (tpg->alpha_red_only == red_only)
2938c2ecf20Sopenharmony_ci		return;
2948c2ecf20Sopenharmony_ci	tpg->alpha_red_only = red_only;
2958c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
2968c2ecf20Sopenharmony_ci}
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_cistatic inline void tpg_s_brightness(struct tpg_data *tpg,
2998c2ecf20Sopenharmony_ci					u8 brightness)
3008c2ecf20Sopenharmony_ci{
3018c2ecf20Sopenharmony_ci	if (tpg->brightness == brightness)
3028c2ecf20Sopenharmony_ci		return;
3038c2ecf20Sopenharmony_ci	tpg->brightness = brightness;
3048c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
3058c2ecf20Sopenharmony_ci}
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_cistatic inline void tpg_s_contrast(struct tpg_data *tpg,
3088c2ecf20Sopenharmony_ci					u8 contrast)
3098c2ecf20Sopenharmony_ci{
3108c2ecf20Sopenharmony_ci	if (tpg->contrast == contrast)
3118c2ecf20Sopenharmony_ci		return;
3128c2ecf20Sopenharmony_ci	tpg->contrast = contrast;
3138c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
3148c2ecf20Sopenharmony_ci}
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_cistatic inline void tpg_s_saturation(struct tpg_data *tpg,
3178c2ecf20Sopenharmony_ci					u8 saturation)
3188c2ecf20Sopenharmony_ci{
3198c2ecf20Sopenharmony_ci	if (tpg->saturation == saturation)
3208c2ecf20Sopenharmony_ci		return;
3218c2ecf20Sopenharmony_ci	tpg->saturation = saturation;
3228c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
3238c2ecf20Sopenharmony_ci}
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_cistatic inline void tpg_s_hue(struct tpg_data *tpg,
3268c2ecf20Sopenharmony_ci					s16 hue)
3278c2ecf20Sopenharmony_ci{
3288c2ecf20Sopenharmony_ci	hue = clamp_t(s16, hue, -128, 128);
3298c2ecf20Sopenharmony_ci	if (tpg->hue == hue)
3308c2ecf20Sopenharmony_ci		return;
3318c2ecf20Sopenharmony_ci	tpg->hue = hue;
3328c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
3338c2ecf20Sopenharmony_ci}
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_cistatic inline void tpg_s_rgb_range(struct tpg_data *tpg,
3368c2ecf20Sopenharmony_ci					unsigned rgb_range)
3378c2ecf20Sopenharmony_ci{
3388c2ecf20Sopenharmony_ci	if (tpg->rgb_range == rgb_range)
3398c2ecf20Sopenharmony_ci		return;
3408c2ecf20Sopenharmony_ci	tpg->rgb_range = rgb_range;
3418c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
3428c2ecf20Sopenharmony_ci}
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_cistatic inline void tpg_s_real_rgb_range(struct tpg_data *tpg,
3458c2ecf20Sopenharmony_ci					unsigned rgb_range)
3468c2ecf20Sopenharmony_ci{
3478c2ecf20Sopenharmony_ci	if (tpg->real_rgb_range == rgb_range)
3488c2ecf20Sopenharmony_ci		return;
3498c2ecf20Sopenharmony_ci	tpg->real_rgb_range = rgb_range;
3508c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
3518c2ecf20Sopenharmony_ci}
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_cistatic inline void tpg_s_colorspace(struct tpg_data *tpg, u32 colorspace)
3548c2ecf20Sopenharmony_ci{
3558c2ecf20Sopenharmony_ci	if (tpg->colorspace == colorspace)
3568c2ecf20Sopenharmony_ci		return;
3578c2ecf20Sopenharmony_ci	tpg->colorspace = colorspace;
3588c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
3598c2ecf20Sopenharmony_ci}
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_cistatic inline u32 tpg_g_colorspace(const struct tpg_data *tpg)
3628c2ecf20Sopenharmony_ci{
3638c2ecf20Sopenharmony_ci	return tpg->colorspace;
3648c2ecf20Sopenharmony_ci}
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_cistatic inline void tpg_s_ycbcr_enc(struct tpg_data *tpg, u32 ycbcr_enc)
3678c2ecf20Sopenharmony_ci{
3688c2ecf20Sopenharmony_ci	if (tpg->ycbcr_enc == ycbcr_enc)
3698c2ecf20Sopenharmony_ci		return;
3708c2ecf20Sopenharmony_ci	tpg->ycbcr_enc = ycbcr_enc;
3718c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
3728c2ecf20Sopenharmony_ci}
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_cistatic inline u32 tpg_g_ycbcr_enc(const struct tpg_data *tpg)
3758c2ecf20Sopenharmony_ci{
3768c2ecf20Sopenharmony_ci	return tpg->ycbcr_enc;
3778c2ecf20Sopenharmony_ci}
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_cistatic inline void tpg_s_hsv_enc(struct tpg_data *tpg, u32 hsv_enc)
3808c2ecf20Sopenharmony_ci{
3818c2ecf20Sopenharmony_ci	if (tpg->hsv_enc == hsv_enc)
3828c2ecf20Sopenharmony_ci		return;
3838c2ecf20Sopenharmony_ci	tpg->hsv_enc = hsv_enc;
3848c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
3858c2ecf20Sopenharmony_ci}
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_cistatic inline u32 tpg_g_hsv_enc(const struct tpg_data *tpg)
3888c2ecf20Sopenharmony_ci{
3898c2ecf20Sopenharmony_ci	return tpg->hsv_enc;
3908c2ecf20Sopenharmony_ci}
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_cistatic inline void tpg_s_xfer_func(struct tpg_data *tpg, u32 xfer_func)
3938c2ecf20Sopenharmony_ci{
3948c2ecf20Sopenharmony_ci	if (tpg->xfer_func == xfer_func)
3958c2ecf20Sopenharmony_ci		return;
3968c2ecf20Sopenharmony_ci	tpg->xfer_func = xfer_func;
3978c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
3988c2ecf20Sopenharmony_ci}
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_cistatic inline u32 tpg_g_xfer_func(const struct tpg_data *tpg)
4018c2ecf20Sopenharmony_ci{
4028c2ecf20Sopenharmony_ci	return tpg->xfer_func;
4038c2ecf20Sopenharmony_ci}
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_cistatic inline void tpg_s_quantization(struct tpg_data *tpg, u32 quantization)
4068c2ecf20Sopenharmony_ci{
4078c2ecf20Sopenharmony_ci	if (tpg->quantization == quantization)
4088c2ecf20Sopenharmony_ci		return;
4098c2ecf20Sopenharmony_ci	tpg->quantization = quantization;
4108c2ecf20Sopenharmony_ci	tpg->recalc_colors = true;
4118c2ecf20Sopenharmony_ci}
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_cistatic inline u32 tpg_g_quantization(const struct tpg_data *tpg)
4148c2ecf20Sopenharmony_ci{
4158c2ecf20Sopenharmony_ci	return tpg->quantization;
4168c2ecf20Sopenharmony_ci}
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_cistatic inline unsigned tpg_g_buffers(const struct tpg_data *tpg)
4198c2ecf20Sopenharmony_ci{
4208c2ecf20Sopenharmony_ci	return tpg->buffers;
4218c2ecf20Sopenharmony_ci}
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_cistatic inline unsigned tpg_g_planes(const struct tpg_data *tpg)
4248c2ecf20Sopenharmony_ci{
4258c2ecf20Sopenharmony_ci	return tpg->interleaved ? 1 : tpg->planes;
4268c2ecf20Sopenharmony_ci}
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_cistatic inline bool tpg_g_interleaved(const struct tpg_data *tpg)
4298c2ecf20Sopenharmony_ci{
4308c2ecf20Sopenharmony_ci	return tpg->interleaved;
4318c2ecf20Sopenharmony_ci}
4328c2ecf20Sopenharmony_ci
4338c2ecf20Sopenharmony_cistatic inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane)
4348c2ecf20Sopenharmony_ci{
4358c2ecf20Sopenharmony_ci	return tpg->twopixelsize[plane];
4368c2ecf20Sopenharmony_ci}
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_cistatic inline unsigned tpg_hdiv(const struct tpg_data *tpg,
4398c2ecf20Sopenharmony_ci				  unsigned plane, unsigned x)
4408c2ecf20Sopenharmony_ci{
4418c2ecf20Sopenharmony_ci	return ((x / tpg->hdownsampling[plane]) & tpg->hmask[plane]) *
4428c2ecf20Sopenharmony_ci		tpg->twopixelsize[plane] / 2;
4438c2ecf20Sopenharmony_ci}
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_cistatic inline unsigned tpg_hscale(const struct tpg_data *tpg, unsigned x)
4468c2ecf20Sopenharmony_ci{
4478c2ecf20Sopenharmony_ci	return (x * tpg->scaled_width) / tpg->src_width;
4488c2ecf20Sopenharmony_ci}
4498c2ecf20Sopenharmony_ci
4508c2ecf20Sopenharmony_cistatic inline unsigned tpg_hscale_div(const struct tpg_data *tpg,
4518c2ecf20Sopenharmony_ci				      unsigned plane, unsigned x)
4528c2ecf20Sopenharmony_ci{
4538c2ecf20Sopenharmony_ci	return tpg_hdiv(tpg, plane, tpg_hscale(tpg, x));
4548c2ecf20Sopenharmony_ci}
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_cistatic inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned plane)
4578c2ecf20Sopenharmony_ci{
4588c2ecf20Sopenharmony_ci	return tpg->bytesperline[plane];
4598c2ecf20Sopenharmony_ci}
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_cistatic inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsigned bpl)
4628c2ecf20Sopenharmony_ci{
4638c2ecf20Sopenharmony_ci	unsigned p;
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci	if (tpg->buffers > 1) {
4668c2ecf20Sopenharmony_ci		tpg->bytesperline[plane] = bpl;
4678c2ecf20Sopenharmony_ci		return;
4688c2ecf20Sopenharmony_ci	}
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci	for (p = 0; p < tpg_g_planes(tpg); p++) {
4718c2ecf20Sopenharmony_ci		unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ci		tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p];
4748c2ecf20Sopenharmony_ci	}
4758c2ecf20Sopenharmony_ci	if (tpg_g_interleaved(tpg))
4768c2ecf20Sopenharmony_ci		tpg->bytesperline[1] = tpg->bytesperline[0];
4778c2ecf20Sopenharmony_ci}
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_cistatic inline unsigned tpg_g_line_width(const struct tpg_data *tpg, unsigned plane)
4818c2ecf20Sopenharmony_ci{
4828c2ecf20Sopenharmony_ci	unsigned w = 0;
4838c2ecf20Sopenharmony_ci	unsigned p;
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci	if (tpg->buffers > 1)
4868c2ecf20Sopenharmony_ci		return tpg_g_bytesperline(tpg, plane);
4878c2ecf20Sopenharmony_ci	for (p = 0; p < tpg_g_planes(tpg); p++) {
4888c2ecf20Sopenharmony_ci		unsigned plane_w = tpg_g_bytesperline(tpg, p);
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_ci		w += plane_w / tpg->vdownsampling[p];
4918c2ecf20Sopenharmony_ci	}
4928c2ecf20Sopenharmony_ci	return w;
4938c2ecf20Sopenharmony_ci}
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_cistatic inline unsigned tpg_calc_line_width(const struct tpg_data *tpg,
4968c2ecf20Sopenharmony_ci					   unsigned plane, unsigned bpl)
4978c2ecf20Sopenharmony_ci{
4988c2ecf20Sopenharmony_ci	unsigned w = 0;
4998c2ecf20Sopenharmony_ci	unsigned p;
5008c2ecf20Sopenharmony_ci
5018c2ecf20Sopenharmony_ci	if (tpg->buffers > 1)
5028c2ecf20Sopenharmony_ci		return bpl;
5038c2ecf20Sopenharmony_ci	for (p = 0; p < tpg_g_planes(tpg); p++) {
5048c2ecf20Sopenharmony_ci		unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
5058c2ecf20Sopenharmony_ci
5068c2ecf20Sopenharmony_ci		plane_w /= tpg->hdownsampling[p];
5078c2ecf20Sopenharmony_ci		w += plane_w / tpg->vdownsampling[p];
5088c2ecf20Sopenharmony_ci	}
5098c2ecf20Sopenharmony_ci	return w;
5108c2ecf20Sopenharmony_ci}
5118c2ecf20Sopenharmony_ci
5128c2ecf20Sopenharmony_cistatic inline unsigned tpg_calc_plane_size(const struct tpg_data *tpg, unsigned plane)
5138c2ecf20Sopenharmony_ci{
5148c2ecf20Sopenharmony_ci	if (plane >= tpg_g_planes(tpg))
5158c2ecf20Sopenharmony_ci		return 0;
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci	return tpg_g_bytesperline(tpg, plane) * tpg->buf_height /
5188c2ecf20Sopenharmony_ci	       tpg->vdownsampling[plane];
5198c2ecf20Sopenharmony_ci}
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_cistatic inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h)
5228c2ecf20Sopenharmony_ci{
5238c2ecf20Sopenharmony_ci	tpg->buf_height = h;
5248c2ecf20Sopenharmony_ci}
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_cistatic inline void tpg_s_field(struct tpg_data *tpg, unsigned field, bool alternate)
5278c2ecf20Sopenharmony_ci{
5288c2ecf20Sopenharmony_ci	tpg->field = field;
5298c2ecf20Sopenharmony_ci	tpg->field_alternate = alternate;
5308c2ecf20Sopenharmony_ci}
5318c2ecf20Sopenharmony_ci
5328c2ecf20Sopenharmony_cistatic inline void tpg_s_perc_fill(struct tpg_data *tpg,
5338c2ecf20Sopenharmony_ci				      unsigned perc_fill)
5348c2ecf20Sopenharmony_ci{
5358c2ecf20Sopenharmony_ci	tpg->perc_fill = perc_fill;
5368c2ecf20Sopenharmony_ci}
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_cistatic inline unsigned tpg_g_perc_fill(const struct tpg_data *tpg)
5398c2ecf20Sopenharmony_ci{
5408c2ecf20Sopenharmony_ci	return tpg->perc_fill;
5418c2ecf20Sopenharmony_ci}
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_cistatic inline void tpg_s_perc_fill_blank(struct tpg_data *tpg,
5448c2ecf20Sopenharmony_ci					 bool perc_fill_blank)
5458c2ecf20Sopenharmony_ci{
5468c2ecf20Sopenharmony_ci	tpg->perc_fill_blank = perc_fill_blank;
5478c2ecf20Sopenharmony_ci}
5488c2ecf20Sopenharmony_ci
5498c2ecf20Sopenharmony_cistatic inline void tpg_s_video_aspect(struct tpg_data *tpg,
5508c2ecf20Sopenharmony_ci					enum tpg_video_aspect vid_aspect)
5518c2ecf20Sopenharmony_ci{
5528c2ecf20Sopenharmony_ci	if (tpg->vid_aspect == vid_aspect)
5538c2ecf20Sopenharmony_ci		return;
5548c2ecf20Sopenharmony_ci	tpg->vid_aspect = vid_aspect;
5558c2ecf20Sopenharmony_ci	tpg->recalc_square_border = true;
5568c2ecf20Sopenharmony_ci}
5578c2ecf20Sopenharmony_ci
5588c2ecf20Sopenharmony_cistatic inline enum tpg_video_aspect tpg_g_video_aspect(const struct tpg_data *tpg)
5598c2ecf20Sopenharmony_ci{
5608c2ecf20Sopenharmony_ci	return tpg->vid_aspect;
5618c2ecf20Sopenharmony_ci}
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_cistatic inline void tpg_s_pixel_aspect(struct tpg_data *tpg,
5648c2ecf20Sopenharmony_ci					enum tpg_pixel_aspect pix_aspect)
5658c2ecf20Sopenharmony_ci{
5668c2ecf20Sopenharmony_ci	if (tpg->pix_aspect == pix_aspect)
5678c2ecf20Sopenharmony_ci		return;
5688c2ecf20Sopenharmony_ci	tpg->pix_aspect = pix_aspect;
5698c2ecf20Sopenharmony_ci	tpg->recalc_square_border = true;
5708c2ecf20Sopenharmony_ci}
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_cistatic inline void tpg_s_show_border(struct tpg_data *tpg,
5738c2ecf20Sopenharmony_ci					bool show_border)
5748c2ecf20Sopenharmony_ci{
5758c2ecf20Sopenharmony_ci	tpg->show_border = show_border;
5768c2ecf20Sopenharmony_ci}
5778c2ecf20Sopenharmony_ci
5788c2ecf20Sopenharmony_cistatic inline void tpg_s_show_square(struct tpg_data *tpg,
5798c2ecf20Sopenharmony_ci					bool show_square)
5808c2ecf20Sopenharmony_ci{
5818c2ecf20Sopenharmony_ci	tpg->show_square = show_square;
5828c2ecf20Sopenharmony_ci}
5838c2ecf20Sopenharmony_ci
5848c2ecf20Sopenharmony_cistatic inline void tpg_s_insert_sav(struct tpg_data *tpg, bool insert_sav)
5858c2ecf20Sopenharmony_ci{
5868c2ecf20Sopenharmony_ci	tpg->insert_sav = insert_sav;
5878c2ecf20Sopenharmony_ci}
5888c2ecf20Sopenharmony_ci
5898c2ecf20Sopenharmony_cistatic inline void tpg_s_insert_eav(struct tpg_data *tpg, bool insert_eav)
5908c2ecf20Sopenharmony_ci{
5918c2ecf20Sopenharmony_ci	tpg->insert_eav = insert_eav;
5928c2ecf20Sopenharmony_ci}
5938c2ecf20Sopenharmony_ci
5948c2ecf20Sopenharmony_civoid tpg_update_mv_step(struct tpg_data *tpg);
5958c2ecf20Sopenharmony_ci
5968c2ecf20Sopenharmony_cistatic inline void tpg_s_mv_hor_mode(struct tpg_data *tpg,
5978c2ecf20Sopenharmony_ci				enum tpg_move_mode mv_hor_mode)
5988c2ecf20Sopenharmony_ci{
5998c2ecf20Sopenharmony_ci	tpg->mv_hor_mode = mv_hor_mode;
6008c2ecf20Sopenharmony_ci	tpg_update_mv_step(tpg);
6018c2ecf20Sopenharmony_ci}
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_cistatic inline void tpg_s_mv_vert_mode(struct tpg_data *tpg,
6048c2ecf20Sopenharmony_ci				enum tpg_move_mode mv_vert_mode)
6058c2ecf20Sopenharmony_ci{
6068c2ecf20Sopenharmony_ci	tpg->mv_vert_mode = mv_vert_mode;
6078c2ecf20Sopenharmony_ci	tpg_update_mv_step(tpg);
6088c2ecf20Sopenharmony_ci}
6098c2ecf20Sopenharmony_ci
6108c2ecf20Sopenharmony_cistatic inline void tpg_init_mv_count(struct tpg_data *tpg)
6118c2ecf20Sopenharmony_ci{
6128c2ecf20Sopenharmony_ci	tpg->mv_hor_count = tpg->mv_vert_count = 0;
6138c2ecf20Sopenharmony_ci}
6148c2ecf20Sopenharmony_ci
6158c2ecf20Sopenharmony_cistatic inline void tpg_update_mv_count(struct tpg_data *tpg, bool frame_is_field)
6168c2ecf20Sopenharmony_ci{
6178c2ecf20Sopenharmony_ci	tpg->mv_hor_count += tpg->mv_hor_step * (frame_is_field ? 1 : 2);
6188c2ecf20Sopenharmony_ci	tpg->mv_vert_count += tpg->mv_vert_step * (frame_is_field ? 1 : 2);
6198c2ecf20Sopenharmony_ci}
6208c2ecf20Sopenharmony_ci
6218c2ecf20Sopenharmony_cistatic inline void tpg_s_hflip(struct tpg_data *tpg, bool hflip)
6228c2ecf20Sopenharmony_ci{
6238c2ecf20Sopenharmony_ci	if (tpg->hflip == hflip)
6248c2ecf20Sopenharmony_ci		return;
6258c2ecf20Sopenharmony_ci	tpg->hflip = hflip;
6268c2ecf20Sopenharmony_ci	tpg_update_mv_step(tpg);
6278c2ecf20Sopenharmony_ci	tpg->recalc_lines = true;
6288c2ecf20Sopenharmony_ci}
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_cistatic inline bool tpg_g_hflip(const struct tpg_data *tpg)
6318c2ecf20Sopenharmony_ci{
6328c2ecf20Sopenharmony_ci	return tpg->hflip;
6338c2ecf20Sopenharmony_ci}
6348c2ecf20Sopenharmony_ci
6358c2ecf20Sopenharmony_cistatic inline void tpg_s_vflip(struct tpg_data *tpg, bool vflip)
6368c2ecf20Sopenharmony_ci{
6378c2ecf20Sopenharmony_ci	tpg->vflip = vflip;
6388c2ecf20Sopenharmony_ci}
6398c2ecf20Sopenharmony_ci
6408c2ecf20Sopenharmony_cistatic inline bool tpg_g_vflip(const struct tpg_data *tpg)
6418c2ecf20Sopenharmony_ci{
6428c2ecf20Sopenharmony_ci	return tpg->vflip;
6438c2ecf20Sopenharmony_ci}
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_cistatic inline bool tpg_pattern_is_static(const struct tpg_data *tpg)
6468c2ecf20Sopenharmony_ci{
6478c2ecf20Sopenharmony_ci	return tpg->pattern != TPG_PAT_NOISE &&
6488c2ecf20Sopenharmony_ci	       tpg->mv_hor_mode == TPG_MOVE_NONE &&
6498c2ecf20Sopenharmony_ci	       tpg->mv_vert_mode == TPG_MOVE_NONE;
6508c2ecf20Sopenharmony_ci}
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_ci#endif
653