Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/i2c Add driver for NXP TDA19988 HDMI encoder



details:   https://anonhg.NetBSD.org/src/rev/d5fe53b25dd0
branches:  trunk
changeset: 460785:d5fe53b25dd0
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Nov 03 22:57:52 2019 +0000

description:
Add driver for NXP TDA19988 HDMI encoder

diffstat:

 sys/dev/i2c/files.i2c  |    7 +-
 sys/dev/i2c/tda19988.c |  930 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 936 insertions(+), 1 deletions(-)

diffs (truncated from 952 to 300 lines):

diff -r 21d6d7e78f32 -r d5fe53b25dd0 sys/dev/i2c/files.i2c
--- a/sys/dev/i2c/files.i2c     Sun Nov 03 22:55:34 2019 +0000
+++ b/sys/dev/i2c/files.i2c     Sun Nov 03 22:57:52 2019 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.i2c,v 1.103 2019/11/01 09:59:22 jmcneill Exp $
+#      $NetBSD: files.i2c,v 1.104 2019/11/03 22:57:52 jmcneill Exp $
 
 obsolete defflag       opt_i2cbus.h            I2C_SCAN
 define i2cbus { }
@@ -373,3 +373,8 @@
 device twl
 attach twl at iic
 file   dev/i2c/twl4030.c                       twl
