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