1*caa6f4a7SDmitry Baryshkov // SPDX-License-Identifier: GPL-2.0-only 2*caa6f4a7SDmitry Baryshkov /* 3*caa6f4a7SDmitry Baryshkov * TDA9950 Consumer Electronics Control driver 4*caa6f4a7SDmitry Baryshkov * 5*caa6f4a7SDmitry Baryshkov * The NXP TDA9950 implements the HDMI Consumer Electronics Control 6*caa6f4a7SDmitry Baryshkov * interface. The host interface is similar to a mailbox: the data 7*caa6f4a7SDmitry Baryshkov * registers starting at REG_CDR0 are written to send a command to the 8*caa6f4a7SDmitry Baryshkov * internal CPU, and replies are read from these registers. 9*caa6f4a7SDmitry Baryshkov * 10*caa6f4a7SDmitry Baryshkov * As the data registers represent a mailbox, they must be accessed 11*caa6f4a7SDmitry Baryshkov * as a single I2C transaction. See the TDA9950 data sheet for details. 12*caa6f4a7SDmitry Baryshkov */ 13*caa6f4a7SDmitry Baryshkov #include <linux/delay.h> 14*caa6f4a7SDmitry Baryshkov #include <linux/i2c.h> 15*caa6f4a7SDmitry Baryshkov #include <linux/interrupt.h> 16*caa6f4a7SDmitry Baryshkov #include <linux/module.h> 17*caa6f4a7SDmitry Baryshkov #include <linux/platform_data/tda9950.h> 18*caa6f4a7SDmitry Baryshkov #include <linux/slab.h> 19*caa6f4a7SDmitry Baryshkov #include <drm/drm_edid.h> 20*caa6f4a7SDmitry Baryshkov #include <media/cec.h> 21*caa6f4a7SDmitry Baryshkov #include <media/cec-notifier.h> 22*caa6f4a7SDmitry Baryshkov 23*caa6f4a7SDmitry Baryshkov enum { 24*caa6f4a7SDmitry Baryshkov REG_CSR = 0x00, 25*caa6f4a7SDmitry Baryshkov CSR_BUSY = BIT(7), 26*caa6f4a7SDmitry Baryshkov CSR_INT = BIT(6), 27*caa6f4a7SDmitry Baryshkov CSR_ERR = BIT(5), 28*caa6f4a7SDmitry Baryshkov 29*caa6f4a7SDmitry Baryshkov REG_CER = 0x01, 30*caa6f4a7SDmitry Baryshkov 31*caa6f4a7SDmitry Baryshkov REG_CVR = 0x02, 32*caa6f4a7SDmitry Baryshkov 33*caa6f4a7SDmitry Baryshkov REG_CCR = 0x03, 34*caa6f4a7SDmitry Baryshkov CCR_RESET = BIT(7), 35*caa6f4a7SDmitry Baryshkov CCR_ON = BIT(6), 36*caa6f4a7SDmitry Baryshkov 37*caa6f4a7SDmitry Baryshkov REG_ACKH = 0x04, 38*caa6f4a7SDmitry Baryshkov REG_ACKL = 0x05, 39*caa6f4a7SDmitry Baryshkov 40*caa6f4a7SDmitry Baryshkov REG_CCONR = 0x06, 41*caa6f4a7SDmitry Baryshkov CCONR_ENABLE_ERROR = BIT(4), 42*caa6f4a7SDmitry Baryshkov CCONR_RETRY_MASK = 7, 43*caa6f4a7SDmitry Baryshkov 44*caa6f4a7SDmitry Baryshkov REG_CDR0 = 0x07, 45*caa6f4a7SDmitry Baryshkov 46*caa6f4a7SDmitry Baryshkov CDR1_REQ = 0x00, 47*caa6f4a7SDmitry Baryshkov CDR1_CNF = 0x01, 48*caa6f4a7SDmitry Baryshkov CDR1_IND = 0x81, 49*caa6f4a7SDmitry Baryshkov CDR1_ERR = 0x82, 50*caa6f4a7SDmitry Baryshkov CDR1_IER = 0x83, 51*caa6f4a7SDmitry Baryshkov 52*caa6f4a7SDmitry Baryshkov CDR2_CNF_SUCCESS = 0x00, 53*caa6f4a7SDmitry Baryshkov CDR2_CNF_OFF_STATE = 0x80, 54*caa6f4a7SDmitry Baryshkov CDR2_CNF_BAD_REQ = 0x81, 55*caa6f4a7SDmitry Baryshkov CDR2_CNF_CEC_ACCESS = 0x82, 56*caa6f4a7SDmitry Baryshkov CDR2_CNF_ARB_ERROR = 0x83, 57*caa6f4a7SDmitry Baryshkov CDR2_CNF_BAD_TIMING = 0x84, 58*caa6f4a7SDmitry Baryshkov CDR2_CNF_NACK_ADDR = 0x85, 59*caa6f4a7SDmitry Baryshkov CDR2_CNF_NACK_DATA = 0x86, 60*caa6f4a7SDmitry Baryshkov }; 61*caa6f4a7SDmitry Baryshkov 62*caa6f4a7SDmitry Baryshkov struct tda9950_priv { 63*caa6f4a7SDmitry Baryshkov struct i2c_client *client; 64*caa6f4a7SDmitry Baryshkov struct device *hdmi; 65*caa6f4a7SDmitry Baryshkov struct cec_adapter *adap; 66*caa6f4a7SDmitry Baryshkov struct tda9950_glue *glue; 67*caa6f4a7SDmitry Baryshkov u16 addresses; 68*caa6f4a7SDmitry Baryshkov struct cec_msg rx_msg; 69*caa6f4a7SDmitry Baryshkov struct cec_notifier *notify; 70*caa6f4a7SDmitry Baryshkov bool open; 71*caa6f4a7SDmitry Baryshkov }; 72*caa6f4a7SDmitry Baryshkov 73*caa6f4a7SDmitry Baryshkov static int tda9950_write_range(struct i2c_client *client, u8 addr, u8 *p, int cnt) 74*caa6f4a7SDmitry Baryshkov { 75*caa6f4a7SDmitry Baryshkov struct i2c_msg msg; 76*caa6f4a7SDmitry Baryshkov u8 buf[CEC_MAX_MSG_SIZE + 3]; 77*caa6f4a7SDmitry Baryshkov int ret; 78*caa6f4a7SDmitry Baryshkov 79*caa6f4a7SDmitry Baryshkov if (WARN_ON(cnt > sizeof(buf) - 1)) 80*caa6f4a7SDmitry Baryshkov return -EINVAL; 81*caa6f4a7SDmitry Baryshkov 82*caa6f4a7SDmitry Baryshkov buf[0] = addr; 83*caa6f4a7SDmitry Baryshkov memcpy(buf + 1, p, cnt); 84*caa6f4a7SDmitry Baryshkov 85*caa6f4a7SDmitry Baryshkov msg.addr = client->addr; 86*caa6f4a7SDmitry Baryshkov msg.flags = 0; 87*caa6f4a7SDmitry Baryshkov msg.len = cnt + 1; 88*caa6f4a7SDmitry Baryshkov msg.buf = buf; 89*caa6f4a7SDmitry Baryshkov 90*caa6f4a7SDmitry Baryshkov dev_dbg(&client->dev, "wr 0x%02x: %*ph\n", addr, cnt, p); 91*caa6f4a7SDmitry Baryshkov 92*caa6f4a7SDmitry Baryshkov ret = i2c_transfer(client->adapter, &msg, 1); 93*caa6f4a7SDmitry Baryshkov if (ret < 0) 94*caa6f4a7SDmitry Baryshkov dev_err(&client->dev, "Error %d writing to cec:0x%x\n", ret, addr); 95*caa6f4a7SDmitry Baryshkov return ret < 0 ? ret : 0; 96*caa6f4a7SDmitry Baryshkov } 97*caa6f4a7SDmitry Baryshkov 98*caa6f4a7SDmitry Baryshkov static void tda9950_write(struct i2c_client *client, u8 addr, u8 val) 99*caa6f4a7SDmitry Baryshkov { 100*caa6f4a7SDmitry Baryshkov tda9950_write_range(client, addr, &val, 1); 101*caa6f4a7SDmitry Baryshkov } 102*caa6f4a7SDmitry Baryshkov 103*caa6f4a7SDmitry Baryshkov static int tda9950_read_range(struct i2c_client *client, u8 addr, u8 *p, int cnt) 104*caa6f4a7SDmitry Baryshkov { 105*caa6f4a7SDmitry Baryshkov struct i2c_msg msg[2]; 106*caa6f4a7SDmitry Baryshkov int ret; 107*caa6f4a7SDmitry Baryshkov 108*caa6f4a7SDmitry Baryshkov msg[0].addr = client->addr; 109*caa6f4a7SDmitry Baryshkov msg[0].flags = 0; 110*caa6f4a7SDmitry Baryshkov msg[0].len = 1; 111*caa6f4a7SDmitry Baryshkov msg[0].buf = &addr; 112*caa6f4a7SDmitry Baryshkov msg[1].addr = client->addr; 113*caa6f4a7SDmitry Baryshkov msg[1].flags = I2C_M_RD; 114*caa6f4a7SDmitry Baryshkov msg[1].len = cnt; 115*caa6f4a7SDmitry Baryshkov msg[1].buf = p; 116*caa6f4a7SDmitry Baryshkov 117*caa6f4a7SDmitry Baryshkov ret = i2c_transfer(client->adapter, msg, 2); 118*caa6f4a7SDmitry Baryshkov if (ret < 0) 119*caa6f4a7SDmitry Baryshkov dev_err(&client->dev, "Error %d reading from cec:0x%x\n", ret, addr); 120*caa6f4a7SDmitry Baryshkov 121*caa6f4a7SDmitry Baryshkov dev_dbg(&client->dev, "rd 0x%02x: %*ph\n", addr, cnt, p); 122*caa6f4a7SDmitry Baryshkov 123*caa6f4a7SDmitry Baryshkov return ret; 124*caa6f4a7SDmitry Baryshkov } 125*caa6f4a7SDmitry Baryshkov 126*caa6f4a7SDmitry Baryshkov static u8 tda9950_read(struct i2c_client *client, u8 addr) 127*caa6f4a7SDmitry Baryshkov { 128*caa6f4a7SDmitry Baryshkov int ret; 129*caa6f4a7SDmitry Baryshkov u8 val; 130*caa6f4a7SDmitry Baryshkov 131*caa6f4a7SDmitry Baryshkov ret = tda9950_read_range(client, addr, &val, 1); 132*caa6f4a7SDmitry Baryshkov if (ret < 0) 133*caa6f4a7SDmitry Baryshkov val = 0; 134*caa6f4a7SDmitry Baryshkov 135*caa6f4a7SDmitry Baryshkov return val; 136*caa6f4a7SDmitry Baryshkov } 137*caa6f4a7SDmitry Baryshkov 138*caa6f4a7SDmitry Baryshkov static irqreturn_t tda9950_irq(int irq, void *data) 139*caa6f4a7SDmitry Baryshkov { 140*caa6f4a7SDmitry Baryshkov struct tda9950_priv *priv = data; 141*caa6f4a7SDmitry Baryshkov unsigned int tx_status; 142*caa6f4a7SDmitry Baryshkov u8 csr, cconr, buf[19]; 143*caa6f4a7SDmitry Baryshkov u8 arb_lost_cnt, nack_cnt, err_cnt; 144*caa6f4a7SDmitry Baryshkov 145*caa6f4a7SDmitry Baryshkov if (!priv->open) 146*caa6f4a7SDmitry Baryshkov return IRQ_NONE; 147*caa6f4a7SDmitry Baryshkov 148*caa6f4a7SDmitry Baryshkov csr = tda9950_read(priv->client, REG_CSR); 149*caa6f4a7SDmitry Baryshkov if (!(csr & CSR_INT)) 150*caa6f4a7SDmitry Baryshkov return IRQ_NONE; 151*caa6f4a7SDmitry Baryshkov 152*caa6f4a7SDmitry Baryshkov cconr = tda9950_read(priv->client, REG_CCONR) & CCONR_RETRY_MASK; 153*caa6f4a7SDmitry Baryshkov 154*caa6f4a7SDmitry Baryshkov tda9950_read_range(priv->client, REG_CDR0, buf, sizeof(buf)); 155*caa6f4a7SDmitry Baryshkov 156*caa6f4a7SDmitry Baryshkov /* 157*caa6f4a7SDmitry Baryshkov * This should never happen: the data sheet says that there will 158*caa6f4a7SDmitry Baryshkov * always be a valid message if the interrupt line is asserted. 159*caa6f4a7SDmitry Baryshkov */ 160*caa6f4a7SDmitry Baryshkov if (buf[0] == 0) { 161*caa6f4a7SDmitry Baryshkov dev_warn(&priv->client->dev, "interrupt pending, but no message?\n"); 162*caa6f4a7SDmitry Baryshkov return IRQ_NONE; 163*caa6f4a7SDmitry Baryshkov } 164*caa6f4a7SDmitry Baryshkov 165*caa6f4a7SDmitry Baryshkov switch (buf[1]) { 166*caa6f4a7SDmitry Baryshkov case CDR1_CNF: /* transmit result */ 167*caa6f4a7SDmitry Baryshkov arb_lost_cnt = nack_cnt = err_cnt = 0; 168*caa6f4a7SDmitry Baryshkov switch (buf[2]) { 169*caa6f4a7SDmitry Baryshkov case CDR2_CNF_SUCCESS: 170*caa6f4a7SDmitry Baryshkov tx_status = CEC_TX_STATUS_OK; 171*caa6f4a7SDmitry Baryshkov break; 172*caa6f4a7SDmitry Baryshkov 173*caa6f4a7SDmitry Baryshkov case CDR2_CNF_ARB_ERROR: 174*caa6f4a7SDmitry Baryshkov tx_status = CEC_TX_STATUS_ARB_LOST; 175*caa6f4a7SDmitry Baryshkov arb_lost_cnt = cconr; 176*caa6f4a7SDmitry Baryshkov break; 177*caa6f4a7SDmitry Baryshkov 178*caa6f4a7SDmitry Baryshkov case CDR2_CNF_NACK_ADDR: 179*caa6f4a7SDmitry Baryshkov tx_status = CEC_TX_STATUS_NACK; 180*caa6f4a7SDmitry Baryshkov nack_cnt = cconr; 181*caa6f4a7SDmitry Baryshkov break; 182*caa6f4a7SDmitry Baryshkov 183*caa6f4a7SDmitry Baryshkov default: /* some other error, refer to TDA9950 docs */ 184*caa6f4a7SDmitry Baryshkov dev_err(&priv->client->dev, "CNF reply error 0x%02x\n", 185*caa6f4a7SDmitry Baryshkov buf[2]); 186*caa6f4a7SDmitry Baryshkov tx_status = CEC_TX_STATUS_ERROR; 187*caa6f4a7SDmitry Baryshkov err_cnt = cconr; 188*caa6f4a7SDmitry Baryshkov break; 189*caa6f4a7SDmitry Baryshkov } 190*caa6f4a7SDmitry Baryshkov /* TDA9950 executes all retries for us */ 191*caa6f4a7SDmitry Baryshkov if (tx_status != CEC_TX_STATUS_OK) 192*caa6f4a7SDmitry Baryshkov tx_status |= CEC_TX_STATUS_MAX_RETRIES; 193*caa6f4a7SDmitry Baryshkov cec_transmit_done(priv->adap, tx_status, arb_lost_cnt, 194*caa6f4a7SDmitry Baryshkov nack_cnt, 0, err_cnt); 195*caa6f4a7SDmitry Baryshkov break; 196*caa6f4a7SDmitry Baryshkov 197*caa6f4a7SDmitry Baryshkov case CDR1_IND: 198*caa6f4a7SDmitry Baryshkov priv->rx_msg.len = buf[0] - 2; 199*caa6f4a7SDmitry Baryshkov if (priv->rx_msg.len > CEC_MAX_MSG_SIZE) 200*caa6f4a7SDmitry Baryshkov priv->rx_msg.len = CEC_MAX_MSG_SIZE; 201*caa6f4a7SDmitry Baryshkov 202*caa6f4a7SDmitry Baryshkov memcpy(priv->rx_msg.msg, buf + 2, priv->rx_msg.len); 203*caa6f4a7SDmitry Baryshkov cec_received_msg(priv->adap, &priv->rx_msg); 204*caa6f4a7SDmitry Baryshkov break; 205*caa6f4a7SDmitry Baryshkov 206*caa6f4a7SDmitry Baryshkov default: /* unknown */ 207*caa6f4a7SDmitry Baryshkov dev_err(&priv->client->dev, "unknown service id 0x%02x\n", 208*caa6f4a7SDmitry Baryshkov buf[1]); 209*caa6f4a7SDmitry Baryshkov break; 210*caa6f4a7SDmitry Baryshkov } 211*caa6f4a7SDmitry Baryshkov 212*caa6f4a7SDmitry Baryshkov return IRQ_HANDLED; 213*caa6f4a7SDmitry Baryshkov } 214*caa6f4a7SDmitry Baryshkov 215*caa6f4a7SDmitry Baryshkov static int tda9950_cec_transmit(struct cec_adapter *adap, u8 attempts, 216*caa6f4a7SDmitry Baryshkov u32 signal_free_time, struct cec_msg *msg) 217*caa6f4a7SDmitry Baryshkov { 218*caa6f4a7SDmitry Baryshkov struct tda9950_priv *priv = adap->priv; 219*caa6f4a7SDmitry Baryshkov u8 buf[CEC_MAX_MSG_SIZE + 2]; 220*caa6f4a7SDmitry Baryshkov 221*caa6f4a7SDmitry Baryshkov buf[0] = 2 + msg->len; 222*caa6f4a7SDmitry Baryshkov buf[1] = CDR1_REQ; 223*caa6f4a7SDmitry Baryshkov memcpy(buf + 2, msg->msg, msg->len); 224*caa6f4a7SDmitry Baryshkov 225*caa6f4a7SDmitry Baryshkov if (attempts > 5) 226*caa6f4a7SDmitry Baryshkov attempts = 5; 227*caa6f4a7SDmitry Baryshkov 228*caa6f4a7SDmitry Baryshkov tda9950_write(priv->client, REG_CCONR, attempts); 229*caa6f4a7SDmitry Baryshkov 230*caa6f4a7SDmitry Baryshkov return tda9950_write_range(priv->client, REG_CDR0, buf, 2 + msg->len); 231*caa6f4a7SDmitry Baryshkov } 232*caa6f4a7SDmitry Baryshkov 233*caa6f4a7SDmitry Baryshkov static int tda9950_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) 234*caa6f4a7SDmitry Baryshkov { 235*caa6f4a7SDmitry Baryshkov struct tda9950_priv *priv = adap->priv; 236*caa6f4a7SDmitry Baryshkov u16 addresses; 237*caa6f4a7SDmitry Baryshkov u8 buf[2]; 238*caa6f4a7SDmitry Baryshkov 239*caa6f4a7SDmitry Baryshkov if (addr == CEC_LOG_ADDR_INVALID) 240*caa6f4a7SDmitry Baryshkov addresses = priv->addresses = 0; 241*caa6f4a7SDmitry Baryshkov else 242*caa6f4a7SDmitry Baryshkov addresses = priv->addresses |= BIT(addr); 243*caa6f4a7SDmitry Baryshkov 244*caa6f4a7SDmitry Baryshkov /* TDA9950 doesn't want address 15 set */ 245*caa6f4a7SDmitry Baryshkov addresses &= 0x7fff; 246*caa6f4a7SDmitry Baryshkov buf[0] = addresses >> 8; 247*caa6f4a7SDmitry Baryshkov buf[1] = addresses; 248*caa6f4a7SDmitry Baryshkov 249*caa6f4a7SDmitry Baryshkov return tda9950_write_range(priv->client, REG_ACKH, buf, 2); 250*caa6f4a7SDmitry Baryshkov } 251*caa6f4a7SDmitry Baryshkov 252*caa6f4a7SDmitry Baryshkov /* 253*caa6f4a7SDmitry Baryshkov * When operating as part of the TDA998x, we need additional handling 254*caa6f4a7SDmitry Baryshkov * to initialise and shut down the TDA9950 part of the device. These 255*caa6f4a7SDmitry Baryshkov * two hooks are provided to allow the TDA998x code to perform those 256*caa6f4a7SDmitry Baryshkov * activities. 257*caa6f4a7SDmitry Baryshkov */ 258*caa6f4a7SDmitry Baryshkov static int tda9950_glue_open(struct tda9950_priv *priv) 259*caa6f4a7SDmitry Baryshkov { 260*caa6f4a7SDmitry Baryshkov int ret = 0; 261*caa6f4a7SDmitry Baryshkov 262*caa6f4a7SDmitry Baryshkov if (priv->glue && priv->glue->open) 263*caa6f4a7SDmitry Baryshkov ret = priv->glue->open(priv->glue->data); 264*caa6f4a7SDmitry Baryshkov 265*caa6f4a7SDmitry Baryshkov priv->open = true; 266*caa6f4a7SDmitry Baryshkov 267*caa6f4a7SDmitry Baryshkov return ret; 268*caa6f4a7SDmitry Baryshkov } 269*caa6f4a7SDmitry Baryshkov 270*caa6f4a7SDmitry Baryshkov static void tda9950_glue_release(struct tda9950_priv *priv) 271*caa6f4a7SDmitry Baryshkov { 272*caa6f4a7SDmitry Baryshkov priv->open = false; 273*caa6f4a7SDmitry Baryshkov 274*caa6f4a7SDmitry Baryshkov if (priv->glue && priv->glue->release) 275*caa6f4a7SDmitry Baryshkov priv->glue->release(priv->glue->data); 276*caa6f4a7SDmitry Baryshkov } 277*caa6f4a7SDmitry Baryshkov 278*caa6f4a7SDmitry Baryshkov static int tda9950_open(struct tda9950_priv *priv) 279*caa6f4a7SDmitry Baryshkov { 280*caa6f4a7SDmitry Baryshkov struct i2c_client *client = priv->client; 281*caa6f4a7SDmitry Baryshkov int ret; 282*caa6f4a7SDmitry Baryshkov 283*caa6f4a7SDmitry Baryshkov ret = tda9950_glue_open(priv); 284*caa6f4a7SDmitry Baryshkov if (ret) 285*caa6f4a7SDmitry Baryshkov return ret; 286*caa6f4a7SDmitry Baryshkov 287*caa6f4a7SDmitry Baryshkov /* Reset the TDA9950, and wait 250ms for it to recover */ 288*caa6f4a7SDmitry Baryshkov tda9950_write(client, REG_CCR, CCR_RESET); 289*caa6f4a7SDmitry Baryshkov msleep(250); 290*caa6f4a7SDmitry Baryshkov 291*caa6f4a7SDmitry Baryshkov tda9950_cec_adap_log_addr(priv->adap, CEC_LOG_ADDR_INVALID); 292*caa6f4a7SDmitry Baryshkov 293*caa6f4a7SDmitry Baryshkov /* Start the command processor */ 294*caa6f4a7SDmitry Baryshkov tda9950_write(client, REG_CCR, CCR_ON); 295*caa6f4a7SDmitry Baryshkov 296*caa6f4a7SDmitry Baryshkov return 0; 297*caa6f4a7SDmitry Baryshkov } 298*caa6f4a7SDmitry Baryshkov 299*caa6f4a7SDmitry Baryshkov static void tda9950_release(struct tda9950_priv *priv) 300*caa6f4a7SDmitry Baryshkov { 301*caa6f4a7SDmitry Baryshkov struct i2c_client *client = priv->client; 302*caa6f4a7SDmitry Baryshkov int timeout = 50; 303*caa6f4a7SDmitry Baryshkov u8 csr; 304*caa6f4a7SDmitry Baryshkov 305*caa6f4a7SDmitry Baryshkov /* Stop the command processor */ 306*caa6f4a7SDmitry Baryshkov tda9950_write(client, REG_CCR, 0); 307*caa6f4a7SDmitry Baryshkov 308*caa6f4a7SDmitry Baryshkov /* Wait up to .5s for it to signal non-busy */ 309*caa6f4a7SDmitry Baryshkov do { 310*caa6f4a7SDmitry Baryshkov csr = tda9950_read(client, REG_CSR); 311*caa6f4a7SDmitry Baryshkov if (!(csr & CSR_BUSY) || !--timeout) 312*caa6f4a7SDmitry Baryshkov break; 313*caa6f4a7SDmitry Baryshkov msleep(10); 314*caa6f4a7SDmitry Baryshkov } while (1); 315*caa6f4a7SDmitry Baryshkov 316*caa6f4a7SDmitry Baryshkov /* Warn the user that their IRQ may die if it's shared. */ 317*caa6f4a7SDmitry Baryshkov if (csr & CSR_BUSY) 318*caa6f4a7SDmitry Baryshkov dev_warn(&client->dev, "command processor failed to stop, irq%d may die (csr=0x%02x)\n", 319*caa6f4a7SDmitry Baryshkov client->irq, csr); 320*caa6f4a7SDmitry Baryshkov 321*caa6f4a7SDmitry Baryshkov tda9950_glue_release(priv); 322*caa6f4a7SDmitry Baryshkov } 323*caa6f4a7SDmitry Baryshkov 324*caa6f4a7SDmitry Baryshkov static int tda9950_cec_adap_enable(struct cec_adapter *adap, bool enable) 325*caa6f4a7SDmitry Baryshkov { 326*caa6f4a7SDmitry Baryshkov struct tda9950_priv *priv = adap->priv; 327*caa6f4a7SDmitry Baryshkov 328*caa6f4a7SDmitry Baryshkov if (!enable) { 329*caa6f4a7SDmitry Baryshkov tda9950_release(priv); 330*caa6f4a7SDmitry Baryshkov return 0; 331*caa6f4a7SDmitry Baryshkov } else { 332*caa6f4a7SDmitry Baryshkov return tda9950_open(priv); 333*caa6f4a7SDmitry Baryshkov } 334*caa6f4a7SDmitry Baryshkov } 335*caa6f4a7SDmitry Baryshkov 336*caa6f4a7SDmitry Baryshkov static const struct cec_adap_ops tda9950_cec_ops = { 337*caa6f4a7SDmitry Baryshkov .adap_enable = tda9950_cec_adap_enable, 338*caa6f4a7SDmitry Baryshkov .adap_log_addr = tda9950_cec_adap_log_addr, 339*caa6f4a7SDmitry Baryshkov .adap_transmit = tda9950_cec_transmit, 340*caa6f4a7SDmitry Baryshkov }; 341*caa6f4a7SDmitry Baryshkov 342*caa6f4a7SDmitry Baryshkov /* 343*caa6f4a7SDmitry Baryshkov * When operating as part of the TDA998x, we need to claim additional 344*caa6f4a7SDmitry Baryshkov * resources. These two hooks permit the management of those resources. 345*caa6f4a7SDmitry Baryshkov */ 346*caa6f4a7SDmitry Baryshkov static void tda9950_devm_glue_exit(void *data) 347*caa6f4a7SDmitry Baryshkov { 348*caa6f4a7SDmitry Baryshkov struct tda9950_glue *glue = data; 349*caa6f4a7SDmitry Baryshkov 350*caa6f4a7SDmitry Baryshkov if (glue && glue->exit) 351*caa6f4a7SDmitry Baryshkov glue->exit(glue->data); 352*caa6f4a7SDmitry Baryshkov } 353*caa6f4a7SDmitry Baryshkov 354*caa6f4a7SDmitry Baryshkov static int tda9950_devm_glue_init(struct device *dev, struct tda9950_glue *glue) 355*caa6f4a7SDmitry Baryshkov { 356*caa6f4a7SDmitry Baryshkov int ret; 357*caa6f4a7SDmitry Baryshkov 358*caa6f4a7SDmitry Baryshkov if (glue && glue->init) { 359*caa6f4a7SDmitry Baryshkov ret = glue->init(glue->data); 360*caa6f4a7SDmitry Baryshkov if (ret) 361*caa6f4a7SDmitry Baryshkov return ret; 362*caa6f4a7SDmitry Baryshkov } 363*caa6f4a7SDmitry Baryshkov 364*caa6f4a7SDmitry Baryshkov ret = devm_add_action(dev, tda9950_devm_glue_exit, glue); 365*caa6f4a7SDmitry Baryshkov if (ret) 366*caa6f4a7SDmitry Baryshkov tda9950_devm_glue_exit(glue); 367*caa6f4a7SDmitry Baryshkov 368*caa6f4a7SDmitry Baryshkov return ret; 369*caa6f4a7SDmitry Baryshkov } 370*caa6f4a7SDmitry Baryshkov 371*caa6f4a7SDmitry Baryshkov static void tda9950_cec_del(void *data) 372*caa6f4a7SDmitry Baryshkov { 373*caa6f4a7SDmitry Baryshkov struct tda9950_priv *priv = data; 374*caa6f4a7SDmitry Baryshkov 375*caa6f4a7SDmitry Baryshkov cec_delete_adapter(priv->adap); 376*caa6f4a7SDmitry Baryshkov } 377*caa6f4a7SDmitry Baryshkov 378*caa6f4a7SDmitry Baryshkov static int tda9950_probe(struct i2c_client *client) 379*caa6f4a7SDmitry Baryshkov { 380*caa6f4a7SDmitry Baryshkov struct tda9950_glue *glue = client->dev.platform_data; 381*caa6f4a7SDmitry Baryshkov struct device *dev = &client->dev; 382*caa6f4a7SDmitry Baryshkov struct tda9950_priv *priv; 383*caa6f4a7SDmitry Baryshkov unsigned long irqflags; 384*caa6f4a7SDmitry Baryshkov int ret; 385*caa6f4a7SDmitry Baryshkov u8 cvr; 386*caa6f4a7SDmitry Baryshkov 387*caa6f4a7SDmitry Baryshkov /* 388*caa6f4a7SDmitry Baryshkov * We must have I2C functionality: our multi-byte accesses 389*caa6f4a7SDmitry Baryshkov * must be performed as a single contiguous transaction. 390*caa6f4a7SDmitry Baryshkov */ 391*caa6f4a7SDmitry Baryshkov if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 392*caa6f4a7SDmitry Baryshkov dev_err(&client->dev, 393*caa6f4a7SDmitry Baryshkov "adapter does not support I2C functionality\n"); 394*caa6f4a7SDmitry Baryshkov return -ENXIO; 395*caa6f4a7SDmitry Baryshkov } 396*caa6f4a7SDmitry Baryshkov 397*caa6f4a7SDmitry Baryshkov /* We must have an interrupt to be functional. */ 398*caa6f4a7SDmitry Baryshkov if (client->irq <= 0) { 399*caa6f4a7SDmitry Baryshkov dev_err(&client->dev, "driver requires an interrupt\n"); 400*caa6f4a7SDmitry Baryshkov return -ENXIO; 401*caa6f4a7SDmitry Baryshkov } 402*caa6f4a7SDmitry Baryshkov 403*caa6f4a7SDmitry Baryshkov priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 404*caa6f4a7SDmitry Baryshkov if (!priv) 405*caa6f4a7SDmitry Baryshkov return -ENOMEM; 406*caa6f4a7SDmitry Baryshkov 407*caa6f4a7SDmitry Baryshkov priv->client = client; 408*caa6f4a7SDmitry Baryshkov priv->glue = glue; 409*caa6f4a7SDmitry Baryshkov 410*caa6f4a7SDmitry Baryshkov i2c_set_clientdata(client, priv); 411*caa6f4a7SDmitry Baryshkov 412*caa6f4a7SDmitry Baryshkov /* 413*caa6f4a7SDmitry Baryshkov * If we're part of a TDA998x, we want the class devices to be 414*caa6f4a7SDmitry Baryshkov * associated with the HDMI Tx so we have a tight relationship 415*caa6f4a7SDmitry Baryshkov * between the HDMI interface and the CEC interface. 416*caa6f4a7SDmitry Baryshkov */ 417*caa6f4a7SDmitry Baryshkov priv->hdmi = dev; 418*caa6f4a7SDmitry Baryshkov if (glue && glue->parent) 419*caa6f4a7SDmitry Baryshkov priv->hdmi = glue->parent; 420*caa6f4a7SDmitry Baryshkov 421*caa6f4a7SDmitry Baryshkov priv->adap = cec_allocate_adapter(&tda9950_cec_ops, priv, "tda9950", 422*caa6f4a7SDmitry Baryshkov CEC_CAP_DEFAULTS | 423*caa6f4a7SDmitry Baryshkov CEC_CAP_CONNECTOR_INFO, 424*caa6f4a7SDmitry Baryshkov CEC_MAX_LOG_ADDRS); 425*caa6f4a7SDmitry Baryshkov if (IS_ERR(priv->adap)) 426*caa6f4a7SDmitry Baryshkov return PTR_ERR(priv->adap); 427*caa6f4a7SDmitry Baryshkov 428*caa6f4a7SDmitry Baryshkov ret = devm_add_action(dev, tda9950_cec_del, priv); 429*caa6f4a7SDmitry Baryshkov if (ret) { 430*caa6f4a7SDmitry Baryshkov cec_delete_adapter(priv->adap); 431*caa6f4a7SDmitry Baryshkov return ret; 432*caa6f4a7SDmitry Baryshkov } 433*caa6f4a7SDmitry Baryshkov 434*caa6f4a7SDmitry Baryshkov ret = tda9950_devm_glue_init(dev, glue); 435*caa6f4a7SDmitry Baryshkov if (ret) 436*caa6f4a7SDmitry Baryshkov return ret; 437*caa6f4a7SDmitry Baryshkov 438*caa6f4a7SDmitry Baryshkov ret = tda9950_glue_open(priv); 439*caa6f4a7SDmitry Baryshkov if (ret) 440*caa6f4a7SDmitry Baryshkov return ret; 441*caa6f4a7SDmitry Baryshkov 442*caa6f4a7SDmitry Baryshkov cvr = tda9950_read(client, REG_CVR); 443*caa6f4a7SDmitry Baryshkov 444*caa6f4a7SDmitry Baryshkov dev_info(&client->dev, 445*caa6f4a7SDmitry Baryshkov "TDA9950 CEC interface, hardware version %u.%u\n", 446*caa6f4a7SDmitry Baryshkov cvr >> 4, cvr & 15); 447*caa6f4a7SDmitry Baryshkov 448*caa6f4a7SDmitry Baryshkov tda9950_glue_release(priv); 449*caa6f4a7SDmitry Baryshkov 450*caa6f4a7SDmitry Baryshkov irqflags = IRQF_TRIGGER_FALLING; 451*caa6f4a7SDmitry Baryshkov if (glue) 452*caa6f4a7SDmitry Baryshkov irqflags = glue->irq_flags; 453*caa6f4a7SDmitry Baryshkov 454*caa6f4a7SDmitry Baryshkov ret = devm_request_threaded_irq(dev, client->irq, NULL, tda9950_irq, 455*caa6f4a7SDmitry Baryshkov irqflags | IRQF_SHARED | IRQF_ONESHOT, 456*caa6f4a7SDmitry Baryshkov dev_name(&client->dev), priv); 457*caa6f4a7SDmitry Baryshkov if (ret < 0) 458*caa6f4a7SDmitry Baryshkov return ret; 459*caa6f4a7SDmitry Baryshkov 460*caa6f4a7SDmitry Baryshkov priv->notify = cec_notifier_cec_adap_register(priv->hdmi, NULL, 461*caa6f4a7SDmitry Baryshkov priv->adap); 462*caa6f4a7SDmitry Baryshkov if (!priv->notify) 463*caa6f4a7SDmitry Baryshkov return -ENOMEM; 464*caa6f4a7SDmitry Baryshkov 465*caa6f4a7SDmitry Baryshkov ret = cec_register_adapter(priv->adap, priv->hdmi); 466*caa6f4a7SDmitry Baryshkov if (ret < 0) { 467*caa6f4a7SDmitry Baryshkov cec_notifier_cec_adap_unregister(priv->notify, priv->adap); 468*caa6f4a7SDmitry Baryshkov return ret; 469*caa6f4a7SDmitry Baryshkov } 470*caa6f4a7SDmitry Baryshkov 471*caa6f4a7SDmitry Baryshkov /* 472*caa6f4a7SDmitry Baryshkov * CEC documentation says we must not call cec_delete_adapter 473*caa6f4a7SDmitry Baryshkov * after a successful call to cec_register_adapter(). 474*caa6f4a7SDmitry Baryshkov */ 475*caa6f4a7SDmitry Baryshkov devm_remove_action(dev, tda9950_cec_del, priv); 476*caa6f4a7SDmitry Baryshkov 477*caa6f4a7SDmitry Baryshkov return 0; 478*caa6f4a7SDmitry Baryshkov } 479*caa6f4a7SDmitry Baryshkov 480*caa6f4a7SDmitry Baryshkov static void tda9950_remove(struct i2c_client *client) 481*caa6f4a7SDmitry Baryshkov { 482*caa6f4a7SDmitry Baryshkov struct tda9950_priv *priv = i2c_get_clientdata(client); 483*caa6f4a7SDmitry Baryshkov 484*caa6f4a7SDmitry Baryshkov cec_notifier_cec_adap_unregister(priv->notify, priv->adap); 485*caa6f4a7SDmitry Baryshkov cec_unregister_adapter(priv->adap); 486*caa6f4a7SDmitry Baryshkov } 487*caa6f4a7SDmitry Baryshkov 488*caa6f4a7SDmitry Baryshkov static struct i2c_device_id tda9950_ids[] = { 489*caa6f4a7SDmitry Baryshkov { "tda9950" }, 490*caa6f4a7SDmitry Baryshkov { } 491*caa6f4a7SDmitry Baryshkov }; 492*caa6f4a7SDmitry Baryshkov MODULE_DEVICE_TABLE(i2c, tda9950_ids); 493*caa6f4a7SDmitry Baryshkov 494*caa6f4a7SDmitry Baryshkov static struct i2c_driver tda9950_driver = { 495*caa6f4a7SDmitry Baryshkov .probe = tda9950_probe, 496*caa6f4a7SDmitry Baryshkov .remove = tda9950_remove, 497*caa6f4a7SDmitry Baryshkov .driver = { 498*caa6f4a7SDmitry Baryshkov .name = "tda9950", 499*caa6f4a7SDmitry Baryshkov }, 500*caa6f4a7SDmitry Baryshkov .id_table = tda9950_ids, 501*caa6f4a7SDmitry Baryshkov }; 502*caa6f4a7SDmitry Baryshkov 503*caa6f4a7SDmitry Baryshkov module_i2c_driver(tda9950_driver); 504*caa6f4a7SDmitry Baryshkov 505*caa6f4a7SDmitry Baryshkov MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>"); 506*caa6f4a7SDmitry Baryshkov MODULE_DESCRIPTION("TDA9950/TDA998x Consumer Electronics Control Driver"); 507*caa6f4a7SDmitry Baryshkov MODULE_LICENSE("GPL v2"); 508