2 * TDA9950 Consumer Electronics Control driver
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * The NXP TDA9950 implements the HDMI Consumer Electronics Control
9 * interface. The host interface is similar to a mailbox: the data
10 * registers starting at REG_CDR0 are written to send a command to the
11 * internal CPU, and replies are read from these registers.
13 * As the data registers represent a mailbox, they must be accessed
14 * as a single I2C transaction. See the TDA9950 data sheet for details.
16 #include <linux/delay.h>
17 #include <linux/i2c.h>
18 #include <linux/interrupt.h>
19 #include <linux/module.h>
20 #include <linux/platform_data/tda9950.h>
21 #include <linux/slab.h>
22 #include <drm/drm_edid.h>
23 #include <media/cec.h>
24 #include <media/cec-notifier.h>
44 CCONR_ENABLE_ERROR
= BIT(4),
55 CDR2_CNF_SUCCESS
= 0x00,
56 CDR2_CNF_OFF_STATE
= 0x80,
57 CDR2_CNF_BAD_REQ
= 0x81,
58 CDR2_CNF_CEC_ACCESS
= 0x82,
59 CDR2_CNF_ARB_ERROR
= 0x83,
60 CDR2_CNF_BAD_TIMING
= 0x84,
61 CDR2_CNF_NACK_ADDR
= 0x85,
62 CDR2_CNF_NACK_DATA
= 0x86,
66 struct i2c_client
*client
;
68 struct cec_adapter
*adap
;
69 struct tda9950_glue
*glue
;
71 struct cec_msg rx_msg
;
72 struct cec_notifier
*notify
;
76 static int tda9950_write_range(struct i2c_client
*client
, u8 addr
, u8
*p
, int cnt
)
79 u8 buf
[CEC_MAX_MSG_SIZE
+ 3];
82 if (WARN_ON(cnt
> sizeof(buf
) - 1))
86 memcpy(buf
+ 1, p
, cnt
);
88 msg
.addr
= client
->addr
;
93 dev_dbg(&client
->dev
, "wr 0x%02x: %*ph\n", addr
, cnt
, p
);
95 ret
= i2c_transfer(client
->adapter
, &msg
, 1);
97 dev_err(&client
->dev
, "Error %d writing to cec:0x%x\n", ret
, addr
);
98 return ret
< 0 ? ret
: 0;
101 static void tda9950_write(struct i2c_client
*client
, u8 addr
, u8 val
)
103 tda9950_write_range(client
, addr
, &val
, 1);
106 static int tda9950_read_range(struct i2c_client
*client
, u8 addr
, u8
*p
, int cnt
)
108 struct i2c_msg msg
[2];
111 msg
[0].addr
= client
->addr
;
115 msg
[1].addr
= client
->addr
;
116 msg
[1].flags
= I2C_M_RD
;
120 ret
= i2c_transfer(client
->adapter
, msg
, 2);
122 dev_err(&client
->dev
, "Error %d reading from cec:0x%x\n", ret
, addr
);
124 dev_dbg(&client
->dev
, "rd 0x%02x: %*ph\n", addr
, cnt
, p
);
129 static u8
tda9950_read(struct i2c_client
*client
, u8 addr
)
134 ret
= tda9950_read_range(client
, addr
, &val
, 1);
141 static irqreturn_t
tda9950_irq(int irq
, void *data
)
143 struct tda9950_priv
*priv
= data
;
144 unsigned int tx_status
;
145 u8 csr
, cconr
, buf
[19];
146 u8 arb_lost_cnt
, nack_cnt
, err_cnt
;
151 csr
= tda9950_read(priv
->client
, REG_CSR
);
152 if (!(csr
& CSR_INT
))
155 cconr
= tda9950_read(priv
->client
, REG_CCONR
) & CCONR_RETRY_MASK
;
157 tda9950_read_range(priv
->client
, REG_CDR0
, buf
, sizeof(buf
));
160 * This should never happen: the data sheet says that there will
161 * always be a valid message if the interrupt line is asserted.
164 dev_warn(&priv
->client
->dev
, "interrupt pending, but no message?\n");
169 case CDR1_CNF
: /* transmit result */
170 arb_lost_cnt
= nack_cnt
= err_cnt
= 0;
172 case CDR2_CNF_SUCCESS
:
173 tx_status
= CEC_TX_STATUS_OK
;
176 case CDR2_CNF_ARB_ERROR
:
177 tx_status
= CEC_TX_STATUS_ARB_LOST
;
178 arb_lost_cnt
= cconr
;
181 case CDR2_CNF_NACK_ADDR
:
182 tx_status
= CEC_TX_STATUS_NACK
;
186 default: /* some other error, refer to TDA9950 docs */
187 dev_err(&priv
->client
->dev
, "CNF reply error 0x%02x\n",
189 tx_status
= CEC_TX_STATUS_ERROR
;
193 /* TDA9950 executes all retries for us */
194 if (tx_status
!= CEC_TX_STATUS_OK
)
195 tx_status
|= CEC_TX_STATUS_MAX_RETRIES
;
196 cec_transmit_done(priv
->adap
, tx_status
, arb_lost_cnt
,
197 nack_cnt
, 0, err_cnt
);
201 priv
->rx_msg
.len
= buf
[0] - 2;
202 if (priv
->rx_msg
.len
> CEC_MAX_MSG_SIZE
)
203 priv
->rx_msg
.len
= CEC_MAX_MSG_SIZE
;
205 memcpy(priv
->rx_msg
.msg
, buf
+ 2, priv
->rx_msg
.len
);
206 cec_received_msg(priv
->adap
, &priv
->rx_msg
);
209 default: /* unknown */
210 dev_err(&priv
->client
->dev
, "unknown service id 0x%02x\n",
218 static int tda9950_cec_transmit(struct cec_adapter
*adap
, u8 attempts
,
219 u32 signal_free_time
, struct cec_msg
*msg
)
221 struct tda9950_priv
*priv
= adap
->priv
;
222 u8 buf
[CEC_MAX_MSG_SIZE
+ 2];
224 buf
[0] = 2 + msg
->len
;
226 memcpy(buf
+ 2, msg
->msg
, msg
->len
);
231 tda9950_write(priv
->client
, REG_CCONR
, attempts
);
233 return tda9950_write_range(priv
->client
, REG_CDR0
, buf
, 2 + msg
->len
);
236 static int tda9950_cec_adap_log_addr(struct cec_adapter
*adap
, u8 addr
)
238 struct tda9950_priv
*priv
= adap
->priv
;
242 if (addr
== CEC_LOG_ADDR_INVALID
)
243 addresses
= priv
->addresses
= 0;
245 addresses
= priv
->addresses
|= BIT(addr
);
247 /* TDA9950 doesn't want address 15 set */
249 buf
[0] = addresses
>> 8;
252 return tda9950_write_range(priv
->client
, REG_ACKH
, buf
, 2);
256 * When operating as part of the TDA998x, we need additional handling
257 * to initialise and shut down the TDA9950 part of the device. These
258 * two hooks are provided to allow the TDA998x code to perform those
261 static int tda9950_glue_open(struct tda9950_priv
*priv
)
265 if (priv
->glue
&& priv
->glue
->open
)
266 ret
= priv
->glue
->open(priv
->glue
->data
);
273 static void tda9950_glue_release(struct tda9950_priv
*priv
)
277 if (priv
->glue
&& priv
->glue
->release
)
278 priv
->glue
->release(priv
->glue
->data
);
281 static int tda9950_open(struct tda9950_priv
*priv
)
283 struct i2c_client
*client
= priv
->client
;
286 ret
= tda9950_glue_open(priv
);
290 /* Reset the TDA9950, and wait 250ms for it to recover */
291 tda9950_write(client
, REG_CCR
, CCR_RESET
);
294 tda9950_cec_adap_log_addr(priv
->adap
, CEC_LOG_ADDR_INVALID
);
296 /* Start the command processor */
297 tda9950_write(client
, REG_CCR
, CCR_ON
);
302 static void tda9950_release(struct tda9950_priv
*priv
)
304 struct i2c_client
*client
= priv
->client
;
308 /* Stop the command processor */
309 tda9950_write(client
, REG_CCR
, 0);
311 /* Wait up to .5s for it to signal non-busy */
313 csr
= tda9950_read(client
, REG_CSR
);
314 if (!(csr
& CSR_BUSY
) || !--timeout
)
319 /* Warn the user that their IRQ may die if it's shared. */
321 dev_warn(&client
->dev
, "command processor failed to stop, irq%d may die (csr=0x%02x)\n",
324 tda9950_glue_release(priv
);
327 static int tda9950_cec_adap_enable(struct cec_adapter
*adap
, bool enable
)
329 struct tda9950_priv
*priv
= adap
->priv
;
332 tda9950_release(priv
);
335 return tda9950_open(priv
);
339 static const struct cec_adap_ops tda9950_cec_ops
= {
340 .adap_enable
= tda9950_cec_adap_enable
,
341 .adap_log_addr
= tda9950_cec_adap_log_addr
,
342 .adap_transmit
= tda9950_cec_transmit
,
346 * When operating as part of the TDA998x, we need to claim additional
347 * resources. These two hooks permit the management of those resources.
349 static void tda9950_devm_glue_exit(void *data
)
351 struct tda9950_glue
*glue
= data
;
353 if (glue
&& glue
->exit
)
354 glue
->exit(glue
->data
);
357 static int tda9950_devm_glue_init(struct device
*dev
, struct tda9950_glue
*glue
)
361 if (glue
&& glue
->init
) {
362 ret
= glue
->init(glue
->data
);
367 ret
= devm_add_action(dev
, tda9950_devm_glue_exit
, glue
);
369 tda9950_devm_glue_exit(glue
);
374 static void tda9950_cec_del(void *data
)
376 struct tda9950_priv
*priv
= data
;
378 cec_delete_adapter(priv
->adap
);
381 static int tda9950_probe(struct i2c_client
*client
,
382 const struct i2c_device_id
*id
)
384 struct tda9950_glue
*glue
= client
->dev
.platform_data
;
385 struct device
*dev
= &client
->dev
;
386 struct tda9950_priv
*priv
;
387 unsigned long irqflags
;
392 * We must have I2C functionality: our multi-byte accesses
393 * must be performed as a single contiguous transaction.
395 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_I2C
)) {
396 dev_err(&client
->dev
,
397 "adapter does not support I2C functionality\n");
401 /* We must have an interrupt to be functional. */
402 if (client
->irq
<= 0) {
403 dev_err(&client
->dev
, "driver requires an interrupt\n");
407 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
411 priv
->client
= client
;
414 i2c_set_clientdata(client
, priv
);
417 * If we're part of a TDA998x, we want the class devices to be
418 * associated with the HDMI Tx so we have a tight relationship
419 * between the HDMI interface and the CEC interface.
422 if (glue
&& glue
->parent
)
423 priv
->hdmi
= glue
->parent
;
425 priv
->adap
= cec_allocate_adapter(&tda9950_cec_ops
, priv
, "tda9950",
428 if (IS_ERR(priv
->adap
))
429 return PTR_ERR(priv
->adap
);
431 ret
= devm_add_action(dev
, tda9950_cec_del
, priv
);
433 cec_delete_adapter(priv
->adap
);
437 ret
= tda9950_devm_glue_init(dev
, glue
);
441 ret
= tda9950_glue_open(priv
);
445 cvr
= tda9950_read(client
, REG_CVR
);
447 dev_info(&client
->dev
,
448 "TDA9950 CEC interface, hardware version %u.%u\n",
451 tda9950_glue_release(priv
);
453 irqflags
= IRQF_TRIGGER_FALLING
;
455 irqflags
= glue
->irq_flags
;
457 ret
= devm_request_threaded_irq(dev
, client
->irq
, NULL
, tda9950_irq
,
458 irqflags
| IRQF_SHARED
| IRQF_ONESHOT
,
459 dev_name(&client
->dev
), priv
);
463 priv
->notify
= cec_notifier_get(priv
->hdmi
);
467 ret
= cec_register_adapter(priv
->adap
, priv
->hdmi
);
469 cec_notifier_put(priv
->notify
);
474 * CEC documentation says we must not call cec_delete_adapter
475 * after a successful call to cec_register_adapter().
477 devm_remove_action(dev
, tda9950_cec_del
, priv
);
479 cec_register_cec_notifier(priv
->adap
, priv
->notify
);
484 static int tda9950_remove(struct i2c_client
*client
)
486 struct tda9950_priv
*priv
= i2c_get_clientdata(client
);
488 cec_unregister_adapter(priv
->adap
);
489 cec_notifier_put(priv
->notify
);
494 static struct i2c_device_id tda9950_ids
[] = {
498 MODULE_DEVICE_TABLE(i2c
, tda9950_ids
);
500 static struct i2c_driver tda9950_driver
= {
501 .probe
= tda9950_probe
,
502 .remove
= tda9950_remove
,
506 .id_table
= tda9950_ids
,
509 module_i2c_driver(tda9950_driver
);
511 MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
512 MODULE_DESCRIPTION("TDA9950/TDA998x Consumer Electronics Control Driver");
513 MODULE_LICENSE("GPL v2");