GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / media / platform / amphion / vpu_color.c
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(colorprimaries, ARRAY_SIZE(colorprimaries), 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(colortransfers, ARRAY_SIZE(colortransfers), 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(colormatrixcoefs, ARRAY_SIZE(colormatrixcoefs), 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 }