tda998x_drv.c revision 893c3e538dc338509b0c1121173355e8cfa34ff0
1e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* 2e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * Copyright (C) 2012 Texas Instruments 3e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * Author: Rob Clark <robdclark@gmail.com> 4e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * 5e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * This program is free software; you can redistribute it and/or modify it 6e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * under the terms of the GNU General Public License version 2 as published by 7e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * the Free Software Foundation. 8e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * 9e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * This program is distributed in the hope that it will be useful, but WITHOUT 10e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * more details. 13e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * 14e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * You should have received a copy of the GNU General Public License along with 15e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * this program. If not, see <http://www.gnu.org/licenses/>. 16e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 17e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 18e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 19e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 20893c3e538dc338509b0c1121173355e8cfa34ff0Russell King#include <linux/hdmi.h> 21e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <linux/module.h> 22e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 23e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drmP.h> 24e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drm_crtc_helper.h> 25e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drm_encoder_slave.h> 26e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drm_edid.h> 27c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#include <drm/i2c/tda998x.h> 28e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 29e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) 30e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 31e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstruct tda998x_priv { 32e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *cec; 33e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint16_t rev; 34e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t current_page; 35e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int dpms; 36c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King bool is_hdmi_sink; 375e74c22cd1e0f9e49573fe580de47e198ee04975Russell King u8 vip_cntrl_0; 385e74c22cd1e0f9e49573fe580de47e198ee04975Russell King u8 vip_cntrl_1; 395e74c22cd1e0f9e49573fe580de47e198ee04975Russell King u8 vip_cntrl_2; 40c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King struct tda998x_encoder_params params; 41e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 42e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 43e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define to_tda998x_priv(x) ((struct tda998x_priv *)to_encoder_slave(x)->slave_priv) 44e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 45e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* The TDA9988 series of devices use a paged register scheme.. to simplify 46e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * things we encode the page # in upper bits of the register #. To read/ 47e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * write a given register, we need to make sure CURPAGE register is set 48e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * appropriately. Which implies reads/writes are not atomic. Fun! 49e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 50e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 51e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG(page, addr) (((page) << 8) | (addr)) 52e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG2ADDR(reg) ((reg) & 0xff) 53e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG2PAGE(reg) (((reg) >> 8) & 0xff) 54e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 55e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CURPAGE 0xff /* write */ 56e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 57e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 58e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 00h: General Control */ 59e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VERSION_LSB REG(0x00, 0x00) /* read */ 60e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_MAIN_CNTRL0 REG(0x00, 0x01) /* read/write */ 61e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_SR (1 << 0) 62e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_DECS (1 << 1) 63e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_DEHS (1 << 2) 64e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_CECS (1 << 3) 65e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_CEHS (1 << 4) 66e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_SCALER (1 << 7) 67e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VERSION_MSB REG(0x00, 0x02) /* read */ 68e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_SOFTRESET REG(0x00, 0x0a) /* write */ 69e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SOFTRESET_AUDIO (1 << 0) 70e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SOFTRESET_I2C_MASTER (1 << 1) 71e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_DISABLE REG(0x00, 0x0b) /* read/write */ 72e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CCLK_ON REG(0x00, 0x0c) /* read/write */ 73e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_I2C_MASTER REG(0x00, 0x0d) /* read/write */ 74e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define I2C_MASTER_DIS_MM (1 << 0) 75e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define I2C_MASTER_DIS_FILT (1 << 1) 76e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define I2C_MASTER_APP_STRT_LAT (1 << 2) 77c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_FEAT_POWERDOWN REG(0x00, 0x0e) /* read/write */ 78c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define FEAT_POWERDOWN_SPDIF (1 << 3) 79e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_INT_FLAGS_0 REG(0x00, 0x0f) /* read/write */ 80e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_INT_FLAGS_1 REG(0x00, 0x10) /* read/write */ 81e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_INT_FLAGS_2 REG(0x00, 0x11) /* read/write */ 82e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define INT_FLAGS_2_EDID_BLK_RD (1 << 1) 83c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ENA_ACLK REG(0x00, 0x16) /* read/write */ 84e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_VP_0 REG(0x00, 0x18) /* read/write */ 85e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_VP_1 REG(0x00, 0x19) /* read/write */ 86e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_VP_2 REG(0x00, 0x1a) /* read/write */ 87e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_AP REG(0x00, 0x1e) /* read/write */ 88e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_0 REG(0x00, 0x20) /* write */ 89e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_MIRR_A (1 << 7) 90e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_SWAP_A(x) (((x) & 7) << 4) 91e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_MIRR_B (1 << 3) 92e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_SWAP_B(x) (((x) & 7) << 0) 93e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_1 REG(0x00, 0x21) /* write */ 94e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_MIRR_C (1 << 7) 95e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_SWAP_C(x) (((x) & 7) << 4) 96e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_MIRR_D (1 << 3) 97e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_SWAP_D(x) (((x) & 7) << 0) 98e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_2 REG(0x00, 0x22) /* write */ 99e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_MIRR_E (1 << 7) 100e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_SWAP_E(x) (((x) & 7) << 4) 101e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_MIRR_F (1 << 3) 102e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_SWAP_F(x) (((x) & 7) << 0) 103e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_3 REG(0x00, 0x23) /* write */ 104e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_X_TGL (1 << 0) 105e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_H_TGL (1 << 1) 106e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_V_TGL (1 << 2) 107e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_EMB (1 << 3) 108e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_SYNC_DE (1 << 4) 109e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_SYNC_HS (1 << 5) 110e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_DE_INT (1 << 6) 111e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_EDGE (1 << 7) 112e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_4 REG(0x00, 0x24) /* write */ 113e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_BLC(x) (((x) & 3) << 0) 114e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_BLANKIT(x) (((x) & 3) << 2) 115e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_CCIR656 (1 << 4) 116e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_656_ALT (1 << 5) 117e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_TST_656 (1 << 6) 118e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_TST_PAT (1 << 7) 119e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_5 REG(0x00, 0x25) /* write */ 120e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_5_CKCASE (1 << 0) 121e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_5_SP_CNT(x) (((x) & 3) << 1) 122c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_MUX_AP REG(0x00, 0x26) /* read/write */ 123bcb2481df01a9aee7a09b20d43194011edd35754Russell King#define REG_MUX_VP_VIP_OUT REG(0x00, 0x27) /* read/write */ 124e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_MAT_CONTRL REG(0x00, 0x80) /* write */ 125e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAT_CONTRL_MAT_SC(x) (((x) & 3) << 0) 126e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAT_CONTRL_MAT_BP (1 << 2) 127e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIDFORMAT REG(0x00, 0xa0) /* write */ 128e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFPIX_MSB REG(0x00, 0xa1) /* write */ 129e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFPIX_LSB REG(0x00, 0xa2) /* write */ 130e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFLINE_MSB REG(0x00, 0xa3) /* write */ 131e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFLINE_LSB REG(0x00, 0xa4) /* write */ 132e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NPIX_MSB REG(0x00, 0xa5) /* write */ 133e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NPIX_LSB REG(0x00, 0xa6) /* write */ 134e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NLINE_MSB REG(0x00, 0xa7) /* write */ 135e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NLINE_LSB REG(0x00, 0xa8) /* write */ 136e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_STRT_1_MSB REG(0x00, 0xa9) /* write */ 137e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_STRT_1_LSB REG(0x00, 0xaa) /* write */ 138e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_1_MSB REG(0x00, 0xab) /* write */ 139e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_1_LSB REG(0x00, 0xac) /* write */ 140e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_END_1_MSB REG(0x00, 0xad) /* write */ 141e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_END_1_LSB REG(0x00, 0xae) /* write */ 142e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_1_MSB REG(0x00, 0xaf) /* write */ 143e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_1_LSB REG(0x00, 0xb0) /* write */ 144088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VS_LINE_STRT_2_MSB REG(0x00, 0xb1) /* write */ 145088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VS_LINE_STRT_2_LSB REG(0x00, 0xb2) /* write */ 146e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_2_MSB REG(0x00, 0xb3) /* write */ 147e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_2_LSB REG(0x00, 0xb4) /* write */ 148088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VS_LINE_END_2_MSB REG(0x00, 0xb5) /* write */ 149088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VS_LINE_END_2_LSB REG(0x00, 0xb6) /* write */ 150e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_2_MSB REG(0x00, 0xb7) /* write */ 151e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_2_LSB REG(0x00, 0xb8) /* write */ 152e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_START_MSB REG(0x00, 0xb9) /* write */ 153e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_START_LSB REG(0x00, 0xba) /* write */ 154e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_STOP_MSB REG(0x00, 0xbb) /* write */ 155e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_STOP_LSB REG(0x00, 0xbc) /* write */ 156e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_START_1_MSB REG(0x00, 0xbd) /* write */ 157e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_START_1_LSB REG(0x00, 0xbe) /* write */ 158e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_END_1_MSB REG(0x00, 0xbf) /* write */ 159e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_END_1_LSB REG(0x00, 0xc0) /* write */ 160088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VWIN_START_2_MSB REG(0x00, 0xc1) /* write */ 161088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VWIN_START_2_LSB REG(0x00, 0xc2) /* write */ 162088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VWIN_END_2_MSB REG(0x00, 0xc3) /* write */ 163088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VWIN_END_2_LSB REG(0x00, 0xc4) /* write */ 164e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_START_MSB REG(0x00, 0xc5) /* write */ 165e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_START_LSB REG(0x00, 0xc6) /* write */ 166e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_STOP_MSB REG(0x00, 0xc7) /* write */ 167e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_STOP_LSB REG(0x00, 0xc8) /* write */ 168e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TBG_CNTRL_0 REG(0x00, 0xca) /* write */ 169088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_0_TOP_TGL (1 << 0) 170088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_0_TOP_SEL (1 << 1) 171088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_0_DE_EXT (1 << 2) 172088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_0_TOP_EXT (1 << 3) 173e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_0_FRAME_DIS (1 << 5) 174e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_0_SYNC_MTHD (1 << 6) 175e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_0_SYNC_ONCE (1 << 7) 176e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TBG_CNTRL_1 REG(0x00, 0xcb) /* write */ 177088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_H_TGL (1 << 0) 178088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_V_TGL (1 << 1) 179088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_TGL_EN (1 << 2) 180088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_X_EXT (1 << 3) 181088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_H_EXT (1 << 4) 182088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_V_EXT (1 << 5) 183e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_1_DWIN_DIS (1 << 6) 184e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENABLE_SPACE REG(0x00, 0xd6) /* write */ 185e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HVF_CNTRL_0 REG(0x00, 0xe4) /* write */ 186e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_SM (1 << 7) 187e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_RWB (1 << 6) 188e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_PREFIL(x) (((x) & 3) << 2) 189e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_INTPOL(x) (((x) & 3) << 0) 190e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HVF_CNTRL_1 REG(0x00, 0xe5) /* write */ 191e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_FOR (1 << 0) 192e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_YUVBLK (1 << 1) 193e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_VQR(x) (((x) & 3) << 2) 194e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4) 195e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_SEMI_PLANAR (1 << 6) 196e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */ 197c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_I2S_FORMAT REG(0x00, 0xfc) /* read/write */ 198c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define I2S_FORMAT(x) (((x) & 3) << 0) 199c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_AIP_CLKSEL REG(0x00, 0xfd) /* write */ 200c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AIP_CLKSEL_FS(x) (((x) & 3) << 0) 201c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AIP_CLKSEL_CLK_POL(x) (((x) & 1) << 2) 202c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AIP_CLKSEL_AIP(x) (((x) & 7) << 3) 203e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 204e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 205e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 02h: PLL settings */ 206e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SERIAL_1 REG(0x02, 0x00) /* read/write */ 207e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_1_SRL_FDN (1 << 0) 208e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_1_SRL_IZ(x) (((x) & 3) << 1) 209e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_1_SRL_MAN_IZ (1 << 6) 210e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SERIAL_2 REG(0x02, 0x01) /* read/write */ 211e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_2_SRL_NOSC(x) (((x) & 3) << 0) 212e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4) 213e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SERIAL_3 REG(0x02, 0x02) /* read/write */ 214e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_3_SRL_CCIR (1 << 0) 215e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_3_SRL_DE (1 << 2) 216e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_3_SRL_PXIN_SEL (1 << 4) 217e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_SERIALIZER REG(0x02, 0x03) /* read/write */ 218e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_BUFFER_OUT REG(0x02, 0x04) /* read/write */ 219e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCG1 REG(0x02, 0x05) /* read/write */ 220e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCG2 REG(0x02, 0x06) /* read/write */ 221e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGN1 REG(0x02, 0x07) /* read/write */ 222e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGN2 REG(0x02, 0x08) /* read/write */ 223e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGR1 REG(0x02, 0x09) /* read/write */ 224e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGR2 REG(0x02, 0x0a) /* read/write */ 225e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_AUDIO_DIV REG(0x02, 0x0e) /* read/write */ 226c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_1 0 227c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_2 1 228c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_4 2 229c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_8 3 230c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_16 4 231c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_32 5 232e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_SEL_CLK REG(0x02, 0x11) /* read/write */ 233e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SEL_CLK_SEL_CLK1 (1 << 0) 234e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SEL_CLK_SEL_VRF_CLK(x) (((x) & 3) << 1) 235e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SEL_CLK_ENA_SC_CLK (1 << 3) 236e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ANA_GENERAL REG(0x02, 0x12) /* read/write */ 237e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 238e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 239e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 09h: EDID Control */ 240e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_EDID_DATA_0 REG(0x09, 0x00) /* read */ 241e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* next 127 successive registers are the EDID block */ 242e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_EDID_CTRL REG(0x09, 0xfa) /* read/write */ 243e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_ADDR REG(0x09, 0xfb) /* read/write */ 244e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_OFFS REG(0x09, 0xfc) /* read/write */ 245e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_SEGM_ADDR REG(0x09, 0xfd) /* read/write */ 246e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_SEGM REG(0x09, 0xfe) /* read/write */ 247e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 248e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 249e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 10h: information frames and packets */ 250c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_IF1_HB0 REG(0x10, 0x20) /* read/write */ 251c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_IF2_HB0 REG(0x10, 0x40) /* read/write */ 252c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_IF3_HB0 REG(0x10, 0x60) /* read/write */ 253c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_IF4_HB0 REG(0x10, 0x80) /* read/write */ 254c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_IF5_HB0 REG(0x10, 0xa0) /* read/write */ 255e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 256e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 257e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 11h: audio settings and content info packets */ 258e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_AIP_CNTRL_0 REG(0x11, 0x00) /* read/write */ 259e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_RST_FIFO (1 << 0) 260e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_SWAP (1 << 1) 261e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_LAYOUT (1 << 2) 262e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_ACR_MAN (1 << 5) 263e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_RST_CTS (1 << 6) 264c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_CA_I2S REG(0x11, 0x01) /* read/write */ 265c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define CA_I2S_CA_I2S(x) (((x) & 31) << 0) 266c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define CA_I2S_HBR_CHSTAT (1 << 6) 267c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_LATENCY_RD REG(0x11, 0x04) /* read/write */ 268c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_CTS_0 REG(0x11, 0x05) /* read/write */ 269c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_CTS_1 REG(0x11, 0x06) /* read/write */ 270c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_CTS_2 REG(0x11, 0x07) /* read/write */ 271c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_N_0 REG(0x11, 0x08) /* read/write */ 272c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_N_1 REG(0x11, 0x09) /* read/write */ 273c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_N_2 REG(0x11, 0x0a) /* read/write */ 274c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_CTS_N REG(0x11, 0x0c) /* read/write */ 275c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define CTS_N_K(x) (((x) & 7) << 0) 276c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define CTS_N_M(x) (((x) & 3) << 4) 277e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENC_CNTRL REG(0x11, 0x0d) /* read/write */ 278e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define ENC_CNTRL_RST_ENC (1 << 0) 279e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define ENC_CNTRL_RST_SEL (1 << 1) 280e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define ENC_CNTRL_CTL_CODE(x) (((x) & 3) << 2) 281c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_DIP_FLAGS REG(0x11, 0x0e) /* read/write */ 282c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_FLAGS_ACR (1 << 0) 283c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_FLAGS_GC (1 << 1) 284c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_DIP_IF_FLAGS REG(0x11, 0x0f) /* read/write */ 285c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_IF_FLAGS_IF1 (1 << 1) 286c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_IF_FLAGS_IF2 (1 << 2) 287c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_IF_FLAGS_IF3 (1 << 3) 288c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_IF_FLAGS_IF4 (1 << 4) 289c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_IF_FLAGS_IF5 (1 << 5) 290c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_CH_STAT_B(x) REG(0x11, 0x14 + (x)) /* read/write */ 291e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 292e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 293e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 12h: HDCP and OTP */ 294e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TX3 REG(0x12, 0x9a) /* read/write */ 295063b472fbb44ac562797a630ac3516720f588140Russell King#define REG_TX4 REG(0x12, 0x9b) /* read/write */ 296063b472fbb44ac562797a630ac3516720f588140Russell King# define TX4_PD_RAM (1 << 1) 297e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TX33 REG(0x12, 0xb8) /* read/write */ 298e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TX33_HDMI (1 << 1) 299e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 300e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 301e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 13h: Gamut related metadata packets */ 302e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 303e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 304e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 305e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* CEC registers: (not paged) 306e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 307e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CEC_FRO_IM_CLK_CTRL 0xfb /* read/write */ 308e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_GHOST_DIS (1 << 7) 309e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_ENA_OTP (1 << 6) 310e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_IMCLK_SEL (1 << 1) 311e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_FRO_DIV (1 << 0) 312e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CEC_RXSHPDLEV 0xfe /* read */ 313e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_RXSHPDLEV_RXSENS (1 << 0) 314e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_RXSHPDLEV_HPD (1 << 1) 315e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 316e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CEC_ENAMODS 0xff /* read/write */ 317e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_DIS_FRO (1 << 6) 318e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_DIS_CCLK (1 << 5) 319e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_EN_RXSENS (1 << 2) 320e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_EN_HDMI (1 << 1) 321e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_EN_CEC (1 << 0) 322e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 323e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 324e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Device versions: */ 325e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA9989N2 0x0101 326e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA19989 0x0201 327e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA19989N2 0x0202 328e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA19988 0x0301 329e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 330e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 331e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkcec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val) 332e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 333e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = to_tda998x_priv(encoder)->cec; 334e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = {addr, val}; 335e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 336e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 337e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); 338e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 339e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d writing to cec:0x%x\n", ret, addr); 340e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 341e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 342e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic uint8_t 343e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkcec_read(struct drm_encoder *encoder, uint8_t addr) 344e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 345e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = to_tda998x_priv(encoder)->cec; 346e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t val; 347e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 348e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 349e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, &addr, sizeof(addr)); 350e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 351e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 352e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 353e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_recv(client, &val, sizeof(val)); 354e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 355e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 356e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 357e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return val; 358e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 359e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 360e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d reading from cec:0x%x\n", ret, addr); 361e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 362e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 363e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 364e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 365e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkset_page(struct drm_encoder *encoder, uint16_t reg) 366e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 367e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct tda998x_priv *priv = to_tda998x_priv(encoder); 368e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 369e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (REG2PAGE(reg) != priv->current_page) { 370e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 371e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = { 372e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark REG_CURPAGE, REG2PAGE(reg) 373e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark }; 374e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret = i2c_master_send(client, buf, sizeof(buf)); 375e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 376e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d writing to REG_CURPAGE\n", ret); 377e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 378e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->current_page = REG2PAGE(reg); 379e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 380e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 381e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 382e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 383e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_read_range(struct drm_encoder *encoder, uint16_t reg, char *buf, int cnt) 384e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 385e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 386e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t addr = REG2ADDR(reg); 387e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 388e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 389e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark set_page(encoder, reg); 390e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 391e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, &addr, sizeof(addr)); 392e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 393e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 394e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 395e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_recv(client, buf, cnt); 396e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 397e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 398e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 399e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return ret; 400e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 401e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 402e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); 403e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return ret; 404e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 405e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 406c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic void 407c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingreg_write_range(struct drm_encoder *encoder, uint16_t reg, uint8_t *p, int cnt) 408c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 409c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 410c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King uint8_t buf[cnt+1]; 411c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King int ret; 412c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 413c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[0] = REG2ADDR(reg); 414c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King memcpy(&buf[1], p, cnt); 415c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 416c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King set_page(encoder, reg); 417c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 418c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King ret = i2c_master_send(client, buf, cnt + 1); 419c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King if (ret < 0) 420c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); 421c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 422c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 423e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic uint8_t 424e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_read(struct drm_encoder *encoder, uint16_t reg) 425e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 426e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t val = 0; 427e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_read_range(encoder, reg, &val, sizeof(val)); 428e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return val; 429e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 430e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 431e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 432e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_write(struct drm_encoder *encoder, uint16_t reg, uint8_t val) 433e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 434e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 435e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = {REG2ADDR(reg), val}; 436e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 437e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 438e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark set_page(encoder, reg); 439e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 440e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); 441e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 442e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); 443e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 444e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 445e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 446e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_write16(struct drm_encoder *encoder, uint16_t reg, uint16_t val) 447e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 448e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 449e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; 450e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 451e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 452e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark set_page(encoder, reg); 453e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 454e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); 455e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 456e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); 457e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 458e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 459e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 460e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_set(struct drm_encoder *encoder, uint16_t reg, uint8_t val) 461e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 462e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, reg, reg_read(encoder, reg) | val); 463e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 464e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 465e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 466e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkreg_clear(struct drm_encoder *encoder, uint16_t reg, uint8_t val) 467e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 468e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, reg, reg_read(encoder, reg) & ~val); 469e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 470e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 471e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 472e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_reset(struct drm_encoder *encoder) 473e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 474e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* reset audio and i2c master: */ 475e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); 476e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark msleep(50); 477e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); 478e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark msleep(50); 479e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 480e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* reset transmitter: */ 481e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); 482e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); 483e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 484e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* PLL registers common configuration */ 485e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SERIAL_1, 0x00); 486e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1)); 487e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SERIAL_3, 0x00); 488e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_SERIALIZER, 0x00); 489e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_BUFFER_OUT, 0x00); 490e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCG1, 0x00); 491c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write(encoder, REG_AUDIO_DIV, AUDIO_DIV_SERCLK_8); 492e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_SEL_CLK, SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); 493e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCGN1, 0xfa); 494e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCGN2, 0x00); 495e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCGR1, 0x5b); 496e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCGR2, 0x00); 497e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SCG2, 0x10); 498bcb2481df01a9aee7a09b20d43194011edd35754Russell King 499bcb2481df01a9aee7a09b20d43194011edd35754Russell King /* Write the default value MUX register */ 500bcb2481df01a9aee7a09b20d43194011edd35754Russell King reg_write(encoder, REG_MUX_VP_VIP_OUT, 0x24); 501e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 502e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 503c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic uint8_t tda998x_cksum(uint8_t *buf, size_t bytes) 504c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 505c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King uint8_t sum = 0; 506c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 507c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King while (bytes--) 508c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King sum += *buf++; 509c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King return (255 - sum) + 1; 510c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 511c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 512c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define HB(x) (x) 513c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define PB(x) (HB(2) + 1 + (x)) 514c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 515c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic void 516c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingtda998x_write_if(struct drm_encoder *encoder, uint8_t bit, uint16_t addr, 517c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King uint8_t *buf, size_t size) 518c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 519c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(0)] = tda998x_cksum(buf, size); 520c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 521c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_clear(encoder, REG_DIP_IF_FLAGS, bit); 522c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write_range(encoder, addr, buf, size); 523c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_set(encoder, REG_DIP_IF_FLAGS, bit); 524c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 525c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 526c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic void 527c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingtda998x_write_aif(struct drm_encoder *encoder, struct tda998x_encoder_params *p) 528c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 529c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King uint8_t buf[PB(5) + 1]; 530c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 531c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[HB(0)] = 0x84; 532c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[HB(1)] = 0x01; 533c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[HB(2)] = 10; 534c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(0)] = 0; 535c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */ 536c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */ 537c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(4)] = p->audio_frame[4]; 538c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */ 539c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 540c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King tda998x_write_if(encoder, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, 541c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King sizeof(buf)); 542c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 543c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 544c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic void 545c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingtda998x_write_avi(struct drm_encoder *encoder, struct drm_display_mode *mode) 546c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 547c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King uint8_t buf[PB(13) + 1]; 548c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 549c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King memset(buf, 0, sizeof(buf)); 550c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[HB(0)] = 0x82; 551c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[HB(1)] = 0x02; 552c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[HB(2)] = 13; 553893c3e538dc338509b0c1121173355e8cfa34ff0Russell King buf[PB(1)] = HDMI_SCAN_MODE_UNDERSCAN; 554893c3e538dc338509b0c1121173355e8cfa34ff0Russell King buf[PB(3)] = HDMI_QUANTIZATION_RANGE_FULL << 2; 555c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(4)] = drm_match_cea_mode(mode); 556c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 557c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King tda998x_write_if(encoder, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf, 558c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King sizeof(buf)); 559c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 560c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 561c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic void tda998x_audio_mute(struct drm_encoder *encoder, bool on) 562c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 563c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King if (on) { 564c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_set(encoder, REG_SOFTRESET, SOFTRESET_AUDIO); 565c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_clear(encoder, REG_SOFTRESET, SOFTRESET_AUDIO); 566c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); 567c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King } else { 568c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); 569c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King } 570c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 571c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 572c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic void 573c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingtda998x_configure_audio(struct drm_encoder *encoder, 574c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King struct drm_display_mode *mode, struct tda998x_encoder_params *p) 575c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 576c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King uint8_t buf[6], clksel_aip, clksel_fs, ca_i2s, cts_n, adiv; 577c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King uint32_t n; 578c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 579c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Enable audio ports */ 580c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write(encoder, REG_ENA_AP, p->audio_cfg); 581c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write(encoder, REG_ENA_ACLK, p->audio_clk_cfg); 582c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 583c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Set audio input source */ 584c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King switch (p->audio_format) { 585c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King case AFMT_SPDIF: 586c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write(encoder, REG_MUX_AP, 0x40); 587c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King clksel_aip = AIP_CLKSEL_AIP(0); 588c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* FS64SPDIF */ 589c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King clksel_fs = AIP_CLKSEL_FS(2); 590c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King cts_n = CTS_N_M(3) | CTS_N_K(3); 591c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King ca_i2s = 0; 592c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King break; 593c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 594c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King case AFMT_I2S: 595c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write(encoder, REG_MUX_AP, 0x64); 596c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King clksel_aip = AIP_CLKSEL_AIP(1); 597c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* ACLK */ 598c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King clksel_fs = AIP_CLKSEL_FS(0); 599c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King cts_n = CTS_N_M(3) | CTS_N_K(3); 600c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King ca_i2s = CA_I2S_CA_I2S(0); 601c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King break; 6023b28802e37bb1ca1cab584f679c42e72a7e384f8David Herrmann 6033b28802e37bb1ca1cab584f679c42e72a7e384f8David Herrmann default: 6043b28802e37bb1ca1cab584f679c42e72a7e384f8David Herrmann BUG(); 6053b28802e37bb1ca1cab584f679c42e72a7e384f8David Herrmann return; 606c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King } 607c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 608c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write(encoder, REG_AIP_CLKSEL, clksel_aip); 609c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_LAYOUT); 610c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 611c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Enable automatic CTS generation */ 612c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_ACR_MAN); 613c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write(encoder, REG_CTS_N, cts_n); 614c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 615c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* 616c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * Audio input somehow depends on HDMI line rate which is 617c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * related to pixclk. Testing showed that modes with pixclk 618c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * >100MHz need a larger divider while <40MHz need the default. 619c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * There is no detailed info in the datasheet, so we just 620c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * assume 100MHz requires larger divider. 621c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King */ 622c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King if (mode->clock > 100000) 623c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King adiv = AUDIO_DIV_SERCLK_16; 624c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King else 625c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King adiv = AUDIO_DIV_SERCLK_8; 626c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write(encoder, REG_AUDIO_DIV, adiv); 627c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 628c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* 629c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * This is the approximate value of N, which happens to be 630c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * the recommended values for non-coherent clocks. 631c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King */ 632c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King n = 128 * p->audio_sample_rate / 1000; 633c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 634c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Write the CTS and N values */ 635c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[0] = 0x44; 636c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[1] = 0x42; 637c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[2] = 0x01; 638c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[3] = n; 639c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[4] = n >> 8; 640c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[5] = n >> 16; 641c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write_range(encoder, REG_ACR_CTS_0, buf, 6); 642c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 643c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Set CTS clock reference */ 644c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write(encoder, REG_AIP_CLKSEL, clksel_aip | clksel_fs); 645c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 646c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Reset CTS generator */ 647c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); 648c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); 649c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 650c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Write the channel status */ 651c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[0] = 0x04; 652c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[1] = 0x00; 653c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[2] = 0x00; 654c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[3] = 0xf1; 655c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write_range(encoder, REG_CH_STAT_B(0), buf, 4); 656c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 657c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King tda998x_audio_mute(encoder, true); 658c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King mdelay(20); 659c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King tda998x_audio_mute(encoder, false); 660c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 661c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Write the audio information packet */ 662c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King tda998x_write_aif(encoder, p); 663c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 664c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 665e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* DRM encoder functions */ 666e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 667e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 668e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_set_config(struct drm_encoder *encoder, void *params) 669e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 670c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King struct tda998x_priv *priv = to_tda998x_priv(encoder); 671c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King struct tda998x_encoder_params *p = params; 672c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 673c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) | 674c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) | 675c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King VIP_CNTRL_0_SWAP_B(p->swap_b) | 676c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0); 677c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) | 678c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) | 679c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King VIP_CNTRL_1_SWAP_D(p->swap_d) | 680c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0); 681c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) | 682c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) | 683c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King VIP_CNTRL_2_SWAP_F(p->swap_f) | 684c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0); 685c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 686c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King priv->params = *p; 687e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 688e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 689e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 690e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_dpms(struct drm_encoder *encoder, int mode) 691e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 692e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct tda998x_priv *priv = to_tda998x_priv(encoder); 693e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 694e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* we only care about on or off: */ 695e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode != DRM_MODE_DPMS_ON) 696e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark mode = DRM_MODE_DPMS_OFF; 697e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 698e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode == priv->dpms) 699e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return; 700e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 701e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark switch (mode) { 702e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case DRM_MODE_DPMS_ON: 703c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* enable video ports, audio will be enabled later */ 704e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_0, 0xff); 705e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_1, 0xff); 706e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_2, 0xff); 707e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set muxing after enabling ports: */ 7085e74c22cd1e0f9e49573fe580de47e198ee04975Russell King reg_write(encoder, REG_VIP_CNTRL_0, priv->vip_cntrl_0); 7095e74c22cd1e0f9e49573fe580de47e198ee04975Russell King reg_write(encoder, REG_VIP_CNTRL_1, priv->vip_cntrl_1); 7105e74c22cd1e0f9e49573fe580de47e198ee04975Russell King reg_write(encoder, REG_VIP_CNTRL_2, priv->vip_cntrl_2); 711e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark break; 712e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case DRM_MODE_DPMS_OFF: 713db6aaf4d55f95dcb6b162c3a59b56eb1e85ccdfeRussell King /* disable video ports */ 714e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_0, 0x00); 715e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_1, 0x00); 716e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENA_VP_2, 0x00); 717e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark break; 718e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 719e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 720e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->dpms = mode; 721e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 722e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 723e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 724e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_save(struct drm_encoder *encoder) 725e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 726e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 727e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 728e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 729e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 730e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_restore(struct drm_encoder *encoder) 731e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 732e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 733e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 734e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 735e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic bool 736e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_mode_fixup(struct drm_encoder *encoder, 737e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark const struct drm_display_mode *mode, 738e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_display_mode *adjusted_mode) 739e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 740e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return true; 741e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 742e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 743e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 744e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_mode_valid(struct drm_encoder *encoder, 745e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_display_mode *mode) 746e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 747e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return MODE_OK; 748e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 749e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 750e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 751e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_mode_set(struct drm_encoder *encoder, 752e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_display_mode *mode, 753e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_display_mode *adjusted_mode) 754e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 755e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct tda998x_priv *priv = to_tda998x_priv(encoder); 756088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t ref_pix, ref_line, n_pix, n_line; 757088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t hs_pix_s, hs_pix_e; 758088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; 759088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t vs2_pix_s, vs2_pix_e, vs2_line_s, vs2_line_e; 760088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t vwin1_line_s, vwin1_line_e; 761088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t vwin2_line_s, vwin2_line_e; 762088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t de_pix_s, de_pix_e; 763e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t reg, div, rep; 764e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 765088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth /* 766088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * Internally TDA998x is using ITU-R BT.656 style sync but 767088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * we get VESA style sync. TDA998x is using a reference pixel 768088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * relative to ITU to sync to the input frame and for output 769088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * sync generation. Currently, we are using reference detection 770088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * from HS/VS, i.e. REFPIX/REFLINE denote frame start sync point 771088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * which is position of rising VS with coincident rising HS. 772088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * 773088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * Now there is some issues to take care of: 774088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * - HDMI data islands require sync-before-active 775088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * - TDA998x register values must be > 0 to be enabled 776088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * - REFLINE needs an additional offset of +1 777088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * - REFPIX needs an addtional offset of +1 for UYUV and +3 for RGB 778088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * 779088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * So we add +1 to all horizontal and vertical register values, 780088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * plus an additional +3 for REFPIX as we are using RGB input only. 781e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 782088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth n_pix = mode->htotal; 783088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth n_line = mode->vtotal; 784088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth 785088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth hs_pix_e = mode->hsync_end - mode->hdisplay; 786088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth hs_pix_s = mode->hsync_start - mode->hdisplay; 787088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth de_pix_e = mode->htotal; 788088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth de_pix_s = mode->htotal - mode->hdisplay; 789088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth ref_pix = 3 + hs_pix_s; 790088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth 791179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth /* 792179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth * Attached LCD controllers may generate broken sync. Allow 793179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth * those to adjust the position of the rising VS edge by adding 794179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth * HSKEW to ref_pix. 795179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth */ 796179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth if (adjusted_mode->flags & DRM_MODE_FLAG_HSKEW) 797179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth ref_pix += adjusted_mode->hskew; 798179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth 799088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth if ((mode->flags & DRM_MODE_FLAG_INTERLACE) == 0) { 800088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth ref_line = 1 + mode->vsync_start - mode->vdisplay; 801088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin1_line_s = mode->vtotal - mode->vdisplay - 1; 802088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin1_line_e = vwin1_line_s + mode->vdisplay; 803088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_pix_s = vs1_pix_e = hs_pix_s; 804088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_line_s = mode->vsync_start - mode->vdisplay; 805088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_line_e = vs1_line_s + 806088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth mode->vsync_end - mode->vsync_start; 807088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin2_line_s = vwin2_line_e = 0; 808088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs2_pix_s = vs2_pix_e = 0; 809088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs2_line_s = vs2_line_e = 0; 810088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth } else { 811088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth ref_line = 1 + (mode->vsync_start - mode->vdisplay)/2; 812088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin1_line_s = (mode->vtotal - mode->vdisplay)/2; 813088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin1_line_e = vwin1_line_s + mode->vdisplay/2; 814088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_pix_s = vs1_pix_e = hs_pix_s; 815088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_line_s = (mode->vsync_start - mode->vdisplay)/2; 816088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_line_e = vs1_line_s + 817088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth (mode->vsync_end - mode->vsync_start)/2; 818088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin2_line_s = vwin1_line_s + mode->vtotal/2; 819088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin2_line_e = vwin2_line_s + mode->vdisplay/2; 820088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs2_pix_s = vs2_pix_e = hs_pix_s + mode->htotal/2; 821088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs2_line_s = vs1_line_s + mode->vtotal/2 ; 822088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs2_line_e = vs2_line_s + 823088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth (mode->vsync_end - mode->vsync_start)/2; 824088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth } 825e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 826e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark div = 148500 / mode->clock; 827e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 828e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* mute the audio FIFO: */ 829e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); 830e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 831e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set HDMI HDCP mode off: */ 832e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); 833e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_TX33, TX33_HDMI); 834e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 835e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(0)); 836e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* no pre-filter or interpolator: */ 837e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_HVF_CNTRL_0, HVF_CNTRL_0_PREFIL(0) | 838e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark HVF_CNTRL_0_INTPOL(0)); 839e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0)); 840e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_VIP_CNTRL_4, VIP_CNTRL_4_BLANKIT(0) | 841e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark VIP_CNTRL_4_BLC(0)); 842e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR); 843e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 844e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IZ); 845e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_DE); 846e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_SERIALIZER, 0); 847e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); 848e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 849e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */ 850e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark rep = 0; 851e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_RPT_CNTRL, 0); 852e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | 853e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); 854e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 855e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | 856e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark PLL_SERIAL_2_SRL_PR(rep)); 857e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 858e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set color matrix bypass flag: */ 859e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_MAT_CONTRL, MAT_CONTRL_MAT_BP); 860e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 861e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set BIAS tmds value: */ 862e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ANA_GENERAL, 0x09); 863e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 864e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_MTHD); 865e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 866088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth /* 867088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * Sync on rising HSYNC/VSYNC 868088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth */ 869e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_VIP_CNTRL_3, 0); 870e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_SYNC_HS); 871088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth 872088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth /* 873088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * TDA19988 requires high-active sync at input stage, 874088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * so invert low-active sync provided by master encoder here 875088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth */ 876088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth if (mode->flags & DRM_MODE_FLAG_NHSYNC) 877088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_H_TGL); 878e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode->flags & DRM_MODE_FLAG_NVSYNC) 879e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_V_TGL); 880e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 881088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth /* 882088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * Always generate sync polarity relative to input sync and 883088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * revert input stage toggled sync at output stage 884088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth */ 885088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg = TBG_CNTRL_1_TGL_EN; 886e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode->flags & DRM_MODE_FLAG_NHSYNC) 887088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg |= TBG_CNTRL_1_H_TGL; 888088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth if (mode->flags & DRM_MODE_FLAG_NVSYNC) 889088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg |= TBG_CNTRL_1_V_TGL; 890088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write(encoder, REG_TBG_CNTRL_1, reg); 891e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 892e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_VIDFORMAT, 0x00); 893088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_REFPIX_MSB, ref_pix); 894088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_REFLINE_MSB, ref_line); 895088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_NPIX_MSB, n_pix); 896088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_NLINE_MSB, n_line); 897088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VS_LINE_STRT_1_MSB, vs1_line_s); 898088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VS_PIX_STRT_1_MSB, vs1_pix_s); 899088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VS_LINE_END_1_MSB, vs1_line_e); 900088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VS_PIX_END_1_MSB, vs1_pix_e); 901088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VS_LINE_STRT_2_MSB, vs2_line_s); 902088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VS_PIX_STRT_2_MSB, vs2_pix_s); 903088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VS_LINE_END_2_MSB, vs2_line_e); 904088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VS_PIX_END_2_MSB, vs2_pix_e); 905088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_HS_PIX_START_MSB, hs_pix_s); 906088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_HS_PIX_STOP_MSB, hs_pix_e); 907088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VWIN_START_1_MSB, vwin1_line_s); 908088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VWIN_END_1_MSB, vwin1_line_e); 909088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VWIN_START_2_MSB, vwin2_line_s); 910088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_VWIN_END_2_MSB, vwin2_line_e); 911088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_DE_START_MSB, de_pix_s); 912088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth reg_write16(encoder, REG_DE_STOP_MSB, de_pix_e); 913e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 914e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (priv->rev == TDA19988) { 915e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* let incoming pixels fill the active space (if any) */ 916e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_ENABLE_SPACE, 0x01); 917e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 918e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 919e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* must be last register set: */ 920e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE); 921c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 922c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Only setup the info frames if the sink is HDMI */ 923c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King if (priv->is_hdmi_sink) { 924c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* We need to turn HDMI HDCP stuff on to get audio through */ 925c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_clear(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); 926c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_write(encoder, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(1)); 927c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King reg_set(encoder, REG_TX33, TX33_HDMI); 928c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 929c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King tda998x_write_avi(encoder, adjusted_mode); 930c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 931c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King if (priv->params.audio_cfg) 932c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King tda998x_configure_audio(encoder, adjusted_mode, 933c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King &priv->params); 934c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King } 935e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 936e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 937e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic enum drm_connector_status 938e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_detect(struct drm_encoder *encoder, 939e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_connector *connector) 940e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 941e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t val = cec_read(encoder, REG_CEC_RXSHPDLEV); 942e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected : 943e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark connector_status_disconnected; 944e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 945e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 946e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 947e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkread_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) 948e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 949e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t offset, segptr; 950e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret, i; 951e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 952e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* enable EDID read irq: */ 953e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); 954e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 955e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark offset = (blk & 1) ? 128 : 0; 956e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark segptr = blk / 2; 957e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 958e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_DDC_ADDR, 0xa0); 959e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_DDC_OFFS, offset); 960e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_DDC_SEGM_ADDR, 0x60); 961e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_DDC_SEGM, segptr); 962e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 963e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* enable reading EDID: */ 964e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_EDID_CTRL, 0x1); 965e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 966e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* flag must be cleared by sw: */ 967e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_EDID_CTRL, 0x0); 968e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 969e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* wait for block read to complete: */ 970e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark for (i = 100; i > 0; i--) { 971e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t val = reg_read(encoder, REG_INT_FLAGS_2); 972e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (val & INT_FLAGS_2_EDID_BLK_RD) 973e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark break; 974e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark msleep(1); 975e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 976e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 977e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (i == 0) 978e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return -ETIMEDOUT; 979e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 980e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = reg_read_range(encoder, REG_EDID_DATA_0, buf, EDID_LENGTH); 981e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret != EDID_LENGTH) { 982e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(encoder->dev->dev, "failed to read edid block %d: %d", 983e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark blk, ret); 984e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return ret; 985e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 986e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 987e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_clear(encoder, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); 988e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 989e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 990e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 991e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 992e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic uint8_t * 993e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkdo_get_edid(struct drm_encoder *encoder) 994e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 995063b472fbb44ac562797a630ac3516720f588140Russell King struct tda998x_priv *priv = to_tda998x_priv(encoder); 996e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int j = 0, valid_extensions = 0; 997e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t *block, *new; 998e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark bool print_bad_edid = drm_debug & DRM_UT_KMS; 999e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1000e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) 1001e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return NULL; 1002e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1003063b472fbb44ac562797a630ac3516720f588140Russell King if (priv->rev == TDA19988) 1004063b472fbb44ac562797a630ac3516720f588140Russell King reg_clear(encoder, REG_TX4, TX4_PD_RAM); 1005063b472fbb44ac562797a630ac3516720f588140Russell King 1006e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* base block fetch */ 1007e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (read_edid_block(encoder, block, 0)) 1008e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1009e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1010e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!drm_edid_block_valid(block, 0, print_bad_edid)) 1011e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1012e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1013e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* if there's no extensions, we're done */ 1014e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (block[0x7e] == 0) 1015063b472fbb44ac562797a630ac3516720f588140Russell King goto done; 1016e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1017e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL); 1018e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!new) 1019e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1020e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block = new; 1021e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1022e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark for (j = 1; j <= block[0x7e]; j++) { 1023e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t *ext_block = block + (valid_extensions + 1) * EDID_LENGTH; 1024e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (read_edid_block(encoder, ext_block, j)) 1025e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1026e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1027e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!drm_edid_block_valid(ext_block, j, print_bad_edid)) 1028e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1029e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1030e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark valid_extensions++; 1031e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 1032e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1033e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (valid_extensions != block[0x7e]) { 1034e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; 1035e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block[0x7e] = valid_extensions; 1036e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); 1037e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!new) 1038e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1039e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block = new; 1040e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 1041e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1042063b472fbb44ac562797a630ac3516720f588140Russell Kingdone: 1043063b472fbb44ac562797a630ac3516720f588140Russell King if (priv->rev == TDA19988) 1044063b472fbb44ac562797a630ac3516720f588140Russell King reg_set(encoder, REG_TX4, TX4_PD_RAM); 1045063b472fbb44ac562797a630ac3516720f588140Russell King 1046e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return block; 1047e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1048e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 1049063b472fbb44ac562797a630ac3516720f588140Russell King if (priv->rev == TDA19988) 1050063b472fbb44ac562797a630ac3516720f588140Russell King reg_set(encoder, REG_TX4, TX4_PD_RAM); 1051e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_warn(encoder->dev->dev, "failed to read EDID\n"); 1052e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark kfree(block); 1053e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return NULL; 1054e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1055e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1056e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 1057e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_get_modes(struct drm_encoder *encoder, 1058e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_connector *connector) 1059e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1060c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King struct tda998x_priv *priv = to_tda998x_priv(encoder); 1061e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct edid *edid = (struct edid *)do_get_edid(encoder); 1062e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int n = 0; 1063e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1064e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (edid) { 1065e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark drm_mode_connector_update_edid_property(connector, edid); 1066e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark n = drm_add_edid_modes(connector, edid); 1067c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid); 1068e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark kfree(edid); 1069e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 1070e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1071e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return n; 1072e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1073e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1074e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 1075e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_create_resources(struct drm_encoder *encoder, 1076e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_connector *connector) 1077e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1078e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 1079e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 1080e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1081e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1082e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 1083e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_set_property(struct drm_encoder *encoder, 1084e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_connector *connector, 1085e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_property *property, 1086e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint64_t val) 1087e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1088e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 1089e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 1090e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1091e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1092e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 1093e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_destroy(struct drm_encoder *encoder) 1094e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1095e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct tda998x_priv *priv = to_tda998x_priv(encoder); 1096e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark drm_i2c_encoder_destroy(encoder); 1097e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark kfree(priv); 1098e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1099e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1100e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic struct drm_encoder_slave_funcs tda998x_encoder_funcs = { 1101e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .set_config = tda998x_encoder_set_config, 1102e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .destroy = tda998x_encoder_destroy, 1103e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .dpms = tda998x_encoder_dpms, 1104e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .save = tda998x_encoder_save, 1105e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .restore = tda998x_encoder_restore, 1106e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .mode_fixup = tda998x_encoder_mode_fixup, 1107e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .mode_valid = tda998x_encoder_mode_valid, 1108e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .mode_set = tda998x_encoder_mode_set, 1109e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .detect = tda998x_encoder_detect, 1110e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .get_modes = tda998x_encoder_get_modes, 1111e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .create_resources = tda998x_encoder_create_resources, 1112e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .set_property = tda998x_encoder_set_property, 1113e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 1114e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1115e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* I2C driver functions */ 1116e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1117e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 1118e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_probe(struct i2c_client *client, const struct i2c_device_id *id) 1119e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1120e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 1121e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1122e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1123e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 1124e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_remove(struct i2c_client *client) 1125e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1126e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 1127e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1128e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1129e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 1130e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_init(struct i2c_client *client, 1131e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_device *dev, 1132e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_encoder_slave *encoder_slave) 1133e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1134e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_encoder *encoder = &encoder_slave->base; 1135e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct tda998x_priv *priv; 1136e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1137e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1138e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!priv) 1139e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return -ENOMEM; 1140e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 11415e74c22cd1e0f9e49573fe580de47e198ee04975Russell King priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3); 11425e74c22cd1e0f9e49573fe580de47e198ee04975Russell King priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); 11435e74c22cd1e0f9e49573fe580de47e198ee04975Russell King priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5); 11445e74c22cd1e0f9e49573fe580de47e198ee04975Russell King 1145e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->current_page = 0; 1146e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->cec = i2c_new_dummy(client->adapter, 0x34); 1147e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->dpms = DRM_MODE_DPMS_OFF; 1148e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1149e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark encoder_slave->slave_priv = priv; 1150e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark encoder_slave->slave_funcs = &tda998x_encoder_funcs; 1151e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1152e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* wake up the device: */ 1153e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark cec_write(encoder, REG_CEC_ENAMODS, 1154e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); 1155e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1156e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark tda998x_reset(encoder); 1157e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1158e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* read version: */ 1159e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->rev = reg_read(encoder, REG_VERSION_LSB) | 1160e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_read(encoder, REG_VERSION_MSB) << 8; 1161e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1162e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* mask off feature bits: */ 1163e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->rev &= ~0x30; /* not-hdcp and not-scalar bit */ 1164e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1165e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark switch (priv->rev) { 1166e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case TDA9989N2: dev_info(dev->dev, "found TDA9989 n2"); break; 1167e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case TDA19989: dev_info(dev->dev, "found TDA19989"); break; 1168e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case TDA19989N2: dev_info(dev->dev, "found TDA19989 n2"); break; 1169e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case TDA19988: dev_info(dev->dev, "found TDA19988"); break; 1170e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark default: 1171e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG("found unsupported device: %04x", priv->rev); 1172e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1173e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 1174e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1175e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* after reset, enable DDC: */ 1176e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_DDC_DISABLE, 0x00); 1177e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1178e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set clock on DDC channel: */ 1179e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_write(encoder, REG_TX3, 39); 1180e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1181e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* if necessary, disable multi-master: */ 1182e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (priv->rev == TDA19989) 1183e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark reg_set(encoder, REG_I2C_MASTER, I2C_MASTER_DIS_MM); 1184e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1185e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark cec_write(encoder, REG_CEC_FRO_IM_CLK_CTRL, 1186e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL); 1187e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1188e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 1189e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1190e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 1191e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* if encoder_init fails, the encoder slave is never registered, 1192e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * so cleanup here: 1193e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 1194e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (priv->cec) 1195e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark i2c_unregister_device(priv->cec); 1196e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark kfree(priv); 1197e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark encoder_slave->slave_priv = NULL; 1198e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark encoder_slave->slave_funcs = NULL; 1199e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return -ENXIO; 1200e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1201e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1202e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic struct i2c_device_id tda998x_ids[] = { 1203e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark { "tda998x", 0 }, 1204e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark { } 1205e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 1206e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_DEVICE_TABLE(i2c, tda998x_ids); 1207e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1208e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic struct drm_i2c_encoder_driver tda998x_driver = { 1209e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .i2c_driver = { 1210e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .probe = tda998x_probe, 1211e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .remove = tda998x_remove, 1212e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .driver = { 1213e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .name = "tda998x", 1214e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark }, 1215e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .id_table = tda998x_ids, 1216e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark }, 1217e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .encoder_init = tda998x_encoder_init, 1218e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 1219e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1220e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Module initialization */ 1221e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1222e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int __init 1223e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_init(void) 1224e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1225e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 1226e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return drm_i2c_encoder_register(THIS_MODULE, &tda998x_driver); 1227e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1228e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1229e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void __exit 1230e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_exit(void) 1231e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1232e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 1233e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark drm_i2c_encoder_unregister(&tda998x_driver); 1234e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1235e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1236e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_AUTHOR("Rob Clark <robdclark@gmail.com"); 1237e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_DESCRIPTION("NXP Semiconductors TDA998X HDMI Encoder"); 1238e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_LICENSE("GPL"); 1239e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1240e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkmodule_init(tda998x_init); 1241e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkmodule_exit(tda998x_exit); 1242