+
+# NXP TDA19988 HDMI encoder
+device tdahdmi: edid, videomode, drmkms, drmkms_i2c
+attach tdahdmi at iic
+file   dev/i2c/tda19988.c                      tdahdmi
diff -r 21d6d7e78f32 -r d5fe53b25dd0 sys/dev/i2c/tda19988.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/i2c/tda19988.c    Sun Nov 03 22:57:52 2019 +0000
@@ -0,0 +1,930 @@
+/* $NetBSD: tda19988.c,v 1.1 2019/11/03 22:57:52 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo%freebsd.org@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: tda19988.c,v 1.1 2019/11/03 22:57:52 jmcneill Exp $");
+
+/*
+* NXP TDA19988 HDMI encoder 
+*/
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/time.h>
+#include <sys/bus.h>
+#include <sys/types.h>
+
+#include <dev/i2c/i2cvar.h>
+#include <dev/i2c/ddcvar.h>
+#include <dev/i2c/ddcreg.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/fdt_port.h>
+
+#include <dev/videomode/videomode.h>
+#include <dev/videomode/edidvar.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+
+enum {
+       TDA19988_PORT_INPUT = 0
+};
+
+#define        MKREG(page, addr)       (((page) << 8) | (addr))
+
+#define        REGPAGE(reg)            (((reg) >> 8) & 0xff)
+#define        REGADDR(reg)            ((reg) & 0xff)
+
+#define TDA_VERSION            MKREG(0x00, 0x00)
+#define TDA_MAIN_CNTRL0                MKREG(0x00, 0x01)
+#define        MAIN_CNTRL0_SR          (1 << 0)
+#define TDA_VERSION_MSB                MKREG(0x00, 0x02)
+#define        TDA_SOFTRESET           MKREG(0x00, 0x0a)
+#define                SOFTRESET_I2C           (1 << 1)
+#define                SOFTRESET_AUDIO         (1 << 0)
+#define        TDA_DDC_CTRL            MKREG(0x00, 0x0b)
+#define                DDC_ENABLE              0
+#define        TDA_CCLK                MKREG(0x00, 0x0c)
+#define                CCLK_ENABLE             1
+#define        TDA_INT_FLAGS_2         MKREG(0x00, 0x11)
+#define                INT_FLAGS_2_EDID_BLK_RD (1 << 1)
+
+#define        TDA_VIP_CNTRL_0         MKREG(0x00, 0x20)
+#define        TDA_VIP_CNTRL_1         MKREG(0x00, 0x21)
+#define        TDA_VIP_CNTRL_2         MKREG(0x00, 0x22)
+#define        TDA_VIP_CNTRL_3         MKREG(0x00, 0x23)
+#define                VIP_CNTRL_3_SYNC_HS     (2 << 4)
+#define                VIP_CNTRL_3_V_TGL       (1 << 2)
+#define                VIP_CNTRL_3_H_TGL       (1 << 1)
+
+#define        TDA_VIP_CNTRL_4         MKREG(0x00, 0x24)
+#define                VIP_CNTRL_4_BLANKIT_NDE         (0 << 2)
+#define                VIP_CNTRL_4_BLANKIT_HS_VS       (1 << 2)
+#define                VIP_CNTRL_4_BLANKIT_NHS_VS      (2 << 2)
+#define                VIP_CNTRL_4_BLANKIT_HE_VE       (3 << 2)
+#define                VIP_CNTRL_4_BLC_NONE            (0 << 0)
+#define                VIP_CNTRL_4_BLC_RGB444          (1 << 0)
+#define                VIP_CNTRL_4_BLC_YUV444          (2 << 0)
+#define                VIP_CNTRL_4_BLC_YUV422          (3 << 0)
+#define        TDA_VIP_CNTRL_5         MKREG(0x00, 0x25)
+#define                VIP_CNTRL_5_SP_CNT(n)   (((n) & 3) << 1)
+#define        TDA_MUX_VP_VIP_OUT      MKREG(0x00, 0x27)
+#define TDA_MAT_CONTRL         MKREG(0x00, 0x80)
+#define                MAT_CONTRL_MAT_BP       (1 << 2)
+#define        TDA_VIDFORMAT           MKREG(0x00, 0xa0)
+#define        TDA_REFPIX_MSB          MKREG(0x00, 0xa1)
+#define        TDA_REFPIX_LSB          MKREG(0x00, 0xa2)
+#define        TDA_REFLINE_MSB         MKREG(0x00, 0xa3)
+#define        TDA_REFLINE_LSB         MKREG(0x00, 0xa4)
+#define        TDA_NPIX_MSB            MKREG(0x00, 0xa5)
+#define        TDA_NPIX_LSB            MKREG(0x00, 0xa6)
+#define        TDA_NLINE_MSB           MKREG(0x00, 0xa7)
+#define        TDA_NLINE_LSB           MKREG(0x00, 0xa8)
+#define        TDA_VS_LINE_STRT_1_MSB  MKREG(0x00, 0xa9)
+#define        TDA_VS_LINE_STRT_1_LSB  MKREG(0x00, 0xaa)
+#define        TDA_VS_PIX_STRT_1_MSB   MKREG(0x00, 0xab)
+#define        TDA_VS_PIX_STRT_1_LSB   MKREG(0x00, 0xac)
+#define        TDA_VS_LINE_END_1_MSB   MKREG(0x00, 0xad)
+#define        TDA_VS_LINE_END_1_LSB   MKREG(0x00, 0xae)
+#define        TDA_VS_PIX_END_1_MSB    MKREG(0x00, 0xaf)
+#define        TDA_VS_PIX_END_1_LSB    MKREG(0x00, 0xb0)
+#define        TDA_VS_LINE_STRT_2_MSB  MKREG(0x00, 0xb1)
+#define        TDA_VS_LINE_STRT_2_LSB  MKREG(0x00, 0xb2)
+#define        TDA_VS_PIX_STRT_2_MSB   MKREG(0x00, 0xb3)
+#define        TDA_VS_PIX_STRT_2_LSB   MKREG(0x00, 0xb4)
+#define        TDA_VS_LINE_END_2_MSB   MKREG(0x00, 0xb5)
+#define        TDA_VS_LINE_END_2_LSB   MKREG(0x00, 0xb6)
+#define        TDA_VS_PIX_END_2_MSB    MKREG(0x00, 0xb7)
+#define        TDA_VS_PIX_END_2_LSB    MKREG(0x00, 0xb8)
+#define        TDA_HS_PIX_START_MSB    MKREG(0x00, 0xb9)
+#define        TDA_HS_PIX_START_LSB    MKREG(0x00, 0xba)
+#define        TDA_HS_PIX_STOP_MSB     MKREG(0x00, 0xbb)
+#define        TDA_HS_PIX_STOP_LSB     MKREG(0x00, 0xbc)
+#define        TDA_VWIN_START_1_MSB    MKREG(0x00, 0xbd)
+#define        TDA_VWIN_START_1_LSB    MKREG(0x00, 0xbe)
+#define        TDA_VWIN_END_1_MSB      MKREG(0x00, 0xbf)
+#define        TDA_VWIN_END_1_LSB      MKREG(0x00, 0xc0)
+#define        TDA_VWIN_START_2_MSB    MKREG(0x00, 0xc1)
+#define        TDA_VWIN_START_2_LSB    MKREG(0x00, 0xc2)
+#define        TDA_VWIN_END_2_MSB      MKREG(0x00, 0xc3)
+#define        TDA_VWIN_END_2_LSB      MKREG(0x00, 0xc4)
+#define        TDA_DE_START_MSB        MKREG(0x00, 0xc5)
+#define        TDA_DE_START_LSB        MKREG(0x00, 0xc6)
+#define        TDA_DE_STOP_MSB         MKREG(0x00, 0xc7)
+#define        TDA_DE_STOP_LSB         MKREG(0x00, 0xc8)
+
+#define        TDA_TBG_CNTRL_0         MKREG(0x00, 0xca)
+#define                TBG_CNTRL_0_SYNC_ONCE   (1 << 7)
+#define                TBG_CNTRL_0_SYNC_MTHD   (1 << 6)
+
+#define        TDA_TBG_CNTRL_1         MKREG(0x00, 0xcb)
+#define                TBG_CNTRL_1_DWIN_DIS    (1 << 6)
+#define                TBG_CNTRL_1_TGL_EN      (1 << 2)
+#define                TBG_CNTRL_1_V_TGL       (1 << 1)
+#define                TBG_CNTRL_1_H_TGL       (1 << 0)
+
+#define        TDA_HVF_CNTRL_0         MKREG(0x00, 0xe4)
+#define                HVF_CNTRL_0_PREFIL_NONE         (0 << 2)
+#define                HVF_CNTRL_0_INTPOL_BYPASS       (0 << 0)
+#define        TDA_HVF_CNTRL_1         MKREG(0x00, 0xe5)
+#define                HVF_CNTRL_1_VQR(x)      (((x) & 3) << 2)
+#define                HVF_CNTRL_1_VQR_FULL    HVF_CNTRL_1_VQR(0)
+#define        TDA_ENABLE_SPACE        MKREG(0x00, 0xd6)
+#define        TDA_RPT_CNTRL           MKREG(0x00, 0xf0)
+
+#define        TDA_PLL_SERIAL_1        MKREG(0x02, 0x00)
+#define                PLL_SERIAL_1_SRL_MAN_IP (1 << 6)
+#define        TDA_PLL_SERIAL_2        MKREG(0x02, 0x01)
+#define                PLL_SERIAL_2_SRL_PR(x)          (((x) & 0xf) << 4)
+#define                PLL_SERIAL_2_SRL_NOSC(x)        (((x) & 0x3) << 0)
+#define        TDA_PLL_SERIAL_3        MKREG(0x02, 0x02)
+#define                PLL_SERIAL_3_SRL_PXIN_SEL       (1 << 4)
+#define                PLL_SERIAL_3_SRL_DE             (1 << 2)
+#define                PLL_SERIAL_3_SRL_CCIR           (1 << 0)
+#define        TDA_SERIALIZER          MKREG(0x02, 0x03)
+#define        TDA_BUFFER_OUT          MKREG(0x02, 0x04)
+#define        TDA_PLL_SCG1            MKREG(0x02, 0x05)
+#define        TDA_PLL_SCG2            MKREG(0x02, 0x06)
+#define        TDA_PLL_SCGN1           MKREG(0x02, 0x07)
+#define        TDA_PLL_SCGN2           MKREG(0x02, 0x08)
+#define        TDA_PLL_SCGR1           MKREG(0x02, 0x09)
+#define        TDA_PLL_SCGR2           MKREG(0x02, 0x0a)
+
+#define        TDA_SEL_CLK             MKREG(0x02, 0x11)
+#define                SEL_CLK_ENA_SC_CLK      (1 << 3)
+#define                SEL_CLK_SEL_VRF_CLK(x)  (((x) & 3) << 1)
+#define                SEL_CLK_SEL_CLK1        (1 << 0)
+#define        TDA_ANA_GENERAL         MKREG(0x02, 0x12)
+
+#define        TDA_EDID_DATA0          MKREG(0x09, 0x00)
+#define        TDA_EDID_CTRL           MKREG(0x09, 0xfa)
+#define        TDA_DDC_ADDR            MKREG(0x09, 0xfb)
+#define        TDA_DDC_OFFS            MKREG(0x09, 0xfc)
+#define        TDA_DDC_SEGM_ADDR       MKREG(0x09, 0xfd)
+#define        TDA_DDC_SEGM            MKREG(0x09, 0xfe)
+
+#define        TDA_IF_VSP              MKREG(0x10, 0x20)
+#define        TDA_IF_AVI              MKREG(0x10, 0x40)
+#define        TDA_IF_SPD              MKREG(0x10, 0x60)
+#define        TDA_IF_AUD              MKREG(0x10, 0x80)
+#define        TDA_IF_MPS              MKREG(0x10, 0xa0)
+
+#define        TDA_ENC_CNTRL           MKREG(0x11, 0x0d)
+#define                ENC_CNTRL_DVI_MODE      (0 << 2)
+#define                ENC_CNTRL_HDMI_MODE     (1 << 2)
+#define        TDA_DIP_IF_FLAGS        MKREG(0x11, 0x0f)
+#define                DIP_IF_FLAGS_IF5        (1 << 5)
+#define                DIP_IF_FLAGS_IF4        (1 << 4)
+#define                DIP_IF_FLAGS_IF3        (1 << 3)
+#define                DIP_IF_FLAGS_IF2        (1 << 2) /* AVI IF on page 10h */
+#define                DIP_IF_FLAGS_IF1        (1 << 1)
+
+#define        TDA_TX3                 MKREG(0x12, 0x9a)
+#define        TDA_TX4                 MKREG(0x12, 0x9b)
+#define                TX4_PD_RAM              (1 << 1)
+#define        TDA_HDCP_TX33           MKREG(0x12, 0xb8)
+#define                HDCP_TX33_HDMI          (1 << 1)
+
+#define        TDA_CURPAGE_ADDR        0xff
+
+#define        TDA_CEC_RXSHPDLEV       0xfe
+#define                RXSHPDLEV_HPD   __BIT(1)
+
+#define        TDA_CEC_ENAMODS         0xff
+#define                ENAMODS_RXSENS          (1 << 2)
+#define                ENAMODS_HDMI            (1 << 1)
+#define        TDA_CEC_FRO_IM_CLK_CTRL 0xfb
+#define                CEC_FRO_IM_CLK_CTRL_GHOST_DIS   (1 << 7)
+#define                CEC_FRO_IM_CLK_CTRL_IMCLK_SEL   (1 << 1)
+
+/* EDID reading */ 
+#define        MAX_READ_ATTEMPTS       100
+
+/* EDID fields */
+#define        EDID_MODES0             35
+#define        EDID_MODES1             36
+#define        EDID_TIMING_START       38
+#define        EDID_TIMING_END         54
+#define        EDID_TIMING_X(v)        (((v) + 31) * 8)
+#define        EDID_FREQ(v)            (((v) & 0x3f) + 60)
+#define        EDID_RATIO(v)           (((v) >> 6) & 0x3)
+#define        EDID_RATIO_10x16        0
+#define        EDID_RATIO_3x4          1       
+#define        EDID_RATIO_4x5          2       
+#define        EDID_RATIO_9x16         3
+
+#define        TDA19988                0x0301
+
+static const struct device_compatible_entry compat_data[] = {
+       { "nxp,tda998x",        1 },
+       { NULL }
+};
+
+struct tda19988_softc;
+
+struct tda19988_connector {
+       struct drm_connector    base;
+       struct tda19988_softc   *sc;
+};
+
+struct tda19988_softc {
+       device_t                sc_dev;
+       i2c_tag_t               sc_i2c;
+       i2c_addr_t              sc_addr;
+       uint32_t                sc_cec_addr;
+       uint16_t                sc_version;
+       int                     sc_current_page;
+       uint8_t                 *sc_edid;
+       uint32_t                sc_edid_len;
+
+       struct drm_bridge       sc_bridge;
+       struct tda19988_connector sc_connector;
+
+       struct fdt_device_ports sc_ports;
+       struct drm_display_mode sc_curmode;
+};
+
+#define        to_tda_connector(x)     container_of(x, struct tda19988_connector, base)
+
+static int
+tda19988_set_page(struct tda19988_softc *sc, uint8_t page)



Home | Main Index | Thread Index | Old Index