Skip to content

Commit 795e4fe

Browse files
mripardpelwell
authored andcommitted
media: tc358743: Fix the RGB MBUS format
Upstream series https://lore.kernel.org/linux-media/[email protected]/ 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 <[email protected]>
1 parent 857c767 commit 795e4fe

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
@@ -680,6 +680,7 @@ static void tc358743_set_ref_clk(struct v4l2_subdev *sd)
680680
static void tc358743_set_csi_color_space(struct v4l2_subdev *sd)
681681
{
682682
struct tc358743_state *state = to_state(sd);
683+
struct device *dev = &state->i2c_client->dev;
683684

684685
switch (state->mbus_fmt_code) {
685686
case MEDIA_BUS_FMT_UYVY8_1X16:
@@ -695,7 +696,17 @@ static void tc358743_set_csi_color_space(struct v4l2_subdev *sd)
695696
mutex_unlock(&state->confctl_mutex);
696697
break;
697698
case MEDIA_BUS_FMT_RGB888_1X24:
698-
v4l2_dbg(2, debug, sd, "%s: RGB 888 24-bit\n", __func__);
699+
/*
700+
* The driver was initially introduced with RGB888
701+
* support, but CSI really means BGR.
702+
*
703+
* Since we might have applications that would have
704+
* hard-coded the RGB888, let's support both.
705+
*/
706+
dev_warn_once(dev, "RGB format isn't actually supported by the hardware. The application should be fixed to use BGR.");
707+
fallthrough;
708+
case MEDIA_BUS_FMT_BGR888_1X24:
709+
v4l2_dbg(2, debug, sd, "%s: BGR 888 24-bit\n", __func__);
699710
i2c_wr8_and_or(sd, VOUT_SET2,
700711
~(MASK_SEL422 | MASK_VOUT_422FIL_100) & 0xff,
701712
0x00);
@@ -1356,11 +1367,26 @@ static int tc358743_log_status(struct v4l2_subdev *sd)
13561367
v4l2_info(sd, "Stopped: %s\n",
13571368
(i2c_rd16(sd, CSI_STATUS) & MASK_S_HLT) ?
13581369
"yes" : "no");
1359-
v4l2_info(sd, "Color space: %s\n",
1360-
state->mbus_fmt_code == MEDIA_BUS_FMT_UYVY8_1X16 ?
1361-
"YCbCr 422 16-bit" :
1362-
state->mbus_fmt_code == MEDIA_BUS_FMT_RGB888_1X24 ?
1363-
"RGB 888 24-bit" : "Unsupported");
1370+
1371+
switch (state->mbus_fmt_code) {
1372+
case MEDIA_BUS_FMT_BGR888_1X24:
1373+
/*
1374+
* The driver was initially introduced with RGB888
1375+
* support, but CSI really means BGR.
1376+
*
1377+
* Since we might have applications that would have
1378+
* hard-coded the RGB888, let's support both.
1379+
*/
1380+
case MEDIA_BUS_FMT_RGB888_1X24:
1381+
v4l2_info(sd, "Color space: BGR 888 24-bit\n");
1382+
break;
1383+
case MEDIA_BUS_FMT_UYVY8_1X16:
1384+
v4l2_info(sd, "Color space: YCbCr 422 16-bit\n");
1385+
break;
1386+
default:
1387+
v4l2_info(sd, "Color space: Unsupported\n");
1388+
break;
1389+
}
13641390

13651391
v4l2_info(sd, "-----%s status-----\n", is_hdmi(sd) ? "HDMI" : "DVI-D");
13661392
v4l2_info(sd, "HDCP encrypted content: %s\n",
@@ -1697,11 +1723,18 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd,
16971723
{
16981724
switch (code->index) {
16991725
case 0:
1700-
code->code = MEDIA_BUS_FMT_RGB888_1X24;
1726+
code->code = MEDIA_BUS_FMT_BGR888_1X24;
17011727
break;
17021728
case 1:
17031729
code->code = MEDIA_BUS_FMT_UYVY8_1X16;
17041730
break;
1731+
case 2:
1732+
/*
1733+
* We need to keep RGB888 for backward compatibility,
1734+
* but we should list it last for userspace to pick BGR.
1735+
*/
1736+
code->code = MEDIA_BUS_FMT_RGB888_1X24;
1737+
break;
17051738
default:
17061739
return -EINVAL;
17071740
}
@@ -1711,6 +1744,7 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd,
17111744
static u32 tc358743_g_colorspace(u32 code)
17121745
{
17131746
switch (code) {
1747+
case MEDIA_BUS_FMT_BGR888_1X24:
17141748
case MEDIA_BUS_FMT_RGB888_1X24:
17151749
return V4L2_COLORSPACE_SRGB;
17161750
case MEDIA_BUS_FMT_UYVY8_1X16:
@@ -1748,7 +1782,8 @@ static int tc358743_set_fmt(struct v4l2_subdev *sd,
17481782
u32 code = format->format.code; /* is overwritten by get_fmt */
17491783
int ret = tc358743_get_fmt(sd, sd_state, format);
17501784

1751-
if (code == MEDIA_BUS_FMT_RGB888_1X24 ||
1785+
if (code == MEDIA_BUS_FMT_BGR888_1X24 ||
1786+
code == MEDIA_BUS_FMT_RGB888_1X24 ||
17521787
code == MEDIA_BUS_FMT_UYVY8_1X16)
17531788
format->format.code = code;
17541789
format->format.colorspace = tc358743_g_colorspace(format->format.code);
@@ -2168,7 +2203,7 @@ static int tc358743_probe(struct i2c_client *client)
21682203
if (err < 0)
21692204
goto err_hdl;
21702205

2171-
state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24;
2206+
state->mbus_fmt_code = MEDIA_BUS_FMT_BGR888_1X24;
21722207

21732208
sd->dev = &client->dev;
21742209

0 commit comments

Comments
 (0)