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