Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * vimc-common.c Virtual Media Controller Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "vimc-common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * in the scaler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) static const struct vimc_pix_map vimc_pix_map_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	/* TODO: add all missing formats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	/* RGB formats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 		.code = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 			MEDIA_BUS_FMT_BGR888_1X24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 			MEDIA_BUS_FMT_BGR888_3X8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 		.pixelformat = V4L2_PIX_FMT_BGR24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 		.bpp = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		.bayer = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		.code = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 			MEDIA_BUS_FMT_RGB888_1X24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 			MEDIA_BUS_FMT_RGB888_2X12_BE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 			MEDIA_BUS_FMT_RGB888_2X12_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 			MEDIA_BUS_FMT_RGB888_3X8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 			MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 			MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 			MEDIA_BUS_FMT_RGB888_1X32_PADHI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			MEDIA_BUS_FMT_GBR888_1X24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		.pixelformat = V4L2_PIX_FMT_RGB24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		.bpp = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		.bayer = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		.code = { MEDIA_BUS_FMT_ARGB8888_1X32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		.pixelformat = V4L2_PIX_FMT_ARGB32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		.bpp = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		.bayer = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	/* Bayer formats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		.code = { MEDIA_BUS_FMT_SBGGR8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		.pixelformat = V4L2_PIX_FMT_SBGGR8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		.code = { MEDIA_BUS_FMT_SGBRG8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		.pixelformat = V4L2_PIX_FMT_SGBRG8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		.code = { MEDIA_BUS_FMT_SGRBG8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		.pixelformat = V4L2_PIX_FMT_SGRBG8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		.code = { MEDIA_BUS_FMT_SRGGB8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		.pixelformat = V4L2_PIX_FMT_SRGGB8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		.code = { MEDIA_BUS_FMT_SBGGR10_1X10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		.pixelformat = V4L2_PIX_FMT_SBGGR10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		.bpp = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		.code = { MEDIA_BUS_FMT_SGBRG10_1X10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		.pixelformat = V4L2_PIX_FMT_SGBRG10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		.bpp = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		.code = { MEDIA_BUS_FMT_SGRBG10_1X10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		.pixelformat = V4L2_PIX_FMT_SGRBG10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		.bpp = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		.code = { MEDIA_BUS_FMT_SRGGB10_1X10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		.pixelformat = V4L2_PIX_FMT_SRGGB10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		.bpp = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	/* 10bit raw bayer a-law compressed to 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		.code = { MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		.pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		.code = { MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		.pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		.code = { MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		.pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		.code = { MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		.pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	/* 10bit raw bayer DPCM compressed to 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		.code = { MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		.pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		.code = { MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		.pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		.code = { MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		.pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		.code = { MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		.pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		.bpp = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		.code = { MEDIA_BUS_FMT_SBGGR12_1X12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		.pixelformat = V4L2_PIX_FMT_SBGGR12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		.bpp = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		.code = { MEDIA_BUS_FMT_SGBRG12_1X12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		.pixelformat = V4L2_PIX_FMT_SGBRG12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		.bpp = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		.code = { MEDIA_BUS_FMT_SGRBG12_1X12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		.pixelformat = V4L2_PIX_FMT_SGRBG12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		.bpp = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		.code = { MEDIA_BUS_FMT_SRGGB12_1X12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		.pixelformat = V4L2_PIX_FMT_SRGGB12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		.bpp = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		.bayer = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) bool vimc_is_source(struct media_entity *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	for (i = 0; i < ent->num_pads; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		if (ent->pads[i].flags & MEDIA_PAD_FL_SINK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	if (i >= ARRAY_SIZE(vimc_pix_map_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	return &vimc_pix_map_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u32 vimc_mbus_code_by_index(unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		for (j = 0; j < ARRAY_SIZE(vimc_pix_map_list[i].code); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			if (!vimc_pix_map_list[i].code[j])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			if (!index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				return vimc_pix_map_list[i].code[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			index--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		for (j = 0; j < ARRAY_SIZE(vimc_pix_map_list[i].code); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			if (vimc_pix_map_list[i].code[j] == code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 				return &vimc_pix_map_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		if (vimc_pix_map_list[i].pixelformat == pixelformat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			return &vimc_pix_map_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int vimc_get_pix_format(struct media_pad *pad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			       struct v4l2_pix_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	if (is_media_entity_v4l2_subdev(pad->entity)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		struct v4l2_subdev *sd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			media_entity_to_v4l2_subdev(pad->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		struct v4l2_subdev_format sd_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		const struct vimc_pix_map *pix_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		sd_fmt.pad = pad->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		v4l2_fill_pix_format(fmt, &sd_fmt.format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		pix_map = vimc_pix_map_by_code(sd_fmt.format.code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		fmt->pixelformat = pix_map->pixelformat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	} else if (is_media_entity_v4l2_video_device(pad->entity)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		struct video_device *vdev = container_of(pad->entity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 							 struct video_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 							 entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		struct vimc_ent_device *ved = video_get_drvdata(vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		if (!ved->vdev_get_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		ved->vdev_get_format(ved, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int vimc_vdev_link_validate(struct media_link *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	struct v4l2_pix_format source_fmt, sink_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	ret = vimc_get_pix_format(link->source, &source_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	ret = vimc_get_pix_format(link->sink, &sink_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	pr_info("vimc link validate: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		"%s:src:%dx%d (0x%x, %d, %d, %d, %d) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		"%s:snk:%dx%d (0x%x, %d, %d, %d, %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		/* src */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		link->source->entity->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		source_fmt.width, source_fmt.height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		source_fmt.pixelformat, source_fmt.colorspace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		source_fmt.quantization, source_fmt.xfer_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		source_fmt.ycbcr_enc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		/* sink */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		link->sink->entity->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		sink_fmt.width, sink_fmt.height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		sink_fmt.pixelformat, sink_fmt.colorspace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		sink_fmt.quantization, sink_fmt.xfer_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		sink_fmt.ycbcr_enc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	/* The width, height and pixelformat must match. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	if (source_fmt.width != sink_fmt.width ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	    source_fmt.height != sink_fmt.height ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	    source_fmt.pixelformat != sink_fmt.pixelformat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		return -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	 * The field order must match, or the sink field order must be NONE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	 * to support interlaced hardware connected to bridges that support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	 * progressive formats only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (source_fmt.field != sink_fmt.field &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	    sink_fmt.field != V4L2_FIELD_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		return -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	 * If colorspace is DEFAULT, then assume all the colorimetry is also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	 * DEFAULT, return 0 to skip comparing the other colorimetry parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	if (source_fmt.colorspace == V4L2_COLORSPACE_DEFAULT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	    sink_fmt.colorspace == V4L2_COLORSPACE_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	/* Colorspace must match. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	if (source_fmt.colorspace != sink_fmt.colorspace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		return -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	/* Colorimetry must match if they are not set to DEFAULT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	if (source_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	    sink_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	    source_fmt.ycbcr_enc != sink_fmt.ycbcr_enc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		return -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	if (source_fmt.quantization != V4L2_QUANTIZATION_DEFAULT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	    sink_fmt.quantization != V4L2_QUANTIZATION_DEFAULT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	    source_fmt.quantization != sink_fmt.quantization)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		return -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (source_fmt.xfer_func != V4L2_XFER_FUNC_DEFAULT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	    sink_fmt.xfer_func != V4L2_XFER_FUNC_DEFAULT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	    source_fmt.xfer_func != sink_fmt.xfer_func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		return -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static const struct media_entity_operations vimc_ent_sd_mops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	.link_validate = v4l2_subdev_link_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int vimc_ent_sd_register(struct vimc_ent_device *ved,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			 struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			 struct v4l2_device *v4l2_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			 const char *const name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			 u32 function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			 u16 num_pads,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			 struct media_pad *pads,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			 const struct v4l2_subdev_ops *sd_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	/* Fill the vimc_ent_device struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	ved->ent = &sd->entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	/* Initialize the subdev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	v4l2_subdev_init(sd, sd_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	sd->entity.function = function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	sd->entity.ops = &vimc_ent_sd_mops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	sd->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	strscpy(sd->name, name, sizeof(sd->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	v4l2_set_subdevdata(sd, ved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	/* Expose this subdev to user space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	if (sd->ctrl_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	/* Initialize the media entity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	ret = media_entity_pads_init(&sd->entity, num_pads, pads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	/* Register the subdev with the v4l2 and the media framework */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	ret = v4l2_device_register_subdev(v4l2_dev, sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		dev_err(v4l2_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 			"%s: subdev register failed (err=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 			name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		goto err_clean_m_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) err_clean_m_ent:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	media_entity_cleanup(&sd->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }