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