1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright 2020-2021 NXP |
4 | */ |
5 | |
6 | #include <linux/init.h> |
7 | #include <linux/device.h> |
8 | #include <linux/ioctl.h> |
9 | #include <linux/list.h> |
10 | #include <linux/module.h> |
11 | #include <linux/kernel.h> |
12 | #include <linux/slab.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/types.h> |
15 | #include <media/v4l2-device.h> |
16 | #include "vpu.h" |
17 | #include "vpu_helpers.h" |
18 | |
19 | static const u8 colorprimaries[] = { |
20 | V4L2_COLORSPACE_LAST, |
21 | V4L2_COLORSPACE_REC709, /*Rec. ITU-R BT.709-6*/ |
22 | 0, |
23 | 0, |
24 | V4L2_COLORSPACE_470_SYSTEM_M, /*Rec. ITU-R BT.470-6 System M*/ |
25 | V4L2_COLORSPACE_470_SYSTEM_BG, /*Rec. ITU-R BT.470-6 System B, G*/ |
26 | V4L2_COLORSPACE_SMPTE170M, /*SMPTE170M*/ |
27 | V4L2_COLORSPACE_SMPTE240M, /*SMPTE240M*/ |
28 | 0, /*Generic film*/ |
29 | V4L2_COLORSPACE_BT2020, /*Rec. ITU-R BT.2020-2*/ |
30 | 0, /*SMPTE ST 428-1*/ |
31 | }; |
32 | |
33 | static const u8 colortransfers[] = { |
34 | V4L2_XFER_FUNC_LAST, |
35 | V4L2_XFER_FUNC_709, /*Rec. ITU-R BT.709-6*/ |
36 | 0, |
37 | 0, |
38 | 0, /*Rec. ITU-R BT.470-6 System M*/ |
39 | 0, /*Rec. ITU-R BT.470-6 System B, G*/ |
40 | V4L2_XFER_FUNC_709, /*SMPTE170M*/ |
41 | V4L2_XFER_FUNC_SMPTE240M, /*SMPTE240M*/ |
42 | V4L2_XFER_FUNC_NONE, /*Linear transfer characteristics*/ |
43 | 0, |
44 | 0, |
45 | 0, /*IEC 61966-2-4*/ |
46 | 0, /*Rec. ITU-R BT.1361-0 extended colour gamut*/ |
47 | V4L2_XFER_FUNC_SRGB, /*IEC 61966-2-1 sRGB or sYCC*/ |
48 | V4L2_XFER_FUNC_709, /*Rec. ITU-R BT.2020-2 (10 bit system)*/ |
49 | V4L2_XFER_FUNC_709, /*Rec. ITU-R BT.2020-2 (12 bit system)*/ |
50 | V4L2_XFER_FUNC_SMPTE2084, /*SMPTE ST 2084*/ |
51 | 0, /*SMPTE ST 428-1*/ |
52 | 0 /*Rec. ITU-R BT.2100-0 hybrid log-gamma (HLG)*/ |
53 | }; |
54 | |
55 | static const u8 colormatrixcoefs[] = { |
56 | V4L2_YCBCR_ENC_LAST, |
57 | V4L2_YCBCR_ENC_709, /*Rec. ITU-R BT.709-6*/ |
58 | 0, |
59 | 0, |
60 | 0, /*Title 47 Code of Federal Regulations*/ |
61 | V4L2_YCBCR_ENC_601, /*Rec. ITU-R BT.601-7 625*/ |
62 | V4L2_YCBCR_ENC_601, /*Rec. ITU-R BT.601-7 525*/ |
63 | V4L2_YCBCR_ENC_SMPTE240M, /*SMPTE240M*/ |
64 | 0, |
65 | V4L2_YCBCR_ENC_BT2020, /*Rec. ITU-R BT.2020-2*/ |
66 | V4L2_YCBCR_ENC_BT2020_CONST_LUM /*Rec. ITU-R BT.2020-2 constant*/ |
67 | }; |
68 | |
69 | u32 vpu_color_cvrt_primaries_v2i(u32 primaries) |
70 | { |
71 | return vpu_helper_find_in_array_u8(array: colorprimaries, ARRAY_SIZE(colorprimaries), x: primaries); |
72 | } |
73 | |
74 | u32 vpu_color_cvrt_primaries_i2v(u32 primaries) |
75 | { |
76 | return primaries < ARRAY_SIZE(colorprimaries) ? colorprimaries[primaries] : 0; |
77 | } |
78 | |
79 | u32 vpu_color_cvrt_transfers_v2i(u32 transfers) |
80 | { |
81 | return vpu_helper_find_in_array_u8(array: colortransfers, ARRAY_SIZE(colortransfers), x: transfers); |
82 | } |
83 | |
84 | u32 vpu_color_cvrt_transfers_i2v(u32 transfers) |
85 | { |
86 | return transfers < ARRAY_SIZE(colortransfers) ? colortransfers[transfers] : 0; |
87 | } |
88 | |
89 | u32 vpu_color_cvrt_matrix_v2i(u32 matrix) |
90 | { |
91 | return vpu_helper_find_in_array_u8(array: colormatrixcoefs, ARRAY_SIZE(colormatrixcoefs), x: matrix); |
92 | } |
93 | |
94 | u32 vpu_color_cvrt_matrix_i2v(u32 matrix) |
95 | { |
96 | return matrix < ARRAY_SIZE(colormatrixcoefs) ? colormatrixcoefs[matrix] : 0; |
97 | } |
98 | |
99 | u32 vpu_color_cvrt_full_range_v2i(u32 full_range) |
100 | { |
101 | return (full_range == V4L2_QUANTIZATION_FULL_RANGE); |
102 | } |
103 | |
104 | u32 vpu_color_cvrt_full_range_i2v(u32 full_range) |
105 | { |
106 | if (full_range) |
107 | return V4L2_QUANTIZATION_FULL_RANGE; |
108 | |
109 | return V4L2_QUANTIZATION_LIM_RANGE; |
110 | } |
111 | |
112 | int vpu_color_check_primaries(u32 primaries) |
113 | { |
114 | return vpu_color_cvrt_primaries_v2i(primaries) ? 0 : -EINVAL; |
115 | } |
116 | |
117 | int vpu_color_check_transfers(u32 transfers) |
118 | { |
119 | return vpu_color_cvrt_transfers_v2i(transfers) ? 0 : -EINVAL; |
120 | } |
121 | |
122 | int vpu_color_check_matrix(u32 matrix) |
123 | { |
124 | return vpu_color_cvrt_matrix_v2i(matrix) ? 0 : -EINVAL; |
125 | } |
126 | |
127 | int vpu_color_check_full_range(u32 full_range) |
128 | { |
129 | int ret = -EINVAL; |
130 | |
131 | switch (full_range) { |
132 | case V4L2_QUANTIZATION_FULL_RANGE: |
133 | case V4L2_QUANTIZATION_LIM_RANGE: |
134 | ret = 0; |
135 | break; |
136 | default: |
137 | break; |
138 | } |
139 | |
140 | return ret; |
141 | } |
142 | |
143 | int vpu_color_get_default(u32 primaries, u32 *ptransfers, u32 *pmatrix, u32 *pfull_range) |
144 | { |
145 | u32 transfers; |
146 | u32 matrix; |
147 | u32 full_range; |
148 | |
149 | switch (primaries) { |
150 | case V4L2_COLORSPACE_REC709: |
151 | transfers = V4L2_XFER_FUNC_709; |
152 | matrix = V4L2_YCBCR_ENC_709; |
153 | break; |
154 | case V4L2_COLORSPACE_470_SYSTEM_M: |
155 | case V4L2_COLORSPACE_470_SYSTEM_BG: |
156 | case V4L2_COLORSPACE_SMPTE170M: |
157 | transfers = V4L2_XFER_FUNC_709; |
158 | matrix = V4L2_YCBCR_ENC_601; |
159 | break; |
160 | case V4L2_COLORSPACE_SMPTE240M: |
161 | transfers = V4L2_XFER_FUNC_SMPTE240M; |
162 | matrix = V4L2_YCBCR_ENC_SMPTE240M; |
163 | break; |
164 | case V4L2_COLORSPACE_BT2020: |
165 | transfers = V4L2_XFER_FUNC_709; |
166 | matrix = V4L2_YCBCR_ENC_BT2020; |
167 | break; |
168 | default: |
169 | transfers = V4L2_XFER_FUNC_DEFAULT; |
170 | matrix = V4L2_YCBCR_ENC_DEFAULT; |
171 | break; |
172 | } |
173 | full_range = V4L2_QUANTIZATION_LIM_RANGE; |
174 | |
175 | if (ptransfers) |
176 | *ptransfers = transfers; |
177 | if (pmatrix) |
178 | *pmatrix = matrix; |
179 | if (pfull_range) |
180 | *pfull_range = full_range; |
181 | |
182 | return 0; |
183 | } |
184 | |