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 18c707c3619ca81f499a5ce032021405e989a96ff0Russell King#include <linux/component.h> 19893c3e538dc338509b0c1121173355e8cfa34ff0Russell King#include <linux/hdmi.h> 20e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <linux/module.h> 2112473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine#include <linux/irq.h> 22f0b33b282c17337276504d6a700d0f558f1a6891Jean-Francois Moine#include <sound/asoundef.h> 23e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 24e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drmP.h> 25e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drm_crtc_helper.h> 26e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drm_encoder_slave.h> 27e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#include <drm/drm_edid.h> 28c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#include <drm/i2c/tda998x.h> 29e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 30e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) 31e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 32e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstruct tda998x_priv { 33e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct i2c_client *cec; 342f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine struct i2c_client *hdmi; 35e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint16_t rev; 36e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t current_page; 37e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int dpms; 38c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King bool is_hdmi_sink; 395e74c22cd1e0f9e49573fe580de47e198ee04975Russell King u8 vip_cntrl_0; 405e74c22cd1e0f9e49573fe580de47e198ee04975Russell King u8 vip_cntrl_1; 415e74c22cd1e0f9e49573fe580de47e198ee04975Russell King u8 vip_cntrl_2; 42c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King struct tda998x_encoder_params params; 4312473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine 4412473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine wait_queue_head_t wq_edid; 4512473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine volatile int wq_edid_wait; 4612473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine struct drm_encoder *encoder; 47e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 48e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 49e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define to_tda998x_priv(x) ((struct tda998x_priv *)to_encoder_slave(x)->slave_priv) 50e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 51e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* The TDA9988 series of devices use a paged register scheme.. to simplify 52e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * things we encode the page # in upper bits of the register #. To read/ 53e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * write a given register, we need to make sure CURPAGE register is set 54e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * appropriately. Which implies reads/writes are not atomic. Fun! 55e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 56e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 57e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG(page, addr) (((page) << 8) | (addr)) 58e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG2ADDR(reg) ((reg) & 0xff) 59e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG2PAGE(reg) (((reg) >> 8) & 0xff) 60e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 61e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CURPAGE 0xff /* write */ 62e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 63e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 64e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 00h: General Control */ 65e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VERSION_LSB REG(0x00, 0x00) /* read */ 66e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_MAIN_CNTRL0 REG(0x00, 0x01) /* read/write */ 67e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_SR (1 << 0) 68e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_DECS (1 << 1) 69e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_DEHS (1 << 2) 70e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_CECS (1 << 3) 71e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_CEHS (1 << 4) 72e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAIN_CNTRL0_SCALER (1 << 7) 73e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VERSION_MSB REG(0x00, 0x02) /* read */ 74e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_SOFTRESET REG(0x00, 0x0a) /* write */ 75e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SOFTRESET_AUDIO (1 << 0) 76e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SOFTRESET_I2C_MASTER (1 << 1) 77e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_DISABLE REG(0x00, 0x0b) /* read/write */ 78e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CCLK_ON REG(0x00, 0x0c) /* read/write */ 79e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_I2C_MASTER REG(0x00, 0x0d) /* read/write */ 80e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define I2C_MASTER_DIS_MM (1 << 0) 81e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define I2C_MASTER_DIS_FILT (1 << 1) 82e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define I2C_MASTER_APP_STRT_LAT (1 << 2) 83c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_FEAT_POWERDOWN REG(0x00, 0x0e) /* read/write */ 84c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define FEAT_POWERDOWN_SPDIF (1 << 3) 85e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_INT_FLAGS_0 REG(0x00, 0x0f) /* read/write */ 86e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_INT_FLAGS_1 REG(0x00, 0x10) /* read/write */ 87e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_INT_FLAGS_2 REG(0x00, 0x11) /* read/write */ 88e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define INT_FLAGS_2_EDID_BLK_RD (1 << 1) 89c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ENA_ACLK REG(0x00, 0x16) /* read/write */ 90e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_VP_0 REG(0x00, 0x18) /* read/write */ 91e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_VP_1 REG(0x00, 0x19) /* read/write */ 92e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_VP_2 REG(0x00, 0x1a) /* read/write */ 93e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENA_AP REG(0x00, 0x1e) /* read/write */ 94e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_0 REG(0x00, 0x20) /* write */ 95e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_MIRR_A (1 << 7) 96e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_SWAP_A(x) (((x) & 7) << 4) 97e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_MIRR_B (1 << 3) 98e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_0_SWAP_B(x) (((x) & 7) << 0) 99e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_1 REG(0x00, 0x21) /* write */ 100e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_MIRR_C (1 << 7) 101e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_SWAP_C(x) (((x) & 7) << 4) 102e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_MIRR_D (1 << 3) 103e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_1_SWAP_D(x) (((x) & 7) << 0) 104e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_2 REG(0x00, 0x22) /* write */ 105e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_MIRR_E (1 << 7) 106e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_SWAP_E(x) (((x) & 7) << 4) 107e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_MIRR_F (1 << 3) 108e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_2_SWAP_F(x) (((x) & 7) << 0) 109e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_3 REG(0x00, 0x23) /* write */ 110e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_X_TGL (1 << 0) 111e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_H_TGL (1 << 1) 112e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_V_TGL (1 << 2) 113e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_EMB (1 << 3) 114e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_SYNC_DE (1 << 4) 115e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_SYNC_HS (1 << 5) 116e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_DE_INT (1 << 6) 117e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_3_EDGE (1 << 7) 118e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_4 REG(0x00, 0x24) /* write */ 119e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_BLC(x) (((x) & 3) << 0) 120e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_BLANKIT(x) (((x) & 3) << 2) 121e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_CCIR656 (1 << 4) 122e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_656_ALT (1 << 5) 123e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_TST_656 (1 << 6) 124e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_4_TST_PAT (1 << 7) 125e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIP_CNTRL_5 REG(0x00, 0x25) /* write */ 126e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_5_CKCASE (1 << 0) 127e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define VIP_CNTRL_5_SP_CNT(x) (((x) & 3) << 1) 128c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_MUX_AP REG(0x00, 0x26) /* read/write */ 12910df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine# define MUX_AP_SELECT_I2S 0x64 13010df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine# define MUX_AP_SELECT_SPDIF 0x40 131bcb2481df01a9aee7a09b20d43194011edd35754Russell King#define REG_MUX_VP_VIP_OUT REG(0x00, 0x27) /* read/write */ 132e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_MAT_CONTRL REG(0x00, 0x80) /* write */ 133e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAT_CONTRL_MAT_SC(x) (((x) & 3) << 0) 134e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define MAT_CONTRL_MAT_BP (1 << 2) 135e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VIDFORMAT REG(0x00, 0xa0) /* write */ 136e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFPIX_MSB REG(0x00, 0xa1) /* write */ 137e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFPIX_LSB REG(0x00, 0xa2) /* write */ 138e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFLINE_MSB REG(0x00, 0xa3) /* write */ 139e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_REFLINE_LSB REG(0x00, 0xa4) /* write */ 140e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NPIX_MSB REG(0x00, 0xa5) /* write */ 141e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NPIX_LSB REG(0x00, 0xa6) /* write */ 142e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NLINE_MSB REG(0x00, 0xa7) /* write */ 143e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_NLINE_LSB REG(0x00, 0xa8) /* write */ 144e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_STRT_1_MSB REG(0x00, 0xa9) /* write */ 145e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_STRT_1_LSB REG(0x00, 0xaa) /* write */ 146e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_1_MSB REG(0x00, 0xab) /* write */ 147e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_1_LSB REG(0x00, 0xac) /* write */ 148e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_END_1_MSB REG(0x00, 0xad) /* write */ 149e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_LINE_END_1_LSB REG(0x00, 0xae) /* write */ 150e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_1_MSB REG(0x00, 0xaf) /* write */ 151e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_1_LSB REG(0x00, 0xb0) /* write */ 152088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VS_LINE_STRT_2_MSB REG(0x00, 0xb1) /* write */ 153088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VS_LINE_STRT_2_LSB REG(0x00, 0xb2) /* write */ 154e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_2_MSB REG(0x00, 0xb3) /* write */ 155e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_STRT_2_LSB REG(0x00, 0xb4) /* write */ 156088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VS_LINE_END_2_MSB REG(0x00, 0xb5) /* write */ 157088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VS_LINE_END_2_LSB REG(0x00, 0xb6) /* write */ 158e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_2_MSB REG(0x00, 0xb7) /* write */ 159e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VS_PIX_END_2_LSB REG(0x00, 0xb8) /* write */ 160e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_START_MSB REG(0x00, 0xb9) /* write */ 161e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_START_LSB REG(0x00, 0xba) /* write */ 162e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_STOP_MSB REG(0x00, 0xbb) /* write */ 163e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HS_PIX_STOP_LSB REG(0x00, 0xbc) /* write */ 164e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_START_1_MSB REG(0x00, 0xbd) /* write */ 165e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_START_1_LSB REG(0x00, 0xbe) /* write */ 166e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_END_1_MSB REG(0x00, 0xbf) /* write */ 167e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_VWIN_END_1_LSB REG(0x00, 0xc0) /* write */ 168088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VWIN_START_2_MSB REG(0x00, 0xc1) /* write */ 169088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VWIN_START_2_LSB REG(0x00, 0xc2) /* write */ 170088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VWIN_END_2_MSB REG(0x00, 0xc3) /* write */ 171088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth#define REG_VWIN_END_2_LSB REG(0x00, 0xc4) /* write */ 172e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_START_MSB REG(0x00, 0xc5) /* write */ 173e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_START_LSB REG(0x00, 0xc6) /* write */ 174e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_STOP_MSB REG(0x00, 0xc7) /* write */ 175e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DE_STOP_LSB REG(0x00, 0xc8) /* write */ 176e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TBG_CNTRL_0 REG(0x00, 0xca) /* write */ 177088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_0_TOP_TGL (1 << 0) 178088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_0_TOP_SEL (1 << 1) 179088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_0_DE_EXT (1 << 2) 180088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_0_TOP_EXT (1 << 3) 181e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_0_FRAME_DIS (1 << 5) 182e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_0_SYNC_MTHD (1 << 6) 183e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_0_SYNC_ONCE (1 << 7) 184e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TBG_CNTRL_1 REG(0x00, 0xcb) /* write */ 185088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_H_TGL (1 << 0) 186088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_V_TGL (1 << 1) 187088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_TGL_EN (1 << 2) 188088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_X_EXT (1 << 3) 189088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_H_EXT (1 << 4) 190088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth# define TBG_CNTRL_1_V_EXT (1 << 5) 191e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TBG_CNTRL_1_DWIN_DIS (1 << 6) 192e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENABLE_SPACE REG(0x00, 0xd6) /* write */ 193e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HVF_CNTRL_0 REG(0x00, 0xe4) /* write */ 194e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_SM (1 << 7) 195e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_RWB (1 << 6) 196e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_PREFIL(x) (((x) & 3) << 2) 197e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_0_INTPOL(x) (((x) & 3) << 0) 198e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_HVF_CNTRL_1 REG(0x00, 0xe5) /* write */ 199e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_FOR (1 << 0) 200e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_YUVBLK (1 << 1) 201e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_VQR(x) (((x) & 3) << 2) 202e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4) 203e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define HVF_CNTRL_1_SEMI_PLANAR (1 << 6) 204e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */ 205c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_I2S_FORMAT REG(0x00, 0xfc) /* read/write */ 206c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define I2S_FORMAT(x) (((x) & 3) << 0) 207c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_AIP_CLKSEL REG(0x00, 0xfd) /* write */ 20810df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine# define AIP_CLKSEL_AIP_SPDIF (0 << 3) 20910df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine# define AIP_CLKSEL_AIP_I2S (1 << 3) 21010df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine# define AIP_CLKSEL_FS_ACLK (0 << 0) 21110df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine# define AIP_CLKSEL_FS_MCLK (1 << 0) 21210df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine# define AIP_CLKSEL_FS_FS64SPDIF (2 << 0) 213e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 214e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 02h: PLL settings */ 215e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SERIAL_1 REG(0x02, 0x00) /* read/write */ 216e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_1_SRL_FDN (1 << 0) 217e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_1_SRL_IZ(x) (((x) & 3) << 1) 218e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_1_SRL_MAN_IZ (1 << 6) 219e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SERIAL_2 REG(0x02, 0x01) /* read/write */ 2203ae471f73a1d581e078b5b06d08d7b82833a093fJean-Francois Moine# define PLL_SERIAL_2_SRL_NOSC(x) ((x) << 0) 221e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4) 222e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SERIAL_3 REG(0x02, 0x02) /* read/write */ 223e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_3_SRL_CCIR (1 << 0) 224e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_3_SRL_DE (1 << 2) 225e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define PLL_SERIAL_3_SRL_PXIN_SEL (1 << 4) 226e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_SERIALIZER REG(0x02, 0x03) /* read/write */ 227e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_BUFFER_OUT REG(0x02, 0x04) /* read/write */ 228e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCG1 REG(0x02, 0x05) /* read/write */ 229e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCG2 REG(0x02, 0x06) /* read/write */ 230e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGN1 REG(0x02, 0x07) /* read/write */ 231e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGN2 REG(0x02, 0x08) /* read/write */ 232e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGR1 REG(0x02, 0x09) /* read/write */ 233e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_PLL_SCGR2 REG(0x02, 0x0a) /* read/write */ 234e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_AUDIO_DIV REG(0x02, 0x0e) /* read/write */ 235c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_1 0 236c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_2 1 237c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_4 2 238c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_8 3 239c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_16 4 240c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define AUDIO_DIV_SERCLK_32 5 241e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_SEL_CLK REG(0x02, 0x11) /* read/write */ 242e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SEL_CLK_SEL_CLK1 (1 << 0) 243e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SEL_CLK_SEL_VRF_CLK(x) (((x) & 3) << 1) 244e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define SEL_CLK_ENA_SC_CLK (1 << 3) 245e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ANA_GENERAL REG(0x02, 0x12) /* read/write */ 246e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 247e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 248e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 09h: EDID Control */ 249e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_EDID_DATA_0 REG(0x09, 0x00) /* read */ 250e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* next 127 successive registers are the EDID block */ 251e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_EDID_CTRL REG(0x09, 0xfa) /* read/write */ 252e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_ADDR REG(0x09, 0xfb) /* read/write */ 253e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_OFFS REG(0x09, 0xfc) /* read/write */ 254e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_SEGM_ADDR REG(0x09, 0xfd) /* read/write */ 255e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_DDC_SEGM REG(0x09, 0xfe) /* read/write */ 256e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 257e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 258e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 10h: information frames and packets */ 259c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_IF1_HB0 REG(0x10, 0x20) /* read/write */ 260c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_IF2_HB0 REG(0x10, 0x40) /* read/write */ 261c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_IF3_HB0 REG(0x10, 0x60) /* read/write */ 262c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_IF4_HB0 REG(0x10, 0x80) /* read/write */ 263c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_IF5_HB0 REG(0x10, 0xa0) /* read/write */ 264e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 265e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 266e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 11h: audio settings and content info packets */ 267e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_AIP_CNTRL_0 REG(0x11, 0x00) /* read/write */ 268e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_RST_FIFO (1 << 0) 269e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_SWAP (1 << 1) 270e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_LAYOUT (1 << 2) 271e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_ACR_MAN (1 << 5) 272e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define AIP_CNTRL_0_RST_CTS (1 << 6) 273c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_CA_I2S REG(0x11, 0x01) /* read/write */ 274c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define CA_I2S_CA_I2S(x) (((x) & 31) << 0) 275c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define CA_I2S_HBR_CHSTAT (1 << 6) 276c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_LATENCY_RD REG(0x11, 0x04) /* read/write */ 277c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_CTS_0 REG(0x11, 0x05) /* read/write */ 278c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_CTS_1 REG(0x11, 0x06) /* read/write */ 279c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_CTS_2 REG(0x11, 0x07) /* read/write */ 280c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_N_0 REG(0x11, 0x08) /* read/write */ 281c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_N_1 REG(0x11, 0x09) /* read/write */ 282c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_ACR_N_2 REG(0x11, 0x0a) /* read/write */ 283c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_CTS_N REG(0x11, 0x0c) /* read/write */ 284c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define CTS_N_K(x) (((x) & 7) << 0) 285c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define CTS_N_M(x) (((x) & 3) << 4) 286e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_ENC_CNTRL REG(0x11, 0x0d) /* read/write */ 287e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define ENC_CNTRL_RST_ENC (1 << 0) 288e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define ENC_CNTRL_RST_SEL (1 << 1) 289e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define ENC_CNTRL_CTL_CODE(x) (((x) & 3) << 2) 290c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_DIP_FLAGS REG(0x11, 0x0e) /* read/write */ 291c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_FLAGS_ACR (1 << 0) 292c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_FLAGS_GC (1 << 1) 293c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_DIP_IF_FLAGS REG(0x11, 0x0f) /* read/write */ 294c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_IF_FLAGS_IF1 (1 << 1) 295c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_IF_FLAGS_IF2 (1 << 2) 296c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_IF_FLAGS_IF3 (1 << 3) 297c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_IF_FLAGS_IF4 (1 << 4) 298c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King# define DIP_IF_FLAGS_IF5 (1 << 5) 299c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define REG_CH_STAT_B(x) REG(0x11, 0x14 + (x)) /* read/write */ 300e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 301e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 302e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 12h: HDCP and OTP */ 303e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TX3 REG(0x12, 0x9a) /* read/write */ 304063b472fbb44ac562797a630ac3516720f588140Russell King#define REG_TX4 REG(0x12, 0x9b) /* read/write */ 305063b472fbb44ac562797a630ac3516720f588140Russell King# define TX4_PD_RAM (1 << 1) 306e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_TX33 REG(0x12, 0xb8) /* read/write */ 307e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define TX33_HDMI (1 << 1) 308e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 309e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 310e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Page 13h: Gamut related metadata packets */ 311e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 312e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 313e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 314e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* CEC registers: (not paged) 315e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 31612473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine#define REG_CEC_INTSTATUS 0xee /* read */ 31712473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine# define CEC_INTSTATUS_CEC (1 << 0) 31812473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine# define CEC_INTSTATUS_HDMI (1 << 1) 319e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CEC_FRO_IM_CLK_CTRL 0xfb /* read/write */ 320e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_GHOST_DIS (1 << 7) 321e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_ENA_OTP (1 << 6) 322e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_IMCLK_SEL (1 << 1) 323e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_FRO_IM_CLK_CTRL_FRO_DIV (1 << 0) 32412473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine#define REG_CEC_RXSHPDINTENA 0xfc /* read/write */ 32512473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine#define REG_CEC_RXSHPDINT 0xfd /* read */ 326e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CEC_RXSHPDLEV 0xfe /* read */ 327e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_RXSHPDLEV_RXSENS (1 << 0) 328e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_RXSHPDLEV_HPD (1 << 1) 329e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 330e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define REG_CEC_ENAMODS 0xff /* read/write */ 331e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_DIS_FRO (1 << 6) 332e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_DIS_CCLK (1 << 5) 333e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_EN_RXSENS (1 << 2) 334e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_EN_HDMI (1 << 1) 335e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark# define CEC_ENAMODS_EN_CEC (1 << 0) 336e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 337e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 338e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Device versions: */ 339e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA9989N2 0x0101 340e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA19989 0x0201 341e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA19989N2 0x0202 342e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark#define TDA19988 0x0301 343e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 344e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 3452f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinecec_write(struct tda998x_priv *priv, uint16_t addr, uint8_t val) 346e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 3472f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine struct i2c_client *client = priv->cec; 348e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = {addr, val}; 349e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 350e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 351704d63f59900968b9b5ae92549c49db0686b87e3Jean-Francois Moine ret = i2c_master_send(client, buf, sizeof(buf)); 352e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 353e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d writing to cec:0x%x\n", ret, addr); 354e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 355e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 356e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic uint8_t 3572f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinecec_read(struct tda998x_priv *priv, uint8_t addr) 358e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 3592f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine struct i2c_client *client = priv->cec; 360e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t val; 361e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 362e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 363e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, &addr, sizeof(addr)); 364e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 365e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 366e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 367e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_recv(client, &val, sizeof(val)); 368e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 369e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 370e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 371e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return val; 372e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 373e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 374e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d reading from cec:0x%x\n", ret, addr); 375e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 376e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 377e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 3787d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moinestatic int 3792f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moineset_page(struct tda998x_priv *priv, uint16_t reg) 380e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 381e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (REG2PAGE(reg) != priv->current_page) { 3822f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine struct i2c_client *client = priv->hdmi; 383e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = { 384e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark REG_CURPAGE, REG2PAGE(reg) 385e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark }; 386e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret = i2c_master_send(client, buf, sizeof(buf)); 3877d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine if (ret < 0) { 388704d63f59900968b9b5ae92549c49db0686b87e3Jean-Francois Moine dev_err(&client->dev, "setpage %04x err %d\n", 389704d63f59900968b9b5ae92549c49db0686b87e3Jean-Francois Moine reg, ret); 3907d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine return ret; 3917d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine } 392e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 393e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->current_page = REG2PAGE(reg); 394e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 3957d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine return 0; 396e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 397e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 398e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 3992f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinereg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt) 400e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 4012f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine struct i2c_client *client = priv->hdmi; 402e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t addr = REG2ADDR(reg); 403e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 404e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 4057d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine ret = set_page(priv, reg); 4067d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine if (ret < 0) 4077d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine return ret; 408e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 409e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_send(client, &addr, sizeof(addr)); 410e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 411e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 412e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 413e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark ret = i2c_master_recv(client, buf, cnt); 414e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 415e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 416e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 417e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return ret; 418e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 419e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 420e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); 421e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return ret; 422e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 423e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 424c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic void 4252f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinereg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt) 426c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 4272f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine struct i2c_client *client = priv->hdmi; 428c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King uint8_t buf[cnt+1]; 429c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King int ret; 430c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 431c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[0] = REG2ADDR(reg); 432c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King memcpy(&buf[1], p, cnt); 433c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 4347d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine ret = set_page(priv, reg); 4357d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine if (ret < 0) 4367d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine return; 437c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 438c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King ret = i2c_master_send(client, buf, cnt + 1); 439c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King if (ret < 0) 440c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); 441c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 442c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 4437d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moinestatic int 4442f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinereg_read(struct tda998x_priv *priv, uint16_t reg) 445e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 446e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t val = 0; 4477d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine int ret; 4487d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine 4497d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine ret = reg_read_range(priv, reg, &val, sizeof(val)); 4507d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine if (ret < 0) 4517d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine return ret; 452e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return val; 453e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 454e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 455e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 4562f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinereg_write(struct tda998x_priv *priv, uint16_t reg, uint8_t val) 457e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 4582f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine struct i2c_client *client = priv->hdmi; 459e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = {REG2ADDR(reg), val}; 460e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 461e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 4627d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine ret = set_page(priv, reg); 4637d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine if (ret < 0) 4647d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine return; 465e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 466704d63f59900968b9b5ae92549c49db0686b87e3Jean-Francois Moine ret = i2c_master_send(client, buf, sizeof(buf)); 467e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 468e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); 469e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 470e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 471e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 4722f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinereg_write16(struct tda998x_priv *priv, uint16_t reg, uint16_t val) 473e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 4742f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine struct i2c_client *client = priv->hdmi; 475e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; 476e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret; 477e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 4787d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine ret = set_page(priv, reg); 4797d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine if (ret < 0) 4807d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine return; 481e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 482704d63f59900968b9b5ae92549c49db0686b87e3Jean-Francois Moine ret = i2c_master_send(client, buf, sizeof(buf)); 483e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret < 0) 484e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); 485e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 486e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 487e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 4882f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinereg_set(struct tda998x_priv *priv, uint16_t reg, uint8_t val) 489e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 4907d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine int old_val; 4917d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine 4927d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine old_val = reg_read(priv, reg); 4937d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine if (old_val >= 0) 4947d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine reg_write(priv, reg, old_val | val); 495e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 496e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 497e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 4982f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinereg_clear(struct tda998x_priv *priv, uint16_t reg, uint8_t val) 499e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 5007d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine int old_val; 5017d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine 5027d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine old_val = reg_read(priv, reg); 5037d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine if (old_val >= 0) 5047d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine reg_write(priv, reg, old_val & ~val); 505e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 506e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 507e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 5082f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinetda998x_reset(struct tda998x_priv *priv) 509e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 510e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* reset audio and i2c master: */ 51181b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg_write(priv, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); 512e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark msleep(50); 51381b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg_write(priv, REG_SOFTRESET, 0); 514e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark msleep(50); 515e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 516e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* reset transmitter: */ 5172f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_set(priv, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); 5182f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_clear(priv, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); 519e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 520e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* PLL registers common configuration */ 5212f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_PLL_SERIAL_1, 0x00); 5222f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1)); 5232f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_PLL_SERIAL_3, 0x00); 5242f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_SERIALIZER, 0x00); 5252f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_BUFFER_OUT, 0x00); 5262f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_PLL_SCG1, 0x00); 5272f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_AUDIO_DIV, AUDIO_DIV_SERCLK_8); 5282f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_SEL_CLK, SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); 5292f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_PLL_SCGN1, 0xfa); 5302f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_PLL_SCGN2, 0x00); 5312f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_PLL_SCGR1, 0x5b); 5322f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_PLL_SCGR2, 0x00); 5332f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_PLL_SCG2, 0x10); 534bcb2481df01a9aee7a09b20d43194011edd35754Russell King 535bcb2481df01a9aee7a09b20d43194011edd35754Russell King /* Write the default value MUX register */ 5362f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_MUX_VP_VIP_OUT, 0x24); 537e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 538e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 53912473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine/* 54012473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine * only 2 interrupts may occur: screen plug/unplug and EDID read 54112473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine */ 54212473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moinestatic irqreturn_t tda998x_irq_thread(int irq, void *data) 54312473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine{ 54412473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine struct tda998x_priv *priv = data; 54512473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine u8 sta, cec, lvl, flag0, flag1, flag2; 54612473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine 54712473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if (!priv) 54812473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine return IRQ_HANDLED; 54912473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine sta = cec_read(priv, REG_CEC_INTSTATUS); 55012473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine cec = cec_read(priv, REG_CEC_RXSHPDINT); 55112473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine lvl = cec_read(priv, REG_CEC_RXSHPDLEV); 55212473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine flag0 = reg_read(priv, REG_INT_FLAGS_0); 55312473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine flag1 = reg_read(priv, REG_INT_FLAGS_1); 55412473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine flag2 = reg_read(priv, REG_INT_FLAGS_2); 55512473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine DRM_DEBUG_DRIVER( 55612473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine "tda irq sta %02x cec %02x lvl %02x f0 %02x f1 %02x f2 %02x\n", 55712473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine sta, cec, lvl, flag0, flag1, flag2); 55812473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if ((flag2 & INT_FLAGS_2_EDID_BLK_RD) && priv->wq_edid_wait) { 55912473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine priv->wq_edid_wait = 0; 56012473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine wake_up(&priv->wq_edid); 56112473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine } else if (cec != 0) { /* HPD change */ 56212473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if (priv->encoder && priv->encoder->dev) 56312473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine drm_helper_hpd_irq_event(priv->encoder->dev); 56412473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine } 56512473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine return IRQ_HANDLED; 56612473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine} 56712473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine 568c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic uint8_t tda998x_cksum(uint8_t *buf, size_t bytes) 569c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 5708268bd48af9aae5e079d3ba8403ae459ff06cbcbDaniel Vetter int sum = 0; 571c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 572c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King while (bytes--) 5738268bd48af9aae5e079d3ba8403ae459ff06cbcbDaniel Vetter sum -= *buf++; 5748268bd48af9aae5e079d3ba8403ae459ff06cbcbDaniel Vetter return sum; 575c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 576c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 577c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define HB(x) (x) 578c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King#define PB(x) (HB(2) + 1 + (x)) 579c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 580c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic void 5812f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinetda998x_write_if(struct tda998x_priv *priv, uint8_t bit, uint16_t addr, 582c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King uint8_t *buf, size_t size) 583c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 584c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(0)] = tda998x_cksum(buf, size); 585c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 5862f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_clear(priv, REG_DIP_IF_FLAGS, bit); 5872f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write_range(priv, addr, buf, size); 5882f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_set(priv, REG_DIP_IF_FLAGS, bit); 589c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 590c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 591c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic void 5922f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinetda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p) 593c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 5949e541466eed411cb5462fa9e6181c4d409e7e2efJean-Francois Moine u8 buf[PB(HDMI_AUDIO_INFOFRAME_SIZE) + 1]; 595c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 5967288ca07b638db485abec5752bd6b1faed1c33efJean-Francois Moine memset(buf, 0, sizeof(buf)); 5979e541466eed411cb5462fa9e6181c4d409e7e2efJean-Francois Moine buf[HB(0)] = HDMI_INFOFRAME_TYPE_AUDIO; 598c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[HB(1)] = 0x01; 5999e541466eed411cb5462fa9e6181c4d409e7e2efJean-Francois Moine buf[HB(2)] = HDMI_AUDIO_INFOFRAME_SIZE; 600c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */ 601c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */ 602c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(4)] = p->audio_frame[4]; 603c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */ 604c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 6052f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, 606c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King sizeof(buf)); 607c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 608c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 609c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic void 6102f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinetda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode) 611c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 6129e541466eed411cb5462fa9e6181c4d409e7e2efJean-Francois Moine u8 buf[PB(HDMI_AVI_INFOFRAME_SIZE) + 1]; 613c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 614c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King memset(buf, 0, sizeof(buf)); 6159e541466eed411cb5462fa9e6181c4d409e7e2efJean-Francois Moine buf[HB(0)] = HDMI_INFOFRAME_TYPE_AVI; 616c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[HB(1)] = 0x02; 6179e541466eed411cb5462fa9e6181c4d409e7e2efJean-Francois Moine buf[HB(2)] = HDMI_AVI_INFOFRAME_SIZE; 618893c3e538dc338509b0c1121173355e8cfa34ff0Russell King buf[PB(1)] = HDMI_SCAN_MODE_UNDERSCAN; 619bdf6345b3262d0ddbc6405fbc0fedd2941bec08eJean-Francois Moine buf[PB(2)] = HDMI_ACTIVE_ASPECT_PICTURE; 620893c3e538dc338509b0c1121173355e8cfa34ff0Russell King buf[PB(3)] = HDMI_QUANTIZATION_RANGE_FULL << 2; 621c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[PB(4)] = drm_match_cea_mode(mode); 622c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 6232f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf, 624c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King sizeof(buf)); 625c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 626c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 6272f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinestatic void tda998x_audio_mute(struct tda998x_priv *priv, bool on) 628c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 629c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King if (on) { 6302f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_set(priv, REG_SOFTRESET, SOFTRESET_AUDIO); 6312f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_clear(priv, REG_SOFTRESET, SOFTRESET_AUDIO); 6322f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); 633c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King } else { 6342f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); 635c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King } 636c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 637c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 638c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell Kingstatic void 6392f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moinetda998x_configure_audio(struct tda998x_priv *priv, 640c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King struct drm_display_mode *mode, struct tda998x_encoder_params *p) 641c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King{ 64285c988bb26a3da46c04284bc43f93d732986547bJean-Francois Moine uint8_t buf[6], clksel_aip, clksel_fs, cts_n, adiv; 643c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King uint32_t n; 644c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 645c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Enable audio ports */ 6462f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ENA_AP, p->audio_cfg); 6472f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ENA_ACLK, p->audio_clk_cfg); 648c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 649c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Set audio input source */ 650c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King switch (p->audio_format) { 651c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King case AFMT_SPDIF: 65210df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_SPDIF); 65310df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine clksel_aip = AIP_CLKSEL_AIP_SPDIF; 65410df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine clksel_fs = AIP_CLKSEL_FS_FS64SPDIF; 655c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King cts_n = CTS_N_M(3) | CTS_N_K(3); 656c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King break; 657c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 658c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King case AFMT_I2S: 65910df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_I2S); 66010df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine clksel_aip = AIP_CLKSEL_AIP_I2S; 66110df1a95d6457ead03ed804c9abece79023f3f77Jean-Francois Moine clksel_fs = AIP_CLKSEL_FS_ACLK; 662c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King cts_n = CTS_N_M(3) | CTS_N_K(3); 663c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King break; 6643b28802e37bb1ca1cab584f679c42e72a7e384f8David Herrmann 6653b28802e37bb1ca1cab584f679c42e72a7e384f8David Herrmann default: 6663b28802e37bb1ca1cab584f679c42e72a7e384f8David Herrmann BUG(); 6673b28802e37bb1ca1cab584f679c42e72a7e384f8David Herrmann return; 668c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King } 669c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 6702f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_AIP_CLKSEL, clksel_aip); 671a8b517e5312124e2dd7b6d6d9afac458aaecfbf3Jean-Francois Moine reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_LAYOUT | 672a8b517e5312124e2dd7b6d6d9afac458aaecfbf3Jean-Francois Moine AIP_CNTRL_0_ACR_MAN); /* auto CTS */ 6732f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_CTS_N, cts_n); 674c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 675c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* 676c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * Audio input somehow depends on HDMI line rate which is 677c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * related to pixclk. Testing showed that modes with pixclk 678c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * >100MHz need a larger divider while <40MHz need the default. 679c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * There is no detailed info in the datasheet, so we just 680c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * assume 100MHz requires larger divider. 681c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King */ 6822470feccbf030652380c2d73304576137b0fb12eJean-Francois Moine adiv = AUDIO_DIV_SERCLK_8; 683c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King if (mode->clock > 100000) 6842470feccbf030652380c2d73304576137b0fb12eJean-Francois Moine adiv++; /* AUDIO_DIV_SERCLK_16 */ 6852470feccbf030652380c2d73304576137b0fb12eJean-Francois Moine 6862470feccbf030652380c2d73304576137b0fb12eJean-Francois Moine /* S/PDIF asks for a larger divider */ 6872470feccbf030652380c2d73304576137b0fb12eJean-Francois Moine if (p->audio_format == AFMT_SPDIF) 6882470feccbf030652380c2d73304576137b0fb12eJean-Francois Moine adiv++; /* AUDIO_DIV_SERCLK_16 or _32 */ 6892470feccbf030652380c2d73304576137b0fb12eJean-Francois Moine 6902f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_AUDIO_DIV, adiv); 691c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 692c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* 693c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * This is the approximate value of N, which happens to be 694c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King * the recommended values for non-coherent clocks. 695c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King */ 696c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King n = 128 * p->audio_sample_rate / 1000; 697c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 698c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Write the CTS and N values */ 699c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[0] = 0x44; 700c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[1] = 0x42; 701c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[2] = 0x01; 702c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[3] = n; 703c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[4] = n >> 8; 704c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[5] = n >> 16; 7052f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write_range(priv, REG_ACR_CTS_0, buf, 6); 706c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 707c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Set CTS clock reference */ 7082f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_AIP_CLKSEL, clksel_aip | clksel_fs); 709c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 710c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Reset CTS generator */ 7112f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); 7122f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_clear(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS); 713c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 714c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Write the channel status */ 715f0b33b282c17337276504d6a700d0f558f1a6891Jean-Francois Moine buf[0] = IEC958_AES0_CON_NOT_COPYRIGHT; 716c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King buf[1] = 0x00; 717f0b33b282c17337276504d6a700d0f558f1a6891Jean-Francois Moine buf[2] = IEC958_AES3_CON_FS_NOTID; 718f0b33b282c17337276504d6a700d0f558f1a6891Jean-Francois Moine buf[3] = IEC958_AES4_CON_ORIGFS_NOTID | 719f0b33b282c17337276504d6a700d0f558f1a6891Jean-Francois Moine IEC958_AES4_CON_MAX_WORDLEN_24; 7202f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write_range(priv, REG_CH_STAT_B(0), buf, 4); 721c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 7222f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine tda998x_audio_mute(priv, true); 72373d5e253ac641bf95f5836c064128be78f43cd0bJean-Francois Moine msleep(20); 7242f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine tda998x_audio_mute(priv, false); 725c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 726c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Write the audio information packet */ 7272f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine tda998x_write_aif(priv, p); 728c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King} 729c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 730e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* DRM encoder functions */ 731e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 732a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic void tda998x_encoder_set_config(struct tda998x_priv *priv, 733a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King const struct tda998x_encoder_params *p) 734e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 735c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) | 736c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) | 737c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King VIP_CNTRL_0_SWAP_B(p->swap_b) | 738c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0); 739c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) | 740c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) | 741c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King VIP_CNTRL_1_SWAP_D(p->swap_d) | 742c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0); 743c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) | 744c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) | 745c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King VIP_CNTRL_2_SWAP_F(p->swap_f) | 746c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0); 747c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 748c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King priv->params = *p; 749e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 750e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 751a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic void tda998x_encoder_dpms(struct tda998x_priv *priv, int mode) 752e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 753e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* we only care about on or off: */ 754e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode != DRM_MODE_DPMS_ON) 755e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark mode = DRM_MODE_DPMS_OFF; 756e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 757e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode == priv->dpms) 758e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return; 759e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 760e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark switch (mode) { 761e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case DRM_MODE_DPMS_ON: 762c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* enable video ports, audio will be enabled later */ 7632f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ENA_VP_0, 0xff); 7642f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ENA_VP_1, 0xff); 7652f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ENA_VP_2, 0xff); 766e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set muxing after enabling ports: */ 7672f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_VIP_CNTRL_0, priv->vip_cntrl_0); 7682f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_VIP_CNTRL_1, priv->vip_cntrl_1); 7692f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_VIP_CNTRL_2, priv->vip_cntrl_2); 770e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark break; 771e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark case DRM_MODE_DPMS_OFF: 772db6aaf4d55f95dcb6b162c3a59b56eb1e85ccdfeRussell King /* disable video ports */ 7732f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ENA_VP_0, 0x00); 7742f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ENA_VP_1, 0x00); 7752f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ENA_VP_2, 0x00); 776e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark break; 777e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 778e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 779e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->dpms = mode; 780e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 781e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 782e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 783e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_save(struct drm_encoder *encoder) 784e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 785e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 786e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 787e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 788e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 789e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_restore(struct drm_encoder *encoder) 790e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 791e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 792e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 793e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 794e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic bool 795e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_mode_fixup(struct drm_encoder *encoder, 796e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark const struct drm_display_mode *mode, 797e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_display_mode *adjusted_mode) 798e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 799e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return true; 800e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 801e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 802a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic int tda998x_encoder_mode_valid(struct tda998x_priv *priv, 803a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_display_mode *mode) 804e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 80592fbdfcd7d6b9db6b0a738c5bd85a4a9d731629dRussell King if (mode->clock > 150000) 80692fbdfcd7d6b9db6b0a738c5bd85a4a9d731629dRussell King return MODE_CLOCK_HIGH; 80792fbdfcd7d6b9db6b0a738c5bd85a4a9d731629dRussell King if (mode->htotal >= BIT(13)) 80892fbdfcd7d6b9db6b0a738c5bd85a4a9d731629dRussell King return MODE_BAD_HVALUE; 80992fbdfcd7d6b9db6b0a738c5bd85a4a9d731629dRussell King if (mode->vtotal >= BIT(11)) 81092fbdfcd7d6b9db6b0a738c5bd85a4a9d731629dRussell King return MODE_BAD_VVALUE; 811e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return MODE_OK; 812e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 813e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 814e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void 815a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingtda998x_encoder_mode_set(struct tda998x_priv *priv, 816a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_display_mode *mode, 817a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_display_mode *adjusted_mode) 818e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 819088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t ref_pix, ref_line, n_pix, n_line; 820088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t hs_pix_s, hs_pix_e; 821088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; 822088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t vs2_pix_s, vs2_pix_e, vs2_line_s, vs2_line_e; 823088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t vwin1_line_s, vwin1_line_e; 824088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t vwin2_line_s, vwin2_line_e; 825088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth uint16_t de_pix_s, de_pix_e; 826e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t reg, div, rep; 827e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 828088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth /* 829088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * Internally TDA998x is using ITU-R BT.656 style sync but 830088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * we get VESA style sync. TDA998x is using a reference pixel 831088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * relative to ITU to sync to the input frame and for output 832088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * sync generation. Currently, we are using reference detection 833088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * from HS/VS, i.e. REFPIX/REFLINE denote frame start sync point 834088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * which is position of rising VS with coincident rising HS. 835088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * 836088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * Now there is some issues to take care of: 837088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * - HDMI data islands require sync-before-active 838088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * - TDA998x register values must be > 0 to be enabled 839088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * - REFLINE needs an additional offset of +1 840088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * - REFPIX needs an addtional offset of +1 for UYUV and +3 for RGB 841088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * 842088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * So we add +1 to all horizontal and vertical register values, 843088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * plus an additional +3 for REFPIX as we are using RGB input only. 844e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 845088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth n_pix = mode->htotal; 846088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth n_line = mode->vtotal; 847088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth 848088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth hs_pix_e = mode->hsync_end - mode->hdisplay; 849088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth hs_pix_s = mode->hsync_start - mode->hdisplay; 850088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth de_pix_e = mode->htotal; 851088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth de_pix_s = mode->htotal - mode->hdisplay; 852088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth ref_pix = 3 + hs_pix_s; 853088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth 854179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth /* 855179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth * Attached LCD controllers may generate broken sync. Allow 856179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth * those to adjust the position of the rising VS edge by adding 857179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth * HSKEW to ref_pix. 858179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth */ 859179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth if (adjusted_mode->flags & DRM_MODE_FLAG_HSKEW) 860179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth ref_pix += adjusted_mode->hskew; 861179f1aa407b466c06a94f9e54abc948d1e1146e7Sebastian Hesselbarth 862088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth if ((mode->flags & DRM_MODE_FLAG_INTERLACE) == 0) { 863088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth ref_line = 1 + mode->vsync_start - mode->vdisplay; 864088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin1_line_s = mode->vtotal - mode->vdisplay - 1; 865088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin1_line_e = vwin1_line_s + mode->vdisplay; 866088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_pix_s = vs1_pix_e = hs_pix_s; 867088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_line_s = mode->vsync_start - mode->vdisplay; 868088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_line_e = vs1_line_s + 869088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth mode->vsync_end - mode->vsync_start; 870088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin2_line_s = vwin2_line_e = 0; 871088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs2_pix_s = vs2_pix_e = 0; 872088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs2_line_s = vs2_line_e = 0; 873088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth } else { 874088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth ref_line = 1 + (mode->vsync_start - mode->vdisplay)/2; 875088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin1_line_s = (mode->vtotal - mode->vdisplay)/2; 876088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin1_line_e = vwin1_line_s + mode->vdisplay/2; 877088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_pix_s = vs1_pix_e = hs_pix_s; 878088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_line_s = (mode->vsync_start - mode->vdisplay)/2; 879088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs1_line_e = vs1_line_s + 880088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth (mode->vsync_end - mode->vsync_start)/2; 881088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin2_line_s = vwin1_line_s + mode->vtotal/2; 882088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vwin2_line_e = vwin2_line_s + mode->vdisplay/2; 883088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs2_pix_s = vs2_pix_e = hs_pix_s + mode->htotal/2; 884088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs2_line_s = vs1_line_s + mode->vtotal/2 ; 885088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth vs2_line_e = vs2_line_s + 886088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth (mode->vsync_end - mode->vsync_start)/2; 887088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth } 888e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 889e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark div = 148500 / mode->clock; 8903ae471f73a1d581e078b5b06d08d7b82833a093fJean-Francois Moine if (div != 0) { 8913ae471f73a1d581e078b5b06d08d7b82833a093fJean-Francois Moine div--; 8923ae471f73a1d581e078b5b06d08d7b82833a093fJean-Francois Moine if (div > 3) 8933ae471f73a1d581e078b5b06d08d7b82833a093fJean-Francois Moine div = 3; 8943ae471f73a1d581e078b5b06d08d7b82833a093fJean-Francois Moine } 895e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 896e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* mute the audio FIFO: */ 8972f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_set(priv, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); 898e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 899e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set HDMI HDCP mode off: */ 90081b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg_write(priv, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); 9012f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_clear(priv, REG_TX33, TX33_HDMI); 9022f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(0)); 903e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 904e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* no pre-filter or interpolator: */ 9052f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_HVF_CNTRL_0, HVF_CNTRL_0_PREFIL(0) | 906e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark HVF_CNTRL_0_INTPOL(0)); 9072f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0)); 9082f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_VIP_CNTRL_4, VIP_CNTRL_4_BLANKIT(0) | 909e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark VIP_CNTRL_4_BLC(0)); 910e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 9112f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_clear(priv, REG_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IZ); 912a8b517e5312124e2dd7b6d6d9afac458aaecfbf3Jean-Francois Moine reg_clear(priv, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR | 913a8b517e5312124e2dd7b6d6d9afac458aaecfbf3Jean-Francois Moine PLL_SERIAL_3_SRL_DE); 9142f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_SERIALIZER, 0); 9152f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); 916e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 917e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */ 918e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark rep = 0; 9192f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_RPT_CNTRL, 0); 9202f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | 921e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); 922e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 9232f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | 924e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark PLL_SERIAL_2_SRL_PR(rep)); 925e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 926e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set color matrix bypass flag: */ 92781b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg_write(priv, REG_MAT_CONTRL, MAT_CONTRL_MAT_BP | 92881b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine MAT_CONTRL_MAT_SC(1)); 929e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 930e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set BIAS tmds value: */ 9312f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ANA_GENERAL, 0x09); 932e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 933088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth /* 934088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * Sync on rising HSYNC/VSYNC 935088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth */ 93681b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg = VIP_CNTRL_3_SYNC_HS; 937088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth 938088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth /* 939088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * TDA19988 requires high-active sync at input stage, 940088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth * so invert low-active sync provided by master encoder here 941088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth */ 942088d61d1fdfde56850c157138a6dc08880c1853dSebastian Hesselbarth if (mode->flags & DRM_MODE_FLAG_NHSYNC) 94381b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg |= VIP_CNTRL_3_H_TGL; 944e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (mode->flags & DRM_MODE_FLAG_NVSYNC) 94581b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg |= VIP_CNTRL_3_V_TGL; 94681b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg_write(priv, REG_VIP_CNTRL_3, reg); 9472f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine 9482f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_VIDFORMAT, 0x00); 9492f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_REFPIX_MSB, ref_pix); 9502f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_REFLINE_MSB, ref_line); 9512f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_NPIX_MSB, n_pix); 9522f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_NLINE_MSB, n_line); 9532f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VS_LINE_STRT_1_MSB, vs1_line_s); 9542f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VS_PIX_STRT_1_MSB, vs1_pix_s); 9552f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VS_LINE_END_1_MSB, vs1_line_e); 9562f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VS_PIX_END_1_MSB, vs1_pix_e); 9572f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VS_LINE_STRT_2_MSB, vs2_line_s); 9582f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VS_PIX_STRT_2_MSB, vs2_pix_s); 9592f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VS_LINE_END_2_MSB, vs2_line_e); 9602f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VS_PIX_END_2_MSB, vs2_pix_e); 9612f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_HS_PIX_START_MSB, hs_pix_s); 9622f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_HS_PIX_STOP_MSB, hs_pix_e); 9632f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VWIN_START_1_MSB, vwin1_line_s); 9642f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VWIN_END_1_MSB, vwin1_line_e); 9652f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VWIN_START_2_MSB, vwin2_line_s); 9662f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_VWIN_END_2_MSB, vwin2_line_e); 9672f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_DE_START_MSB, de_pix_s); 9682f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write16(priv, REG_DE_STOP_MSB, de_pix_e); 969e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 970e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (priv->rev == TDA19988) { 971e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* let incoming pixels fill the active space (if any) */ 9722f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ENABLE_SPACE, 0x00); 973e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 974e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 97581b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine /* 97681b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine * Always generate sync polarity relative to input sync and 97781b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine * revert input stage toggled sync at output stage 97881b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine */ 97981b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg = TBG_CNTRL_1_DWIN_DIS | TBG_CNTRL_1_TGL_EN; 98081b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine if (mode->flags & DRM_MODE_FLAG_NHSYNC) 98181b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg |= TBG_CNTRL_1_H_TGL; 98281b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine if (mode->flags & DRM_MODE_FLAG_NVSYNC) 98381b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg |= TBG_CNTRL_1_V_TGL; 98481b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg_write(priv, REG_TBG_CNTRL_1, reg); 98581b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine 986e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* must be last register set: */ 98781b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg_write(priv, REG_TBG_CNTRL_0, 0); 988c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 989c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* Only setup the info frames if the sink is HDMI */ 990c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King if (priv->is_hdmi_sink) { 991c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King /* We need to turn HDMI HDCP stuff on to get audio through */ 99281b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg &= ~TBG_CNTRL_1_DWIN_DIS; 99381b53a166f5cdf4e5bec47fc8884c994de82dc6bJean-Francois Moine reg_write(priv, REG_TBG_CNTRL_1, reg); 9942f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(1)); 9952f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_set(priv, REG_TX33, TX33_HDMI); 996c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 9972f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine tda998x_write_avi(priv, adjusted_mode); 998c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King 999c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King if (priv->params.audio_cfg) 10002f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine tda998x_configure_audio(priv, adjusted_mode, 1001c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King &priv->params); 1002c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King } 1003e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1004e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1005e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic enum drm_connector_status 1006a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingtda998x_encoder_detect(struct tda998x_priv *priv) 1007e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 10082f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine uint8_t val = cec_read(priv, REG_CEC_RXSHPDLEV); 10092f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine 1010e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected : 1011e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark connector_status_disconnected; 1012e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1013e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1014a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic int read_edid_block(struct tda998x_priv *priv, uint8_t *buf, int blk) 1015e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1016e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t offset, segptr; 1017e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int ret, i; 1018e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1019e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark offset = (blk & 1) ? 128 : 0; 1020e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark segptr = blk / 2; 1021e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 10222f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_DDC_ADDR, 0xa0); 10232f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_DDC_OFFS, offset); 10242f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_DDC_SEGM_ADDR, 0x60); 10252f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_DDC_SEGM, segptr); 1026e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1027e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* enable reading EDID: */ 102812473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine priv->wq_edid_wait = 1; 10292f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_EDID_CTRL, 0x1); 1030e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1031e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* flag must be cleared by sw: */ 10322f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_EDID_CTRL, 0x0); 1033e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1034e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* wait for block read to complete: */ 103512473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if (priv->hdmi->irq) { 103612473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine i = wait_event_timeout(priv->wq_edid, 103712473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine !priv->wq_edid_wait, 103812473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine msecs_to_jiffies(100)); 103912473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if (i < 0) { 10405e7fe2fef4347d7a09bb15588d8bbe3cb83b6ed4Russell King dev_err(&priv->hdmi->dev, "read edid wait err %d\n", i); 104112473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine return i; 104212473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine } 104312473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine } else { 1044713456db179356c6b32a50ea1910fc509615c457Russell King for (i = 100; i > 0; i--) { 1045713456db179356c6b32a50ea1910fc509615c457Russell King msleep(1); 104612473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine ret = reg_read(priv, REG_INT_FLAGS_2); 104712473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if (ret < 0) 104812473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine return ret; 104912473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if (ret & INT_FLAGS_2_EDID_BLK_RD) 105012473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine break; 105112473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine } 1052e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 1053e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 105412473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if (i == 0) { 10555e7fe2fef4347d7a09bb15588d8bbe3cb83b6ed4Russell King dev_err(&priv->hdmi->dev, "read edid timeout\n"); 1056e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return -ETIMEDOUT; 105712473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine } 1058e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 10592f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine ret = reg_read_range(priv, REG_EDID_DATA_0, buf, EDID_LENGTH); 1060e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (ret != EDID_LENGTH) { 10615e7fe2fef4347d7a09bb15588d8bbe3cb83b6ed4Russell King dev_err(&priv->hdmi->dev, "failed to read edid block %d: %d\n", 10625e7fe2fef4347d7a09bb15588d8bbe3cb83b6ed4Russell King blk, ret); 1063e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return ret; 1064e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 1065e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1066e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 1067e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1068e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1069a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic uint8_t *do_get_edid(struct tda998x_priv *priv) 1070e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1071704d63f59900968b9b5ae92549c49db0686b87e3Jean-Francois Moine int j, valid_extensions = 0; 1072e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t *block, *new; 1073e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark bool print_bad_edid = drm_debug & DRM_UT_KMS; 1074e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1075e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) 1076e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return NULL; 1077e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1078063b472fbb44ac562797a630ac3516720f588140Russell King if (priv->rev == TDA19988) 10792f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_clear(priv, REG_TX4, TX4_PD_RAM); 1080063b472fbb44ac562797a630ac3516720f588140Russell King 1081e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* base block fetch */ 1082a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King if (read_edid_block(priv, block, 0)) 1083e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1084e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1085e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!drm_edid_block_valid(block, 0, print_bad_edid)) 1086e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1087e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1088e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* if there's no extensions, we're done */ 1089e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (block[0x7e] == 0) 1090063b472fbb44ac562797a630ac3516720f588140Russell King goto done; 1091e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1092e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL); 1093e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!new) 1094e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1095e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block = new; 1096e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1097e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark for (j = 1; j <= block[0x7e]; j++) { 1098e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint8_t *ext_block = block + (valid_extensions + 1) * EDID_LENGTH; 1099a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King if (read_edid_block(priv, ext_block, j)) 1100e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1101e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1102e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!drm_edid_block_valid(ext_block, j, print_bad_edid)) 1103e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1104e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1105e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark valid_extensions++; 1106e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 1107e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1108e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (valid_extensions != block[0x7e]) { 1109e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; 1110e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block[0x7e] = valid_extensions; 1111e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); 1112e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (!new) 1113e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1114e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark block = new; 1115e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 1116e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1117063b472fbb44ac562797a630ac3516720f588140Russell Kingdone: 1118063b472fbb44ac562797a630ac3516720f588140Russell King if (priv->rev == TDA19988) 11192f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_set(priv, REG_TX4, TX4_PD_RAM); 1120063b472fbb44ac562797a630ac3516720f588140Russell King 1121e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return block; 1122e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1123e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 1124063b472fbb44ac562797a630ac3516720f588140Russell King if (priv->rev == TDA19988) 11252f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_set(priv, REG_TX4, TX4_PD_RAM); 11265e7fe2fef4347d7a09bb15588d8bbe3cb83b6ed4Russell King dev_warn(&priv->hdmi->dev, "failed to read EDID\n"); 1127e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark kfree(block); 1128e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return NULL; 1129e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1130e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1131e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 1132a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingtda998x_encoder_get_modes(struct tda998x_priv *priv, 1133a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_connector *connector) 1134e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1135a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct edid *edid = (struct edid *)do_get_edid(priv); 1136e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark int n = 0; 1137e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1138e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (edid) { 1139e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark drm_mode_connector_update_edid_property(connector, edid); 1140e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark n = drm_add_edid_modes(connector, edid); 1141c4c11dd160a8cc98f402c4e12f94b1572e822ffdRussell King priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid); 1142e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark kfree(edid); 1143e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 1144e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1145e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return n; 1146e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1147e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1148a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic void tda998x_encoder_set_polling(struct tda998x_priv *priv, 1149a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_connector *connector) 1150e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 115112473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if (priv->hdmi->irq) 115212473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine connector->polled = DRM_CONNECTOR_POLL_HPD; 115312473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine else 115412473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine connector->polled = DRM_CONNECTOR_POLL_CONNECT | 115512473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine DRM_CONNECTOR_POLL_DISCONNECT; 1156e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1157e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1158e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 1159e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_encoder_set_property(struct drm_encoder *encoder, 1160e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_connector *connector, 1161e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark struct drm_property *property, 1162e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark uint64_t val) 1163e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1164e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 1165e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 1166e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1167e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1168a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic void tda998x_destroy(struct tda998x_priv *priv) 1169e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 117012473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine /* disable all IRQs and free the IRQ handler */ 117112473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine cec_write(priv, REG_CEC_RXSHPDINTENA, 0); 117212473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); 117312473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if (priv->hdmi->irq) 117412473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine free_irq(priv->hdmi->irq, priv); 117512473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine 117689fc868674ba36d3a332dd2298fbfda5be724162Jean-Francois Moine i2c_unregister_device(priv->cec); 1177a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King} 1178a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1179a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King/* Slave encoder support */ 1180a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1181a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic void 1182a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingtda998x_encoder_slave_set_config(struct drm_encoder *encoder, void *params) 1183a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King{ 1184a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King tda998x_encoder_set_config(to_tda998x_priv(encoder), params); 1185a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King} 1186a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1187a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic void tda998x_encoder_slave_destroy(struct drm_encoder *encoder) 1188a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King{ 1189a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct tda998x_priv *priv = to_tda998x_priv(encoder); 1190a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1191a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King tda998x_destroy(priv); 11922e48cecb55435e10c93c6aface1a1c7ef32f4e71Guido MartÃnez drm_i2c_encoder_destroy(encoder); 1193e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark kfree(priv); 1194e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1195e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1196a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic void tda998x_encoder_slave_dpms(struct drm_encoder *encoder, int mode) 1197a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King{ 1198a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King tda998x_encoder_dpms(to_tda998x_priv(encoder), mode); 1199a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King} 1200e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1201a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic int tda998x_encoder_slave_mode_valid(struct drm_encoder *encoder, 1202a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_display_mode *mode) 1203a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King{ 1204a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King return tda998x_encoder_mode_valid(to_tda998x_priv(encoder), mode); 1205a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King} 1206e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1207a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic void 1208a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingtda998x_encoder_slave_mode_set(struct drm_encoder *encoder, 1209a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_display_mode *mode, 1210a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_display_mode *adjusted_mode) 1211e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1212a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King tda998x_encoder_mode_set(to_tda998x_priv(encoder), mode, adjusted_mode); 1213a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King} 1214a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1215a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic enum drm_connector_status 1216a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingtda998x_encoder_slave_detect(struct drm_encoder *encoder, 1217a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_connector *connector) 1218a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King{ 1219a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King return tda998x_encoder_detect(to_tda998x_priv(encoder)); 1220a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King} 1221a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1222a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic int tda998x_encoder_slave_get_modes(struct drm_encoder *encoder, 1223a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_connector *connector) 1224a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King{ 1225a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King return tda998x_encoder_get_modes(to_tda998x_priv(encoder), connector); 1226e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1227e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1228e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int 1229a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingtda998x_encoder_slave_create_resources(struct drm_encoder *encoder, 1230a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_connector *connector) 1231e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1232a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King tda998x_encoder_set_polling(to_tda998x_priv(encoder), connector); 1233e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 1234e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1235e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1236a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic struct drm_encoder_slave_funcs tda998x_encoder_slave_funcs = { 1237a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King .set_config = tda998x_encoder_slave_set_config, 1238a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King .destroy = tda998x_encoder_slave_destroy, 1239a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King .dpms = tda998x_encoder_slave_dpms, 1240e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .save = tda998x_encoder_save, 1241e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .restore = tda998x_encoder_restore, 1242e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .mode_fixup = tda998x_encoder_mode_fixup, 1243a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King .mode_valid = tda998x_encoder_slave_mode_valid, 1244a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King .mode_set = tda998x_encoder_slave_mode_set, 1245a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King .detect = tda998x_encoder_slave_detect, 1246a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King .get_modes = tda998x_encoder_slave_get_modes, 1247a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King .create_resources = tda998x_encoder_slave_create_resources, 1248e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .set_property = tda998x_encoder_set_property, 1249e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 1250e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1251e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* I2C driver functions */ 1252e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1253a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) 1254e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 12550d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine struct device_node *np = client->dev.of_node; 12560d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine u32 video; 1257fb7544d7732f780df989fabf31c5852be953daadRussell King int rev_lo, rev_hi, ret; 1258e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 12595e74c22cd1e0f9e49573fe580de47e198ee04975Russell King priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3); 12605e74c22cd1e0f9e49573fe580de47e198ee04975Russell King priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); 12615e74c22cd1e0f9e49573fe580de47e198ee04975Russell King priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5); 12625e74c22cd1e0f9e49573fe580de47e198ee04975Russell King 12632eb4c7b1e7f275fe833aabe0a251b8e3f767fb08Jean-Francois Moine priv->current_page = 0xff; 12642f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine priv->hdmi = client; 1265e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->cec = i2c_new_dummy(client->adapter, 0x34); 1266a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King if (!priv->cec) 12676ae668cc19e8b18df28cd67b3448d9abd79284a4Jean-Francois Moine return -ENODEV; 126812473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine 1269e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->dpms = DRM_MODE_DPMS_OFF; 1270e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1271e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* wake up the device: */ 12722f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine cec_write(priv, REG_CEC_ENAMODS, 1273e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); 1274e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 12752f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine tda998x_reset(priv); 1276e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1277e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* read version: */ 1278fb7544d7732f780df989fabf31c5852be953daadRussell King rev_lo = reg_read(priv, REG_VERSION_LSB); 1279fb7544d7732f780df989fabf31c5852be953daadRussell King rev_hi = reg_read(priv, REG_VERSION_MSB); 1280fb7544d7732f780df989fabf31c5852be953daadRussell King if (rev_lo < 0 || rev_hi < 0) { 1281fb7544d7732f780df989fabf31c5852be953daadRussell King ret = rev_lo < 0 ? rev_lo : rev_hi; 12827d2eadc9b9d4eacc6aa8cc0cb33e05b5a6d30256Jean-Francois Moine goto fail; 1283fb7544d7732f780df989fabf31c5852be953daadRussell King } 1284fb7544d7732f780df989fabf31c5852be953daadRussell King 1285fb7544d7732f780df989fabf31c5852be953daadRussell King priv->rev = rev_lo | rev_hi << 8; 1286e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1287e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* mask off feature bits: */ 1288e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark priv->rev &= ~0x30; /* not-hdcp and not-scalar bit */ 1289e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1290e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark switch (priv->rev) { 1291b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine case TDA9989N2: 1292b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine dev_info(&client->dev, "found TDA9989 n2"); 1293b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine break; 1294b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine case TDA19989: 1295b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine dev_info(&client->dev, "found TDA19989"); 1296b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine break; 1297b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine case TDA19989N2: 1298b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine dev_info(&client->dev, "found TDA19989 n2"); 1299b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine break; 1300b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine case TDA19988: 1301b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine dev_info(&client->dev, "found TDA19988"); 1302b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine break; 1303e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark default: 1304b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine dev_err(&client->dev, "found unsupported device: %04x\n", 1305b728fab7026b9db5a9bb60c7638765cfa4ee50c1Jean-Francois Moine priv->rev); 1306e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark goto fail; 1307e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark } 1308e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1309e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* after reset, enable DDC: */ 13102f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_DDC_DISABLE, 0x00); 1311e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1312e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* set clock on DDC channel: */ 13132f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_write(priv, REG_TX3, 39); 1314e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1315e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* if necessary, disable multi-master: */ 1316e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (priv->rev == TDA19989) 13172f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine reg_set(priv, REG_I2C_MASTER, I2C_MASTER_DIS_MM); 1318e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 13192f7f730a4f0fd3376dda9266203f29ceccd0a67fJean-Francois Moine cec_write(priv, REG_CEC_FRO_IM_CLK_CTRL, 1320e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL); 1321e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 132212473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine /* initialize the optional IRQ */ 132312473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if (client->irq) { 132412473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine int irqf_trigger; 132512473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine 132612473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine /* init read EDID waitqueue */ 132712473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine init_waitqueue_head(&priv->wq_edid); 132812473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine 132912473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine /* clear pending interrupts */ 133012473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine reg_read(priv, REG_INT_FLAGS_0); 133112473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine reg_read(priv, REG_INT_FLAGS_1); 133212473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine reg_read(priv, REG_INT_FLAGS_2); 133312473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine 133412473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine irqf_trigger = 133512473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine irqd_get_trigger_type(irq_get_irq_data(client->irq)); 133612473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine ret = request_threaded_irq(client->irq, NULL, 133712473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine tda998x_irq_thread, 133812473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine irqf_trigger | IRQF_ONESHOT, 133912473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine "tda998x", priv); 134012473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine if (ret) { 134112473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine dev_err(&client->dev, 134212473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine "failed to request IRQ#%u: %d\n", 134312473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine client->irq, ret); 134412473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine goto fail; 134512473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine } 134612473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine 134712473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine /* enable HPD irq */ 134812473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD); 134912473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine } 135012473b7d8e6074c7d4c2816afa6027354ce9a502Jean-Francois Moine 1351e47826274e8871bc6b35f82d35aea53db0f4ae31Jean-Francois Moine /* enable EDID read irq: */ 1352e47826274e8871bc6b35f82d35aea53db0f4ae31Jean-Francois Moine reg_set(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); 1353e47826274e8871bc6b35f82d35aea53db0f4ae31Jean-Francois Moine 13540d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine if (!np) 13550d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine return 0; /* non-DT */ 13560d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine 13570d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine /* get the optional video properties */ 13580d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine ret = of_property_read_u32(np, "video-ports", &video); 13590d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine if (ret == 0) { 13600d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine priv->vip_cntrl_0 = video >> 16; 13610d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine priv->vip_cntrl_1 = video >> 8; 13620d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine priv->vip_cntrl_2 = video; 13630d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine } 13640d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine 1365e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return 0; 1366e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1367e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkfail: 1368e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark /* if encoder_init fails, the encoder slave is never registered, 1369e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark * so cleanup here: 1370e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark */ 1371e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark if (priv->cec) 1372e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark i2c_unregister_device(priv->cec); 1373e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return -ENXIO; 1374e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1375e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1376a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell Kingstatic int tda998x_encoder_init(struct i2c_client *client, 1377a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_device *dev, 1378a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct drm_encoder_slave *encoder_slave) 1379a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King{ 1380a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King struct tda998x_priv *priv; 1381a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King int ret; 1382a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1383a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1384a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King if (!priv) 1385a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King return -ENOMEM; 1386a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1387a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King priv->encoder = &encoder_slave->base; 1388a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1389a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King ret = tda998x_create(client, priv); 1390a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King if (ret) { 1391a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King kfree(priv); 1392a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King return ret; 1393a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King } 1394a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1395a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King encoder_slave->slave_priv = priv; 1396a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King encoder_slave->slave_funcs = &tda998x_encoder_slave_funcs; 1397a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1398a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King return 0; 1399a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King} 1400a8f4d4d63739e4bca459ff40636f1d9e4b7ef5e6Russell King 1401c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstruct tda998x_priv2 { 1402c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct tda998x_priv base; 1403c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct drm_encoder encoder; 1404c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct drm_connector connector; 1405c707c3619ca81f499a5ce032021405e989a96ff0Russell King}; 1406c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1407c707c3619ca81f499a5ce032021405e989a96ff0Russell King#define conn_to_tda998x_priv2(x) \ 1408c707c3619ca81f499a5ce032021405e989a96ff0Russell King container_of(x, struct tda998x_priv2, connector); 1409c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1410c707c3619ca81f499a5ce032021405e989a96ff0Russell King#define enc_to_tda998x_priv2(x) \ 1411c707c3619ca81f499a5ce032021405e989a96ff0Russell King container_of(x, struct tda998x_priv2, encoder); 1412c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1413c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic void tda998x_encoder2_dpms(struct drm_encoder *encoder, int mode) 1414c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1415c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder); 1416c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1417c707c3619ca81f499a5ce032021405e989a96ff0Russell King tda998x_encoder_dpms(&priv->base, mode); 1418c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1419c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1420c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic void tda998x_encoder_prepare(struct drm_encoder *encoder) 1421c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1422c707c3619ca81f499a5ce032021405e989a96ff0Russell King tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_OFF); 1423c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1424c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1425c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic void tda998x_encoder_commit(struct drm_encoder *encoder) 1426c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1427c707c3619ca81f499a5ce032021405e989a96ff0Russell King tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_ON); 1428c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1429c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1430c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic void tda998x_encoder2_mode_set(struct drm_encoder *encoder, 1431c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct drm_display_mode *mode, 1432c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct drm_display_mode *adjusted_mode) 1433c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1434c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder); 1435c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1436c707c3619ca81f499a5ce032021405e989a96ff0Russell King tda998x_encoder_mode_set(&priv->base, mode, adjusted_mode); 1437c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1438c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1439c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { 1440c707c3619ca81f499a5ce032021405e989a96ff0Russell King .dpms = tda998x_encoder2_dpms, 1441c707c3619ca81f499a5ce032021405e989a96ff0Russell King .save = tda998x_encoder_save, 1442c707c3619ca81f499a5ce032021405e989a96ff0Russell King .restore = tda998x_encoder_restore, 1443c707c3619ca81f499a5ce032021405e989a96ff0Russell King .mode_fixup = tda998x_encoder_mode_fixup, 1444c707c3619ca81f499a5ce032021405e989a96ff0Russell King .prepare = tda998x_encoder_prepare, 1445c707c3619ca81f499a5ce032021405e989a96ff0Russell King .commit = tda998x_encoder_commit, 1446c707c3619ca81f499a5ce032021405e989a96ff0Russell King .mode_set = tda998x_encoder2_mode_set, 1447c707c3619ca81f499a5ce032021405e989a96ff0Russell King}; 1448c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1449c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic void tda998x_encoder_destroy(struct drm_encoder *encoder) 1450c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1451c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder); 1452c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1453c707c3619ca81f499a5ce032021405e989a96ff0Russell King tda998x_destroy(&priv->base); 1454c707c3619ca81f499a5ce032021405e989a96ff0Russell King drm_encoder_cleanup(encoder); 1455c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1456c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1457c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic const struct drm_encoder_funcs tda998x_encoder_funcs = { 1458c707c3619ca81f499a5ce032021405e989a96ff0Russell King .destroy = tda998x_encoder_destroy, 1459c707c3619ca81f499a5ce032021405e989a96ff0Russell King}; 1460c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1461c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic int tda998x_connector_get_modes(struct drm_connector *connector) 1462c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1463c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); 1464c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1465c707c3619ca81f499a5ce032021405e989a96ff0Russell King return tda998x_encoder_get_modes(&priv->base, connector); 1466c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1467c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1468c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic int tda998x_connector_mode_valid(struct drm_connector *connector, 1469c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct drm_display_mode *mode) 1470c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1471c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); 1472c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1473c707c3619ca81f499a5ce032021405e989a96ff0Russell King return tda998x_encoder_mode_valid(&priv->base, mode); 1474c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1475c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1476c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic struct drm_encoder * 1477c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingtda998x_connector_best_encoder(struct drm_connector *connector) 1478c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1479c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); 1480c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1481c707c3619ca81f499a5ce032021405e989a96ff0Russell King return &priv->encoder; 1482c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1483c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1484c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic 1485c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingconst struct drm_connector_helper_funcs tda998x_connector_helper_funcs = { 1486c707c3619ca81f499a5ce032021405e989a96ff0Russell King .get_modes = tda998x_connector_get_modes, 1487c707c3619ca81f499a5ce032021405e989a96ff0Russell King .mode_valid = tda998x_connector_mode_valid, 1488c707c3619ca81f499a5ce032021405e989a96ff0Russell King .best_encoder = tda998x_connector_best_encoder, 1489c707c3619ca81f499a5ce032021405e989a96ff0Russell King}; 1490c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1491c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic enum drm_connector_status 1492c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingtda998x_connector_detect(struct drm_connector *connector, bool force) 1493c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1494c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); 1495c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1496c707c3619ca81f499a5ce032021405e989a96ff0Russell King return tda998x_encoder_detect(&priv->base); 1497c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1498c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1499c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic void tda998x_connector_destroy(struct drm_connector *connector) 1500c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 150174cd62ea46f19c41ef20a85792414973ba629cdeDave Airlie drm_connector_unregister(connector); 1502c707c3619ca81f499a5ce032021405e989a96ff0Russell King drm_connector_cleanup(connector); 1503c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1504c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1505c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic const struct drm_connector_funcs tda998x_connector_funcs = { 1506c707c3619ca81f499a5ce032021405e989a96ff0Russell King .dpms = drm_helper_connector_dpms, 1507c707c3619ca81f499a5ce032021405e989a96ff0Russell King .fill_modes = drm_helper_probe_single_connector_modes, 1508c707c3619ca81f499a5ce032021405e989a96ff0Russell King .detect = tda998x_connector_detect, 1509c707c3619ca81f499a5ce032021405e989a96ff0Russell King .destroy = tda998x_connector_destroy, 1510c707c3619ca81f499a5ce032021405e989a96ff0Russell King}; 1511c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1512c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic int tda998x_bind(struct device *dev, struct device *master, void *data) 1513c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1514c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct tda998x_encoder_params *params = dev->platform_data; 1515c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct i2c_client *client = to_i2c_client(dev); 1516c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct drm_device *drm = data; 1517c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct tda998x_priv2 *priv; 1518c707c3619ca81f499a5ce032021405e989a96ff0Russell King int ret; 1519c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1520c707c3619ca81f499a5ce032021405e989a96ff0Russell King priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 1521c707c3619ca81f499a5ce032021405e989a96ff0Russell King if (!priv) 1522c707c3619ca81f499a5ce032021405e989a96ff0Russell King return -ENOMEM; 1523c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1524c707c3619ca81f499a5ce032021405e989a96ff0Russell King dev_set_drvdata(dev, priv); 1525c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1526c707c3619ca81f499a5ce032021405e989a96ff0Russell King priv->base.encoder = &priv->encoder; 1527c707c3619ca81f499a5ce032021405e989a96ff0Russell King priv->connector.interlace_allowed = 1; 1528c707c3619ca81f499a5ce032021405e989a96ff0Russell King priv->encoder.possible_crtcs = 1 << 0; 1529c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1530c707c3619ca81f499a5ce032021405e989a96ff0Russell King ret = tda998x_create(client, &priv->base); 1531c707c3619ca81f499a5ce032021405e989a96ff0Russell King if (ret) 1532c707c3619ca81f499a5ce032021405e989a96ff0Russell King return ret; 1533c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1534c707c3619ca81f499a5ce032021405e989a96ff0Russell King if (!dev->of_node && params) 1535c707c3619ca81f499a5ce032021405e989a96ff0Russell King tda998x_encoder_set_config(&priv->base, params); 1536c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1537c707c3619ca81f499a5ce032021405e989a96ff0Russell King tda998x_encoder_set_polling(&priv->base, &priv->connector); 1538c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1539c707c3619ca81f499a5ce032021405e989a96ff0Russell King drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); 1540c707c3619ca81f499a5ce032021405e989a96ff0Russell King ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, 1541c707c3619ca81f499a5ce032021405e989a96ff0Russell King DRM_MODE_ENCODER_TMDS); 1542c707c3619ca81f499a5ce032021405e989a96ff0Russell King if (ret) 1543c707c3619ca81f499a5ce032021405e989a96ff0Russell King goto err_encoder; 1544c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1545c707c3619ca81f499a5ce032021405e989a96ff0Russell King drm_connector_helper_add(&priv->connector, 1546c707c3619ca81f499a5ce032021405e989a96ff0Russell King &tda998x_connector_helper_funcs); 1547c707c3619ca81f499a5ce032021405e989a96ff0Russell King ret = drm_connector_init(drm, &priv->connector, 1548c707c3619ca81f499a5ce032021405e989a96ff0Russell King &tda998x_connector_funcs, 1549c707c3619ca81f499a5ce032021405e989a96ff0Russell King DRM_MODE_CONNECTOR_HDMIA); 1550c707c3619ca81f499a5ce032021405e989a96ff0Russell King if (ret) 1551c707c3619ca81f499a5ce032021405e989a96ff0Russell King goto err_connector; 1552c707c3619ca81f499a5ce032021405e989a96ff0Russell King 155374cd62ea46f19c41ef20a85792414973ba629cdeDave Airlie ret = drm_connector_register(&priv->connector); 1554c707c3619ca81f499a5ce032021405e989a96ff0Russell King if (ret) 1555c707c3619ca81f499a5ce032021405e989a96ff0Russell King goto err_sysfs; 1556c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1557c707c3619ca81f499a5ce032021405e989a96ff0Russell King priv->connector.encoder = &priv->encoder; 1558c707c3619ca81f499a5ce032021405e989a96ff0Russell King drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); 1559c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1560c707c3619ca81f499a5ce032021405e989a96ff0Russell King return 0; 1561c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1562c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingerr_sysfs: 1563c707c3619ca81f499a5ce032021405e989a96ff0Russell King drm_connector_cleanup(&priv->connector); 1564c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingerr_connector: 1565c707c3619ca81f499a5ce032021405e989a96ff0Russell King drm_encoder_cleanup(&priv->encoder); 1566c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingerr_encoder: 1567c707c3619ca81f499a5ce032021405e989a96ff0Russell King tda998x_destroy(&priv->base); 1568c707c3619ca81f499a5ce032021405e989a96ff0Russell King return ret; 1569c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1570c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1571c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic void tda998x_unbind(struct device *dev, struct device *master, 1572c707c3619ca81f499a5ce032021405e989a96ff0Russell King void *data) 1573c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1574c707c3619ca81f499a5ce032021405e989a96ff0Russell King struct tda998x_priv2 *priv = dev_get_drvdata(dev); 1575c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1576c707c3619ca81f499a5ce032021405e989a96ff0Russell King drm_connector_cleanup(&priv->connector); 1577c707c3619ca81f499a5ce032021405e989a96ff0Russell King drm_encoder_cleanup(&priv->encoder); 1578c707c3619ca81f499a5ce032021405e989a96ff0Russell King tda998x_destroy(&priv->base); 1579c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1580c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1581c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic const struct component_ops tda998x_ops = { 1582c707c3619ca81f499a5ce032021405e989a96ff0Russell King .bind = tda998x_bind, 1583c707c3619ca81f499a5ce032021405e989a96ff0Russell King .unbind = tda998x_unbind, 1584c707c3619ca81f499a5ce032021405e989a96ff0Russell King}; 1585c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1586c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic int 1587c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingtda998x_probe(struct i2c_client *client, const struct i2c_device_id *id) 1588c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1589c707c3619ca81f499a5ce032021405e989a96ff0Russell King return component_add(&client->dev, &tda998x_ops); 1590c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1591c707c3619ca81f499a5ce032021405e989a96ff0Russell King 1592c707c3619ca81f499a5ce032021405e989a96ff0Russell Kingstatic int tda998x_remove(struct i2c_client *client) 1593c707c3619ca81f499a5ce032021405e989a96ff0Russell King{ 1594c707c3619ca81f499a5ce032021405e989a96ff0Russell King component_del(&client->dev, &tda998x_ops); 1595c707c3619ca81f499a5ce032021405e989a96ff0Russell King return 0; 1596c707c3619ca81f499a5ce032021405e989a96ff0Russell King} 1597c707c3619ca81f499a5ce032021405e989a96ff0Russell King 15980d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine#ifdef CONFIG_OF 15990d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moinestatic const struct of_device_id tda998x_dt_ids[] = { 16000d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine { .compatible = "nxp,tda998x", }, 16010d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine { } 16020d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine}; 16030d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois MoineMODULE_DEVICE_TABLE(of, tda998x_dt_ids); 16040d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine#endif 16050d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine 1606e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic struct i2c_device_id tda998x_ids[] = { 1607e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark { "tda998x", 0 }, 1608e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark { } 1609e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 1610e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_DEVICE_TABLE(i2c, tda998x_ids); 1611e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1612e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic struct drm_i2c_encoder_driver tda998x_driver = { 1613e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .i2c_driver = { 1614e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .probe = tda998x_probe, 1615e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .remove = tda998x_remove, 1616e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .driver = { 1617e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .name = "tda998x", 16180d44ea190387e21a7e6f6d7c9dd44df2e85d007aJean-Francois Moine .of_match_table = of_match_ptr(tda998x_dt_ids), 1619e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark }, 1620e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .id_table = tda998x_ids, 1621e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark }, 1622e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark .encoder_init = tda998x_encoder_init, 1623e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark}; 1624e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1625e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark/* Module initialization */ 1626e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1627e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic int __init 1628e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_init(void) 1629e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1630e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 1631e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark return drm_i2c_encoder_register(THIS_MODULE, &tda998x_driver); 1632e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1633e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1634e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkstatic void __exit 1635e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarktda998x_exit(void) 1636e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark{ 1637e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark DBG(""); 1638e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark drm_i2c_encoder_unregister(&tda998x_driver); 1639e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark} 1640e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1641e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_AUTHOR("Rob Clark <robdclark@gmail.com"); 1642e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_DESCRIPTION("NXP Semiconductors TDA998X HDMI Encoder"); 1643e7792ce2da5ded80861db787ace9b57ecf7bc96cRob ClarkMODULE_LICENSE("GPL"); 1644e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clark 1645e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkmodule_init(tda998x_init); 1646e7792ce2da5ded80861db787ace9b57ecf7bc96cRob Clarkmodule_exit(tda998x_exit); 1647