Skip to content

Commit 2679781

Browse files
mripard6by9
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 7c49e17 commit 2679781

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
@@ -649,6 +649,7 @@ static void tc358743_set_ref_clk(struct v4l2_subdev *sd)
649649
static void tc358743_set_csi_color_space(struct v4l2_subdev *sd)
650650
{
651651
struct tc358743_state *state = to_state(sd);
652+
struct device *dev = &state->i2c_client->dev;
652653

653654
switch (state->mbus_fmt_code) {
654655
case MEDIA_BUS_FMT_UYVY8_1X16:
@@ -664,7 +665,17 @@ static void tc358743_set_csi_color_space(struct v4l2_subdev *sd)
664665
mutex_unlock(&state->confctl_mutex);
665666
break;
666667
case MEDIA_BUS_FMT_RGB888_1X24:
667-
v4l2_dbg(2, debug, sd, "%s: RGB 888 24-bit\n", __func__);
668+
/*
669+
* The driver was initially introduced with RGB888
670+
* support, but CSI really means BGR.
671+
*
672+
* Since we might have applications that would have
673+
* hard-coded the RGB888, let's support both.
674+
*/
675+
dev_warn_once(dev, "RGB format isn't actually supported by the hardware. The application should be fixed to use BGR.");
676+
fallthrough;
677+
case MEDIA_BUS_FMT_BGR888_1X24:
678+
v4l2_dbg(2, debug, sd, "%s: BGR 888 24-bit\n", __func__);
668679
i2c_wr8_and_or(sd, VOUT_SET2,
669680
~(MASK_SEL422 | MASK_VOUT_422FIL_100) & 0xff,
670681
0x00);
@@ -1325,11 +1336,26 @@ static int tc358743_log_status(struct v4l2_subdev *sd)
13251336
v4l2_info(sd, "Stopped: %s\n",
13261337
(i2c_rd16(sd, CSI_STATUS) & MASK_S_HLT) ?
13271338
"yes" : "no");
1328-
v4l2_info(sd, "Color space: %s\n",
1329-
state->mbus_fmt_code == MEDIA_BUS_FMT_UYVY8_1X16 ?
1330-
"YCbCr 422 16-bit" :
1331-
state->mbus_fmt_code == MEDIA_BUS_FMT_RGB888_1X24 ?
1332-
"RGB 888 24-bit" : "Unsupported");
1339+
1340+
switch (state->mbus_fmt_code) {
1341+
case MEDIA_BUS_FMT_BGR888_1X24:
1342+
/*
1343+
* The driver was initially introduced with RGB888
1344+
* support, but CSI really means BGR.
1345+
*
1346+
* Since we might have applications that would have
1347+
* hard-coded the RGB888, let's support both.
1348+
*/
1349+
case MEDIA_BUS_FMT_RGB888_1X24:
1350+
v4l2_info(sd, "Color space: BGR 888 24-bit\n");
1351+
break;
1352+
case MEDIA_BUS_FMT_UYVY8_1X16:
1353+
v4l2_info(sd, "Color space: YCbCr 422 16-bit\n");
1354+
break;
1355+
default:
1356+
v4l2_info(sd, "Color space: Unsupported\n");
1357+
break;
1358+
}
13331359

13341360
v4l2_info(sd, "-----%s status-----\n", is_hdmi(sd) ? "HDMI" : "DVI-D");
13351361
v4l2_info(sd, "HDCP encrypted content: %s\n",
@@ -1666,11 +1692,18 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd,
16661692
{
16671693
switch (code->index) {
16681694
case 0:
1669-
code->code = MEDIA_BUS_FMT_RGB888_1X24;
1695+
code->code = MEDIA_BUS_FMT_BGR888_1X24;
16701696
break;
16711697
case 1:
16721698
code->code = MEDIA_BUS_FMT_UYVY8_1X16;
16731699
break;
1700+
case 2:
1701+
/*
1702+
* We need to keep RGB888 for backward compatibility,
1703+
* but we should list it last for userspace to pick BGR.
1704+
*/
1705+
code->code = MEDIA_BUS_FMT_RGB888_1X24;
1706+
break;
16741707
default:
16751708
return -EINVAL;
16761709
}
@@ -1680,6 +1713,7 @@ static int tc358743_enum_mbus_code(struct v4l2_subdev *sd,
16801713
static u32 tc358743_g_colorspace(u32 code)
16811714
{
16821715
switch (code) {
1716+
case MEDIA_BUS_FMT_BGR888_1X24:
16831717
case MEDIA_BUS_FMT_RGB888_1X24:
16841718
return V4L2_COLORSPACE_SRGB;
16851719
case MEDIA_BUS_FMT_UYVY8_1X16:
@@ -1717,7 +1751,8 @@ static int tc358743_set_fmt(struct v4l2_subdev *sd,
17171751
u32 code = format->format.code; /* is overwritten by get_fmt */
17181752
int ret = tc358743_get_fmt(sd, sd_state, format);
17191753

1720-
if (code == MEDIA_BUS_FMT_RGB888_1X24 ||
1754+
if (code == MEDIA_BUS_FMT_BGR888_1X24 ||
1755+
code == MEDIA_BUS_FMT_RGB888_1X24 ||
17211756
code == MEDIA_BUS_FMT_UYVY8_1X16)
17221757
format->format.code = code;
17231758
format->format.colorspace = tc358743_g_colorspace(format->format.code);
@@ -2137,7 +2172,7 @@ static int tc358743_probe(struct i2c_client *client)
21372172
if (err < 0)
21382173
goto err_hdl;
21392174

2140-
state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24;
2175+
state->mbus_fmt_code = MEDIA_BUS_FMT_BGR888_1X24;
21412176

21422177
sd->dev = &client->dev;
21432178

0 commit comments

Comments
 (0)