[PATCH] Driver for Toshiba TC358743 HDMI to CSI-2 bridge
From: Mats Randgaard The driver is tested on our hardware and all the implemented features works as expected. Missing features: - CEC support - HDCP repeater support - IR support Signed-off-by: Mats Randgaard --- MAINTAINERS|6 + drivers/media/i2c/Kconfig |9 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/tc358743.c | 1838 drivers/media/i2c/tc358743_regs.h | 680 + include/media/tc358743.h | 92 ++ include/uapi/linux/v4l2-controls.h |4 + 7 files changed, 2630 insertions(+) create mode 100644 drivers/media/i2c/tc358743.c create mode 100644 drivers/media/i2c/tc358743_regs.h create mode 100644 include/media/tc358743.h diff --git a/MAINTAINERS b/MAINTAINERS index 30e7e38..49e9f84 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9856,6 +9856,12 @@ L: platform-driver-...@vger.kernel.org S: Orphan F: drivers/platform/x86/toshiba_acpi.c +TOSHIBA TC358743 DRIVER +M: Mats Randgaard +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/i2c/tc358743* + TOSHIBA SMM DRIVER M: Jonathan Buzzard L: tlinux-us...@tce.toshiba-dme.co.jp diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 6f30ea7..e352daa 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -285,6 +285,15 @@ config VIDEO_SAA711X To compile this driver as a module, choose M here: the module will be called saa7115. +config VIDEO_TC358743 + tristate "Toshiba TC358743 decoder" + depends on VIDEO_V4L2 && I2C + ---help--- + Support for the Toshiba TC358743 HDMI to MIPI CSI-2 bridge + + To compile this driver as a module, choose M here: the + module will be called tc358743. + config VIDEO_TVP514X tristate "Texas Instruments TVP514x video decoder" depends on VIDEO_V4L2 && I2C diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index f165fae..07db257 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -78,3 +78,4 @@ obj-$(CONFIG_VIDEO_AK881X)+= ak881x.o obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o obj-$(CONFIG_VIDEO_OV2659) += ov2659.o +obj-$(CONFIG_VIDEO_TC358743) += tc358743.o diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c new file mode 100644 index 000..e9328c4 --- /dev/null +++ b/drivers/media/i2c/tc358743.c @@ -0,0 +1,1838 @@ +/* + * tc358743 - Toshiba HDMI to CSI-2 bridge + * + * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights + * reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +/* + * References (c = chapter, p = page): + * REF_01 - Toshiba, TC358743XBG (H2C), Functional Specification, Rev 0.60 + * REF_02 - Toshiba, TC358743XBG_HDMI-CSI_Tv11p_nm.xls + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tc358743_regs.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "debug level (0-3)"); + +MODULE_DESCRIPTION("Toshiba TC358743 HDMI to CSI-2 bridge driver"); +MODULE_AUTHOR("Ramakrishnan Muthukrishnan "); +MODULE_AUTHOR("Mikhail Khelik "); +MODULE_AUTHOR("Mats Randgaard "); +MODULE_LICENSE("GPL"); + +#define EDID_NUM_BLOCKS_MAX 8 +#define EDID_BLOCK_SIZE 128 + +static const struct v4l2_dv_timings_cap tc358743_timings_cap = { + .type = V4L2_DV_BT_656_1120, + /* keep this initialization for compatibility with GCC < 4.4.6 */ + .reserved = { 0 }, + /* Pixel clock from REF_01 p. 20. Min/max height/width are unknown */ + V4L2_INIT_BT_TIMINGS(1, 1, 1, 1, 0, 16500, + V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | + V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT, + V4L2_DV_BT_CAP_PROGRESSIVE | + V4L2_DV_BT_CAP_REDUCED_BLANKING | + V4L2_DV_BT_CAP_CUSTOM) +}; + +struct tc358743_state { + struct tc358743_platform_data pdata; + struct v4l2_subdev sd; + struct media_pad pad; + struct v4l2_ctrl_handler hdl; + struct i2c_client *i2c_client; + +
Re: [PATCH] Driver for Toshiba TC358743 HDMI to CSI-2 bridge
Hi Mats, I have a few comments, see below: On 05/06/15 11:27, matra...@cisco.com wrote: > From: Mats Randgaard > > The driver is tested on our hardware and all the implemented features > works as expected. > > Missing features: > - CEC support > - HDCP repeater support > - IR support > > Signed-off-by: Mats Randgaard > --- > MAINTAINERS|6 + > drivers/media/i2c/Kconfig |9 + > drivers/media/i2c/Makefile |1 + > drivers/media/i2c/tc358743.c | 1838 > > drivers/media/i2c/tc358743_regs.h | 680 + > include/media/tc358743.h | 92 ++ > include/uapi/linux/v4l2-controls.h |4 + > 7 files changed, 2630 insertions(+) > create mode 100644 drivers/media/i2c/tc358743.c > create mode 100644 drivers/media/i2c/tc358743_regs.h > create mode 100644 include/media/tc358743.h > > diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c > new file mode 100644 > index 000..e9328c4 > --- /dev/null > +++ b/drivers/media/i2c/tc358743.c > @@ -0,0 +1,1838 @@ > +/* --- AVI --- */ > + > +struct aviInfoFrame { > + u8 f17; > + u8 y10; > + u8 a0; > + u8 b10; > + u8 s10; > + u8 c10; > + u8 m10; > + u8 r3210; > + u8 itc; > + u8 ec210; > + u8 q10; > + u8 sc10; > + u8 f47; > + u8 vic; > + u8 yq10; > + u8 cn10; > + u8 pr3210; > + u16 etb; > + u16 sbb; > + u16 elb; > + u16 srb; > +}; > + > +static const char *y10Text[4] = { > + "RGB", > + "YCbCr 4:2:2", > + "YCbCr 4:4:4", > + "Future", > +}; > + > +static const char *c10Text[4] = { > + "No Data", > + "SMPTE 170M", > + "ITU-R 709", > + "Extended Colorimetry information valid", > +}; > + > +static const char *itcText[2] = { > + "No Data", > + "IT content", > +}; > + > +static const char *ec210Text[8] = { > + "xvYCC601", > + "xvYCC709", > + "sYCC601", > + "AdobeYCC601", > + "AdobeRGB", > + "5 reserved", > + "6 reserved", > + "7 reserved", > +}; > + > +static const char *q10Text[4] = { > + "Default", > + "Limited Range", > + "Full Range", > + "Reserved", > +}; > + > +static void parse_avi_infoframe(struct v4l2_subdev *sd, u8 *buf, > + struct aviInfoFrame *avi) > +{ > + avi->f17 = (buf[1] >> 7) & 0x1; > + avi->y10 = (buf[1] >> 5) & 0x3; > + avi->a0 = (buf[1] >> 4) & 0x1; > + avi->b10 = (buf[1] >> 2) & 0x3; > + avi->s10 = buf[1] & 0x3; > + avi->c10 = (buf[2] >> 6) & 0x3; > + avi->m10 = (buf[2] >> 4) & 0x3; > + avi->r3210 = buf[2] & 0xf; > + avi->itc = (buf[3] >> 7) & 0x1; > + avi->ec210 = (buf[3] >> 4) & 0x7; > + avi->q10 = (buf[3] >> 2) & 0x3; > + avi->sc10 = buf[3] & 0x3; > + avi->f47 = (buf[4] >> 7) & 0x1; > + avi->vic = buf[4] & 0x7f; > + avi->yq10 = (buf[5] >> 6) & 0x3; > + avi->cn10 = (buf[5] >> 4) & 0x3; > + avi->pr3210 = buf[5] & 0xf; > + avi->etb = buf[6] + 256 * buf[7]; > + avi->sbb = buf[8] + 256 * buf[9]; > + avi->elb = buf[10] + 256 * buf[11]; > + avi->srb = buf[12] + 256 * buf[13]; > +} > + > +static void print_avi_infoframe(struct v4l2_subdev *sd) > +{ > + u8 buf[14]; > + u8 avi_len; > + u8 avi_ver; > + struct aviInfoFrame avi; > + > + if (!is_hdmi(sd)) { > + v4l2_info(sd, "receive DVI-D signal (AVI infoframe not > supported)\n"); > + return; > + } > + > + avi_ver = i2c_rd8(sd, PK_AVI_1HEAD); > + avi_len = i2c_rd8(sd, PK_AVI_2HEAD); > + v4l2_info(sd, "AVI infoframe version %d (%d byte)\n", avi_ver, avi_len); > + > + if (avi_ver != 0x02) > + return; > + > + i2c_rd(sd, PK_AVI_0BYTE, buf, ARRAY_SIZE(buf)); > + > + v4l2_info(sd, "\t%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x > %02x %02x %02x\n", > + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], > + buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], > + buf[13]); > + > + parse_avi_infoframe(sd, buf, &avi); > + > + if (avi.vic) > + v4l2_info(sd, "\tVIC: %d\n", avi.vic); > + if (avi.itc) > + v4l2_info(sd, "\t%s\n", itcText[avi.itc]); > + > + if (avi.y10) > + v4l2_info(sd, "\t%s %s\n", y10Text[avi.y10], > + !avi.c10 ? "" : > + (avi.c10 == 0x3 ? ec210Text[avi.ec210] : > + c10Text[avi.c10])); > + else > + v4l2_info(sd, "\t%s %s\n", y10Text[avi.y10], q10Text[avi.q10]); > +} The drivers/video/hdmi.c has new InfoFrame logging functions that should be used instead rather than duplicating code. See adv7842_log_infoframes in the adv7842 driver. > +static int tc358743_get_fmt(struct v4l2_subdev *sd, > + struct v4l2_subdev_pad_config *cfg, > + str
Re: [PATCH] Driver for Toshiba TC358743 HDMI to CSI-2 bridge
Hi Mats, Here is one more: On 05/06/15 11:27, matra...@cisco.com wrote: > From: Mats Randgaard > > The driver is tested on our hardware and all the implemented features > works as expected. > > Missing features: > - CEC support > - HDCP repeater support > - IR support > > Signed-off-by: Mats Randgaard > --- > MAINTAINERS|6 + > drivers/media/i2c/Kconfig |9 + > drivers/media/i2c/Makefile |1 + > drivers/media/i2c/tc358743.c | 1838 > > drivers/media/i2c/tc358743_regs.h | 680 + > include/media/tc358743.h | 92 ++ > include/uapi/linux/v4l2-controls.h |4 + > 7 files changed, 2630 insertions(+) > create mode 100644 drivers/media/i2c/tc358743.c > create mode 100644 drivers/media/i2c/tc358743_regs.h > create mode 100644 include/media/tc358743.h > > +static int tc358743_set_fmt(struct v4l2_subdev *sd, > + struct v4l2_subdev_pad_config *cfg, > + struct v4l2_subdev_format *format) > +{ > + struct tc358743_state *state = to_state(sd); > + > + if (format->pad != 0) > + return -EINVAL; > + > + switch (format->format.code) { > + case MEDIA_BUS_FMT_RGB888_1X24: > + case MEDIA_BUS_FMT_UYVY8_1X16: > + state->mbus_fmt_code = format->format.code; > + break; > + default: > + return -EINVAL; > + } > + > + enable_stream(sd, false); > + tc358743_set_pll(sd); > + tc358743_set_csi(sd); > + tc358743_set_csi_color_space(sd); > + > + return 0; > +} I'd rewrite this as follows: static int tc358743_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *format) { struct tc358743_state *state = to_state(sd); u32 code = format->format.code; /* is overwritten by get_fmt */ int ret = tc358743_get_fmt(sd, cfg, format); format->format.code = code; if (ret) return ret; switch (code) { case MEDIA_BUS_FMT_RGB888_1X24: case MEDIA_BUS_FMT_UYVY8_1X16: break; default: return -EINVAL; } if (format->which == V4L2_SUBDEV_FORMAT_TRY) return 0; enable_stream(sd, false); tc358743_set_pll(sd); tc358743_set_csi(sd); tc358743_set_csi_color_space(sd); return 0; } The call to tc358743_get_fmt() ensures that all the other fields are filled in correctly, and the FORMAT_TRY check ensures that calling this with FORMAT_TRY doesn't actually change anything. Obviously, set_fmt should be moved after get_fmt so that it can call the get_fmt function, and like get_fmt it should be moved to the PAD OPS section. Regards, Hans -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html