| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From ed9e7a6b3346b186a7bd22d9b62072e55ff7b9c5 Mon Sep 17 00:00:00 2001 |
| 2 | From: Sandor Yu <Sandor.yu@nxp.com> |
| 3 | Date: Mon, 2 Sep 2019 14:57:05 +0800 |
| 4 | Subject: [PATCH] drm: bridge: cadence: Add CEC driver for cdns mhdp hdmi |
| 5 | |
| 6 | Add cec driver for cdns mhdp hdmi. |
| 7 | |
| 8 | Signed-off-by: Sandor Yu <Sandor.yu@nxp.com> |
| 9 | --- |
| 10 | drivers/gpu/drm/bridge/cadence/Kconfig | 3 + |
| 11 | drivers/gpu/drm/bridge/cadence/Makefile | 1 + |
| 12 | drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 0 |
| 13 | drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 9 + |
| 14 | drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c | 347 ++++++++++++++++++++++ |
| 15 | drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 0 |
| 16 | drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c | 0 |
| 17 | include/drm/bridge/cdns-mhdp-common.h | 24 +- |
| 18 | 8 files changed, 382 insertions(+), 2 deletions(-) |
| 19 | mode change 100755 => 100644 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c |
| 20 | mode change 100755 => 100644 drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c |
| 21 | create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c |
| 22 | mode change 100755 => 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c |
| 23 | mode change 100755 => 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c |
| 24 | |
| 25 | --- a/drivers/gpu/drm/bridge/cadence/Kconfig |
| 26 | +++ b/drivers/gpu/drm/bridge/cadence/Kconfig |
| 27 | @@ -14,3 +14,6 @@ config DRM_CDNS_DP |
| 28 | |
| 29 | config DRM_CDNS_AUDIO |
| 30 | tristate "Cadence MHDP Audio driver" |
| 31 | + |
| 32 | +config DRM_CDNS_HDMI_CEC |
| 33 | + tristate "Cadence MHDP HDMI CEC driver" |
| 34 | --- a/drivers/gpu/drm/bridge/cadence/Makefile |
| 35 | +++ b/drivers/gpu/drm/bridge/cadence/Makefile |
| 36 | @@ -2,3 +2,4 @@ obj-$(CONFIG_DRM_CDNS_MHDP) += cdns-mhdp |
| 37 | obj-$(CONFIG_DRM_CDNS_HDMI) += cdns-hdmi-core.o |
| 38 | obj-$(CONFIG_DRM_CDNS_DP) += cdns-dp-core.o |
| 39 | obj-$(CONFIG_DRM_CDNS_AUDIO) += cdns-mhdp-audio.o |
| 40 | +obj-$(CONFIG_DRM_CDNS_HDMI_CEC) += cdns-mhdp-cec.o |
| 41 | --- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c |
| 42 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c |
| 43 | @@ -515,6 +515,11 @@ __cdns_hdmi_probe(struct platform_device |
| 44 | /* register audio driver */ |
| 45 | cdns_mhdp_register_audio_driver(dev); |
| 46 | |
| 47 | + /* register cec driver */ |
| 48 | +#ifdef CONFIG_DRM_CDNS_HDMI_CEC |
| 49 | + cdns_mhdp_register_cec_driver(dev); |
| 50 | +#endif |
| 51 | + |
| 52 | return hdmi; |
| 53 | |
| 54 | err_out: |
| 55 | @@ -524,6 +529,10 @@ err_out: |
| 56 | |
| 57 | static void __cdns_hdmi_remove(struct cdns_mhdp_device *mhdp) |
| 58 | { |
| 59 | + /* unregister cec driver */ |
| 60 | +#ifdef CONFIG_DRM_CDNS_HDMI_CEC |
| 61 | + cdns_mhdp_unregister_cec_driver(mhdp->dev); |
| 62 | +#endif |
| 63 | cdns_mhdp_unregister_audio_driver(mhdp->dev); |
| 64 | } |
| 65 | |
| 66 | --- /dev/null |
| 67 | +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c |
| 68 | @@ -0,0 +1,347 @@ |
| 69 | +/* |
| 70 | + * Copyright 2019 NXP |
| 71 | + * |
| 72 | + * This program is free software; you can redistribute it and/or |
| 73 | + * modify it under the terms of the GNU General Public License |
| 74 | + * as published by the Free Software Foundation; either version 2 |
| 75 | + * of the License, or (at your option) any later version. |
| 76 | + * |
| 77 | + * This program is distributed in the hope that it will be useful, |
| 78 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 79 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 80 | + * GNU General Public License for more details. |
| 81 | + */ |
| 82 | +#include <linux/module.h> |
| 83 | +#include <linux/workqueue.h> |
| 84 | +#include <linux/kthread.h> |
| 85 | +#include <linux/freezer.h> |
| 86 | +#include <drm/bridge/cdns-mhdp-common.h> |
| 87 | + |
| 88 | +#define CEC_NAME "cdns-mhdp-cec" |
| 89 | + |
| 90 | +#define REG_ADDR_OFF 4 |
| 91 | +#define MAX_LA_IDX 4 |
| 92 | +#define MAX_LA_VAL 15 |
| 93 | + |
| 94 | +/* regsiter define */ |
| 95 | +#define TX_MSG_HEADER 0x33800 |
| 96 | +#define TX_MSG_LENGTH 0x33840 |
| 97 | +#define TX_MSG_CMD 0x33844 |
| 98 | +#define RX_MSG_CMD 0x33850 |
| 99 | +#define RX_CLEAR_BUF 0x33854 |
| 100 | +#define LOGICAL_ADDRESS_LA0 0x33858 |
| 101 | + |
| 102 | +#define CLK_DIV_MSB 0x3386c |
| 103 | +#define CLK_DIV_LSB 0x33870 |
| 104 | +#define RX_MSG_DATA1 0x33900 |
| 105 | +#define RX_MSG_LENGTH 0x33940 |
| 106 | +#define RX_MSG_STATUS 0x33944 |
| 107 | +#define NUM_OF_MSG_RX_BUF 0x33948 |
| 108 | +#define TX_MSG_STATUS 0x3394c |
| 109 | +#define DB_L_TIMER 0x33980 |
| 110 | + |
| 111 | +/** |
| 112 | + * CEC Transceiver operation. |
| 113 | + */ |
| 114 | +enum { |
| 115 | + CEC_TX_STOP, |
| 116 | + CEC_TX_TRANSMIT, |
| 117 | + CEC_TX_ABORT, |
| 118 | + CEC_TX_ABORT_AND_TRANSMIT |
| 119 | +}; |
| 120 | + |
| 121 | +/** |
| 122 | + * CEC Transceiver status. |
| 123 | + */ |
| 124 | +enum { |
| 125 | + CEC_STS_IDLE, |
| 126 | + CEC_STS_BUSY, |
| 127 | + CEC_STS_SUCCESS, |
| 128 | + CEC_STS_ERROR |
| 129 | +}; |
| 130 | + |
| 131 | +/** |
| 132 | + * CEC Receiver operation. |
| 133 | + */ |
| 134 | +enum { |
| 135 | + CEC_RX_STOP, |
| 136 | + CEC_RX_READ, |
| 137 | + CEC_RX_DISABLE, |
| 138 | + CEC_RX_ABORT_AND_CLR_FIFO |
| 139 | +}; |
| 140 | +/** |
| 141 | + * Maximum number of Messages in the RX Buffers. |
| 142 | + */ |
| 143 | +#define CEC_MAX_RX_MSGS 2 |
| 144 | + |
| 145 | +static u32 mhdp_cec_read(struct cdns_mhdp_cec *cec, u32 offset) |
| 146 | +{ |
| 147 | + struct cdns_mhdp_device *mhdp = |
| 148 | + container_of(cec, struct cdns_mhdp_device, hdmi.cec); |
| 149 | + return cdns_mhdp_bus_read(mhdp, offset); |
| 150 | +} |
| 151 | + |
| 152 | +static void mhdp_cec_write(struct cdns_mhdp_cec *cec, u32 offset, u32 val) |
| 153 | +{ |
| 154 | + struct cdns_mhdp_device *mhdp = |
| 155 | + container_of(cec, struct cdns_mhdp_device, hdmi.cec); |
| 156 | + cdns_mhdp_bus_write(val, mhdp, offset); |
| 157 | +} |
| 158 | + |
| 159 | +static void mhdp_cec_clear_rx_buffer(struct cdns_mhdp_cec *cec) |
| 160 | +{ |
| 161 | + mhdp_cec_write(cec, RX_CLEAR_BUF, 1); |
| 162 | + mhdp_cec_write(cec, RX_CLEAR_BUF, 0); |
| 163 | +} |
| 164 | + |
| 165 | +static void mhdp_cec_set_divider(struct cdns_mhdp_cec *cec) |
| 166 | +{ |
| 167 | + struct cdns_mhdp_device *mhdp = |
| 168 | + container_of(cec, struct cdns_mhdp_device, hdmi.cec); |
| 169 | + u32 clk_div; |
| 170 | + |
| 171 | + /* Set clock divider */ |
| 172 | + clk_div = cdns_mhdp_get_fw_clk(mhdp) * 10; |
| 173 | + |
| 174 | + mhdp_cec_write(cec, CLK_DIV_MSB, |
| 175 | + (clk_div >> 8) & 0xFF); |
| 176 | + mhdp_cec_write(cec, CLK_DIV_LSB, clk_div & 0xFF); |
| 177 | +} |
| 178 | + |
| 179 | +static u32 mhdp_cec_read_message(struct cdns_mhdp_cec *cec) |
| 180 | +{ |
| 181 | + struct cec_msg *msg = &cec->msg; |
| 182 | + int len; |
| 183 | + int i; |
| 184 | + |
| 185 | + mhdp_cec_write(cec, RX_MSG_CMD, CEC_RX_READ); |
| 186 | + |
| 187 | + len = mhdp_cec_read(cec, RX_MSG_LENGTH); |
| 188 | + msg->len = len + 1; |
| 189 | + dev_dbg(cec->dev, "RX MSG len =%d\n", len); |
| 190 | + |
| 191 | + /* Read RX MSG bytes */ |
| 192 | + for (i = 0; i < msg->len; ++i) { |
| 193 | + msg->msg[i] = (u8) mhdp_cec_read(cec, RX_MSG_DATA1 + (i * REG_ADDR_OFF)); |
| 194 | + dev_dbg(cec->dev, "RX MSG[%d]=0x%x\n", i, msg->msg[i]); |
| 195 | + } |
| 196 | + |
| 197 | + mhdp_cec_write(cec, RX_MSG_CMD, CEC_RX_STOP); |
| 198 | + |
| 199 | + return true; |
| 200 | +} |
| 201 | + |
| 202 | +static u32 mhdp_cec_write_message(struct cdns_mhdp_cec *cec, struct cec_msg *msg) |
| 203 | +{ |
| 204 | + u8 i; |
| 205 | + |
| 206 | + mhdp_cec_write(cec, TX_MSG_CMD, CEC_TX_STOP); |
| 207 | + |
| 208 | + if (msg->len > CEC_MAX_MSG_SIZE) { |
| 209 | + dev_err(cec->dev, "Invalid MSG size!\n"); |
| 210 | + return -EINVAL; |
| 211 | + } |
| 212 | + |
| 213 | + for (i = 0; i < msg->len; ++i) |
| 214 | + printk("msg[%d]=0x%x\n",i, msg->msg[i]); |
| 215 | + |
| 216 | + /* Write Message to register */ |
| 217 | + for (i = 0; i < msg->len; ++i) { |
| 218 | + mhdp_cec_write(cec, TX_MSG_HEADER + (i * REG_ADDR_OFF), |
| 219 | + msg->msg[i]); |
| 220 | + } |
| 221 | + /* Write Message Length (payload + opcode) */ |
| 222 | + mhdp_cec_write(cec, TX_MSG_LENGTH, msg->len - 1); |
| 223 | + |
| 224 | + mhdp_cec_write(cec, TX_MSG_CMD, CEC_TX_TRANSMIT); |
| 225 | + |
| 226 | + return true; |
| 227 | +} |
| 228 | + |
| 229 | +//static void cec_abort_tx_transfer(struct cdns_mhdp_cec *cec) |
| 230 | +//{ |
| 231 | +// cec_write(cec, TX_MSG_CMD, CEC_TX_ABORT); |
| 232 | +// cec_write(cec, TX_MSG_CMD, CEC_TX_STOP); |
| 233 | +//} |
| 234 | + |
| 235 | +static int mhdp_cec_set_logical_addr(struct cdns_mhdp_cec *cec, u32 la) |
| 236 | +{ |
| 237 | + u8 i; |
| 238 | + u8 la_reg; |
| 239 | + |
| 240 | + if (la >= MAX_LA_VAL) { |
| 241 | + dev_err(cec->dev, "Error logical Addr\n"); |
| 242 | + return -EINVAL; |
| 243 | + } |
| 244 | + |
| 245 | + for (i = 0; i < MAX_LA_IDX; ++i) { |
| 246 | + la_reg = |
| 247 | + mhdp_cec_read(cec, LOGICAL_ADDRESS_LA0 + (i * REG_ADDR_OFF)); |
| 248 | + |
| 249 | + if (la_reg & 0x10) |
| 250 | + continue; |
| 251 | + |
| 252 | + if ((la_reg & 0xF) == la) { |
| 253 | + dev_warn(cec->dev, "Warning. LA already in use.\n"); |
| 254 | + return true; |
| 255 | + } |
| 256 | + |
| 257 | + la = (la & 0xF) | (1 << 4); |
| 258 | + |
| 259 | + mhdp_cec_write(cec, LOGICAL_ADDRESS_LA0 + (i * REG_ADDR_OFF), la); |
| 260 | + return true; |
| 261 | + } |
| 262 | + |
| 263 | + dev_warn(cec->dev, "All LA in use\n"); |
| 264 | + |
| 265 | + return false; |
| 266 | +} |
| 267 | + |
| 268 | +static int mhdp_cec_poll_worker(void *_cec) |
| 269 | +{ |
| 270 | + struct cdns_mhdp_cec *cec = (struct cdns_mhdp_cec *)_cec; |
| 271 | + int num_rx_msgs, i; |
| 272 | + int sts; |
| 273 | + |
| 274 | + set_freezable(); |
| 275 | + |
| 276 | + for (;;) { |
| 277 | + if (kthread_freezable_should_stop(NULL)) |
| 278 | + break; |
| 279 | + |
| 280 | + /* Check TX State */ |
| 281 | + sts = mhdp_cec_read(cec, TX_MSG_STATUS); |
| 282 | + switch (sts) { |
| 283 | + case CEC_STS_SUCCESS: |
| 284 | + cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, |
| 285 | + 0); |
| 286 | + mhdp_cec_write(cec, TX_MSG_CMD, CEC_TX_STOP); |
| 287 | + break; |
| 288 | + case CEC_STS_ERROR: |
| 289 | + mhdp_cec_write(cec, TX_MSG_CMD, CEC_TX_STOP); |
| 290 | + cec_transmit_done(cec->adap, |
| 291 | + CEC_TX_STATUS_MAX_RETRIES | |
| 292 | + CEC_TX_STATUS_NACK, 0, 1, 0, 0); |
| 293 | + break; |
| 294 | + case CEC_STS_BUSY: |
| 295 | + default: |
| 296 | + break; |
| 297 | + } |
| 298 | + |
| 299 | + /* Check RX State */ |
| 300 | + sts = mhdp_cec_read(cec, RX_MSG_STATUS); |
| 301 | + num_rx_msgs = mhdp_cec_read(cec, NUM_OF_MSG_RX_BUF); |
| 302 | + switch (sts) { |
| 303 | + case CEC_STS_SUCCESS: |
| 304 | + if (num_rx_msgs == 0xf) |
| 305 | + num_rx_msgs = CEC_MAX_RX_MSGS; |
| 306 | + |
| 307 | + if (num_rx_msgs > CEC_MAX_RX_MSGS) { |
| 308 | + dev_err(cec->dev, "Error rx msg num %d\n", |
| 309 | + num_rx_msgs); |
| 310 | + mhdp_cec_clear_rx_buffer(cec); |
| 311 | + break; |
| 312 | + } |
| 313 | + |
| 314 | + /* Rx FIFO Depth 2 RX MSG */ |
| 315 | + for (i = 0; i < num_rx_msgs; i++) { |
| 316 | + mhdp_cec_read_message(cec); |
| 317 | + cec->msg.rx_status = CEC_RX_STATUS_OK; |
| 318 | + cec_received_msg(cec->adap, &cec->msg); |
| 319 | + } |
| 320 | + break; |
| 321 | + default: |
| 322 | + break; |
| 323 | + } |
| 324 | + |
| 325 | + if (!kthread_should_stop()) |
| 326 | + schedule_timeout_idle(20); |
| 327 | + } |
| 328 | + |
| 329 | + return 0; |
| 330 | +} |
| 331 | + |
| 332 | +static int mhdp_cec_adap_enable(struct cec_adapter *adap, bool enable) |
| 333 | +{ |
| 334 | + struct cdns_mhdp_cec *cec = adap->priv; |
| 335 | + |
| 336 | + if (enable) { |
| 337 | + mhdp_cec_write(cec, DB_L_TIMER, 0x10); |
| 338 | + mhdp_cec_set_divider(cec); |
| 339 | + } else |
| 340 | + mhdp_cec_set_divider(cec); |
| 341 | + |
| 342 | + return 0; |
| 343 | +} |
| 344 | + |
| 345 | +static int mhdp_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) |
| 346 | +{ |
| 347 | + struct cdns_mhdp_cec *cec = adap->priv; |
| 348 | + |
| 349 | + return mhdp_cec_set_logical_addr(cec, addr); |
| 350 | +} |
| 351 | + |
| 352 | +static int mhdp_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, |
| 353 | + u32 signal_free_time, struct cec_msg *msg) |
| 354 | +{ |
| 355 | + struct cdns_mhdp_cec *cec = adap->priv; |
| 356 | + |
| 357 | + mhdp_cec_write_message(cec, msg); |
| 358 | + |
| 359 | + return 0; |
| 360 | +} |
| 361 | + |
| 362 | +static const struct cec_adap_ops cdns_mhdp_cec_adap_ops = { |
| 363 | + .adap_enable = mhdp_cec_adap_enable, |
| 364 | + .adap_log_addr = mhdp_cec_adap_log_addr, |
| 365 | + .adap_transmit = mhdp_cec_adap_transmit, |
| 366 | +}; |
| 367 | + |
| 368 | +int cdns_mhdp_register_cec_driver(struct device *dev) |
| 369 | +{ |
| 370 | + struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); |
| 371 | + struct cdns_mhdp_cec *cec = &mhdp->hdmi.cec; |
| 372 | + int ret; |
| 373 | + |
| 374 | + cec->adap = cec_allocate_adapter(&cdns_mhdp_cec_adap_ops, cec, |
| 375 | + CEC_NAME, |
| 376 | + CEC_CAP_PHYS_ADDR | CEC_CAP_LOG_ADDRS | |
| 377 | + CEC_CAP_TRANSMIT | CEC_CAP_PASSTHROUGH |
| 378 | + | CEC_CAP_RC, 1); |
| 379 | + ret = PTR_ERR_OR_ZERO(cec->adap); |
| 380 | + if (ret) |
| 381 | + return ret; |
| 382 | + ret = cec_register_adapter(cec->adap, dev); |
| 383 | + if (ret) { |
| 384 | + cec_delete_adapter(cec->adap); |
| 385 | + return ret; |
| 386 | + } |
| 387 | + |
| 388 | + cec->dev = dev; |
| 389 | + |
| 390 | + cec->cec_worker = kthread_create(mhdp_cec_poll_worker, cec, "cdns-mhdp-cec"); |
| 391 | + if (IS_ERR(cec->cec_worker)) |
| 392 | + dev_err(cec->dev, "failed create hdp cec thread\n"); |
| 393 | + |
| 394 | + wake_up_process(cec->cec_worker); |
| 395 | + |
| 396 | + dev_dbg(dev, "CEC successfuly probed\n"); |
| 397 | + return 0; |
| 398 | +} |
| 399 | + |
| 400 | +int cdns_mhdp_unregister_cec_driver(struct device *dev) |
| 401 | +{ |
| 402 | + struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); |
| 403 | + struct cdns_mhdp_cec *cec = &mhdp->hdmi.cec; |
| 404 | + |
| 405 | + if (cec->cec_worker) { |
| 406 | + kthread_stop(cec->cec_worker); |
| 407 | + cec->cec_worker = NULL; |
| 408 | + } |
| 409 | + cec_unregister_adapter(cec->adap); |
| 410 | + return 0; |
| 411 | +} |
| 412 | + |
| 413 | +MODULE_AUTHOR("Sandor.Yu@NXP.com"); |
| 414 | +MODULE_LICENSE("GPL"); |
| 415 | +MODULE_DESCRIPTION("NXP CDNS MHDP CEC driver"); |
| 416 | --- a/include/drm/bridge/cdns-mhdp-common.h |
| 417 | +++ b/include/drm/bridge/cdns-mhdp-common.h |
| 418 | @@ -21,7 +21,7 @@ |
| 419 | #include <drm/drm_connector.h> |
| 420 | #include <drm/drm_dp_helper.h> |
| 421 | #include <drm/drm_dp_mst_helper.h> |
| 422 | - |
| 423 | +#include <media/cec.h> |
| 424 | #include <linux/bitops.h> |
| 425 | |
| 426 | #define ADDR_IMEM 0x10000 |
| 427 | @@ -605,6 +605,17 @@ struct cdns_mhdp_connector { |
| 428 | struct cdns_mhdp_bridge *bridge; |
| 429 | }; |
| 430 | |
| 431 | +#ifdef CONFIG_DRM_CDNS_HDMI_CEC |
| 432 | +struct cdns_mhdp_cec { |
| 433 | + struct cec_adapter *adap; |
| 434 | + struct device *dev; |
| 435 | + struct mutex lock; |
| 436 | + |
| 437 | + struct cec_msg msg; |
| 438 | + struct task_struct *cec_worker; |
| 439 | +}; |
| 440 | +#endif |
| 441 | + |
| 442 | struct cdns_mhdp_device { |
| 443 | void __iomem *regs; |
| 444 | |
| 445 | @@ -633,7 +644,7 @@ struct cdns_mhdp_device { |
| 446 | bool plugged; |
| 447 | |
| 448 | union { |
| 449 | - struct cdn_dp_data { |
| 450 | + struct _dp_data { |
| 451 | struct drm_dp_link link; |
| 452 | struct drm_dp_aux aux; |
| 453 | struct cdns_mhdp_host host; |
| 454 | @@ -645,6 +656,9 @@ struct cdns_mhdp_device { |
| 455 | u32 num_lanes; |
| 456 | } dp; |
| 457 | struct _hdmi_data { |
| 458 | +#ifdef CONFIG_DRM_CDNS_HDMI_CEC |
| 459 | + struct cdns_mhdp_cec cec; |
| 460 | +#endif |
| 461 | u32 char_rate; |
| 462 | u32 hdmi_type; |
| 463 | } hdmi; |
| 464 | @@ -713,4 +727,10 @@ int cdns_hdmi_disable_gcp(struct cdns_mh |
| 465 | int cdns_hdmi_enable_gcp(struct cdns_mhdp_device *mhdp); |
| 466 | |
| 467 | bool cdns_mhdp_check_alive(struct cdns_mhdp_device *mhdp); |
| 468 | +/* CEC */ |
| 469 | +#ifdef CONFIG_DRM_CDNS_HDMI_CEC |
| 470 | +int cdns_mhdp_register_cec_driver(struct device *dev); |
| 471 | +int cdns_mhdp_unregister_cec_driver(struct device *dev); |
| 472 | +#endif |
| 473 | + |
| 474 | #endif /* CDNS_MHDP_COMMON_H_ */ |