Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i2c: tda9950: add CEC driver

Add a CEC driver for the TDA9950, which is a stand-alone I2C CEC device,
but is also integrated into HDMI transceivers such as the TDA9989 and
TDA19989.

The TDA9950 contains a command processor which handles retransmissions
and the low level bus protocol. The driver just has to read and write
the messages, and handle error conditions.

Reviewed-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

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