Skip to content

Commit 5e9a64e

Browse files
mripardpopcornmix
authored andcommitted
media: tc358743: Fix the RGB MBUS format
Upstream series https://lore.kernel.org/linux-media/20250917-csi-bgr-rgb-v3-0-0145571b3aa4@kernel.org/ The tc358743 is an HDMI to MIPI-CSI2 bridge. It can output all three HDMI 1.4 video formats: RGB 4:4:4, YCbCr 4:2:2, and YCbCr 4:4:4. RGB 4:4:4 is converted to the MIPI-CSI2 RGB888 video format, and listed in the driver as MEDIA_BUS_FMT_RGB888_1X24. Most CSI2 receiver drivers then map MEDIA_BUS_FMT_RGB888_1X24 to V4L2_PIX_FMT_RGB24. However, V4L2_PIX_FMT_RGB24 is defined as having its color components in the R, G and B order, from left to right. MIPI-CSI2 however defines the RGB888 format with blue first. This essentially means that the R and B will be swapped compared to what V4L2_PIX_FMT_RGB24 defines. The proper MBUS format would be BGR888, so let's use that. Fixes: d32d986 ("[media] Driver for Toshiba TC358743 HDMI to CSI-2 bridge") Signed-off-by: Maxime Ripard <mripard@kernel.org>
1 parent d3b93c4 commit 5e9a64e

File tree

1 file changed

+44
-9
lines changed

1 file changed

+44
-9
lines changed

drivers/media/i2c/tc358743.c

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,7 @@ static void tc358743_set_ref_clk(struct v4l2_subdev *sd)
756756
static void tc358743_set_csi_color_space(struct v4l2_subdev *sd)
757757
{
758758
struct tc358743_state *state = to_state(sd);
759+
struct device *dev = &state->i2c_client->dev;
759760

760761
switch (state->mbus_fmt_code) {
761762
case MEDIA_BUS_FMT_UYVY8_1X16:
@@ -771,7 +772,17 @@ static void tc358743_set_csi_color_space(struct v4l2_subdev *sd)
771772
mutex_unlock(&state->confctl_mutex);
772773
break;
773774
case MEDIA_BUS_FMT_RGB888_1X24:
774-
v4l2_dbg(2, debug, sd, "%s: RGB 888 24-bit\n", __func__);
775+
/*
776+
* The driver was initially introduced with RGB888
777+
* support, but CSI really means BGR.
778+
*
779+
* Since we might have applications that would have
780+
* hard-coded the RGB888, let's support both.
781+
*/
782+
dev_warn_once(dev, "RGB format isn't actually supported by the hardware. The application should be fixed to use BGR.");
783+
fallthrough;
784+
case MEDIA_BUS_FMT_BGR888_1X24:
785+
v4l2_dbg(2, debug, sd, "%s: BGR 888 24-bit\n", __func__);
775786
i2c_wr8_and_or(sd, VOUT_SET2,
776787
~(MASK_SEL422 | MASK_VOUT_422FIL_100) & 0xff,
777788
0x00);
@@ -1432,11 +1443,26 @@ static int tc358743_log_status(struct v4l2_subdev *sd)
14321443
v4l2_info(sd, "Stopped: %s\n",
14331444
(i2c_rd16(sd, CSI_STATUS) & MASK_S_HLT) ?
14341445
"yes" : "no");
1435-
v4l2_info(sd, "Color space: %s\n",
1436-
state->mbus_fmt_code == MEDIA_BUS_FMT_UYVY8_1X16 ?
1437-
"YCbCr 422 16-bit" :
1438-
state->mbus_fmt_code == MEDIA_BUS_FMT_RGB888_1X24 ?
1439-
"RGB 888 24-bit" : "Unsupported");
1446+
1447+
switch (state->mbus_fmt_code) {
1448+
case MEDIA_BUS_FMT_BGR888_1X24:
1449+
/*
1450+
* The driver was initially introduced with RGB888
1451+
* support, but CSI really means BGR.
1452+
*
1453+
* Since we might have applications that would have
1454+
* hard-coded the RGB888, let's support both.
1455+
*/
1456+
case MEDIA_BUS_FMT_RGB888_1X24:
1457+
v4l2_info(sd, "Color space: BGR 888 24-bit\n");
1458+
break;
1459+
case MEDIA_BUS_FMT_UYVY8_1X16:
1460+
v4l2_info(sd, "Color space: YCbCr 422 16-bit\n");
1461+
break;
1462+
default:
1463+
v4l2_info(sd, "Color space: Unsupported\n");
1464+
break;
1465+
}
14401466

14411467
v4l2_info(sd, "-----%s status-----\n", is_hdmi(sd) ? "HDMI" : "DVI-D");
14421468
v4l2_info(sd, "HDCP encrypted content: %s\n",
@@ -1773,11 +1799,18 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd,
17731799
{
17741800
switch (code->index) {
17751801
case 0:
1776-
code->code = MEDIA_BUS_FMT_RGB888_1X24;
1802+
code->code = MEDIA_BUS_FMT_BGR888_1X24;
17771803
break;
17781804
case 1:
17791805
code->code = MEDIA_BUS_FMT_UYVY8_1X16;
17801806
break;
1807+
case 2:
1808+
/*
1809+
* We need to keep RGB888 for backward compatibility,
1810+
* but we should list it last for userspace to pick BGR.
1811+
*/
1812+
code->code = MEDIA_BUS_FMT_RGB888_1X24;
1813+
break;
17811814
default:
17821815
return -EINVAL;
17831816
}
@@ -1787,6 +1820,7 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd,
17871820
static u32 tc358743_g_colorspace(u32 code)
17881821
{
17891822
switch (code) {
1823+
case MEDIA_BUS_FMT_BGR888_1X24:
17901824
case MEDIA_BUS_FMT_RGB888_1X24:
17911825
return V4L2_COLORSPACE_SRGB;
17921826
case MEDIA_BUS_FMT_UYVY8_1X16:
@@ -1824,7 +1858,8 @@ static int tc358743_set_fmt(struct v4l2_subdev *sd,
18241858
u32 code = format->format.code; /* is overwritten by get_fmt */
18251859
int ret = tc358743_get_fmt(sd, sd_state, format);
18261860

1827-
if (code == MEDIA_BUS_FMT_RGB888_1X24 ||
1861+
if (code == MEDIA_BUS_FMT_BGR888_1X24 ||
1862+
code == MEDIA_BUS_FMT_RGB888_1X24 ||
18281863
code == MEDIA_BUS_FMT_UYVY8_1X16)
18291864
format->format.code = code;
18301865
format->format.colorspace = tc358743_g_colorspace(format->format.code);
@@ -2244,7 +2279,7 @@ static int tc358743_probe(struct i2c_client *client)
22442279
if (err < 0)
22452280
goto err_hdl;
22462281

2247-
state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24;
2282+
state->mbus_fmt_code = MEDIA_BUS_FMT_BGR888_1X24;
22482283

22492284
sd->dev = &client->dev;
22502285

0 commit comments

Comments
 (0)