^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) }