ch7322.c (13887B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Driver for the Chrontel CH7322 CEC Controller 4 * 5 * Copyright 2020 Google LLC. 6 */ 7 8/* 9 * Notes 10 * 11 * - This device powers on in Auto Mode which has limited functionality. This 12 * driver disables Auto Mode when it attaches. 13 * 14 */ 15 16#include <linux/cec.h> 17#include <linux/dmi.h> 18#include <linux/i2c.h> 19#include <linux/interrupt.h> 20#include <linux/module.h> 21#include <linux/mutex.h> 22#include <linux/pci.h> 23#include <linux/regmap.h> 24#include <media/cec.h> 25#include <media/cec-notifier.h> 26 27#define CH7322_WRITE 0x00 28#define CH7322_WRITE_MSENT 0x80 29#define CH7322_WRITE_BOK 0x40 30#define CH7322_WRITE_NMASK 0x0f 31 32/* Write buffer is 0x01-0x10 */ 33#define CH7322_WRBUF 0x01 34#define CH7322_WRBUF_LEN 0x10 35 36#define CH7322_READ 0x40 37#define CH7322_READ_NRDT 0x80 38#define CH7322_READ_MSENT 0x20 39#define CH7322_READ_NMASK 0x0f 40 41/* Read buffer is 0x41-0x50 */ 42#define CH7322_RDBUF 0x41 43#define CH7322_RDBUF_LEN 0x10 44 45#define CH7322_MODE 0x11 46#define CH7322_MODE_AUTO 0x78 47#define CH7322_MODE_SW 0xb5 48 49#define CH7322_RESET 0x12 50#define CH7322_RESET_RST 0x00 51 52#define CH7322_POWER 0x13 53#define CH7322_POWER_FPD 0x04 54 55#define CH7322_CFG0 0x17 56#define CH7322_CFG0_EOBEN 0x40 57#define CH7322_CFG0_PEOB 0x20 58#define CH7322_CFG0_CLRSPP 0x10 59#define CH7322_CFG0_FLOW 0x08 60 61#define CH7322_CFG1 0x1a 62#define CH7322_CFG1_STDBYO 0x04 63#define CH7322_CFG1_HPBP 0x02 64#define CH7322_CFG1_PIO 0x01 65 66#define CH7322_INTCTL 0x1b 67#define CH7322_INTCTL_INTPB 0x80 68#define CH7322_INTCTL_STDBY 0x40 69#define CH7322_INTCTL_HPDFALL 0x20 70#define CH7322_INTCTL_HPDRISE 0x10 71#define CH7322_INTCTL_RXMSG 0x08 72#define CH7322_INTCTL_TXMSG 0x04 73#define CH7322_INTCTL_NEWPHA 0x02 74#define CH7322_INTCTL_ERROR 0x01 75 76#define CH7322_DVCLKFNH 0x1d 77#define CH7322_DVCLKFNL 0x1e 78 79#define CH7322_CTL 0x31 80#define CH7322_CTL_FSTDBY 0x80 81#define CH7322_CTL_PLSEN 0x40 82#define CH7322_CTL_PLSPB 0x20 83#define CH7322_CTL_SPADL 0x10 84#define CH7322_CTL_HINIT 0x08 85#define CH7322_CTL_WPHYA 0x04 86#define CH7322_CTL_H1T 0x02 87#define CH7322_CTL_S1T 0x01 88 89#define CH7322_PAWH 0x32 90#define CH7322_PAWL 0x33 91 92#define CH7322_ADDLW 0x34 93#define CH7322_ADDLW_MASK 0xf0 94 95#define CH7322_ADDLR 0x3d 96#define CH7322_ADDLR_HPD 0x80 97#define CH7322_ADDLR_MASK 0x0f 98 99#define CH7322_INTDATA 0x3e 100#define CH7322_INTDATA_MODE 0x80 101#define CH7322_INTDATA_STDBY 0x40 102#define CH7322_INTDATA_HPDFALL 0x20 103#define CH7322_INTDATA_HPDRISE 0x10 104#define CH7322_INTDATA_RXMSG 0x08 105#define CH7322_INTDATA_TXMSG 0x04 106#define CH7322_INTDATA_NEWPHA 0x02 107#define CH7322_INTDATA_ERROR 0x01 108 109#define CH7322_EVENT 0x3f 110#define CH7322_EVENT_TXERR 0x80 111#define CH7322_EVENT_HRST 0x40 112#define CH7322_EVENT_HFST 0x20 113#define CH7322_EVENT_PHACHG 0x10 114#define CH7322_EVENT_ACTST 0x08 115#define CH7322_EVENT_PHARDY 0x04 116#define CH7322_EVENT_BSOK 0x02 117#define CH7322_EVENT_ERRADCF 0x01 118 119#define CH7322_DID 0x51 120#define CH7322_DID_CH7322 0x5b 121#define CH7322_DID_CH7323 0x5f 122 123#define CH7322_REVISIONID 0x52 124 125#define CH7322_PARH 0x53 126#define CH7322_PARL 0x54 127 128#define CH7322_IOCFG2 0x75 129#define CH7322_IOCFG_CIO 0x80 130#define CH7322_IOCFG_IOCFGMASK 0x78 131#define CH7322_IOCFG_AUDIO 0x04 132#define CH7322_IOCFG_SPAMST 0x02 133#define CH7322_IOCFG_SPAMSP 0x01 134 135#define CH7322_CTL3 0x7b 136#define CH7322_CTL3_SWENA 0x80 137#define CH7322_CTL3_FC_INIT 0x40 138#define CH7322_CTL3_SML_FL 0x20 139#define CH7322_CTL3_SM_RDST 0x10 140#define CH7322_CTL3_SPP_CIAH 0x08 141#define CH7322_CTL3_SPP_CIAL 0x04 142#define CH7322_CTL3_SPP_ACTH 0x02 143#define CH7322_CTL3_SPP_ACTL 0x01 144 145/* BOK status means NACK */ 146#define CH7322_TX_FLAG_NACK BIT(0) 147/* Device will retry automatically */ 148#define CH7322_TX_FLAG_RETRY BIT(1) 149 150struct ch7322 { 151 struct i2c_client *i2c; 152 struct regmap *regmap; 153 struct cec_adapter *cec; 154 struct mutex mutex; /* device access mutex */ 155 u8 tx_flags; 156}; 157 158static const struct regmap_config ch7322_regmap = { 159 .reg_bits = 8, 160 .val_bits = 8, 161 .max_register = 0x7f, 162 .disable_locking = true, 163}; 164 165static int ch7322_send_message(struct ch7322 *ch7322, const struct cec_msg *msg) 166{ 167 unsigned int val; 168 unsigned int len = msg->len; 169 int ret; 170 int i; 171 172 WARN_ON(!mutex_is_locked(&ch7322->mutex)); 173 174 if (len > CH7322_WRBUF_LEN || len < 1) 175 return -EINVAL; 176 177 ret = regmap_read(ch7322->regmap, CH7322_WRITE, &val); 178 if (ret) 179 return ret; 180 181 /* Buffer not ready */ 182 if (!(val & CH7322_WRITE_MSENT)) 183 return -EBUSY; 184 185 if (cec_msg_opcode(msg) == -1 && 186 cec_msg_initiator(msg) == cec_msg_destination(msg)) { 187 ch7322->tx_flags = CH7322_TX_FLAG_NACK | CH7322_TX_FLAG_RETRY; 188 } else if (cec_msg_is_broadcast(msg)) { 189 ch7322->tx_flags = CH7322_TX_FLAG_NACK; 190 } else { 191 ch7322->tx_flags = CH7322_TX_FLAG_RETRY; 192 } 193 194 ret = regmap_write(ch7322->regmap, CH7322_WRITE, len - 1); 195 if (ret) 196 return ret; 197 198 for (i = 0; i < len; i++) { 199 ret = regmap_write(ch7322->regmap, 200 CH7322_WRBUF + i, msg->msg[i]); 201 if (ret) 202 return ret; 203 } 204 205 return 0; 206} 207 208static int ch7322_receive_message(struct ch7322 *ch7322, struct cec_msg *msg) 209{ 210 unsigned int val; 211 int ret = 0; 212 int i; 213 214 WARN_ON(!mutex_is_locked(&ch7322->mutex)); 215 216 ret = regmap_read(ch7322->regmap, CH7322_READ, &val); 217 if (ret) 218 return ret; 219 220 /* Message not ready */ 221 if (!(val & CH7322_READ_NRDT)) 222 return -EIO; 223 224 msg->len = (val & CH7322_READ_NMASK) + 1; 225 226 /* Read entire RDBUF to clear state */ 227 for (i = 0; i < CH7322_RDBUF_LEN; i++) { 228 ret = regmap_read(ch7322->regmap, CH7322_RDBUF + i, &val); 229 if (ret) 230 return ret; 231 msg->msg[i] = (u8)val; 232 } 233 234 return 0; 235} 236 237static void ch7322_tx_done(struct ch7322 *ch7322) 238{ 239 int ret; 240 unsigned int val; 241 u8 status, flags; 242 243 mutex_lock(&ch7322->mutex); 244 ret = regmap_read(ch7322->regmap, CH7322_WRITE, &val); 245 flags = ch7322->tx_flags; 246 mutex_unlock(&ch7322->mutex); 247 248 /* 249 * The device returns a one-bit OK status which usually means ACK but 250 * actually means NACK when sending a logical address query or a 251 * broadcast. 252 */ 253 if (ret) 254 status = CEC_TX_STATUS_ERROR; 255 else if ((val & CH7322_WRITE_BOK) && (flags & CH7322_TX_FLAG_NACK)) 256 status = CEC_TX_STATUS_NACK; 257 else if (val & CH7322_WRITE_BOK) 258 status = CEC_TX_STATUS_OK; 259 else if (flags & CH7322_TX_FLAG_NACK) 260 status = CEC_TX_STATUS_OK; 261 else 262 status = CEC_TX_STATUS_NACK; 263 264 if (status == CEC_TX_STATUS_NACK && (flags & CH7322_TX_FLAG_RETRY)) 265 status |= CEC_TX_STATUS_MAX_RETRIES; 266 267 cec_transmit_attempt_done(ch7322->cec, status); 268} 269 270static void ch7322_rx_done(struct ch7322 *ch7322) 271{ 272 struct cec_msg msg; 273 int ret; 274 275 mutex_lock(&ch7322->mutex); 276 ret = ch7322_receive_message(ch7322, &msg); 277 mutex_unlock(&ch7322->mutex); 278 279 if (ret) 280 dev_err(&ch7322->i2c->dev, "cec receive error: %d\n", ret); 281 else 282 cec_received_msg(ch7322->cec, &msg); 283} 284 285/* 286 * This device can either monitor the DDC lines to obtain the physical address 287 * or it can allow the host to program it. This driver lets the device obtain 288 * it. 289 */ 290static void ch7322_phys_addr(struct ch7322 *ch7322) 291{ 292 unsigned int pah, pal; 293 int ret = 0; 294 295 mutex_lock(&ch7322->mutex); 296 ret |= regmap_read(ch7322->regmap, CH7322_PARH, &pah); 297 ret |= regmap_read(ch7322->regmap, CH7322_PARL, &pal); 298 mutex_unlock(&ch7322->mutex); 299 300 if (ret) 301 dev_err(&ch7322->i2c->dev, "phys addr error\n"); 302 else 303 cec_s_phys_addr(ch7322->cec, pal | (pah << 8), false); 304} 305 306static irqreturn_t ch7322_irq(int irq, void *dev) 307{ 308 struct ch7322 *ch7322 = dev; 309 unsigned int data = 0; 310 311 mutex_lock(&ch7322->mutex); 312 regmap_read(ch7322->regmap, CH7322_INTDATA, &data); 313 regmap_write(ch7322->regmap, CH7322_INTDATA, data); 314 mutex_unlock(&ch7322->mutex); 315 316 if (data & CH7322_INTDATA_HPDFALL) 317 cec_phys_addr_invalidate(ch7322->cec); 318 319 if (data & CH7322_INTDATA_TXMSG) 320 ch7322_tx_done(ch7322); 321 322 if (data & CH7322_INTDATA_RXMSG) 323 ch7322_rx_done(ch7322); 324 325 if (data & CH7322_INTDATA_NEWPHA) 326 ch7322_phys_addr(ch7322); 327 328 if (data & CH7322_INTDATA_ERROR) 329 dev_dbg(&ch7322->i2c->dev, "unknown error\n"); 330 331 return IRQ_HANDLED; 332} 333 334/* This device is always enabled */ 335static int ch7322_cec_adap_enable(struct cec_adapter *adap, bool enable) 336{ 337 return 0; 338} 339 340static int ch7322_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) 341{ 342 struct ch7322 *ch7322 = cec_get_drvdata(adap); 343 int ret; 344 345 mutex_lock(&ch7322->mutex); 346 ret = regmap_update_bits(ch7322->regmap, CH7322_ADDLW, 347 CH7322_ADDLW_MASK, log_addr << 4); 348 mutex_unlock(&ch7322->mutex); 349 350 return ret; 351} 352 353static int ch7322_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, 354 u32 signal_free_time, struct cec_msg *msg) 355{ 356 struct ch7322 *ch7322 = cec_get_drvdata(adap); 357 int ret; 358 359 mutex_lock(&ch7322->mutex); 360 ret = ch7322_send_message(ch7322, msg); 361 mutex_unlock(&ch7322->mutex); 362 363 return ret; 364} 365 366static const struct cec_adap_ops ch7322_cec_adap_ops = { 367 .adap_enable = ch7322_cec_adap_enable, 368 .adap_log_addr = ch7322_cec_adap_log_addr, 369 .adap_transmit = ch7322_cec_adap_transmit, 370}; 371 372#if IS_ENABLED(CONFIG_PCI) && IS_ENABLED(CONFIG_DMI) 373 374struct ch7322_conn_match { 375 const char *dev_name; 376 const char *pci_name; 377 const char *port_name; 378}; 379 380static struct ch7322_conn_match google_endeavour[] = { 381 { "i2c-PRP0001:00", "0000:00:02.0", "Port B" }, 382 { "i2c-PRP0001:01", "0000:00:02.0", "Port C" }, 383 { }, 384}; 385 386static const struct dmi_system_id ch7322_dmi_table[] = { 387 { 388 .matches = { 389 DMI_MATCH(DMI_BOARD_VENDOR, "Google"), 390 DMI_MATCH(DMI_BOARD_NAME, "Endeavour"), 391 }, 392 .driver_data = google_endeavour, 393 }, 394 { }, 395}; 396 397/* Make a best-effort attempt to locate a matching HDMI port */ 398static int ch7322_get_port(struct i2c_client *client, 399 struct device **dev, 400 const char **port) 401{ 402 const struct dmi_system_id *system; 403 const struct ch7322_conn_match *conn; 404 405 *dev = NULL; 406 *port = NULL; 407 408 system = dmi_first_match(ch7322_dmi_table); 409 if (!system) 410 return 0; 411 412 for (conn = system->driver_data; conn->dev_name; conn++) { 413 if (!strcmp(dev_name(&client->dev), conn->dev_name)) { 414 struct device *d; 415 416 d = bus_find_device_by_name(&pci_bus_type, NULL, 417 conn->pci_name); 418 if (!d) 419 return -EPROBE_DEFER; 420 421 put_device(d); 422 423 *dev = d; 424 *port = conn->port_name; 425 426 return 0; 427 } 428 } 429 430 return 0; 431} 432 433#else 434 435static int ch7322_get_port(struct i2c_client *client, 436 struct device **dev, 437 const char **port) 438{ 439 *dev = NULL; 440 *port = NULL; 441 442 return 0; 443} 444 445#endif 446 447static int ch7322_probe(struct i2c_client *client) 448{ 449 struct device *hdmi_dev; 450 const char *port_name; 451 struct ch7322 *ch7322; 452 struct cec_notifier *notifier = NULL; 453 u32 caps = CEC_CAP_DEFAULTS; 454 int ret; 455 unsigned int val; 456 457 ret = ch7322_get_port(client, &hdmi_dev, &port_name); 458 if (ret) 459 return ret; 460 461 if (hdmi_dev) 462 caps |= CEC_CAP_CONNECTOR_INFO; 463 464 ch7322 = devm_kzalloc(&client->dev, sizeof(*ch7322), GFP_KERNEL); 465 if (!ch7322) 466 return -ENOMEM; 467 468 ch7322->regmap = devm_regmap_init_i2c(client, &ch7322_regmap); 469 if (IS_ERR(ch7322->regmap)) 470 return PTR_ERR(ch7322->regmap); 471 472 ret = regmap_read(ch7322->regmap, CH7322_DID, &val); 473 if (ret) 474 return ret; 475 476 if (val != CH7322_DID_CH7322) 477 return -EOPNOTSUPP; 478 479 mutex_init(&ch7322->mutex); 480 ch7322->i2c = client; 481 ch7322->tx_flags = 0; 482 483 i2c_set_clientdata(client, ch7322); 484 485 /* Disable auto mode */ 486 ret = regmap_write(ch7322->regmap, CH7322_MODE, CH7322_MODE_SW); 487 if (ret) 488 goto err_mutex; 489 490 /* Enable logical address register */ 491 ret = regmap_update_bits(ch7322->regmap, CH7322_CTL, 492 CH7322_CTL_SPADL, CH7322_CTL_SPADL); 493 if (ret) 494 goto err_mutex; 495 496 ch7322->cec = cec_allocate_adapter(&ch7322_cec_adap_ops, ch7322, 497 dev_name(&client->dev), 498 caps, 1); 499 500 if (IS_ERR(ch7322->cec)) { 501 ret = PTR_ERR(ch7322->cec); 502 goto err_mutex; 503 } 504 505 ch7322->cec->adap_controls_phys_addr = true; 506 507 if (hdmi_dev) { 508 notifier = cec_notifier_cec_adap_register(hdmi_dev, 509 port_name, 510 ch7322->cec); 511 if (!notifier) { 512 ret = -ENOMEM; 513 goto err_cec; 514 } 515 } 516 517 /* Configure, mask, and clear interrupt */ 518 ret = regmap_write(ch7322->regmap, CH7322_CFG1, 0); 519 if (ret) 520 goto err_notifier; 521 ret = regmap_write(ch7322->regmap, CH7322_INTCTL, CH7322_INTCTL_INTPB); 522 if (ret) 523 goto err_notifier; 524 ret = regmap_write(ch7322->regmap, CH7322_INTDATA, 0xff); 525 if (ret) 526 goto err_notifier; 527 528 /* If HPD is up read physical address */ 529 ret = regmap_read(ch7322->regmap, CH7322_ADDLR, &val); 530 if (ret) 531 goto err_notifier; 532 if (val & CH7322_ADDLR_HPD) 533 ch7322_phys_addr(ch7322); 534 535 ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, 536 ch7322_irq, 537 IRQF_ONESHOT | IRQF_TRIGGER_RISING, 538 client->name, ch7322); 539 if (ret) 540 goto err_notifier; 541 542 /* Unmask interrupt */ 543 mutex_lock(&ch7322->mutex); 544 ret = regmap_write(ch7322->regmap, CH7322_INTCTL, 0xff); 545 mutex_unlock(&ch7322->mutex); 546 547 if (ret) 548 goto err_notifier; 549 550 ret = cec_register_adapter(ch7322->cec, &client->dev); 551 if (ret) 552 goto err_notifier; 553 554 dev_info(&client->dev, "device registered\n"); 555 556 return 0; 557 558err_notifier: 559 if (notifier) 560 cec_notifier_cec_adap_unregister(notifier, ch7322->cec); 561err_cec: 562 cec_delete_adapter(ch7322->cec); 563err_mutex: 564 mutex_destroy(&ch7322->mutex); 565 return ret; 566} 567 568static int ch7322_remove(struct i2c_client *client) 569{ 570 struct ch7322 *ch7322 = i2c_get_clientdata(client); 571 572 /* Mask interrupt */ 573 mutex_lock(&ch7322->mutex); 574 regmap_write(ch7322->regmap, CH7322_INTCTL, CH7322_INTCTL_INTPB); 575 mutex_unlock(&ch7322->mutex); 576 577 cec_unregister_adapter(ch7322->cec); 578 mutex_destroy(&ch7322->mutex); 579 580 dev_info(&client->dev, "device unregistered\n"); 581 582 return 0; 583} 584 585static const struct of_device_id ch7322_of_match[] = { 586 { .compatible = "chrontel,ch7322", }, 587 {}, 588}; 589MODULE_DEVICE_TABLE(of, ch7322_of_match); 590 591static struct i2c_driver ch7322_i2c_driver = { 592 .driver = { 593 .name = "ch7322", 594 .of_match_table = of_match_ptr(ch7322_of_match), 595 }, 596 .probe_new = ch7322_probe, 597 .remove = ch7322_remove, 598}; 599 600module_i2c_driver(ch7322_i2c_driver); 601 602MODULE_DESCRIPTION("Chrontel CH7322 CEC Controller Driver"); 603MODULE_AUTHOR("Jeff Chase <jnchase@google.com>"); 604MODULE_LICENSE("GPL");