From mboxrd@z Thu Jan 1 00:00:00 1970 From: moinejf@free.fr (Jean-Francois Moine) Date: Thu, 9 Jan 2014 11:57:24 +0100 Subject: [PATCH v2 1/28] drm/i2c: tda998x: simplify the i2c read/write functions Message-ID: <20140109115724.61340f29@armhf> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org This patch simplifies the i2c read/write functions and permits them to be easily called in more contexts. Signed-off-by: Jean-Francois Moine --- drivers/gpu/drm/i2c/tda998x_drv.c | 322 +++++++++++---------- 1 file changed, 162 insertions(+), 160 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 400b0c4..26dd299 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -30,6 +30,7 @@ struct tda998x_priv { struct i2c_client *cec; + struct i2c_client *hdmi; uint16_t rev; uint8_t current_page; int dpms; @@ -328,9 +329,9 @@ struct tda998x_priv { #define TDA19988 0x0301 static void -cec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val) +cec_write(struct tda998x_priv *priv, uint16_t addr, uint8_t val) { - struct i2c_client *client = to_tda998x_priv(encoder)->cec; + struct i2c_client *client = priv->cec; uint8_t buf[] = {addr, val}; int ret; @@ -340,9 +341,9 @@ cec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val) } static uint8_t -cec_read(struct drm_encoder *encoder, uint8_t addr) +cec_read(struct tda998x_priv *priv, uint8_t addr) { - struct i2c_client *client = to_tda998x_priv(encoder)->cec; + struct i2c_client *client = priv->cec; uint8_t val; int ret; @@ -362,12 +363,10 @@ fail: } static void -set_page(struct drm_encoder *encoder, uint16_t reg) +set_page(struct tda998x_priv *priv, uint16_t reg) { - struct tda998x_priv *priv = to_tda998x_priv(encoder); - if (REG2PAGE(reg) != priv->current_page) { - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + struct i2c_client *client = priv->hdmi; uint8_t buf[] = { REG_CURPAGE, REG2PAGE(reg) }; @@ -380,13 +379,13 @@ set_page(struct drm_encoder *encoder, uint16_t reg) } static int -reg_read_range(struct drm_encoder *encoder, uint16_t reg, char *buf, int cnt) +reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt) { - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + struct i2c_client *client = priv->hdmi; uint8_t addr = REG2ADDR(reg); int ret; - set_page(encoder, reg); + set_page(priv, reg); ret = i2c_master_send(client, &addr, sizeof(addr)); if (ret < 0) @@ -404,16 +403,16 @@ fail: } static void -reg_write_range(struct drm_encoder *encoder, uint16_t reg, uint8_t *p, int cnt) +reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt) { - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + struct i2c_client *client = priv->hdmi; uint8_t buf[cnt+1]; int ret; buf[0] = REG2ADDR(reg); memcpy(&buf[1], p, cnt); - set_page(encoder, reg); + set_page(priv, reg); ret = i2c_master_send(client, buf, cnt + 1); if (ret < 0) @@ -421,21 +420,21 @@ reg_write_range(struct drm_encoder *encoder, uint16_t reg, uint8_t *p, int cnt) } static uint8_t -reg_read(struct drm_encoder *encoder, uint16_t reg) +reg_read(struct tda998x_priv *priv, uint16_t reg) { uint8_t val = 0; - reg_read_range(encoder, reg, &val, sizeof(val)); + reg_read_range(priv, reg, &val, sizeof(val)); return val; } static void -reg_write(struct drm_encoder *encoder, uint16_t reg, uint8_t val) +reg_write(struct tda998x_priv *priv, uint16_t reg, uint8_t val) { - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + struct i2c_client *client = priv->hdmi; uint8_t buf[] = {REG2ADDR(reg), val}; int ret; - set_page(encoder, reg); + set_page(priv, reg); ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); if (ret < 0) @@ -443,13 +442,13 @@ reg_write(struct drm_encoder *encoder, uint16_t reg, uint8_t val) } static void -reg_write16(struct drm_encoder *encoder, uint16_t reg, uint16_t val) +reg_write16(struct tda998x_priv *priv, uint16_t reg, uint16_t val) { - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + struct i2c_client *client = priv->hdmi; uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; int ret; - set_page(encoder, reg); + set_page(priv, reg); ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); if (ret < 0) @@ -457,47 +456,47 @@ reg_write16(struct drm_encoder *encoder, uint16_t reg, uint16_t val) } static void -reg_set(struct drm_encoder *encoder, uint16_t reg, uint8_t val) +reg_set(struct tda998x_priv *priv, uint16_t reg, uint8_t val) { - reg_write(encoder, reg, reg_read(encoder, reg) | val); + reg_write(priv, reg, reg_read(priv, reg) | val); } static void -reg_clear(struct drm_encoder *encoder, uint16_t reg, uint8_t val) +reg_clear(struct tda998x_priv *priv, uint16_t reg, uint8_t val) { - reg_write(encoder, reg, reg_read(encoder, reg) & ~val); + reg_write(priv, reg, reg_read(priv, reg) & ~val); } static void -tda998x_reset(struct drm_encoder *encoder) +tda998x_reset(struct tda998x_priv *priv) { /* reset audio and i2c master: */ - reg_set(encoder, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); + reg_set(priv, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); msleep(50); - reg_clear(encoder, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); + reg_clear(priv, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); msleep(50); /* reset transmitter: */ - reg_set(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); - reg_clear(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); + reg_set(priv, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); + reg_clear(priv, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); /* PLL registers common configuration */ - reg_write(encoder, REG_PLL_SERIAL_1, 0x00); - reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1)); - reg_write(encoder, REG_PLL_SERIAL_3, 0x00); - reg_write(encoder, REG_SERIALIZER, 0x00); - reg_write(encoder, REG_BUFFER_OUT, 0x00); - reg_write(encoder, REG_PLL_SCG1, 0x00); - reg_write(encoder, REG_AUDIO_DIV, AUDIO_DIV_SERCLK_8); - reg_write(encoder, REG_SEL_CLK, SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); - reg_write(encoder, REG_PLL_SCGN1, 0xfa); - reg_write(encoder, REG_PLL_SCGN2, 0x00); - reg_write(encoder, REG_PLL_SCGR1, 0x5b); - reg_write(encoder, REG_PLL_SCGR2, 0x00); - reg_write(encoder, REG_PLL_SCG2, 0x10); + reg_write(priv, REG_PLL_SERIAL_1, 0x00); + reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1)); + reg_write(priv, REG_PLL_SERIAL_3, 0x00); + reg_write(priv, REG_SERIALIZER, 0x00); + reg_write(priv, REG_BUFFER_OUT, 0x00); + reg_write(priv, REG_PLL_SCG1, 0x00); + reg_write(priv, REG_AUDIO_DIV, AUDIO_DIV_SERCLK_8); + reg_write(priv, REG_SEL_CLK, SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); + reg_write(priv, REG_PLL_SCGN1, 0xfa); + reg_write(priv, REG_PLL_SCGN2, 0x00); + reg_write(priv, REG_PLL_SCGR1, 0x5b); + reg_write(priv, REG_PLL_SCGR2, 0x00); + reg_write(priv, REG_PLL_SCG2, 0x10); /* Write the default value MUX register */ - reg_write(encoder, REG_MUX_VP_VIP_OUT, 0x24); + reg_write(priv, REG_MUX_VP_VIP_OUT, 0x24); } static uint8_t tda998x_cksum(uint8_t *buf, size_t bytes) @@ -513,18 +512,18 @@ static uint8_t tda998x_cksum(uint8_t *buf, size_t bytes) #define PB(x) (HB(2) + 1 + (x)) static void -tda998x_write_if(struct drm_encoder *encoder, uint8_t bit, uint16_t addr, +tda998x_write_if(struct tda998x_priv *priv, uint8_t bit, uint16_t addr, uint8_t *buf, size_t size) { buf[PB(0)] = tda998x_cksum(buf, size); - reg_clear(encoder, REG_DIP_IF_FLAGS, bit); - reg_write_range(encoder, addr, buf, size); - reg_set(encoder, REG_DIP_IF_FLAGS, bit); + reg_clear(priv, REG_DIP_IF_FLAGS, bit); + reg_write_range(priv, addr, buf, size); + reg_set(priv, REG_DIP_IF_FLAGS, bit); } static void -tda998x_write_aif(struct drm_encoder *encoder, struct tda998x_encoder_params *p) +tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p) { uint8_t buf[PB(5) + 1]; @@ -537,12 +536,12 @@ tda998x_write_aif(struct drm_encoder *encoder, struct tda998x_encoder_params *p) buf[PB(4)] = p->audio_frame[4]; buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */ - tda998x_write_if(encoder, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, + tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, sizeof(buf)); } static void -tda998x_write_avi(struct drm_encoder *encoder, struct drm_display_mode *mode) +tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode) { uint8_t buf[PB(13) + 1]; @@ -554,36 +553,36 @@ tda998x_write_avi(struct drm_encoder *encoder, struct drm_display_mode *mode) buf[PB(3)] = HDMI_QUANTIZATION_RANGE_FULL << 2; buf[PB(4)] = drm_match_cea_mode(mode); - tda998x_write_if(encoder, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf, + tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf, sizeof(buf)); } -static void tda998x_audio_mute(struct drm_encoder *encoder, bool on) +static void tda998x_audio_mute(struct tda998x_priv *priv, bool on) { if (on) { - reg_set(encoder, REG_SOFTRESET, SOFTRESET_AUDIO); - reg_clear(encoder, REG_SOFTRESET, SOFTRESET_AUDIO); - reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); + reg_set(priv, REG_SOFTRESET, SOFTRESET_AUDIO); + reg_clear(priv, REG_SOFTRESET, SOFTRESET_AUDIO); + reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); } else { - reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); + reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); } } static void -tda998x_configure_audio(struct drm_encoder *encoder, +tda998x_configure_audio(struct tda998x_priv *priv, struct drm_display_mode *mode, struct tda998x_encoder_params *p) { uint8_t buf[6], clksel_aip, clksel_fs, ca_i2s, cts_n, adiv; uint32_t n; /* Enable audio ports */ - reg_write(encoder, REG_ENA_AP, p->audio_cfg); - reg_write(encoder, REG_ENA_ACLK, p->audio_clk_cfg); + reg_write(priv, REG_ENA_AP, p->audio_cfg); + reg_write(priv, REG_ENA_ACLK, p->audio_clk_cfg); /* Set audio input source */ switch (p->audio_format) { case AFMT_SPDIF: - reg_write(encoder, REG_MUX_AP, 0x40); + reg_write(priv, REG_MUX_AP, 0x40); clksel_aip = AIP_CLKSEL_AIP(0); /* FS64SPDIF */ clksel_fs = AIP_CLKSEL_FS(2); @@ -592,7 +591,7 @@ tda998x_configure_audio(struct drm_encoder *encoder, break; case AFMT_I2S: - reg_write(encoder, REG_MUX_AP, 0x64); + reg_write(priv, REG_MUX_AP, 0x64); clksel_aip = AIP_CLKSEL_AIP(1); /* ACLK */ clksel_fs = AIP_CLKSEL_FS(0); @@ -605,12 +604,12 @@ tda998x_configure_audio(struct drm_encoder *encoder, return; } - reg_write(encoder, REG_AIP_CLKSEL, clksel_aip); - reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_LAYOUT); + reg_write(priv, REG_AIP_CLKSEL, clksel_aip); + reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_LAYOUT); /* Enable automatic CTS generation */ - reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_ACR_MAN); - reg_write(encoder, REG_CTS_N, cts_n); + reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_ACR_MAN); + reg_write(priv, REG_CTS_N, cts_n); /* * Audio input somehow depends on HDMI line rate which is @@ -623,7 +622,7 @@ tda998x_configure_audio(struct drm_encoder *encoder, adiv = AUDIO_DIV_SERCLK_16; else adiv = AUDIO_DIV_SERCLK_8; - reg_write(encoder, REG_AUDIO_DIV, adiv); + reg_write(priv, REG_AUDIO_DIV, adiv); /* * This is the approximate value of N, which happens to be @@ -638,28 +637,28 @@ tda998x_configure_audio(struct drm_encoder *encoder, buf[3] = n; buf[4] = n >> 8; buf[5] = n >> 16; - reg_write_range(encoder, REG_ACR_CTS_0, buf, 6); + reg_write_range(priv, REG_ACR_CTS_0, buf, 6); /* Set CTS clock reference */ - reg_write(encoder, REG_AIP_CLKSEL, clksel_aip | clksel_fs); + reg_write(priv, REG_AIP_CLKSEL, clksel_aip | clksel_fs); /* Reset CTS generator */ - reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); - reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); + reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); + reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); /* Write the channel status */ buf[0] = 0x04; buf[1] = 0x00; buf[2] = 0x00; buf[3] = 0xf1; - reg_write_range(encoder, REG_CH_STAT_B(0), buf, 4); + reg_write_range(priv, REG_CH_STAT_B(0), buf, 4); - tda998x_audio_mute(encoder, true); + tda998x_audio_mute(priv, true); mdelay(20); - tda998x_audio_mute(encoder, false); + tda998x_audio_mute(priv, false); /* Write the audio information packet */ - tda998x_write_aif(encoder, p); + tda998x_write_aif(priv, p); } /* DRM encoder functions */ @@ -701,19 +700,19 @@ tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) switch (mode) { case DRM_MODE_DPMS_ON: /* enable video ports, audio will be enabled later */ - reg_write(encoder, REG_ENA_VP_0, 0xff); - reg_write(encoder, REG_ENA_VP_1, 0xff); - reg_write(encoder, REG_ENA_VP_2, 0xff); + reg_write(priv, REG_ENA_VP_0, 0xff); + reg_write(priv, REG_ENA_VP_1, 0xff); + reg_write(priv, REG_ENA_VP_2, 0xff); /* set muxing after enabling ports: */ - reg_write(encoder, REG_VIP_CNTRL_0, priv->vip_cntrl_0); - reg_write(encoder, REG_VIP_CNTRL_1, priv->vip_cntrl_1); - reg_write(encoder, REG_VIP_CNTRL_2, priv->vip_cntrl_2); + reg_write(priv, REG_VIP_CNTRL_0, priv->vip_cntrl_0); + reg_write(priv, REG_VIP_CNTRL_1, priv->vip_cntrl_1); + reg_write(priv, REG_VIP_CNTRL_2, priv->vip_cntrl_2); break; case DRM_MODE_DPMS_OFF: /* disable video ports */ - reg_write(encoder, REG_ENA_VP_0, 0x00); - reg_write(encoder, REG_ENA_VP_1, 0x00); - reg_write(encoder, REG_ENA_VP_2, 0x00); + reg_write(priv, REG_ENA_VP_0, 0x00); + reg_write(priv, REG_ENA_VP_1, 0x00); + reg_write(priv, REG_ENA_VP_2, 0x00); break; } @@ -826,57 +825,57 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, div = 148500 / mode->clock; /* mute the audio FIFO: */ - reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); + reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); /* set HDMI HDCP mode off: */ - reg_set(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); - reg_clear(encoder, REG_TX33, TX33_HDMI); + reg_set(priv, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); + reg_clear(priv, REG_TX33, TX33_HDMI); + reg_write(priv, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(0)); - reg_write(encoder, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(0)); /* no pre-filter or interpolator: */ - reg_write(encoder, REG_HVF_CNTRL_0, HVF_CNTRL_0_PREFIL(0) | + reg_write(priv, REG_HVF_CNTRL_0, HVF_CNTRL_0_PREFIL(0) | HVF_CNTRL_0_INTPOL(0)); - reg_write(encoder, REG_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0)); - reg_write(encoder, REG_VIP_CNTRL_4, VIP_CNTRL_4_BLANKIT(0) | + reg_write(priv, REG_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0)); + reg_write(priv, REG_VIP_CNTRL_4, VIP_CNTRL_4_BLANKIT(0) | VIP_CNTRL_4_BLC(0)); - reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR); + reg_clear(priv, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR); - reg_clear(encoder, REG_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IZ); - reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_DE); - reg_write(encoder, REG_SERIALIZER, 0); - reg_write(encoder, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); + reg_clear(priv, REG_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IZ); + reg_clear(priv, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_DE); + reg_write(priv, REG_SERIALIZER, 0); + reg_write(priv, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */ rep = 0; - reg_write(encoder, REG_RPT_CNTRL, 0); - reg_write(encoder, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | + reg_write(priv, REG_RPT_CNTRL, 0); + reg_write(priv, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); - reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | + reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | PLL_SERIAL_2_SRL_PR(rep)); /* set color matrix bypass flag: */ - reg_set(encoder, REG_MAT_CONTRL, MAT_CONTRL_MAT_BP); + reg_set(priv, REG_MAT_CONTRL, MAT_CONTRL_MAT_BP); /* set BIAS tmds value: */ - reg_write(encoder, REG_ANA_GENERAL, 0x09); + reg_write(priv, REG_ANA_GENERAL, 0x09); - reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_MTHD); + reg_clear(priv, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_MTHD); /* * Sync on rising HSYNC/VSYNC */ - reg_write(encoder, REG_VIP_CNTRL_3, 0); - reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_SYNC_HS); + reg_write(priv, REG_VIP_CNTRL_3, 0); + reg_set(priv, REG_VIP_CNTRL_3, VIP_CNTRL_3_SYNC_HS); /* * TDA19988 requires high-active sync at input stage, * so invert low-active sync provided by master encoder here */ if (mode->flags & DRM_MODE_FLAG_NHSYNC) - reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_H_TGL); + reg_set(priv, REG_VIP_CNTRL_3, VIP_CNTRL_3_H_TGL); if (mode->flags & DRM_MODE_FLAG_NVSYNC) - reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_V_TGL); + reg_set(priv, REG_VIP_CNTRL_3, VIP_CNTRL_3_V_TGL); /* * Always generate sync polarity relative to input sync and @@ -887,49 +886,49 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, reg |= TBG_CNTRL_1_H_TGL; if (mode->flags & DRM_MODE_FLAG_NVSYNC) reg |= TBG_CNTRL_1_V_TGL; - reg_write(encoder, REG_TBG_CNTRL_1, reg); - - reg_write(encoder, REG_VIDFORMAT, 0x00); - reg_write16(encoder, REG_REFPIX_MSB, ref_pix); - reg_write16(encoder, REG_REFLINE_MSB, ref_line); - reg_write16(encoder, REG_NPIX_MSB, n_pix); - reg_write16(encoder, REG_NLINE_MSB, n_line); - reg_write16(encoder, REG_VS_LINE_STRT_1_MSB, vs1_line_s); - reg_write16(encoder, REG_VS_PIX_STRT_1_MSB, vs1_pix_s); - reg_write16(encoder, REG_VS_LINE_END_1_MSB, vs1_line_e); - reg_write16(encoder, REG_VS_PIX_END_1_MSB, vs1_pix_e); - reg_write16(encoder, REG_VS_LINE_STRT_2_MSB, vs2_line_s); - reg_write16(encoder, REG_VS_PIX_STRT_2_MSB, vs2_pix_s); - reg_write16(encoder, REG_VS_LINE_END_2_MSB, vs2_line_e); - reg_write16(encoder, REG_VS_PIX_END_2_MSB, vs2_pix_e); - reg_write16(encoder, REG_HS_PIX_START_MSB, hs_pix_s); - reg_write16(encoder, REG_HS_PIX_STOP_MSB, hs_pix_e); - reg_write16(encoder, REG_VWIN_START_1_MSB, vwin1_line_s); - reg_write16(encoder, REG_VWIN_END_1_MSB, vwin1_line_e); - reg_write16(encoder, REG_VWIN_START_2_MSB, vwin2_line_s); - reg_write16(encoder, REG_VWIN_END_2_MSB, vwin2_line_e); - reg_write16(encoder, REG_DE_START_MSB, de_pix_s); - reg_write16(encoder, REG_DE_STOP_MSB, de_pix_e); + reg_write(priv, REG_TBG_CNTRL_1, reg); + + reg_write(priv, REG_VIDFORMAT, 0x00); + reg_write16(priv, REG_REFPIX_MSB, ref_pix); + reg_write16(priv, REG_REFLINE_MSB, ref_line); + reg_write16(priv, REG_NPIX_MSB, n_pix); + reg_write16(priv, REG_NLINE_MSB, n_line); + reg_write16(priv, REG_VS_LINE_STRT_1_MSB, vs1_line_s); + reg_write16(priv, REG_VS_PIX_STRT_1_MSB, vs1_pix_s); + reg_write16(priv, REG_VS_LINE_END_1_MSB, vs1_line_e); + reg_write16(priv, REG_VS_PIX_END_1_MSB, vs1_pix_e); + reg_write16(priv, REG_VS_LINE_STRT_2_MSB, vs2_line_s); + reg_write16(priv, REG_VS_PIX_STRT_2_MSB, vs2_pix_s); + reg_write16(priv, REG_VS_LINE_END_2_MSB, vs2_line_e); + reg_write16(priv, REG_VS_PIX_END_2_MSB, vs2_pix_e); + reg_write16(priv, REG_HS_PIX_START_MSB, hs_pix_s); + reg_write16(priv, REG_HS_PIX_STOP_MSB, hs_pix_e); + reg_write16(priv, REG_VWIN_START_1_MSB, vwin1_line_s); + reg_write16(priv, REG_VWIN_END_1_MSB, vwin1_line_e); + reg_write16(priv, REG_VWIN_START_2_MSB, vwin2_line_s); + reg_write16(priv, REG_VWIN_END_2_MSB, vwin2_line_e); + reg_write16(priv, REG_DE_START_MSB, de_pix_s); + reg_write16(priv, REG_DE_STOP_MSB, de_pix_e); if (priv->rev == TDA19988) { /* let incoming pixels fill the active space (if any) */ - reg_write(encoder, REG_ENABLE_SPACE, 0x01); + reg_write(priv, REG_ENABLE_SPACE, 0x01); } /* must be last register set: */ - reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE); + reg_clear(priv, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE); /* Only setup the info frames if the sink is HDMI */ if (priv->is_hdmi_sink) { /* We need to turn HDMI HDCP stuff on to get audio through */ - reg_clear(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); - reg_write(encoder, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(1)); - reg_set(encoder, REG_TX33, TX33_HDMI); + reg_clear(priv, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); + reg_write(priv, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(1)); + reg_set(priv, REG_TX33, TX33_HDMI); - tda998x_write_avi(encoder, adjusted_mode); + tda998x_write_avi(priv, adjusted_mode); if (priv->params.audio_cfg) - tda998x_configure_audio(encoder, adjusted_mode, + tda998x_configure_audio(priv, adjusted_mode, &priv->params); } } @@ -938,7 +937,9 @@ static enum drm_connector_status tda998x_encoder_detect(struct drm_encoder *encoder, struct drm_connector *connector) { - uint8_t val = cec_read(encoder, REG_CEC_RXSHPDLEV); + struct tda998x_priv *priv = to_tda998x_priv(encoder); + uint8_t val = cec_read(priv, REG_CEC_RXSHPDLEV); + return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected : connector_status_disconnected; } @@ -946,29 +947,30 @@ tda998x_encoder_detect(struct drm_encoder *encoder, static int read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) { + struct tda998x_priv *priv = to_tda998x_priv(encoder); uint8_t offset, segptr; int ret, i; /* enable EDID read irq: */ - reg_set(encoder, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); + reg_set(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); offset = (blk & 1) ? 128 : 0; segptr = blk / 2; - reg_write(encoder, REG_DDC_ADDR, 0xa0); - reg_write(encoder, REG_DDC_OFFS, offset); - reg_write(encoder, REG_DDC_SEGM_ADDR, 0x60); - reg_write(encoder, REG_DDC_SEGM, segptr); + reg_write(priv, REG_DDC_ADDR, 0xa0); + reg_write(priv, REG_DDC_OFFS, offset); + reg_write(priv, REG_DDC_SEGM_ADDR, 0x60); + reg_write(priv, REG_DDC_SEGM, segptr); /* enable reading EDID: */ - reg_write(encoder, REG_EDID_CTRL, 0x1); + reg_write(priv, REG_EDID_CTRL, 0x1); /* flag must be cleared by sw: */ - reg_write(encoder, REG_EDID_CTRL, 0x0); + reg_write(priv, REG_EDID_CTRL, 0x0); /* wait for block read to complete: */ for (i = 100; i > 0; i--) { - uint8_t val = reg_read(encoder, REG_INT_FLAGS_2); + uint8_t val = reg_read(priv, REG_INT_FLAGS_2); if (val & INT_FLAGS_2_EDID_BLK_RD) break; msleep(1); @@ -977,14 +979,14 @@ read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) if (i == 0) return -ETIMEDOUT; - ret = reg_read_range(encoder, REG_EDID_DATA_0, buf, EDID_LENGTH); + ret = reg_read_range(priv, REG_EDID_DATA_0, buf, EDID_LENGTH); if (ret != EDID_LENGTH) { dev_err(encoder->dev->dev, "failed to read edid block %d: %d", blk, ret); return ret; } - reg_clear(encoder, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); + reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); return 0; } @@ -1001,7 +1003,7 @@ do_get_edid(struct drm_encoder *encoder) return NULL; if (priv->rev == TDA19988) - reg_clear(encoder, REG_TX4, TX4_PD_RAM); + reg_clear(priv, REG_TX4, TX4_PD_RAM); /* base block fetch */ if (read_edid_block(encoder, block, 0)) @@ -1041,13 +1043,13 @@ do_get_edid(struct drm_encoder *encoder) done: if (priv->rev == TDA19988) - reg_set(encoder, REG_TX4, TX4_PD_RAM); + reg_set(priv, REG_TX4, TX4_PD_RAM); return block; fail: if (priv->rev == TDA19988) - reg_set(encoder, REG_TX4, TX4_PD_RAM); + reg_set(priv, REG_TX4, TX4_PD_RAM); dev_warn(encoder->dev->dev, "failed to read EDID\n"); kfree(block); return NULL; @@ -1131,7 +1133,6 @@ tda998x_encoder_init(struct i2c_client *client, struct drm_device *dev, struct drm_encoder_slave *encoder_slave) { - struct drm_encoder *encoder = &encoder_slave->base; struct tda998x_priv *priv; priv = kzalloc(sizeof(*priv), GFP_KERNEL); @@ -1143,6 +1144,7 @@ tda998x_encoder_init(struct i2c_client *client, priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5); priv->current_page = 0; + priv->hdmi = client; priv->cec = i2c_new_dummy(client->adapter, 0x34); priv->dpms = DRM_MODE_DPMS_OFF; @@ -1150,14 +1152,14 @@ tda998x_encoder_init(struct i2c_client *client, encoder_slave->slave_funcs = &tda998x_encoder_funcs; /* wake up the device: */ - cec_write(encoder, REG_CEC_ENAMODS, + cec_write(priv, REG_CEC_ENAMODS, CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); - tda998x_reset(encoder); + tda998x_reset(priv); /* read version: */ - priv->rev = reg_read(encoder, REG_VERSION_LSB) | - reg_read(encoder, REG_VERSION_MSB) << 8; + priv->rev = reg_read(priv, REG_VERSION_LSB) | + reg_read(priv, REG_VERSION_MSB) << 8; /* mask off feature bits: */ priv->rev &= ~0x30; /* not-hdcp and not-scalar bit */ @@ -1173,16 +1175,16 @@ tda998x_encoder_init(struct i2c_client *client, } /* after reset, enable DDC: */ - reg_write(encoder, REG_DDC_DISABLE, 0x00); + reg_write(priv, REG_DDC_DISABLE, 0x00); /* set clock on DDC channel: */ - reg_write(encoder, REG_TX3, 39); + reg_write(priv, REG_TX3, 39); /* if necessary, disable multi-master: */ if (priv->rev == TDA19989) - reg_set(encoder, REG_I2C_MASTER, I2C_MASTER_DIS_MM); + reg_set(priv, REG_I2C_MASTER, I2C_MASTER_DIS_MM); - cec_write(encoder, REG_CEC_FRO_IM_CLK_CTRL, + cec_write(priv, REG_CEC_FRO_IM_CLK_CTRL, CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL); return 0; -- Ken ar c'henta? | ** Breizh ha Linux atav! ** Jef | http://moinejf.free.fr/ From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jean-Francois Moine Subject: [PATCH v2 1/28] drm/i2c: tda998x: simplify the i2c read/write functions Date: Thu, 9 Jan 2014 11:57:24 +0100 Message-ID: <20140109115724.61340f29@armhf> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from smtp1-g21.free.fr (smtp1-g21.free.fr [212.27.42.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9BFB0FBCA0 for ; Thu, 9 Jan 2014 03:09:07 -0800 (PST) List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org To: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org List-Id: dri-devel@lists.freedesktop.org VGhpcyBwYXRjaCBzaW1wbGlmaWVzIHRoZSBpMmMgcmVhZC93cml0ZSBmdW5jdGlvbnMgYW5kIHBl cm1pdHMgdGhlbSB0bwpiZSBlYXNpbHkgY2FsbGVkIGluIG1vcmUgY29udGV4dHMuCgpTaWduZWQt b2ZmLWJ5OiBKZWFuLUZyYW5jb2lzIE1vaW5lIDxtb2luZWpmQGZyZWUuZnI+Ci0tLQogZHJpdmVy cy9ncHUvZHJtL2kyYy90ZGE5OTh4X2Rydi5jIHwgMzIyICsrKysrKysrKysrLS0tLS0tLS0tLQog MSBmaWxlIGNoYW5nZWQsIDE2MiBpbnNlcnRpb25zKCspLCAxNjAgZGVsZXRpb25zKC0pCgpkaWZm IC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2kyYy90ZGE5OTh4X2Rydi5jIGIvZHJpdmVycy9ncHUv ZHJtL2kyYy90ZGE5OTh4X2Rydi5jCmluZGV4IDQwMGIwYzQuLjI2ZGQyOTkgMTAwNjQ0Ci0tLSBh L2RyaXZlcnMvZ3B1L2RybS9pMmMvdGRhOTk4eF9kcnYuYworKysgYi9kcml2ZXJzL2dwdS9kcm0v aTJjL3RkYTk5OHhfZHJ2LmMKQEAgLTMwLDYgKzMwLDcgQEAKIAogc3RydWN0IHRkYTk5OHhfcHJp diB7CiAJc3RydWN0IGkyY19jbGllbnQgKmNlYzsKKwlzdHJ1Y3QgaTJjX2NsaWVudCAqaGRtaTsK IAl1aW50MTZfdCByZXY7CiAJdWludDhfdCBjdXJyZW50X3BhZ2U7CiAJaW50IGRwbXM7CkBAIC0z MjgsOSArMzI5LDkgQEAgc3RydWN0IHRkYTk5OHhfcHJpdiB7CiAjZGVmaW5lIFREQTE5OTg4ICAg ICAgICAgICAgICAgICAgMHgwMzAxCiAKIHN0YXRpYyB2b2lkCi1jZWNfd3JpdGUoc3RydWN0IGRy bV9lbmNvZGVyICplbmNvZGVyLCB1aW50MTZfdCBhZGRyLCB1aW50OF90IHZhbCkKK2NlY193cml0 ZShzdHJ1Y3QgdGRhOTk4eF9wcml2ICpwcml2LCB1aW50MTZfdCBhZGRyLCB1aW50OF90IHZhbCkK IHsKLQlzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50ID0gdG9fdGRhOTk4eF9wcml2KGVuY29kZXIp LT5jZWM7CisJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCA9IHByaXYtPmNlYzsKIAl1aW50OF90 IGJ1ZltdID0ge2FkZHIsIHZhbH07CiAJaW50IHJldDsKIApAQCAtMzQwLDkgKzM0MSw5IEBAIGNl Y193cml0ZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIsIHVpbnQxNl90IGFkZHIsIHVpbnQ4 X3QgdmFsKQogfQogCiBzdGF0aWMgdWludDhfdAotY2VjX3JlYWQoc3RydWN0IGRybV9lbmNvZGVy ICplbmNvZGVyLCB1aW50OF90IGFkZHIpCitjZWNfcmVhZChzdHJ1Y3QgdGRhOTk4eF9wcml2ICpw cml2LCB1aW50OF90IGFkZHIpCiB7Ci0Jc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCA9IHRvX3Rk YTk5OHhfcHJpdihlbmNvZGVyKS0+Y2VjOworCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQgPSBw cml2LT5jZWM7CiAJdWludDhfdCB2YWw7CiAJaW50IHJldDsKIApAQCAtMzYyLDEyICszNjMsMTAg QEAgZmFpbDoKIH0KIAogc3RhdGljIHZvaWQKLXNldF9wYWdlKHN0cnVjdCBkcm1fZW5jb2RlciAq ZW5jb2RlciwgdWludDE2X3QgcmVnKQorc2V0X3BhZ2Uoc3RydWN0IHRkYTk5OHhfcHJpdiAqcHJp diwgdWludDE2X3QgcmVnKQogewotCXN0cnVjdCB0ZGE5OTh4X3ByaXYgKnByaXYgPSB0b190ZGE5 OTh4X3ByaXYoZW5jb2Rlcik7Ci0KIAlpZiAoUkVHMlBBR0UocmVnKSAhPSBwcml2LT5jdXJyZW50 X3BhZ2UpIHsKLQkJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCA9IGRybV9pMmNfZW5jb2Rlcl9n ZXRfY2xpZW50KGVuY29kZXIpOworCQlzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50ID0gcHJpdi0+ aGRtaTsKIAkJdWludDhfdCBidWZbXSA9IHsKIAkJCQlSRUdfQ1VSUEFHRSwgUkVHMlBBR0UocmVn KQogCQl9OwpAQCAtMzgwLDEzICszNzksMTMgQEAgc2V0X3BhZ2Uoc3RydWN0IGRybV9lbmNvZGVy ICplbmNvZGVyLCB1aW50MTZfdCByZWcpCiB9CiAKIHN0YXRpYyBpbnQKLXJlZ19yZWFkX3Jhbmdl KHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwgdWludDE2X3QgcmVnLCBjaGFyICpidWYsIGlu dCBjbnQpCityZWdfcmVhZF9yYW5nZShzdHJ1Y3QgdGRhOTk4eF9wcml2ICpwcml2LCB1aW50MTZf dCByZWcsIGNoYXIgKmJ1ZiwgaW50IGNudCkKIHsKLQlzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50 ID0gZHJtX2kyY19lbmNvZGVyX2dldF9jbGllbnQoZW5jb2Rlcik7CisJc3RydWN0IGkyY19jbGll bnQgKmNsaWVudCA9IHByaXYtPmhkbWk7CiAJdWludDhfdCBhZGRyID0gUkVHMkFERFIocmVnKTsK IAlpbnQgcmV0OwogCi0Jc2V0X3BhZ2UoZW5jb2RlciwgcmVnKTsKKwlzZXRfcGFnZShwcml2LCBy ZWcpOwogCiAJcmV0ID0gaTJjX21hc3Rlcl9zZW5kKGNsaWVudCwgJmFkZHIsIHNpemVvZihhZGRy KSk7CiAJaWYgKHJldCA8IDApCkBAIC00MDQsMTYgKzQwMywxNiBAQCBmYWlsOgogfQogCiBzdGF0 aWMgdm9pZAotcmVnX3dyaXRlX3JhbmdlKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwgdWlu dDE2X3QgcmVnLCB1aW50OF90ICpwLCBpbnQgY250KQorcmVnX3dyaXRlX3JhbmdlKHN0cnVjdCB0 ZGE5OTh4X3ByaXYgKnByaXYsIHVpbnQxNl90IHJlZywgdWludDhfdCAqcCwgaW50IGNudCkKIHsK LQlzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50ID0gZHJtX2kyY19lbmNvZGVyX2dldF9jbGllbnQo ZW5jb2Rlcik7CisJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCA9IHByaXYtPmhkbWk7CiAJdWlu dDhfdCBidWZbY250KzFdOwogCWludCByZXQ7CiAKIAlidWZbMF0gPSBSRUcyQUREUihyZWcpOwog CW1lbWNweSgmYnVmWzFdLCBwLCBjbnQpOwogCi0Jc2V0X3BhZ2UoZW5jb2RlciwgcmVnKTsKKwlz ZXRfcGFnZShwcml2LCByZWcpOwogCiAJcmV0ID0gaTJjX21hc3Rlcl9zZW5kKGNsaWVudCwgYnVm LCBjbnQgKyAxKTsKIAlpZiAocmV0IDwgMCkKQEAgLTQyMSwyMSArNDIwLDIxIEBAIHJlZ193cml0 ZV9yYW5nZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIsIHVpbnQxNl90IHJlZywgdWludDhf dCAqcCwgaW50IGNudCkKIH0KIAogc3RhdGljIHVpbnQ4X3QKLXJlZ19yZWFkKHN0cnVjdCBkcm1f ZW5jb2RlciAqZW5jb2RlciwgdWludDE2X3QgcmVnKQorcmVnX3JlYWQoc3RydWN0IHRkYTk5OHhf cHJpdiAqcHJpdiwgdWludDE2X3QgcmVnKQogewogCXVpbnQ4X3QgdmFsID0gMDsKLQlyZWdfcmVh ZF9yYW5nZShlbmNvZGVyLCByZWcsICZ2YWwsIHNpemVvZih2YWwpKTsKKwlyZWdfcmVhZF9yYW5n ZShwcml2LCByZWcsICZ2YWwsIHNpemVvZih2YWwpKTsKIAlyZXR1cm4gdmFsOwogfQogCiBzdGF0 aWMgdm9pZAotcmVnX3dyaXRlKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwgdWludDE2X3Qg cmVnLCB1aW50OF90IHZhbCkKK3JlZ193cml0ZShzdHJ1Y3QgdGRhOTk4eF9wcml2ICpwcml2LCB1 aW50MTZfdCByZWcsIHVpbnQ4X3QgdmFsKQogewotCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQg PSBkcm1faTJjX2VuY29kZXJfZ2V0X2NsaWVudChlbmNvZGVyKTsKKwlzdHJ1Y3QgaTJjX2NsaWVu dCAqY2xpZW50ID0gcHJpdi0+aGRtaTsKIAl1aW50OF90IGJ1ZltdID0ge1JFRzJBRERSKHJlZyks IHZhbH07CiAJaW50IHJldDsKIAotCXNldF9wYWdlKGVuY29kZXIsIHJlZyk7CisJc2V0X3BhZ2Uo cHJpdiwgcmVnKTsKIAogCXJldCA9IGkyY19tYXN0ZXJfc2VuZChjbGllbnQsIGJ1ZiwgQVJSQVlf U0laRShidWYpKTsKIAlpZiAocmV0IDwgMCkKQEAgLTQ0MywxMyArNDQyLDEzIEBAIHJlZ193cml0 ZShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIsIHVpbnQxNl90IHJlZywgdWludDhfdCB2YWwp CiB9CiAKIHN0YXRpYyB2b2lkCi1yZWdfd3JpdGUxNihzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29k ZXIsIHVpbnQxNl90IHJlZywgdWludDE2X3QgdmFsKQorcmVnX3dyaXRlMTYoc3RydWN0IHRkYTk5 OHhfcHJpdiAqcHJpdiwgdWludDE2X3QgcmVnLCB1aW50MTZfdCB2YWwpCiB7Ci0Jc3RydWN0IGky Y19jbGllbnQgKmNsaWVudCA9IGRybV9pMmNfZW5jb2Rlcl9nZXRfY2xpZW50KGVuY29kZXIpOwor CXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQgPSBwcml2LT5oZG1pOwogCXVpbnQ4X3QgYnVmW10g PSB7UkVHMkFERFIocmVnKSwgdmFsID4+IDgsIHZhbH07CiAJaW50IHJldDsKIAotCXNldF9wYWdl KGVuY29kZXIsIHJlZyk7CisJc2V0X3BhZ2UocHJpdiwgcmVnKTsKIAogCXJldCA9IGkyY19tYXN0 ZXJfc2VuZChjbGllbnQsIGJ1ZiwgQVJSQVlfU0laRShidWYpKTsKIAlpZiAocmV0IDwgMCkKQEAg LTQ1Nyw0NyArNDU2LDQ3IEBAIHJlZ193cml0ZTE2KHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2Rl ciwgdWludDE2X3QgcmVnLCB1aW50MTZfdCB2YWwpCiB9CiAKIHN0YXRpYyB2b2lkCi1yZWdfc2V0 KHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwgdWludDE2X3QgcmVnLCB1aW50OF90IHZhbCkK K3JlZ19zZXQoc3RydWN0IHRkYTk5OHhfcHJpdiAqcHJpdiwgdWludDE2X3QgcmVnLCB1aW50OF90 IHZhbCkKIHsKLQlyZWdfd3JpdGUoZW5jb2RlciwgcmVnLCByZWdfcmVhZChlbmNvZGVyLCByZWcp IHwgdmFsKTsKKwlyZWdfd3JpdGUocHJpdiwgcmVnLCByZWdfcmVhZChwcml2LCByZWcpIHwgdmFs KTsKIH0KIAogc3RhdGljIHZvaWQKLXJlZ19jbGVhcihzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29k ZXIsIHVpbnQxNl90IHJlZywgdWludDhfdCB2YWwpCityZWdfY2xlYXIoc3RydWN0IHRkYTk5OHhf cHJpdiAqcHJpdiwgdWludDE2X3QgcmVnLCB1aW50OF90IHZhbCkKIHsKLQlyZWdfd3JpdGUoZW5j b2RlciwgcmVnLCByZWdfcmVhZChlbmNvZGVyLCByZWcpICYgfnZhbCk7CisJcmVnX3dyaXRlKHBy aXYsIHJlZywgcmVnX3JlYWQocHJpdiwgcmVnKSAmIH52YWwpOwogfQogCiBzdGF0aWMgdm9pZAot dGRhOTk4eF9yZXNldChzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCit0ZGE5OTh4X3Jlc2V0 KHN0cnVjdCB0ZGE5OTh4X3ByaXYgKnByaXYpCiB7CiAJLyogcmVzZXQgYXVkaW8gYW5kIGkyYyBt YXN0ZXI6ICovCi0JcmVnX3NldChlbmNvZGVyLCBSRUdfU09GVFJFU0VULCBTT0ZUUkVTRVRfQVVE SU8gfCBTT0ZUUkVTRVRfSTJDX01BU1RFUik7CisJcmVnX3NldChwcml2LCBSRUdfU09GVFJFU0VU LCBTT0ZUUkVTRVRfQVVESU8gfCBTT0ZUUkVTRVRfSTJDX01BU1RFUik7CiAJbXNsZWVwKDUwKTsK LQlyZWdfY2xlYXIoZW5jb2RlciwgUkVHX1NPRlRSRVNFVCwgU09GVFJFU0VUX0FVRElPIHwgU09G VFJFU0VUX0kyQ19NQVNURVIpOworCXJlZ19jbGVhcihwcml2LCBSRUdfU09GVFJFU0VULCBTT0ZU UkVTRVRfQVVESU8gfCBTT0ZUUkVTRVRfSTJDX01BU1RFUik7CiAJbXNsZWVwKDUwKTsKIAogCS8q IHJlc2V0IHRyYW5zbWl0dGVyOiAqLwotCXJlZ19zZXQoZW5jb2RlciwgUkVHX01BSU5fQ05UUkww LCBNQUlOX0NOVFJMMF9TUik7Ci0JcmVnX2NsZWFyKGVuY29kZXIsIFJFR19NQUlOX0NOVFJMMCwg TUFJTl9DTlRSTDBfU1IpOworCXJlZ19zZXQocHJpdiwgUkVHX01BSU5fQ05UUkwwLCBNQUlOX0NO VFJMMF9TUik7CisJcmVnX2NsZWFyKHByaXYsIFJFR19NQUlOX0NOVFJMMCwgTUFJTl9DTlRSTDBf U1IpOwogCiAJLyogUExMIHJlZ2lzdGVycyBjb21tb24gY29uZmlndXJhdGlvbiAqLwotCXJlZ193 cml0ZShlbmNvZGVyLCBSRUdfUExMX1NFUklBTF8xLCAweDAwKTsKLQlyZWdfd3JpdGUoZW5jb2Rl ciwgUkVHX1BMTF9TRVJJQUxfMiwgUExMX1NFUklBTF8yX1NSTF9OT1NDKDEpKTsKLQlyZWdfd3Jp dGUoZW5jb2RlciwgUkVHX1BMTF9TRVJJQUxfMywgMHgwMCk7Ci0JcmVnX3dyaXRlKGVuY29kZXIs IFJFR19TRVJJQUxJWkVSLCAgIDB4MDApOwotCXJlZ193cml0ZShlbmNvZGVyLCBSRUdfQlVGRkVS X09VVCwgICAweDAwKTsKLQlyZWdfd3JpdGUoZW5jb2RlciwgUkVHX1BMTF9TQ0cxLCAgICAgMHgw MCk7Ci0JcmVnX3dyaXRlKGVuY29kZXIsIFJFR19BVURJT19ESVYsICAgIEFVRElPX0RJVl9TRVJD TEtfOCk7Ci0JcmVnX3dyaXRlKGVuY29kZXIsIFJFR19TRUxfQ0xLLCAgICAgIFNFTF9DTEtfU0VM X0NMSzEgfCBTRUxfQ0xLX0VOQV9TQ19DTEspOwotCXJlZ193cml0ZShlbmNvZGVyLCBSRUdfUExM X1NDR04xLCAgICAweGZhKTsKLQlyZWdfd3JpdGUoZW5jb2RlciwgUkVHX1BMTF9TQ0dOMiwgICAg MHgwMCk7Ci0JcmVnX3dyaXRlKGVuY29kZXIsIFJFR19QTExfU0NHUjEsICAgIDB4NWIpOwotCXJl Z193cml0ZShlbmNvZGVyLCBSRUdfUExMX1NDR1IyLCAgICAweDAwKTsKLQlyZWdfd3JpdGUoZW5j b2RlciwgUkVHX1BMTF9TQ0cyLCAgICAgMHgxMCk7CisJcmVnX3dyaXRlKHByaXYsIFJFR19QTExf U0VSSUFMXzEsIDB4MDApOworCXJlZ193cml0ZShwcml2LCBSRUdfUExMX1NFUklBTF8yLCBQTExf U0VSSUFMXzJfU1JMX05PU0MoMSkpOworCXJlZ193cml0ZShwcml2LCBSRUdfUExMX1NFUklBTF8z LCAweDAwKTsKKwlyZWdfd3JpdGUocHJpdiwgUkVHX1NFUklBTElaRVIsICAgMHgwMCk7CisJcmVn X3dyaXRlKHByaXYsIFJFR19CVUZGRVJfT1VULCAgIDB4MDApOworCXJlZ193cml0ZShwcml2LCBS RUdfUExMX1NDRzEsICAgICAweDAwKTsKKwlyZWdfd3JpdGUocHJpdiwgUkVHX0FVRElPX0RJViwg ICAgQVVESU9fRElWX1NFUkNMS184KTsKKwlyZWdfd3JpdGUocHJpdiwgUkVHX1NFTF9DTEssICAg ICAgU0VMX0NMS19TRUxfQ0xLMSB8IFNFTF9DTEtfRU5BX1NDX0NMSyk7CisJcmVnX3dyaXRlKHBy aXYsIFJFR19QTExfU0NHTjEsICAgIDB4ZmEpOworCXJlZ193cml0ZShwcml2LCBSRUdfUExMX1ND R04yLCAgICAweDAwKTsKKwlyZWdfd3JpdGUocHJpdiwgUkVHX1BMTF9TQ0dSMSwgICAgMHg1Yik7 CisJcmVnX3dyaXRlKHByaXYsIFJFR19QTExfU0NHUjIsICAgIDB4MDApOworCXJlZ193cml0ZShw cml2LCBSRUdfUExMX1NDRzIsICAgICAweDEwKTsKIAogCS8qIFdyaXRlIHRoZSBkZWZhdWx0IHZh bHVlIE1VWCByZWdpc3RlciAqLwotCXJlZ193cml0ZShlbmNvZGVyLCBSRUdfTVVYX1ZQX1ZJUF9P VVQsIDB4MjQpOworCXJlZ193cml0ZShwcml2LCBSRUdfTVVYX1ZQX1ZJUF9PVVQsIDB4MjQpOwog fQogCiBzdGF0aWMgdWludDhfdCB0ZGE5OTh4X2Nrc3VtKHVpbnQ4X3QgKmJ1Ziwgc2l6ZV90IGJ5 dGVzKQpAQCAtNTEzLDE4ICs1MTIsMTggQEAgc3RhdGljIHVpbnQ4X3QgdGRhOTk4eF9ja3N1bSh1 aW50OF90ICpidWYsIHNpemVfdCBieXRlcykKICNkZWZpbmUgUEIoeCkgKEhCKDIpICsgMSArICh4 KSkKIAogc3RhdGljIHZvaWQKLXRkYTk5OHhfd3JpdGVfaWYoc3RydWN0IGRybV9lbmNvZGVyICpl bmNvZGVyLCB1aW50OF90IGJpdCwgdWludDE2X3QgYWRkciwKK3RkYTk5OHhfd3JpdGVfaWYoc3Ry dWN0IHRkYTk5OHhfcHJpdiAqcHJpdiwgdWludDhfdCBiaXQsIHVpbnQxNl90IGFkZHIsCiAJCSB1 aW50OF90ICpidWYsIHNpemVfdCBzaXplKQogewogCWJ1ZltQQigwKV0gPSB0ZGE5OTh4X2Nrc3Vt KGJ1Ziwgc2l6ZSk7CiAKLQlyZWdfY2xlYXIoZW5jb2RlciwgUkVHX0RJUF9JRl9GTEFHUywgYml0 KTsKLQlyZWdfd3JpdGVfcmFuZ2UoZW5jb2RlciwgYWRkciwgYnVmLCBzaXplKTsKLQlyZWdfc2V0 KGVuY29kZXIsIFJFR19ESVBfSUZfRkxBR1MsIGJpdCk7CisJcmVnX2NsZWFyKHByaXYsIFJFR19E SVBfSUZfRkxBR1MsIGJpdCk7CisJcmVnX3dyaXRlX3JhbmdlKHByaXYsIGFkZHIsIGJ1Ziwgc2l6 ZSk7CisJcmVnX3NldChwcml2LCBSRUdfRElQX0lGX0ZMQUdTLCBiaXQpOwogfQogCiBzdGF0aWMg dm9pZAotdGRhOTk4eF93cml0ZV9haWYoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyLCBzdHJ1 Y3QgdGRhOTk4eF9lbmNvZGVyX3BhcmFtcyAqcCkKK3RkYTk5OHhfd3JpdGVfYWlmKHN0cnVjdCB0 ZGE5OTh4X3ByaXYgKnByaXYsIHN0cnVjdCB0ZGE5OTh4X2VuY29kZXJfcGFyYW1zICpwKQogewog CXVpbnQ4X3QgYnVmW1BCKDUpICsgMV07CiAKQEAgLTUzNywxMiArNTM2LDEyIEBAIHRkYTk5OHhf d3JpdGVfYWlmKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2Rlciwgc3RydWN0IHRkYTk5OHhfZW5j b2Rlcl9wYXJhbXMgKnApCiAJYnVmW1BCKDQpXSA9IHAtPmF1ZGlvX2ZyYW1lWzRdOwogCWJ1ZltQ Qig1KV0gPSBwLT5hdWRpb19mcmFtZVs1XSAmIDB4Zjg7IC8qIERNX0lOSCArIExTViAqLwogCi0J dGRhOTk4eF93cml0ZV9pZihlbmNvZGVyLCBESVBfSUZfRkxBR1NfSUY0LCBSRUdfSUY0X0hCMCwg YnVmLAorCXRkYTk5OHhfd3JpdGVfaWYocHJpdiwgRElQX0lGX0ZMQUdTX0lGNCwgUkVHX0lGNF9I QjAsIGJ1ZiwKIAkJCSBzaXplb2YoYnVmKSk7CiB9CiAKIHN0YXRpYyB2b2lkCi10ZGE5OTh4X3dy aXRlX2F2aShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIsIHN0cnVjdCBkcm1fZGlzcGxheV9t b2RlICptb2RlKQordGRhOTk4eF93cml0ZV9hdmkoc3RydWN0IHRkYTk5OHhfcHJpdiAqcHJpdiwg c3RydWN0IGRybV9kaXNwbGF5X21vZGUgKm1vZGUpCiB7CiAJdWludDhfdCBidWZbUEIoMTMpICsg MV07CiAKQEAgLTU1NCwzNiArNTUzLDM2IEBAIHRkYTk5OHhfd3JpdGVfYXZpKHN0cnVjdCBkcm1f ZW5jb2RlciAqZW5jb2Rlciwgc3RydWN0IGRybV9kaXNwbGF5X21vZGUgKm1vZGUpCiAJYnVmW1BC KDMpXSA9IEhETUlfUVVBTlRJWkFUSU9OX1JBTkdFX0ZVTEwgPDwgMjsKIAlidWZbUEIoNCldID0g ZHJtX21hdGNoX2NlYV9tb2RlKG1vZGUpOwogCi0JdGRhOTk4eF93cml0ZV9pZihlbmNvZGVyLCBE SVBfSUZfRkxBR1NfSUYyLCBSRUdfSUYyX0hCMCwgYnVmLAorCXRkYTk5OHhfd3JpdGVfaWYocHJp diwgRElQX0lGX0ZMQUdTX0lGMiwgUkVHX0lGMl9IQjAsIGJ1ZiwKIAkJCSBzaXplb2YoYnVmKSk7 CiB9CiAKLXN0YXRpYyB2b2lkIHRkYTk5OHhfYXVkaW9fbXV0ZShzdHJ1Y3QgZHJtX2VuY29kZXIg KmVuY29kZXIsIGJvb2wgb24pCitzdGF0aWMgdm9pZCB0ZGE5OTh4X2F1ZGlvX211dGUoc3RydWN0 IHRkYTk5OHhfcHJpdiAqcHJpdiwgYm9vbCBvbikKIHsKIAlpZiAob24pIHsKLQkJcmVnX3NldChl bmNvZGVyLCBSRUdfU09GVFJFU0VULCBTT0ZUUkVTRVRfQVVESU8pOwotCQlyZWdfY2xlYXIoZW5j b2RlciwgUkVHX1NPRlRSRVNFVCwgU09GVFJFU0VUX0FVRElPKTsKLQkJcmVnX3NldChlbmNvZGVy LCBSRUdfQUlQX0NOVFJMXzAsIEFJUF9DTlRSTF8wX1JTVF9GSUZPKTsKKwkJcmVnX3NldChwcml2 LCBSRUdfU09GVFJFU0VULCBTT0ZUUkVTRVRfQVVESU8pOworCQlyZWdfY2xlYXIocHJpdiwgUkVH X1NPRlRSRVNFVCwgU09GVFJFU0VUX0FVRElPKTsKKwkJcmVnX3NldChwcml2LCBSRUdfQUlQX0NO VFJMXzAsIEFJUF9DTlRSTF8wX1JTVF9GSUZPKTsKIAl9IGVsc2UgewotCQlyZWdfY2xlYXIoZW5j b2RlciwgUkVHX0FJUF9DTlRSTF8wLCBBSVBfQ05UUkxfMF9SU1RfRklGTyk7CisJCXJlZ19jbGVh cihwcml2LCBSRUdfQUlQX0NOVFJMXzAsIEFJUF9DTlRSTF8wX1JTVF9GSUZPKTsKIAl9CiB9CiAK IHN0YXRpYyB2b2lkCi10ZGE5OTh4X2NvbmZpZ3VyZV9hdWRpbyhzdHJ1Y3QgZHJtX2VuY29kZXIg KmVuY29kZXIsCit0ZGE5OTh4X2NvbmZpZ3VyZV9hdWRpbyhzdHJ1Y3QgdGRhOTk4eF9wcml2ICpw cml2LAogCQlzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqbW9kZSwgc3RydWN0IHRkYTk5OHhfZW5j b2Rlcl9wYXJhbXMgKnApCiB7CiAJdWludDhfdCBidWZbNl0sIGNsa3NlbF9haXAsIGNsa3NlbF9m cywgY2FfaTJzLCBjdHNfbiwgYWRpdjsKIAl1aW50MzJfdCBuOwogCiAJLyogRW5hYmxlIGF1ZGlv IHBvcnRzICovCi0JcmVnX3dyaXRlKGVuY29kZXIsIFJFR19FTkFfQVAsIHAtPmF1ZGlvX2NmZyk7 Ci0JcmVnX3dyaXRlKGVuY29kZXIsIFJFR19FTkFfQUNMSywgcC0+YXVkaW9fY2xrX2NmZyk7CisJ cmVnX3dyaXRlKHByaXYsIFJFR19FTkFfQVAsIHAtPmF1ZGlvX2NmZyk7CisJcmVnX3dyaXRlKHBy aXYsIFJFR19FTkFfQUNMSywgcC0+YXVkaW9fY2xrX2NmZyk7CiAKIAkvKiBTZXQgYXVkaW8gaW5w dXQgc291cmNlICovCiAJc3dpdGNoIChwLT5hdWRpb19mb3JtYXQpIHsKIAljYXNlIEFGTVRfU1BE SUY6Ci0JCXJlZ193cml0ZShlbmNvZGVyLCBSRUdfTVVYX0FQLCAweDQwKTsKKwkJcmVnX3dyaXRl KHByaXYsIFJFR19NVVhfQVAsIDB4NDApOwogCQljbGtzZWxfYWlwID0gQUlQX0NMS1NFTF9BSVAo MCk7CiAJCS8qIEZTNjRTUERJRiAqLwogCQljbGtzZWxfZnMgPSBBSVBfQ0xLU0VMX0ZTKDIpOwpA QCAtNTkyLDcgKzU5MSw3IEBAIHRkYTk5OHhfY29uZmlndXJlX2F1ZGlvKHN0cnVjdCBkcm1fZW5j b2RlciAqZW5jb2RlciwKIAkJYnJlYWs7CiAKIAljYXNlIEFGTVRfSTJTOgotCQlyZWdfd3JpdGUo ZW5jb2RlciwgUkVHX01VWF9BUCwgMHg2NCk7CisJCXJlZ193cml0ZShwcml2LCBSRUdfTVVYX0FQ LCAweDY0KTsKIAkJY2xrc2VsX2FpcCA9IEFJUF9DTEtTRUxfQUlQKDEpOwogCQkvKiBBQ0xLICov CiAJCWNsa3NlbF9mcyA9IEFJUF9DTEtTRUxfRlMoMCk7CkBAIC02MDUsMTIgKzYwNCwxMiBAQCB0 ZGE5OTh4X2NvbmZpZ3VyZV9hdWRpbyhzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIsCiAJCXJl dHVybjsKIAl9CiAKLQlyZWdfd3JpdGUoZW5jb2RlciwgUkVHX0FJUF9DTEtTRUwsIGNsa3NlbF9h aXApOwotCXJlZ19jbGVhcihlbmNvZGVyLCBSRUdfQUlQX0NOVFJMXzAsIEFJUF9DTlRSTF8wX0xB WU9VVCk7CisJcmVnX3dyaXRlKHByaXYsIFJFR19BSVBfQ0xLU0VMLCBjbGtzZWxfYWlwKTsKKwly ZWdfY2xlYXIocHJpdiwgUkVHX0FJUF9DTlRSTF8wLCBBSVBfQ05UUkxfMF9MQVlPVVQpOwogCiAJ LyogRW5hYmxlIGF1dG9tYXRpYyBDVFMgZ2VuZXJhdGlvbiAqLwotCXJlZ19jbGVhcihlbmNvZGVy LCBSRUdfQUlQX0NOVFJMXzAsIEFJUF9DTlRSTF8wX0FDUl9NQU4pOwotCXJlZ193cml0ZShlbmNv ZGVyLCBSRUdfQ1RTX04sIGN0c19uKTsKKwlyZWdfY2xlYXIocHJpdiwgUkVHX0FJUF9DTlRSTF8w LCBBSVBfQ05UUkxfMF9BQ1JfTUFOKTsKKwlyZWdfd3JpdGUocHJpdiwgUkVHX0NUU19OLCBjdHNf bik7CiAKIAkvKgogCSAqIEF1ZGlvIGlucHV0IHNvbWVob3cgZGVwZW5kcyBvbiBIRE1JIGxpbmUg cmF0ZSB3aGljaCBpcwpAQCAtNjIzLDcgKzYyMiw3IEBAIHRkYTk5OHhfY29uZmlndXJlX2F1ZGlv KHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwKIAkJYWRpdiA9IEFVRElPX0RJVl9TRVJDTEtf MTY7CiAJZWxzZQogCQlhZGl2ID0gQVVESU9fRElWX1NFUkNMS184OwotCXJlZ193cml0ZShlbmNv ZGVyLCBSRUdfQVVESU9fRElWLCBhZGl2KTsKKwlyZWdfd3JpdGUocHJpdiwgUkVHX0FVRElPX0RJ ViwgYWRpdik7CiAKIAkvKgogCSAqIFRoaXMgaXMgdGhlIGFwcHJveGltYXRlIHZhbHVlIG9mIE4s IHdoaWNoIGhhcHBlbnMgdG8gYmUKQEAgLTYzOCwyOCArNjM3LDI4IEBAIHRkYTk5OHhfY29uZmln dXJlX2F1ZGlvKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwKIAlidWZbM10gPSBuOwogCWJ1 Zls0XSA9IG4gPj4gODsKIAlidWZbNV0gPSBuID4+IDE2OwotCXJlZ193cml0ZV9yYW5nZShlbmNv ZGVyLCBSRUdfQUNSX0NUU18wLCBidWYsIDYpOworCXJlZ193cml0ZV9yYW5nZShwcml2LCBSRUdf QUNSX0NUU18wLCBidWYsIDYpOwogCiAJLyogU2V0IENUUyBjbG9jayByZWZlcmVuY2UgKi8KLQly ZWdfd3JpdGUoZW5jb2RlciwgUkVHX0FJUF9DTEtTRUwsIGNsa3NlbF9haXAgfCBjbGtzZWxfZnMp OworCXJlZ193cml0ZShwcml2LCBSRUdfQUlQX0NMS1NFTCwgY2xrc2VsX2FpcCB8IGNsa3NlbF9m cyk7CiAKIAkvKiBSZXNldCBDVFMgZ2VuZXJhdG9yICovCi0JcmVnX3NldChlbmNvZGVyLCBSRUdf QUlQX0NOVFJMXzAsIEFJUF9DTlRSTF8wX1JTVF9DVFMpOwotCXJlZ19jbGVhcihlbmNvZGVyLCBS RUdfQUlQX0NOVFJMXzAsIEFJUF9DTlRSTF8wX1JTVF9DVFMpOworCXJlZ19zZXQocHJpdiwgUkVH X0FJUF9DTlRSTF8wLCBBSVBfQ05UUkxfMF9SU1RfQ1RTKTsKKwlyZWdfY2xlYXIocHJpdiwgUkVH X0FJUF9DTlRSTF8wLCBBSVBfQ05UUkxfMF9SU1RfQ1RTKTsKIAogCS8qIFdyaXRlIHRoZSBjaGFu bmVsIHN0YXR1cyAqLwogCWJ1ZlswXSA9IDB4MDQ7CiAJYnVmWzFdID0gMHgwMDsKIAlidWZbMl0g PSAweDAwOwogCWJ1ZlszXSA9IDB4ZjE7Ci0JcmVnX3dyaXRlX3JhbmdlKGVuY29kZXIsIFJFR19D SF9TVEFUX0IoMCksIGJ1ZiwgNCk7CisJcmVnX3dyaXRlX3JhbmdlKHByaXYsIFJFR19DSF9TVEFU X0IoMCksIGJ1ZiwgNCk7CiAKLQl0ZGE5OTh4X2F1ZGlvX211dGUoZW5jb2RlciwgdHJ1ZSk7CisJ dGRhOTk4eF9hdWRpb19tdXRlKHByaXYsIHRydWUpOwogCW1kZWxheSgyMCk7Ci0JdGRhOTk4eF9h dWRpb19tdXRlKGVuY29kZXIsIGZhbHNlKTsKKwl0ZGE5OTh4X2F1ZGlvX211dGUocHJpdiwgZmFs c2UpOwogCiAJLyogV3JpdGUgdGhlIGF1ZGlvIGluZm9ybWF0aW9uIHBhY2tldCAqLwotCXRkYTk5 OHhfd3JpdGVfYWlmKGVuY29kZXIsIHApOworCXRkYTk5OHhfd3JpdGVfYWlmKHByaXYsIHApOwog fQogCiAvKiBEUk0gZW5jb2RlciBmdW5jdGlvbnMgKi8KQEAgLTcwMSwxOSArNzAwLDE5IEBAIHRk YTk5OHhfZW5jb2Rlcl9kcG1zKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwgaW50IG1vZGUp CiAJc3dpdGNoIChtb2RlKSB7CiAJY2FzZSBEUk1fTU9ERV9EUE1TX09OOgogCQkvKiBlbmFibGUg dmlkZW8gcG9ydHMsIGF1ZGlvIHdpbGwgYmUgZW5hYmxlZCBsYXRlciAqLwotCQlyZWdfd3JpdGUo ZW5jb2RlciwgUkVHX0VOQV9WUF8wLCAweGZmKTsKLQkJcmVnX3dyaXRlKGVuY29kZXIsIFJFR19F TkFfVlBfMSwgMHhmZik7Ci0JCXJlZ193cml0ZShlbmNvZGVyLCBSRUdfRU5BX1ZQXzIsIDB4ZmYp OworCQlyZWdfd3JpdGUocHJpdiwgUkVHX0VOQV9WUF8wLCAweGZmKTsKKwkJcmVnX3dyaXRlKHBy aXYsIFJFR19FTkFfVlBfMSwgMHhmZik7CisJCXJlZ193cml0ZShwcml2LCBSRUdfRU5BX1ZQXzIs IDB4ZmYpOwogCQkvKiBzZXQgbXV4aW5nIGFmdGVyIGVuYWJsaW5nIHBvcnRzOiAqLwotCQlyZWdf d3JpdGUoZW5jb2RlciwgUkVHX1ZJUF9DTlRSTF8wLCBwcml2LT52aXBfY250cmxfMCk7Ci0JCXJl Z193cml0ZShlbmNvZGVyLCBSRUdfVklQX0NOVFJMXzEsIHByaXYtPnZpcF9jbnRybF8xKTsKLQkJ cmVnX3dyaXRlKGVuY29kZXIsIFJFR19WSVBfQ05UUkxfMiwgcHJpdi0+dmlwX2NudHJsXzIpOwor CQlyZWdfd3JpdGUocHJpdiwgUkVHX1ZJUF9DTlRSTF8wLCBwcml2LT52aXBfY250cmxfMCk7CisJ CXJlZ193cml0ZShwcml2LCBSRUdfVklQX0NOVFJMXzEsIHByaXYtPnZpcF9jbnRybF8xKTsKKwkJ cmVnX3dyaXRlKHByaXYsIFJFR19WSVBfQ05UUkxfMiwgcHJpdi0+dmlwX2NudHJsXzIpOwogCQli cmVhazsKIAljYXNlIERSTV9NT0RFX0RQTVNfT0ZGOgogCQkvKiBkaXNhYmxlIHZpZGVvIHBvcnRz ICovCi0JCXJlZ193cml0ZShlbmNvZGVyLCBSRUdfRU5BX1ZQXzAsIDB4MDApOwotCQlyZWdfd3Jp dGUoZW5jb2RlciwgUkVHX0VOQV9WUF8xLCAweDAwKTsKLQkJcmVnX3dyaXRlKGVuY29kZXIsIFJF R19FTkFfVlBfMiwgMHgwMCk7CisJCXJlZ193cml0ZShwcml2LCBSRUdfRU5BX1ZQXzAsIDB4MDAp OworCQlyZWdfd3JpdGUocHJpdiwgUkVHX0VOQV9WUF8xLCAweDAwKTsKKwkJcmVnX3dyaXRlKHBy aXYsIFJFR19FTkFfVlBfMiwgMHgwMCk7CiAJCWJyZWFrOwogCX0KIApAQCAtODI2LDU3ICs4MjUs NTcgQEAgdGRhOTk4eF9lbmNvZGVyX21vZGVfc2V0KHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2Rl ciwKIAlkaXYgPSAxNDg1MDAgLyBtb2RlLT5jbG9jazsKIAogCS8qIG11dGUgdGhlIGF1ZGlvIEZJ Rk86ICovCi0JcmVnX3NldChlbmNvZGVyLCBSRUdfQUlQX0NOVFJMXzAsIEFJUF9DTlRSTF8wX1JT VF9GSUZPKTsKKwlyZWdfc2V0KHByaXYsIFJFR19BSVBfQ05UUkxfMCwgQUlQX0NOVFJMXzBfUlNU X0ZJRk8pOwogCiAJLyogc2V0IEhETUkgSERDUCBtb2RlIG9mZjogKi8KLQlyZWdfc2V0KGVuY29k ZXIsIFJFR19UQkdfQ05UUkxfMSwgVEJHX0NOVFJMXzFfRFdJTl9ESVMpOwotCXJlZ19jbGVhcihl bmNvZGVyLCBSRUdfVFgzMywgVFgzM19IRE1JKTsKKwlyZWdfc2V0KHByaXYsIFJFR19UQkdfQ05U UkxfMSwgVEJHX0NOVFJMXzFfRFdJTl9ESVMpOworCXJlZ19jbGVhcihwcml2LCBSRUdfVFgzMywg VFgzM19IRE1JKTsKKwlyZWdfd3JpdGUocHJpdiwgUkVHX0VOQ19DTlRSTCwgRU5DX0NOVFJMX0NU TF9DT0RFKDApKTsKIAotCXJlZ193cml0ZShlbmNvZGVyLCBSRUdfRU5DX0NOVFJMLCBFTkNfQ05U UkxfQ1RMX0NPREUoMCkpOwogCS8qIG5vIHByZS1maWx0ZXIgb3IgaW50ZXJwb2xhdG9yOiAqLwot CXJlZ193cml0ZShlbmNvZGVyLCBSRUdfSFZGX0NOVFJMXzAsIEhWRl9DTlRSTF8wX1BSRUZJTCgw KSB8CisJcmVnX3dyaXRlKHByaXYsIFJFR19IVkZfQ05UUkxfMCwgSFZGX0NOVFJMXzBfUFJFRklM KDApIHwKIAkJCUhWRl9DTlRSTF8wX0lOVFBPTCgwKSk7Ci0JcmVnX3dyaXRlKGVuY29kZXIsIFJF R19WSVBfQ05UUkxfNSwgVklQX0NOVFJMXzVfU1BfQ05UKDApKTsKLQlyZWdfd3JpdGUoZW5jb2Rl ciwgUkVHX1ZJUF9DTlRSTF80LCBWSVBfQ05UUkxfNF9CTEFOS0lUKDApIHwKKwlyZWdfd3JpdGUo cHJpdiwgUkVHX1ZJUF9DTlRSTF81LCBWSVBfQ05UUkxfNV9TUF9DTlQoMCkpOworCXJlZ193cml0 ZShwcml2LCBSRUdfVklQX0NOVFJMXzQsIFZJUF9DTlRSTF80X0JMQU5LSVQoMCkgfAogCQkJVklQ X0NOVFJMXzRfQkxDKDApKTsKLQlyZWdfY2xlYXIoZW5jb2RlciwgUkVHX1BMTF9TRVJJQUxfMywg UExMX1NFUklBTF8zX1NSTF9DQ0lSKTsKKwlyZWdfY2xlYXIocHJpdiwgUkVHX1BMTF9TRVJJQUxf MywgUExMX1NFUklBTF8zX1NSTF9DQ0lSKTsKIAotCXJlZ19jbGVhcihlbmNvZGVyLCBSRUdfUExM X1NFUklBTF8xLCBQTExfU0VSSUFMXzFfU1JMX01BTl9JWik7Ci0JcmVnX2NsZWFyKGVuY29kZXIs IFJFR19QTExfU0VSSUFMXzMsIFBMTF9TRVJJQUxfM19TUkxfREUpOwotCXJlZ193cml0ZShlbmNv ZGVyLCBSRUdfU0VSSUFMSVpFUiwgMCk7Ci0JcmVnX3dyaXRlKGVuY29kZXIsIFJFR19IVkZfQ05U UkxfMSwgSFZGX0NOVFJMXzFfVlFSKDApKTsKKwlyZWdfY2xlYXIocHJpdiwgUkVHX1BMTF9TRVJJ QUxfMSwgUExMX1NFUklBTF8xX1NSTF9NQU5fSVopOworCXJlZ19jbGVhcihwcml2LCBSRUdfUExM X1NFUklBTF8zLCBQTExfU0VSSUFMXzNfU1JMX0RFKTsKKwlyZWdfd3JpdGUocHJpdiwgUkVHX1NF UklBTElaRVIsIDApOworCXJlZ193cml0ZShwcml2LCBSRUdfSFZGX0NOVFJMXzEsIEhWRl9DTlRS TF8xX1ZRUigwKSk7CiAKIAkvKiBUT0RPIGVuYWJsZSBwaXhlbCByZXBlYXQgZm9yIHBpeGVsIHJh dGVzIGxlc3MgdGhhbiAyNU1zYW1wL3MgKi8KIAlyZXAgPSAwOwotCXJlZ193cml0ZShlbmNvZGVy LCBSRUdfUlBUX0NOVFJMLCAwKTsKLQlyZWdfd3JpdGUoZW5jb2RlciwgUkVHX1NFTF9DTEssIFNF TF9DTEtfU0VMX1ZSRl9DTEsoMCkgfAorCXJlZ193cml0ZShwcml2LCBSRUdfUlBUX0NOVFJMLCAw KTsKKwlyZWdfd3JpdGUocHJpdiwgUkVHX1NFTF9DTEssIFNFTF9DTEtfU0VMX1ZSRl9DTEsoMCkg fAogCQkJU0VMX0NMS19TRUxfQ0xLMSB8IFNFTF9DTEtfRU5BX1NDX0NMSyk7CiAKLQlyZWdfd3Jp dGUoZW5jb2RlciwgUkVHX1BMTF9TRVJJQUxfMiwgUExMX1NFUklBTF8yX1NSTF9OT1NDKGRpdikg fAorCXJlZ193cml0ZShwcml2LCBSRUdfUExMX1NFUklBTF8yLCBQTExfU0VSSUFMXzJfU1JMX05P U0MoZGl2KSB8CiAJCQlQTExfU0VSSUFMXzJfU1JMX1BSKHJlcCkpOwogCiAJLyogc2V0IGNvbG9y IG1hdHJpeCBieXBhc3MgZmxhZzogKi8KLQlyZWdfc2V0KGVuY29kZXIsIFJFR19NQVRfQ09OVFJM LCBNQVRfQ09OVFJMX01BVF9CUCk7CisJcmVnX3NldChwcml2LCBSRUdfTUFUX0NPTlRSTCwgTUFU X0NPTlRSTF9NQVRfQlApOwogCiAJLyogc2V0IEJJQVMgdG1kcyB2YWx1ZTogKi8KLQlyZWdfd3Jp dGUoZW5jb2RlciwgUkVHX0FOQV9HRU5FUkFMLCAweDA5KTsKKwlyZWdfd3JpdGUocHJpdiwgUkVH X0FOQV9HRU5FUkFMLCAweDA5KTsKIAotCXJlZ19jbGVhcihlbmNvZGVyLCBSRUdfVEJHX0NOVFJM XzAsIFRCR19DTlRSTF8wX1NZTkNfTVRIRCk7CisJcmVnX2NsZWFyKHByaXYsIFJFR19UQkdfQ05U UkxfMCwgVEJHX0NOVFJMXzBfU1lOQ19NVEhEKTsKIAogCS8qCiAJICogU3luYyBvbiByaXNpbmcg SFNZTkMvVlNZTkMKIAkgKi8KLQlyZWdfd3JpdGUoZW5jb2RlciwgUkVHX1ZJUF9DTlRSTF8zLCAw KTsKLQlyZWdfc2V0KGVuY29kZXIsIFJFR19WSVBfQ05UUkxfMywgVklQX0NOVFJMXzNfU1lOQ19I Uyk7CisJcmVnX3dyaXRlKHByaXYsIFJFR19WSVBfQ05UUkxfMywgMCk7CisJcmVnX3NldChwcml2 LCBSRUdfVklQX0NOVFJMXzMsIFZJUF9DTlRSTF8zX1NZTkNfSFMpOwogCiAJLyoKIAkgKiBUREEx OTk4OCByZXF1aXJlcyBoaWdoLWFjdGl2ZSBzeW5jIGF0IGlucHV0IHN0YWdlLAogCSAqIHNvIGlu dmVydCBsb3ctYWN0aXZlIHN5bmMgcHJvdmlkZWQgYnkgbWFzdGVyIGVuY29kZXIgaGVyZQogCSAq LwogCWlmIChtb2RlLT5mbGFncyAmIERSTV9NT0RFX0ZMQUdfTkhTWU5DKQotCQlyZWdfc2V0KGVu Y29kZXIsIFJFR19WSVBfQ05UUkxfMywgVklQX0NOVFJMXzNfSF9UR0wpOworCQlyZWdfc2V0KHBy aXYsIFJFR19WSVBfQ05UUkxfMywgVklQX0NOVFJMXzNfSF9UR0wpOwogCWlmIChtb2RlLT5mbGFn cyAmIERSTV9NT0RFX0ZMQUdfTlZTWU5DKQotCQlyZWdfc2V0KGVuY29kZXIsIFJFR19WSVBfQ05U UkxfMywgVklQX0NOVFJMXzNfVl9UR0wpOworCQlyZWdfc2V0KHByaXYsIFJFR19WSVBfQ05UUkxf MywgVklQX0NOVFJMXzNfVl9UR0wpOwogCiAJLyoKIAkgKiBBbHdheXMgZ2VuZXJhdGUgc3luYyBw b2xhcml0eSByZWxhdGl2ZSB0byBpbnB1dCBzeW5jIGFuZApAQCAtODg3LDQ5ICs4ODYsNDkgQEAg dGRhOTk4eF9lbmNvZGVyX21vZGVfc2V0KHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwKIAkJ cmVnIHw9IFRCR19DTlRSTF8xX0hfVEdMOwogCWlmIChtb2RlLT5mbGFncyAmIERSTV9NT0RFX0ZM QUdfTlZTWU5DKQogCQlyZWcgfD0gVEJHX0NOVFJMXzFfVl9UR0w7Ci0JcmVnX3dyaXRlKGVuY29k ZXIsIFJFR19UQkdfQ05UUkxfMSwgcmVnKTsKLQotCXJlZ193cml0ZShlbmNvZGVyLCBSRUdfVklE Rk9STUFULCAweDAwKTsKLQlyZWdfd3JpdGUxNihlbmNvZGVyLCBSRUdfUkVGUElYX01TQiwgcmVm X3BpeCk7Ci0JcmVnX3dyaXRlMTYoZW5jb2RlciwgUkVHX1JFRkxJTkVfTVNCLCByZWZfbGluZSk7 Ci0JcmVnX3dyaXRlMTYoZW5jb2RlciwgUkVHX05QSVhfTVNCLCBuX3BpeCk7Ci0JcmVnX3dyaXRl MTYoZW5jb2RlciwgUkVHX05MSU5FX01TQiwgbl9saW5lKTsKLQlyZWdfd3JpdGUxNihlbmNvZGVy LCBSRUdfVlNfTElORV9TVFJUXzFfTVNCLCB2czFfbGluZV9zKTsKLQlyZWdfd3JpdGUxNihlbmNv ZGVyLCBSRUdfVlNfUElYX1NUUlRfMV9NU0IsIHZzMV9waXhfcyk7Ci0JcmVnX3dyaXRlMTYoZW5j b2RlciwgUkVHX1ZTX0xJTkVfRU5EXzFfTVNCLCB2czFfbGluZV9lKTsKLQlyZWdfd3JpdGUxNihl bmNvZGVyLCBSRUdfVlNfUElYX0VORF8xX01TQiwgdnMxX3BpeF9lKTsKLQlyZWdfd3JpdGUxNihl bmNvZGVyLCBSRUdfVlNfTElORV9TVFJUXzJfTVNCLCB2czJfbGluZV9zKTsKLQlyZWdfd3JpdGUx NihlbmNvZGVyLCBSRUdfVlNfUElYX1NUUlRfMl9NU0IsIHZzMl9waXhfcyk7Ci0JcmVnX3dyaXRl MTYoZW5jb2RlciwgUkVHX1ZTX0xJTkVfRU5EXzJfTVNCLCB2czJfbGluZV9lKTsKLQlyZWdfd3Jp dGUxNihlbmNvZGVyLCBSRUdfVlNfUElYX0VORF8yX01TQiwgdnMyX3BpeF9lKTsKLQlyZWdfd3Jp dGUxNihlbmNvZGVyLCBSRUdfSFNfUElYX1NUQVJUX01TQiwgaHNfcGl4X3MpOwotCXJlZ193cml0 ZTE2KGVuY29kZXIsIFJFR19IU19QSVhfU1RPUF9NU0IsIGhzX3BpeF9lKTsKLQlyZWdfd3JpdGUx NihlbmNvZGVyLCBSRUdfVldJTl9TVEFSVF8xX01TQiwgdndpbjFfbGluZV9zKTsKLQlyZWdfd3Jp dGUxNihlbmNvZGVyLCBSRUdfVldJTl9FTkRfMV9NU0IsIHZ3aW4xX2xpbmVfZSk7Ci0JcmVnX3dy aXRlMTYoZW5jb2RlciwgUkVHX1ZXSU5fU1RBUlRfMl9NU0IsIHZ3aW4yX2xpbmVfcyk7Ci0JcmVn X3dyaXRlMTYoZW5jb2RlciwgUkVHX1ZXSU5fRU5EXzJfTVNCLCB2d2luMl9saW5lX2UpOwotCXJl Z193cml0ZTE2KGVuY29kZXIsIFJFR19ERV9TVEFSVF9NU0IsIGRlX3BpeF9zKTsKLQlyZWdfd3Jp dGUxNihlbmNvZGVyLCBSRUdfREVfU1RPUF9NU0IsIGRlX3BpeF9lKTsKKwlyZWdfd3JpdGUocHJp diwgUkVHX1RCR19DTlRSTF8xLCByZWcpOworCisJcmVnX3dyaXRlKHByaXYsIFJFR19WSURGT1JN QVQsIDB4MDApOworCXJlZ193cml0ZTE2KHByaXYsIFJFR19SRUZQSVhfTVNCLCByZWZfcGl4KTsK KwlyZWdfd3JpdGUxNihwcml2LCBSRUdfUkVGTElORV9NU0IsIHJlZl9saW5lKTsKKwlyZWdfd3Jp dGUxNihwcml2LCBSRUdfTlBJWF9NU0IsIG5fcGl4KTsKKwlyZWdfd3JpdGUxNihwcml2LCBSRUdf TkxJTkVfTVNCLCBuX2xpbmUpOworCXJlZ193cml0ZTE2KHByaXYsIFJFR19WU19MSU5FX1NUUlRf MV9NU0IsIHZzMV9saW5lX3MpOworCXJlZ193cml0ZTE2KHByaXYsIFJFR19WU19QSVhfU1RSVF8x X01TQiwgdnMxX3BpeF9zKTsKKwlyZWdfd3JpdGUxNihwcml2LCBSRUdfVlNfTElORV9FTkRfMV9N U0IsIHZzMV9saW5lX2UpOworCXJlZ193cml0ZTE2KHByaXYsIFJFR19WU19QSVhfRU5EXzFfTVNC LCB2czFfcGl4X2UpOworCXJlZ193cml0ZTE2KHByaXYsIFJFR19WU19MSU5FX1NUUlRfMl9NU0Is IHZzMl9saW5lX3MpOworCXJlZ193cml0ZTE2KHByaXYsIFJFR19WU19QSVhfU1RSVF8yX01TQiwg dnMyX3BpeF9zKTsKKwlyZWdfd3JpdGUxNihwcml2LCBSRUdfVlNfTElORV9FTkRfMl9NU0IsIHZz Ml9saW5lX2UpOworCXJlZ193cml0ZTE2KHByaXYsIFJFR19WU19QSVhfRU5EXzJfTVNCLCB2czJf cGl4X2UpOworCXJlZ193cml0ZTE2KHByaXYsIFJFR19IU19QSVhfU1RBUlRfTVNCLCBoc19waXhf cyk7CisJcmVnX3dyaXRlMTYocHJpdiwgUkVHX0hTX1BJWF9TVE9QX01TQiwgaHNfcGl4X2UpOwor CXJlZ193cml0ZTE2KHByaXYsIFJFR19WV0lOX1NUQVJUXzFfTVNCLCB2d2luMV9saW5lX3MpOwor CXJlZ193cml0ZTE2KHByaXYsIFJFR19WV0lOX0VORF8xX01TQiwgdndpbjFfbGluZV9lKTsKKwly ZWdfd3JpdGUxNihwcml2LCBSRUdfVldJTl9TVEFSVF8yX01TQiwgdndpbjJfbGluZV9zKTsKKwly ZWdfd3JpdGUxNihwcml2LCBSRUdfVldJTl9FTkRfMl9NU0IsIHZ3aW4yX2xpbmVfZSk7CisJcmVn X3dyaXRlMTYocHJpdiwgUkVHX0RFX1NUQVJUX01TQiwgZGVfcGl4X3MpOworCXJlZ193cml0ZTE2 KHByaXYsIFJFR19ERV9TVE9QX01TQiwgZGVfcGl4X2UpOwogCiAJaWYgKHByaXYtPnJldiA9PSBU REExOTk4OCkgewogCQkvKiBsZXQgaW5jb21pbmcgcGl4ZWxzIGZpbGwgdGhlIGFjdGl2ZSBzcGFj ZSAoaWYgYW55KSAqLwotCQlyZWdfd3JpdGUoZW5jb2RlciwgUkVHX0VOQUJMRV9TUEFDRSwgMHgw MSk7CisJCXJlZ193cml0ZShwcml2LCBSRUdfRU5BQkxFX1NQQUNFLCAweDAxKTsKIAl9CiAKIAkv KiBtdXN0IGJlIGxhc3QgcmVnaXN0ZXIgc2V0OiAqLwotCXJlZ19jbGVhcihlbmNvZGVyLCBSRUdf VEJHX0NOVFJMXzAsIFRCR19DTlRSTF8wX1NZTkNfT05DRSk7CisJcmVnX2NsZWFyKHByaXYsIFJF R19UQkdfQ05UUkxfMCwgVEJHX0NOVFJMXzBfU1lOQ19PTkNFKTsKIAogCS8qIE9ubHkgc2V0dXAg dGhlIGluZm8gZnJhbWVzIGlmIHRoZSBzaW5rIGlzIEhETUkgKi8KIAlpZiAocHJpdi0+aXNfaGRt aV9zaW5rKSB7CiAJCS8qIFdlIG5lZWQgdG8gdHVybiBIRE1JIEhEQ1Agc3R1ZmYgb24gdG8gZ2V0 IGF1ZGlvIHRocm91Z2ggKi8KLQkJcmVnX2NsZWFyKGVuY29kZXIsIFJFR19UQkdfQ05UUkxfMSwg VEJHX0NOVFJMXzFfRFdJTl9ESVMpOwotCQlyZWdfd3JpdGUoZW5jb2RlciwgUkVHX0VOQ19DTlRS TCwgRU5DX0NOVFJMX0NUTF9DT0RFKDEpKTsKLQkJcmVnX3NldChlbmNvZGVyLCBSRUdfVFgzMywg VFgzM19IRE1JKTsKKwkJcmVnX2NsZWFyKHByaXYsIFJFR19UQkdfQ05UUkxfMSwgVEJHX0NOVFJM XzFfRFdJTl9ESVMpOworCQlyZWdfd3JpdGUocHJpdiwgUkVHX0VOQ19DTlRSTCwgRU5DX0NOVFJM X0NUTF9DT0RFKDEpKTsKKwkJcmVnX3NldChwcml2LCBSRUdfVFgzMywgVFgzM19IRE1JKTsKIAot CQl0ZGE5OTh4X3dyaXRlX2F2aShlbmNvZGVyLCBhZGp1c3RlZF9tb2RlKTsKKwkJdGRhOTk4eF93 cml0ZV9hdmkocHJpdiwgYWRqdXN0ZWRfbW9kZSk7CiAKIAkJaWYgKHByaXYtPnBhcmFtcy5hdWRp b19jZmcpCi0JCQl0ZGE5OTh4X2NvbmZpZ3VyZV9hdWRpbyhlbmNvZGVyLCBhZGp1c3RlZF9tb2Rl LAorCQkJdGRhOTk4eF9jb25maWd1cmVfYXVkaW8ocHJpdiwgYWRqdXN0ZWRfbW9kZSwKIAkJCQkJ CSZwcml2LT5wYXJhbXMpOwogCX0KIH0KQEAgLTkzOCw3ICs5MzcsOSBAQCBzdGF0aWMgZW51bSBk cm1fY29ubmVjdG9yX3N0YXR1cwogdGRhOTk4eF9lbmNvZGVyX2RldGVjdChzdHJ1Y3QgZHJtX2Vu Y29kZXIgKmVuY29kZXIsCiAJCSAgICAgIHN0cnVjdCBkcm1fY29ubmVjdG9yICpjb25uZWN0b3Ip CiB7Ci0JdWludDhfdCB2YWwgPSBjZWNfcmVhZChlbmNvZGVyLCBSRUdfQ0VDX1JYU0hQRExFVik7 CisJc3RydWN0IHRkYTk5OHhfcHJpdiAqcHJpdiA9IHRvX3RkYTk5OHhfcHJpdihlbmNvZGVyKTsK Kwl1aW50OF90IHZhbCA9IGNlY19yZWFkKHByaXYsIFJFR19DRUNfUlhTSFBETEVWKTsKKwogCXJl dHVybiAodmFsICYgQ0VDX1JYU0hQRExFVl9IUEQpID8gY29ubmVjdG9yX3N0YXR1c19jb25uZWN0 ZWQgOgogCQkJY29ubmVjdG9yX3N0YXR1c19kaXNjb25uZWN0ZWQ7CiB9CkBAIC05NDYsMjkgKzk0 NywzMCBAQCB0ZGE5OTh4X2VuY29kZXJfZGV0ZWN0KHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2Rl ciwKIHN0YXRpYyBpbnQKIHJlYWRfZWRpZF9ibG9jayhzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29k ZXIsIHVpbnQ4X3QgKmJ1ZiwgaW50IGJsaykKIHsKKwlzdHJ1Y3QgdGRhOTk4eF9wcml2ICpwcml2 ID0gdG9fdGRhOTk4eF9wcml2KGVuY29kZXIpOwogCXVpbnQ4X3Qgb2Zmc2V0LCBzZWdwdHI7CiAJ aW50IHJldCwgaTsKIAogCS8qIGVuYWJsZSBFRElEIHJlYWQgaXJxOiAqLwotCXJlZ19zZXQoZW5j b2RlciwgUkVHX0lOVF9GTEFHU18yLCBJTlRfRkxBR1NfMl9FRElEX0JMS19SRCk7CisJcmVnX3Nl dChwcml2LCBSRUdfSU5UX0ZMQUdTXzIsIElOVF9GTEFHU18yX0VESURfQkxLX1JEKTsKIAogCW9m ZnNldCA9IChibGsgJiAxKSA/IDEyOCA6IDA7CiAJc2VncHRyID0gYmxrIC8gMjsKIAotCXJlZ193 cml0ZShlbmNvZGVyLCBSRUdfRERDX0FERFIsIDB4YTApOwotCXJlZ193cml0ZShlbmNvZGVyLCBS RUdfRERDX09GRlMsIG9mZnNldCk7Ci0JcmVnX3dyaXRlKGVuY29kZXIsIFJFR19ERENfU0VHTV9B RERSLCAweDYwKTsKLQlyZWdfd3JpdGUoZW5jb2RlciwgUkVHX0REQ19TRUdNLCBzZWdwdHIpOwor CXJlZ193cml0ZShwcml2LCBSRUdfRERDX0FERFIsIDB4YTApOworCXJlZ193cml0ZShwcml2LCBS RUdfRERDX09GRlMsIG9mZnNldCk7CisJcmVnX3dyaXRlKHByaXYsIFJFR19ERENfU0VHTV9BRERS LCAweDYwKTsKKwlyZWdfd3JpdGUocHJpdiwgUkVHX0REQ19TRUdNLCBzZWdwdHIpOwogCiAJLyog ZW5hYmxlIHJlYWRpbmcgRURJRDogKi8KLQlyZWdfd3JpdGUoZW5jb2RlciwgUkVHX0VESURfQ1RS TCwgMHgxKTsKKwlyZWdfd3JpdGUocHJpdiwgUkVHX0VESURfQ1RSTCwgMHgxKTsKIAogCS8qIGZs YWcgbXVzdCBiZSBjbGVhcmVkIGJ5IHN3OiAqLwotCXJlZ193cml0ZShlbmNvZGVyLCBSRUdfRURJ RF9DVFJMLCAweDApOworCXJlZ193cml0ZShwcml2LCBSRUdfRURJRF9DVFJMLCAweDApOwogCiAJ Lyogd2FpdCBmb3IgYmxvY2sgcmVhZCB0byBjb21wbGV0ZTogKi8KIAlmb3IgKGkgPSAxMDA7IGkg PiAwOyBpLS0pIHsKLQkJdWludDhfdCB2YWwgPSByZWdfcmVhZChlbmNvZGVyLCBSRUdfSU5UX0ZM QUdTXzIpOworCQl1aW50OF90IHZhbCA9IHJlZ19yZWFkKHByaXYsIFJFR19JTlRfRkxBR1NfMik7 CiAJCWlmICh2YWwgJiBJTlRfRkxBR1NfMl9FRElEX0JMS19SRCkKIAkJCWJyZWFrOwogCQltc2xl ZXAoMSk7CkBAIC05NzcsMTQgKzk3OSwxNCBAQCByZWFkX2VkaWRfYmxvY2soc3RydWN0IGRybV9l bmNvZGVyICplbmNvZGVyLCB1aW50OF90ICpidWYsIGludCBibGspCiAJaWYgKGkgPT0gMCkKIAkJ cmV0dXJuIC1FVElNRURPVVQ7CiAKLQlyZXQgPSByZWdfcmVhZF9yYW5nZShlbmNvZGVyLCBSRUdf RURJRF9EQVRBXzAsIGJ1ZiwgRURJRF9MRU5HVEgpOworCXJldCA9IHJlZ19yZWFkX3JhbmdlKHBy aXYsIFJFR19FRElEX0RBVEFfMCwgYnVmLCBFRElEX0xFTkdUSCk7CiAJaWYgKHJldCAhPSBFRElE X0xFTkdUSCkgewogCQlkZXZfZXJyKGVuY29kZXItPmRldi0+ZGV2LCAiZmFpbGVkIHRvIHJlYWQg ZWRpZCBibG9jayAlZDogJWQiLAogCQkJCWJsaywgcmV0KTsKIAkJcmV0dXJuIHJldDsKIAl9CiAK LQlyZWdfY2xlYXIoZW5jb2RlciwgUkVHX0lOVF9GTEFHU18yLCBJTlRfRkxBR1NfMl9FRElEX0JM S19SRCk7CisJcmVnX2NsZWFyKHByaXYsIFJFR19JTlRfRkxBR1NfMiwgSU5UX0ZMQUdTXzJfRURJ RF9CTEtfUkQpOwogCiAJcmV0dXJuIDA7CiB9CkBAIC0xMDAxLDcgKzEwMDMsNyBAQCBkb19nZXRf ZWRpZChzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCiAJCXJldHVybiBOVUxMOwogCiAJaWYg KHByaXYtPnJldiA9PSBUREExOTk4OCkKLQkJcmVnX2NsZWFyKGVuY29kZXIsIFJFR19UWDQsIFRY NF9QRF9SQU0pOworCQlyZWdfY2xlYXIocHJpdiwgUkVHX1RYNCwgVFg0X1BEX1JBTSk7CiAKIAkv KiBiYXNlIGJsb2NrIGZldGNoICovCiAJaWYgKHJlYWRfZWRpZF9ibG9jayhlbmNvZGVyLCBibG9j aywgMCkpCkBAIC0xMDQxLDEzICsxMDQzLDEzIEBAIGRvX2dldF9lZGlkKHN0cnVjdCBkcm1fZW5j b2RlciAqZW5jb2RlcikKIAogZG9uZToKIAlpZiAocHJpdi0+cmV2ID09IFREQTE5OTg4KQotCQly ZWdfc2V0KGVuY29kZXIsIFJFR19UWDQsIFRYNF9QRF9SQU0pOworCQlyZWdfc2V0KHByaXYsIFJF R19UWDQsIFRYNF9QRF9SQU0pOwogCiAJcmV0dXJuIGJsb2NrOwogCiBmYWlsOgogCWlmIChwcml2 LT5yZXYgPT0gVERBMTk5ODgpCi0JCXJlZ19zZXQoZW5jb2RlciwgUkVHX1RYNCwgVFg0X1BEX1JB TSk7CisJCXJlZ19zZXQocHJpdiwgUkVHX1RYNCwgVFg0X1BEX1JBTSk7CiAJZGV2X3dhcm4oZW5j b2Rlci0+ZGV2LT5kZXYsICJmYWlsZWQgdG8gcmVhZCBFRElEXG4iKTsKIAlrZnJlZShibG9jayk7 CiAJcmV0dXJuIE5VTEw7CkBAIC0xMTMxLDcgKzExMzMsNiBAQCB0ZGE5OTh4X2VuY29kZXJfaW5p dChzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LAogCQkgICAgc3RydWN0IGRybV9kZXZpY2UgKmRl diwKIAkJICAgIHN0cnVjdCBkcm1fZW5jb2Rlcl9zbGF2ZSAqZW5jb2Rlcl9zbGF2ZSkKIHsKLQlz dHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIgPSAmZW5jb2Rlcl9zbGF2ZS0+YmFzZTsKIAlzdHJ1 Y3QgdGRhOTk4eF9wcml2ICpwcml2OwogCiAJcHJpdiA9IGt6YWxsb2Moc2l6ZW9mKCpwcml2KSwg R0ZQX0tFUk5FTCk7CkBAIC0xMTQzLDYgKzExNDQsNyBAQCB0ZGE5OTh4X2VuY29kZXJfaW5pdChz dHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LAogCXByaXYtPnZpcF9jbnRybF8yID0gVklQX0NOVFJM XzJfU1dBUF9FKDQpIHwgVklQX0NOVFJMXzJfU1dBUF9GKDUpOwogCiAJcHJpdi0+Y3VycmVudF9w YWdlID0gMDsKKwlwcml2LT5oZG1pID0gY2xpZW50OwogCXByaXYtPmNlYyA9IGkyY19uZXdfZHVt bXkoY2xpZW50LT5hZGFwdGVyLCAweDM0KTsKIAlwcml2LT5kcG1zID0gRFJNX01PREVfRFBNU19P RkY7CiAKQEAgLTExNTAsMTQgKzExNTIsMTQgQEAgdGRhOTk4eF9lbmNvZGVyX2luaXQoc3RydWN0 IGkyY19jbGllbnQgKmNsaWVudCwKIAllbmNvZGVyX3NsYXZlLT5zbGF2ZV9mdW5jcyA9ICZ0ZGE5 OTh4X2VuY29kZXJfZnVuY3M7CiAKIAkvKiB3YWtlIHVwIHRoZSBkZXZpY2U6ICovCi0JY2VjX3dy aXRlKGVuY29kZXIsIFJFR19DRUNfRU5BTU9EUywKKwljZWNfd3JpdGUocHJpdiwgUkVHX0NFQ19F TkFNT0RTLAogCQkJQ0VDX0VOQU1PRFNfRU5fUlhTRU5TIHwgQ0VDX0VOQU1PRFNfRU5fSERNSSk7 CiAKLQl0ZGE5OTh4X3Jlc2V0KGVuY29kZXIpOworCXRkYTk5OHhfcmVzZXQocHJpdik7CiAKIAkv KiByZWFkIHZlcnNpb246ICovCi0JcHJpdi0+cmV2ID0gcmVnX3JlYWQoZW5jb2RlciwgUkVHX1ZF UlNJT05fTFNCKSB8Ci0JCQlyZWdfcmVhZChlbmNvZGVyLCBSRUdfVkVSU0lPTl9NU0IpIDw8IDg7 CisJcHJpdi0+cmV2ID0gcmVnX3JlYWQocHJpdiwgUkVHX1ZFUlNJT05fTFNCKSB8CisJCQlyZWdf cmVhZChwcml2LCBSRUdfVkVSU0lPTl9NU0IpIDw8IDg7CiAKIAkvKiBtYXNrIG9mZiBmZWF0dXJl IGJpdHM6ICovCiAJcHJpdi0+cmV2ICY9IH4weDMwOyAvKiBub3QtaGRjcCBhbmQgbm90LXNjYWxh ciBiaXQgKi8KQEAgLTExNzMsMTYgKzExNzUsMTYgQEAgdGRhOTk4eF9lbmNvZGVyX2luaXQoc3Ry dWN0IGkyY19jbGllbnQgKmNsaWVudCwKIAl9CiAKIAkvKiBhZnRlciByZXNldCwgZW5hYmxlIERE QzogKi8KLQlyZWdfd3JpdGUoZW5jb2RlciwgUkVHX0REQ19ESVNBQkxFLCAweDAwKTsKKwlyZWdf d3JpdGUocHJpdiwgUkVHX0REQ19ESVNBQkxFLCAweDAwKTsKIAogCS8qIHNldCBjbG9jayBvbiBE REMgY2hhbm5lbDogKi8KLQlyZWdfd3JpdGUoZW5jb2RlciwgUkVHX1RYMywgMzkpOworCXJlZ193 cml0ZShwcml2LCBSRUdfVFgzLCAzOSk7CiAKIAkvKiBpZiBuZWNlc3NhcnksIGRpc2FibGUgbXVs dGktbWFzdGVyOiAqLwogCWlmIChwcml2LT5yZXYgPT0gVERBMTk5ODkpCi0JCXJlZ19zZXQoZW5j b2RlciwgUkVHX0kyQ19NQVNURVIsIEkyQ19NQVNURVJfRElTX01NKTsKKwkJcmVnX3NldChwcml2 LCBSRUdfSTJDX01BU1RFUiwgSTJDX01BU1RFUl9ESVNfTU0pOwogCi0JY2VjX3dyaXRlKGVuY29k ZXIsIFJFR19DRUNfRlJPX0lNX0NMS19DVFJMLAorCWNlY193cml0ZShwcml2LCBSRUdfQ0VDX0ZS T19JTV9DTEtfQ1RSTCwKIAkJCUNFQ19GUk9fSU1fQ0xLX0NUUkxfR0hPU1RfRElTIHwgQ0VDX0ZS T19JTV9DTEtfQ1RSTF9JTUNMS19TRUwpOwogCiAJcmV0dXJuIDA7CgoKLS0gCktlbiBhciBjJ2hl bnRhw7EJfAkgICAgICAqKiBCcmVpemggaGEgTGludXggYXRhdiEgKioKSmVmCQl8CQlodHRwOi8v bW9pbmVqZi5mcmVlLmZyLwpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3Rv cC5vcmcKaHR0cDovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1k ZXZlbAo= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754309AbaAILJ1 (ORCPT ); Thu, 9 Jan 2014 06:09:27 -0500 Received: from smtp1-g21.free.fr ([212.27.42.1]:34714 "EHLO smtp1-g21.free.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754020AbaAILJI convert rfc822-to-8bit (ORCPT ); Thu, 9 Jan 2014 06:09:08 -0500 Date: Thu, 9 Jan 2014 11:57:24 +0100 From: Jean-Francois Moine To: dri-devel@lists.freedesktop.org Cc: Dave Airlie , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Rob Clark Subject: [PATCH v2 1/28] drm/i2c: tda998x: simplify the i2c read/write functions Message-ID: <20140109115724.61340f29@armhf> X-Mailer: Claws Mail 3.9.3 (GTK+ 2.24.22; arm-unknown-linux-gnueabihf) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8BIT Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch simplifies the i2c read/write functions and permits them to be easily called in more contexts. Signed-off-by: Jean-Francois Moine --- drivers/gpu/drm/i2c/tda998x_drv.c | 322 +++++++++++---------- 1 file changed, 162 insertions(+), 160 deletions(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 400b0c4..26dd299 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -30,6 +30,7 @@ struct tda998x_priv { struct i2c_client *cec; + struct i2c_client *hdmi; uint16_t rev; uint8_t current_page; int dpms; @@ -328,9 +329,9 @@ struct tda998x_priv { #define TDA19988 0x0301 static void -cec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val) +cec_write(struct tda998x_priv *priv, uint16_t addr, uint8_t val) { - struct i2c_client *client = to_tda998x_priv(encoder)->cec; + struct i2c_client *client = priv->cec; uint8_t buf[] = {addr, val}; int ret; @@ -340,9 +341,9 @@ cec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val) } static uint8_t -cec_read(struct drm_encoder *encoder, uint8_t addr) +cec_read(struct tda998x_priv *priv, uint8_t addr) { - struct i2c_client *client = to_tda998x_priv(encoder)->cec; + struct i2c_client *client = priv->cec; uint8_t val; int ret; @@ -362,12 +363,10 @@ fail: } static void -set_page(struct drm_encoder *encoder, uint16_t reg) +set_page(struct tda998x_priv *priv, uint16_t reg) { - struct tda998x_priv *priv = to_tda998x_priv(encoder); - if (REG2PAGE(reg) != priv->current_page) { - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + struct i2c_client *client = priv->hdmi; uint8_t buf[] = { REG_CURPAGE, REG2PAGE(reg) }; @@ -380,13 +379,13 @@ set_page(struct drm_encoder *encoder, uint16_t reg) } static int -reg_read_range(struct drm_encoder *encoder, uint16_t reg, char *buf, int cnt) +reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt) { - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + struct i2c_client *client = priv->hdmi; uint8_t addr = REG2ADDR(reg); int ret; - set_page(encoder, reg); + set_page(priv, reg); ret = i2c_master_send(client, &addr, sizeof(addr)); if (ret < 0) @@ -404,16 +403,16 @@ fail: } static void -reg_write_range(struct drm_encoder *encoder, uint16_t reg, uint8_t *p, int cnt) +reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt) { - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + struct i2c_client *client = priv->hdmi; uint8_t buf[cnt+1]; int ret; buf[0] = REG2ADDR(reg); memcpy(&buf[1], p, cnt); - set_page(encoder, reg); + set_page(priv, reg); ret = i2c_master_send(client, buf, cnt + 1); if (ret < 0) @@ -421,21 +420,21 @@ reg_write_range(struct drm_encoder *encoder, uint16_t reg, uint8_t *p, int cnt) } static uint8_t -reg_read(struct drm_encoder *encoder, uint16_t reg) +reg_read(struct tda998x_priv *priv, uint16_t reg) { uint8_t val = 0; - reg_read_range(encoder, reg, &val, sizeof(val)); + reg_read_range(priv, reg, &val, sizeof(val)); return val; } static void -reg_write(struct drm_encoder *encoder, uint16_t reg, uint8_t val) +reg_write(struct tda998x_priv *priv, uint16_t reg, uint8_t val) { - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + struct i2c_client *client = priv->hdmi; uint8_t buf[] = {REG2ADDR(reg), val}; int ret; - set_page(encoder, reg); + set_page(priv, reg); ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); if (ret < 0) @@ -443,13 +442,13 @@ reg_write(struct drm_encoder *encoder, uint16_t reg, uint8_t val) } static void -reg_write16(struct drm_encoder *encoder, uint16_t reg, uint16_t val) +reg_write16(struct tda998x_priv *priv, uint16_t reg, uint16_t val) { - struct i2c_client *client = drm_i2c_encoder_get_client(encoder); + struct i2c_client *client = priv->hdmi; uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; int ret; - set_page(encoder, reg); + set_page(priv, reg); ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); if (ret < 0) @@ -457,47 +456,47 @@ reg_write16(struct drm_encoder *encoder, uint16_t reg, uint16_t val) } static void -reg_set(struct drm_encoder *encoder, uint16_t reg, uint8_t val) +reg_set(struct tda998x_priv *priv, uint16_t reg, uint8_t val) { - reg_write(encoder, reg, reg_read(encoder, reg) | val); + reg_write(priv, reg, reg_read(priv, reg) | val); } static void -reg_clear(struct drm_encoder *encoder, uint16_t reg, uint8_t val) +reg_clear(struct tda998x_priv *priv, uint16_t reg, uint8_t val) { - reg_write(encoder, reg, reg_read(encoder, reg) & ~val); + reg_write(priv, reg, reg_read(priv, reg) & ~val); } static void -tda998x_reset(struct drm_encoder *encoder) +tda998x_reset(struct tda998x_priv *priv) { /* reset audio and i2c master: */ - reg_set(encoder, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); + reg_set(priv, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); msleep(50); - reg_clear(encoder, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); + reg_clear(priv, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); msleep(50); /* reset transmitter: */ - reg_set(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); - reg_clear(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); + reg_set(priv, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); + reg_clear(priv, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); /* PLL registers common configuration */ - reg_write(encoder, REG_PLL_SERIAL_1, 0x00); - reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1)); - reg_write(encoder, REG_PLL_SERIAL_3, 0x00); - reg_write(encoder, REG_SERIALIZER, 0x00); - reg_write(encoder, REG_BUFFER_OUT, 0x00); - reg_write(encoder, REG_PLL_SCG1, 0x00); - reg_write(encoder, REG_AUDIO_DIV, AUDIO_DIV_SERCLK_8); - reg_write(encoder, REG_SEL_CLK, SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); - reg_write(encoder, REG_PLL_SCGN1, 0xfa); - reg_write(encoder, REG_PLL_SCGN2, 0x00); - reg_write(encoder, REG_PLL_SCGR1, 0x5b); - reg_write(encoder, REG_PLL_SCGR2, 0x00); - reg_write(encoder, REG_PLL_SCG2, 0x10); + reg_write(priv, REG_PLL_SERIAL_1, 0x00); + reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1)); + reg_write(priv, REG_PLL_SERIAL_3, 0x00); + reg_write(priv, REG_SERIALIZER, 0x00); + reg_write(priv, REG_BUFFER_OUT, 0x00); + reg_write(priv, REG_PLL_SCG1, 0x00); + reg_write(priv, REG_AUDIO_DIV, AUDIO_DIV_SERCLK_8); + reg_write(priv, REG_SEL_CLK, SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); + reg_write(priv, REG_PLL_SCGN1, 0xfa); + reg_write(priv, REG_PLL_SCGN2, 0x00); + reg_write(priv, REG_PLL_SCGR1, 0x5b); + reg_write(priv, REG_PLL_SCGR2, 0x00); + reg_write(priv, REG_PLL_SCG2, 0x10); /* Write the default value MUX register */ - reg_write(encoder, REG_MUX_VP_VIP_OUT, 0x24); + reg_write(priv, REG_MUX_VP_VIP_OUT, 0x24); } static uint8_t tda998x_cksum(uint8_t *buf, size_t bytes) @@ -513,18 +512,18 @@ static uint8_t tda998x_cksum(uint8_t *buf, size_t bytes) #define PB(x) (HB(2) + 1 + (x)) static void -tda998x_write_if(struct drm_encoder *encoder, uint8_t bit, uint16_t addr, +tda998x_write_if(struct tda998x_priv *priv, uint8_t bit, uint16_t addr, uint8_t *buf, size_t size) { buf[PB(0)] = tda998x_cksum(buf, size); - reg_clear(encoder, REG_DIP_IF_FLAGS, bit); - reg_write_range(encoder, addr, buf, size); - reg_set(encoder, REG_DIP_IF_FLAGS, bit); + reg_clear(priv, REG_DIP_IF_FLAGS, bit); + reg_write_range(priv, addr, buf, size); + reg_set(priv, REG_DIP_IF_FLAGS, bit); } static void -tda998x_write_aif(struct drm_encoder *encoder, struct tda998x_encoder_params *p) +tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p) { uint8_t buf[PB(5) + 1]; @@ -537,12 +536,12 @@ tda998x_write_aif(struct drm_encoder *encoder, struct tda998x_encoder_params *p) buf[PB(4)] = p->audio_frame[4]; buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */ - tda998x_write_if(encoder, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, + tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, sizeof(buf)); } static void -tda998x_write_avi(struct drm_encoder *encoder, struct drm_display_mode *mode) +tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode) { uint8_t buf[PB(13) + 1]; @@ -554,36 +553,36 @@ tda998x_write_avi(struct drm_encoder *encoder, struct drm_display_mode *mode) buf[PB(3)] = HDMI_QUANTIZATION_RANGE_FULL << 2; buf[PB(4)] = drm_match_cea_mode(mode); - tda998x_write_if(encoder, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf, + tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf, sizeof(buf)); } -static void tda998x_audio_mute(struct drm_encoder *encoder, bool on) +static void tda998x_audio_mute(struct tda998x_priv *priv, bool on) { if (on) { - reg_set(encoder, REG_SOFTRESET, SOFTRESET_AUDIO); - reg_clear(encoder, REG_SOFTRESET, SOFTRESET_AUDIO); - reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); + reg_set(priv, REG_SOFTRESET, SOFTRESET_AUDIO); + reg_clear(priv, REG_SOFTRESET, SOFTRESET_AUDIO); + reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); } else { - reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); + reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); } } static void -tda998x_configure_audio(struct drm_encoder *encoder, +tda998x_configure_audio(struct tda998x_priv *priv, struct drm_display_mode *mode, struct tda998x_encoder_params *p) { uint8_t buf[6], clksel_aip, clksel_fs, ca_i2s, cts_n, adiv; uint32_t n; /* Enable audio ports */ - reg_write(encoder, REG_ENA_AP, p->audio_cfg); - reg_write(encoder, REG_ENA_ACLK, p->audio_clk_cfg); + reg_write(priv, REG_ENA_AP, p->audio_cfg); + reg_write(priv, REG_ENA_ACLK, p->audio_clk_cfg); /* Set audio input source */ switch (p->audio_format) { case AFMT_SPDIF: - reg_write(encoder, REG_MUX_AP, 0x40); + reg_write(priv, REG_MUX_AP, 0x40); clksel_aip = AIP_CLKSEL_AIP(0); /* FS64SPDIF */ clksel_fs = AIP_CLKSEL_FS(2); @@ -592,7 +591,7 @@ tda998x_configure_audio(struct drm_encoder *encoder, break; case AFMT_I2S: - reg_write(encoder, REG_MUX_AP, 0x64); + reg_write(priv, REG_MUX_AP, 0x64); clksel_aip = AIP_CLKSEL_AIP(1); /* ACLK */ clksel_fs = AIP_CLKSEL_FS(0); @@ -605,12 +604,12 @@ tda998x_configure_audio(struct drm_encoder *encoder, return; } - reg_write(encoder, REG_AIP_CLKSEL, clksel_aip); - reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_LAYOUT); + reg_write(priv, REG_AIP_CLKSEL, clksel_aip); + reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_LAYOUT); /* Enable automatic CTS generation */ - reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_ACR_MAN); - reg_write(encoder, REG_CTS_N, cts_n); + reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_ACR_MAN); + reg_write(priv, REG_CTS_N, cts_n); /* * Audio input somehow depends on HDMI line rate which is @@ -623,7 +622,7 @@ tda998x_configure_audio(struct drm_encoder *encoder, adiv = AUDIO_DIV_SERCLK_16; else adiv = AUDIO_DIV_SERCLK_8; - reg_write(encoder, REG_AUDIO_DIV, adiv); + reg_write(priv, REG_AUDIO_DIV, adiv); /* * This is the approximate value of N, which happens to be @@ -638,28 +637,28 @@ tda998x_configure_audio(struct drm_encoder *encoder, buf[3] = n; buf[4] = n >> 8; buf[5] = n >> 16; - reg_write_range(encoder, REG_ACR_CTS_0, buf, 6); + reg_write_range(priv, REG_ACR_CTS_0, buf, 6); /* Set CTS clock reference */ - reg_write(encoder, REG_AIP_CLKSEL, clksel_aip | clksel_fs); + reg_write(priv, REG_AIP_CLKSEL, clksel_aip | clksel_fs); /* Reset CTS generator */ - reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); - reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); + reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); + reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); /* Write the channel status */ buf[0] = 0x04; buf[1] = 0x00; buf[2] = 0x00; buf[3] = 0xf1; - reg_write_range(encoder, REG_CH_STAT_B(0), buf, 4); + reg_write_range(priv, REG_CH_STAT_B(0), buf, 4); - tda998x_audio_mute(encoder, true); + tda998x_audio_mute(priv, true); mdelay(20); - tda998x_audio_mute(encoder, false); + tda998x_audio_mute(priv, false); /* Write the audio information packet */ - tda998x_write_aif(encoder, p); + tda998x_write_aif(priv, p); } /* DRM encoder functions */ @@ -701,19 +700,19 @@ tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) switch (mode) { case DRM_MODE_DPMS_ON: /* enable video ports, audio will be enabled later */ - reg_write(encoder, REG_ENA_VP_0, 0xff); - reg_write(encoder, REG_ENA_VP_1, 0xff); - reg_write(encoder, REG_ENA_VP_2, 0xff); + reg_write(priv, REG_ENA_VP_0, 0xff); + reg_write(priv, REG_ENA_VP_1, 0xff); + reg_write(priv, REG_ENA_VP_2, 0xff); /* set muxing after enabling ports: */ - reg_write(encoder, REG_VIP_CNTRL_0, priv->vip_cntrl_0); - reg_write(encoder, REG_VIP_CNTRL_1, priv->vip_cntrl_1); - reg_write(encoder, REG_VIP_CNTRL_2, priv->vip_cntrl_2); + reg_write(priv, REG_VIP_CNTRL_0, priv->vip_cntrl_0); + reg_write(priv, REG_VIP_CNTRL_1, priv->vip_cntrl_1); + reg_write(priv, REG_VIP_CNTRL_2, priv->vip_cntrl_2); break; case DRM_MODE_DPMS_OFF: /* disable video ports */ - reg_write(encoder, REG_ENA_VP_0, 0x00); - reg_write(encoder, REG_ENA_VP_1, 0x00); - reg_write(encoder, REG_ENA_VP_2, 0x00); + reg_write(priv, REG_ENA_VP_0, 0x00); + reg_write(priv, REG_ENA_VP_1, 0x00); + reg_write(priv, REG_ENA_VP_2, 0x00); break; } @@ -826,57 +825,57 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, div = 148500 / mode->clock; /* mute the audio FIFO: */ - reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); + reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); /* set HDMI HDCP mode off: */ - reg_set(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); - reg_clear(encoder, REG_TX33, TX33_HDMI); + reg_set(priv, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); + reg_clear(priv, REG_TX33, TX33_HDMI); + reg_write(priv, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(0)); - reg_write(encoder, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(0)); /* no pre-filter or interpolator: */ - reg_write(encoder, REG_HVF_CNTRL_0, HVF_CNTRL_0_PREFIL(0) | + reg_write(priv, REG_HVF_CNTRL_0, HVF_CNTRL_0_PREFIL(0) | HVF_CNTRL_0_INTPOL(0)); - reg_write(encoder, REG_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0)); - reg_write(encoder, REG_VIP_CNTRL_4, VIP_CNTRL_4_BLANKIT(0) | + reg_write(priv, REG_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0)); + reg_write(priv, REG_VIP_CNTRL_4, VIP_CNTRL_4_BLANKIT(0) | VIP_CNTRL_4_BLC(0)); - reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR); + reg_clear(priv, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR); - reg_clear(encoder, REG_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IZ); - reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_DE); - reg_write(encoder, REG_SERIALIZER, 0); - reg_write(encoder, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); + reg_clear(priv, REG_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IZ); + reg_clear(priv, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_DE); + reg_write(priv, REG_SERIALIZER, 0); + reg_write(priv, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */ rep = 0; - reg_write(encoder, REG_RPT_CNTRL, 0); - reg_write(encoder, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | + reg_write(priv, REG_RPT_CNTRL, 0); + reg_write(priv, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); - reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | + reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | PLL_SERIAL_2_SRL_PR(rep)); /* set color matrix bypass flag: */ - reg_set(encoder, REG_MAT_CONTRL, MAT_CONTRL_MAT_BP); + reg_set(priv, REG_MAT_CONTRL, MAT_CONTRL_MAT_BP); /* set BIAS tmds value: */ - reg_write(encoder, REG_ANA_GENERAL, 0x09); + reg_write(priv, REG_ANA_GENERAL, 0x09); - reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_MTHD); + reg_clear(priv, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_MTHD); /* * Sync on rising HSYNC/VSYNC */ - reg_write(encoder, REG_VIP_CNTRL_3, 0); - reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_SYNC_HS); + reg_write(priv, REG_VIP_CNTRL_3, 0); + reg_set(priv, REG_VIP_CNTRL_3, VIP_CNTRL_3_SYNC_HS); /* * TDA19988 requires high-active sync at input stage, * so invert low-active sync provided by master encoder here */ if (mode->flags & DRM_MODE_FLAG_NHSYNC) - reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_H_TGL); + reg_set(priv, REG_VIP_CNTRL_3, VIP_CNTRL_3_H_TGL); if (mode->flags & DRM_MODE_FLAG_NVSYNC) - reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_V_TGL); + reg_set(priv, REG_VIP_CNTRL_3, VIP_CNTRL_3_V_TGL); /* * Always generate sync polarity relative to input sync and @@ -887,49 +886,49 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, reg |= TBG_CNTRL_1_H_TGL; if (mode->flags & DRM_MODE_FLAG_NVSYNC) reg |= TBG_CNTRL_1_V_TGL; - reg_write(encoder, REG_TBG_CNTRL_1, reg); - - reg_write(encoder, REG_VIDFORMAT, 0x00); - reg_write16(encoder, REG_REFPIX_MSB, ref_pix); - reg_write16(encoder, REG_REFLINE_MSB, ref_line); - reg_write16(encoder, REG_NPIX_MSB, n_pix); - reg_write16(encoder, REG_NLINE_MSB, n_line); - reg_write16(encoder, REG_VS_LINE_STRT_1_MSB, vs1_line_s); - reg_write16(encoder, REG_VS_PIX_STRT_1_MSB, vs1_pix_s); - reg_write16(encoder, REG_VS_LINE_END_1_MSB, vs1_line_e); - reg_write16(encoder, REG_VS_PIX_END_1_MSB, vs1_pix_e); - reg_write16(encoder, REG_VS_LINE_STRT_2_MSB, vs2_line_s); - reg_write16(encoder, REG_VS_PIX_STRT_2_MSB, vs2_pix_s); - reg_write16(encoder, REG_VS_LINE_END_2_MSB, vs2_line_e); - reg_write16(encoder, REG_VS_PIX_END_2_MSB, vs2_pix_e); - reg_write16(encoder, REG_HS_PIX_START_MSB, hs_pix_s); - reg_write16(encoder, REG_HS_PIX_STOP_MSB, hs_pix_e); - reg_write16(encoder, REG_VWIN_START_1_MSB, vwin1_line_s); - reg_write16(encoder, REG_VWIN_END_1_MSB, vwin1_line_e); - reg_write16(encoder, REG_VWIN_START_2_MSB, vwin2_line_s); - reg_write16(encoder, REG_VWIN_END_2_MSB, vwin2_line_e); - reg_write16(encoder, REG_DE_START_MSB, de_pix_s); - reg_write16(encoder, REG_DE_STOP_MSB, de_pix_e); + reg_write(priv, REG_TBG_CNTRL_1, reg); + + reg_write(priv, REG_VIDFORMAT, 0x00); + reg_write16(priv, REG_REFPIX_MSB, ref_pix); + reg_write16(priv, REG_REFLINE_MSB, ref_line); + reg_write16(priv, REG_NPIX_MSB, n_pix); + reg_write16(priv, REG_NLINE_MSB, n_line); + reg_write16(priv, REG_VS_LINE_STRT_1_MSB, vs1_line_s); + reg_write16(priv, REG_VS_PIX_STRT_1_MSB, vs1_pix_s); + reg_write16(priv, REG_VS_LINE_END_1_MSB, vs1_line_e); + reg_write16(priv, REG_VS_PIX_END_1_MSB, vs1_pix_e); + reg_write16(priv, REG_VS_LINE_STRT_2_MSB, vs2_line_s); + reg_write16(priv, REG_VS_PIX_STRT_2_MSB, vs2_pix_s); + reg_write16(priv, REG_VS_LINE_END_2_MSB, vs2_line_e); + reg_write16(priv, REG_VS_PIX_END_2_MSB, vs2_pix_e); + reg_write16(priv, REG_HS_PIX_START_MSB, hs_pix_s); + reg_write16(priv, REG_HS_PIX_STOP_MSB, hs_pix_e); + reg_write16(priv, REG_VWIN_START_1_MSB, vwin1_line_s); + reg_write16(priv, REG_VWIN_END_1_MSB, vwin1_line_e); + reg_write16(priv, REG_VWIN_START_2_MSB, vwin2_line_s); + reg_write16(priv, REG_VWIN_END_2_MSB, vwin2_line_e); + reg_write16(priv, REG_DE_START_MSB, de_pix_s); + reg_write16(priv, REG_DE_STOP_MSB, de_pix_e); if (priv->rev == TDA19988) { /* let incoming pixels fill the active space (if any) */ - reg_write(encoder, REG_ENABLE_SPACE, 0x01); + reg_write(priv, REG_ENABLE_SPACE, 0x01); } /* must be last register set: */ - reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE); + reg_clear(priv, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE); /* Only setup the info frames if the sink is HDMI */ if (priv->is_hdmi_sink) { /* We need to turn HDMI HDCP stuff on to get audio through */ - reg_clear(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); - reg_write(encoder, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(1)); - reg_set(encoder, REG_TX33, TX33_HDMI); + reg_clear(priv, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); + reg_write(priv, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(1)); + reg_set(priv, REG_TX33, TX33_HDMI); - tda998x_write_avi(encoder, adjusted_mode); + tda998x_write_avi(priv, adjusted_mode); if (priv->params.audio_cfg) - tda998x_configure_audio(encoder, adjusted_mode, + tda998x_configure_audio(priv, adjusted_mode, &priv->params); } } @@ -938,7 +937,9 @@ static enum drm_connector_status tda998x_encoder_detect(struct drm_encoder *encoder, struct drm_connector *connector) { - uint8_t val = cec_read(encoder, REG_CEC_RXSHPDLEV); + struct tda998x_priv *priv = to_tda998x_priv(encoder); + uint8_t val = cec_read(priv, REG_CEC_RXSHPDLEV); + return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected : connector_status_disconnected; } @@ -946,29 +947,30 @@ tda998x_encoder_detect(struct drm_encoder *encoder, static int read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) { + struct tda998x_priv *priv = to_tda998x_priv(encoder); uint8_t offset, segptr; int ret, i; /* enable EDID read irq: */ - reg_set(encoder, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); + reg_set(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); offset = (blk & 1) ? 128 : 0; segptr = blk / 2; - reg_write(encoder, REG_DDC_ADDR, 0xa0); - reg_write(encoder, REG_DDC_OFFS, offset); - reg_write(encoder, REG_DDC_SEGM_ADDR, 0x60); - reg_write(encoder, REG_DDC_SEGM, segptr); + reg_write(priv, REG_DDC_ADDR, 0xa0); + reg_write(priv, REG_DDC_OFFS, offset); + reg_write(priv, REG_DDC_SEGM_ADDR, 0x60); + reg_write(priv, REG_DDC_SEGM, segptr); /* enable reading EDID: */ - reg_write(encoder, REG_EDID_CTRL, 0x1); + reg_write(priv, REG_EDID_CTRL, 0x1); /* flag must be cleared by sw: */ - reg_write(encoder, REG_EDID_CTRL, 0x0); + reg_write(priv, REG_EDID_CTRL, 0x0); /* wait for block read to complete: */ for (i = 100; i > 0; i--) { - uint8_t val = reg_read(encoder, REG_INT_FLAGS_2); + uint8_t val = reg_read(priv, REG_INT_FLAGS_2); if (val & INT_FLAGS_2_EDID_BLK_RD) break; msleep(1); @@ -977,14 +979,14 @@ read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) if (i == 0) return -ETIMEDOUT; - ret = reg_read_range(encoder, REG_EDID_DATA_0, buf, EDID_LENGTH); + ret = reg_read_range(priv, REG_EDID_DATA_0, buf, EDID_LENGTH); if (ret != EDID_LENGTH) { dev_err(encoder->dev->dev, "failed to read edid block %d: %d", blk, ret); return ret; } - reg_clear(encoder, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); + reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); return 0; } @@ -1001,7 +1003,7 @@ do_get_edid(struct drm_encoder *encoder) return NULL; if (priv->rev == TDA19988) - reg_clear(encoder, REG_TX4, TX4_PD_RAM); + reg_clear(priv, REG_TX4, TX4_PD_RAM); /* base block fetch */ if (read_edid_block(encoder, block, 0)) @@ -1041,13 +1043,13 @@ do_get_edid(struct drm_encoder *encoder) done: if (priv->rev == TDA19988) - reg_set(encoder, REG_TX4, TX4_PD_RAM); + reg_set(priv, REG_TX4, TX4_PD_RAM); return block; fail: if (priv->rev == TDA19988) - reg_set(encoder, REG_TX4, TX4_PD_RAM); + reg_set(priv, REG_TX4, TX4_PD_RAM); dev_warn(encoder->dev->dev, "failed to read EDID\n"); kfree(block); return NULL; @@ -1131,7 +1133,6 @@ tda998x_encoder_init(struct i2c_client *client, struct drm_device *dev, struct drm_encoder_slave *encoder_slave) { - struct drm_encoder *encoder = &encoder_slave->base; struct tda998x_priv *priv; priv = kzalloc(sizeof(*priv), GFP_KERNEL); @@ -1143,6 +1144,7 @@ tda998x_encoder_init(struct i2c_client *client, priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5); priv->current_page = 0; + priv->hdmi = client; priv->cec = i2c_new_dummy(client->adapter, 0x34); priv->dpms = DRM_MODE_DPMS_OFF; @@ -1150,14 +1152,14 @@ tda998x_encoder_init(struct i2c_client *client, encoder_slave->slave_funcs = &tda998x_encoder_funcs; /* wake up the device: */ - cec_write(encoder, REG_CEC_ENAMODS, + cec_write(priv, REG_CEC_ENAMODS, CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); - tda998x_reset(encoder); + tda998x_reset(priv); /* read version: */ - priv->rev = reg_read(encoder, REG_VERSION_LSB) | - reg_read(encoder, REG_VERSION_MSB) << 8; + priv->rev = reg_read(priv, REG_VERSION_LSB) | + reg_read(priv, REG_VERSION_MSB) << 8; /* mask off feature bits: */ priv->rev &= ~0x30; /* not-hdcp and not-scalar bit */ @@ -1173,16 +1175,16 @@ tda998x_encoder_init(struct i2c_client *client, } /* after reset, enable DDC: */ - reg_write(encoder, REG_DDC_DISABLE, 0x00); + reg_write(priv, REG_DDC_DISABLE, 0x00); /* set clock on DDC channel: */ - reg_write(encoder, REG_TX3, 39); + reg_write(priv, REG_TX3, 39); /* if necessary, disable multi-master: */ if (priv->rev == TDA19989) - reg_set(encoder, REG_I2C_MASTER, I2C_MASTER_DIS_MM); + reg_set(priv, REG_I2C_MASTER, I2C_MASTER_DIS_MM); - cec_write(encoder, REG_CEC_FRO_IM_CLK_CTRL, + cec_write(priv, REG_CEC_FRO_IM_CLK_CTRL, CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL); return 0; -- Ken ar c'hentaƱ | ** Breizh ha Linux atav! ** Jef | http://moinejf.free.fr/