root/drivers/gpu/drm/zte/zx_hdmi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hdmi_readb
  2. hdmi_writeb
  3. hdmi_writeb_mask
  4. zx_hdmi_infoframe_trans
  5. zx_hdmi_config_video_vsi
  6. zx_hdmi_config_video_avi
  7. zx_hdmi_encoder_mode_set
  8. zx_hdmi_phy_start
  9. zx_hdmi_hw_enable
  10. zx_hdmi_hw_disable
  11. zx_hdmi_encoder_enable
  12. zx_hdmi_encoder_disable
  13. zx_hdmi_connector_get_modes
  14. zx_hdmi_connector_mode_valid
  15. zx_hdmi_connector_detect
  16. zx_hdmi_register
  17. zx_hdmi_irq_thread
  18. zx_hdmi_irq_handler
  19. zx_hdmi_audio_startup
  20. zx_hdmi_audio_shutdown
  21. zx_hdmi_audio_get_n
  22. zx_hdmi_audio_hw_params
  23. zx_hdmi_audio_digital_mute
  24. zx_hdmi_audio_get_eld
  25. zx_hdmi_audio_register
  26. zx_hdmi_i2c_read
  27. zx_hdmi_i2c_write
  28. zx_hdmi_i2c_xfer
  29. zx_hdmi_i2c_func
  30. zx_hdmi_ddc_register
  31. zx_hdmi_bind
  32. zx_hdmi_unbind
  33. zx_hdmi_probe
  34. zx_hdmi_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright 2016 Linaro Ltd.
   4  * Copyright 2016 ZTE Corporation.
   5  */
   6 
   7 #include <linux/clk.h>
   8 #include <linux/component.h>
   9 #include <linux/delay.h>
  10 #include <linux/err.h>
  11 #include <linux/hdmi.h>
  12 #include <linux/irq.h>
  13 #include <linux/mfd/syscon.h>
  14 #include <linux/module.h>
  15 #include <linux/mutex.h>
  16 #include <linux/of_device.h>
  17 
  18 #include <drm/drm_atomic_helper.h>
  19 #include <drm/drm_edid.h>
  20 #include <drm/drm_of.h>
  21 #include <drm/drm_probe_helper.h>
  22 #include <drm/drm_print.h>
  23 
  24 #include <sound/hdmi-codec.h>
  25 
  26 #include "zx_hdmi_regs.h"
  27 #include "zx_vou.h"
  28 
  29 #define ZX_HDMI_INFOFRAME_SIZE          31
  30 #define DDC_SEGMENT_ADDR                0x30
  31 
  32 struct zx_hdmi_i2c {
  33         struct i2c_adapter adap;
  34         struct mutex lock;
  35 };
  36 
  37 struct zx_hdmi {
  38         struct drm_connector connector;
  39         struct drm_encoder encoder;
  40         struct zx_hdmi_i2c *ddc;
  41         struct device *dev;
  42         struct drm_device *drm;
  43         void __iomem *mmio;
  44         struct clk *cec_clk;
  45         struct clk *osc_clk;
  46         struct clk *xclk;
  47         bool sink_is_hdmi;
  48         bool sink_has_audio;
  49         struct platform_device *audio_pdev;
  50 };
  51 
  52 #define to_zx_hdmi(x) container_of(x, struct zx_hdmi, x)
  53 
  54 static inline u8 hdmi_readb(struct zx_hdmi *hdmi, u16 offset)
  55 {
  56         return readl_relaxed(hdmi->mmio + offset * 4);
  57 }
  58 
  59 static inline void hdmi_writeb(struct zx_hdmi *hdmi, u16 offset, u8 val)
  60 {
  61         writel_relaxed(val, hdmi->mmio + offset * 4);
  62 }
  63 
  64 static inline void hdmi_writeb_mask(struct zx_hdmi *hdmi, u16 offset,
  65                                     u8 mask, u8 val)
  66 {
  67         u8 tmp;
  68 
  69         tmp = hdmi_readb(hdmi, offset);
  70         tmp = (tmp & ~mask) | (val & mask);
  71         hdmi_writeb(hdmi, offset, tmp);
  72 }
  73 
  74 static int zx_hdmi_infoframe_trans(struct zx_hdmi *hdmi,
  75                                    union hdmi_infoframe *frame, u8 fsel)
  76 {
  77         u8 buffer[ZX_HDMI_INFOFRAME_SIZE];
  78         int num;
  79         int i;
  80 
  81         hdmi_writeb(hdmi, TPI_INFO_FSEL, fsel);
  82 
  83         num = hdmi_infoframe_pack(frame, buffer, ZX_HDMI_INFOFRAME_SIZE);
  84         if (num < 0) {
  85                 DRM_DEV_ERROR(hdmi->dev, "failed to pack infoframe: %d\n", num);
  86                 return num;
  87         }
  88 
  89         for (i = 0; i < num; i++)
  90                 hdmi_writeb(hdmi, TPI_INFO_B0 + i, buffer[i]);
  91 
  92         hdmi_writeb_mask(hdmi, TPI_INFO_EN, TPI_INFO_TRANS_RPT,
  93                          TPI_INFO_TRANS_RPT);
  94         hdmi_writeb_mask(hdmi, TPI_INFO_EN, TPI_INFO_TRANS_EN,
  95                          TPI_INFO_TRANS_EN);
  96 
  97         return num;
  98 }
  99 
 100 static int zx_hdmi_config_video_vsi(struct zx_hdmi *hdmi,
 101                                     struct drm_display_mode *mode)
 102 {
 103         union hdmi_infoframe frame;
 104         int ret;
 105 
 106         ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi,
 107                                                           &hdmi->connector,
 108                                                           mode);
 109         if (ret) {
 110                 DRM_DEV_ERROR(hdmi->dev, "failed to get vendor infoframe: %d\n",
 111                               ret);
 112                 return ret;
 113         }
 114 
 115         return zx_hdmi_infoframe_trans(hdmi, &frame, FSEL_VSIF);
 116 }
 117 
 118 static int zx_hdmi_config_video_avi(struct zx_hdmi *hdmi,
 119                                     struct drm_display_mode *mode)
 120 {
 121         union hdmi_infoframe frame;
 122         int ret;
 123 
 124         ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
 125                                                        &hdmi->connector,
 126                                                        mode);
 127         if (ret) {
 128                 DRM_DEV_ERROR(hdmi->dev, "failed to get avi infoframe: %d\n",
 129                               ret);
 130                 return ret;
 131         }
 132 
 133         /* We always use YUV444 for HDMI output. */
 134         frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
 135 
 136         return zx_hdmi_infoframe_trans(hdmi, &frame, FSEL_AVI);
 137 }
 138 
 139 static void zx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
 140                                      struct drm_display_mode *mode,
 141                                      struct drm_display_mode *adj_mode)
 142 {
 143         struct zx_hdmi *hdmi = to_zx_hdmi(encoder);
 144 
 145         if (hdmi->sink_is_hdmi) {
 146                 zx_hdmi_config_video_avi(hdmi, mode);
 147                 zx_hdmi_config_video_vsi(hdmi, mode);
 148         }
 149 }
 150 
 151 static void zx_hdmi_phy_start(struct zx_hdmi *hdmi)
 152 {
 153         /* Copy from ZTE BSP code */
 154         hdmi_writeb(hdmi, 0x222, 0x0);
 155         hdmi_writeb(hdmi, 0x224, 0x4);
 156         hdmi_writeb(hdmi, 0x909, 0x0);
 157         hdmi_writeb(hdmi, 0x7b0, 0x90);
 158         hdmi_writeb(hdmi, 0x7b1, 0x00);
 159         hdmi_writeb(hdmi, 0x7b2, 0xa7);
 160         hdmi_writeb(hdmi, 0x7b8, 0xaa);
 161         hdmi_writeb(hdmi, 0x7b2, 0xa7);
 162         hdmi_writeb(hdmi, 0x7b3, 0x0f);
 163         hdmi_writeb(hdmi, 0x7b4, 0x0f);
 164         hdmi_writeb(hdmi, 0x7b5, 0x55);
 165         hdmi_writeb(hdmi, 0x7b7, 0x03);
 166         hdmi_writeb(hdmi, 0x7b9, 0x12);
 167         hdmi_writeb(hdmi, 0x7ba, 0x32);
 168         hdmi_writeb(hdmi, 0x7bc, 0x68);
 169         hdmi_writeb(hdmi, 0x7be, 0x40);
 170         hdmi_writeb(hdmi, 0x7bf, 0x84);
 171         hdmi_writeb(hdmi, 0x7c1, 0x0f);
 172         hdmi_writeb(hdmi, 0x7c8, 0x02);
 173         hdmi_writeb(hdmi, 0x7c9, 0x03);
 174         hdmi_writeb(hdmi, 0x7ca, 0x40);
 175         hdmi_writeb(hdmi, 0x7dc, 0x31);
 176         hdmi_writeb(hdmi, 0x7e2, 0x04);
 177         hdmi_writeb(hdmi, 0x7e0, 0x06);
 178         hdmi_writeb(hdmi, 0x7cb, 0x68);
 179         hdmi_writeb(hdmi, 0x7f9, 0x02);
 180         hdmi_writeb(hdmi, 0x7b6, 0x02);
 181         hdmi_writeb(hdmi, 0x7f3, 0x0);
 182 }
 183 
 184 static void zx_hdmi_hw_enable(struct zx_hdmi *hdmi)
 185 {
 186         /* Enable pclk */
 187         hdmi_writeb_mask(hdmi, CLKPWD, CLKPWD_PDIDCK, CLKPWD_PDIDCK);
 188 
 189         /* Enable HDMI for TX */
 190         hdmi_writeb_mask(hdmi, FUNC_SEL, FUNC_HDMI_EN, FUNC_HDMI_EN);
 191 
 192         /* Enable deep color packet */
 193         hdmi_writeb_mask(hdmi, P2T_CTRL, P2T_DC_PKT_EN, P2T_DC_PKT_EN);
 194 
 195         /* Enable HDMI/MHL mode for output */
 196         hdmi_writeb_mask(hdmi, TEST_TXCTRL, TEST_TXCTRL_HDMI_MODE,
 197                          TEST_TXCTRL_HDMI_MODE);
 198 
 199         /* Configure reg_qc_sel */
 200         hdmi_writeb(hdmi, HDMICTL4, 0x3);
 201 
 202         /* Enable interrupt */
 203         hdmi_writeb_mask(hdmi, INTR1_MASK, INTR1_MONITOR_DETECT,
 204                          INTR1_MONITOR_DETECT);
 205 
 206         /* Start up phy */
 207         zx_hdmi_phy_start(hdmi);
 208 }
 209 
 210 static void zx_hdmi_hw_disable(struct zx_hdmi *hdmi)
 211 {
 212         /* Disable interrupt */
 213         hdmi_writeb_mask(hdmi, INTR1_MASK, INTR1_MONITOR_DETECT, 0);
 214 
 215         /* Disable deep color packet */
 216         hdmi_writeb_mask(hdmi, P2T_CTRL, P2T_DC_PKT_EN, P2T_DC_PKT_EN);
 217 
 218         /* Disable HDMI for TX */
 219         hdmi_writeb_mask(hdmi, FUNC_SEL, FUNC_HDMI_EN, 0);
 220 
 221         /* Disable pclk */
 222         hdmi_writeb_mask(hdmi, CLKPWD, CLKPWD_PDIDCK, 0);
 223 }
 224 
 225 static void zx_hdmi_encoder_enable(struct drm_encoder *encoder)
 226 {
 227         struct zx_hdmi *hdmi = to_zx_hdmi(encoder);
 228 
 229         clk_prepare_enable(hdmi->cec_clk);
 230         clk_prepare_enable(hdmi->osc_clk);
 231         clk_prepare_enable(hdmi->xclk);
 232 
 233         zx_hdmi_hw_enable(hdmi);
 234 
 235         vou_inf_enable(VOU_HDMI, encoder->crtc);
 236 }
 237 
 238 static void zx_hdmi_encoder_disable(struct drm_encoder *encoder)
 239 {
 240         struct zx_hdmi *hdmi = to_zx_hdmi(encoder);
 241 
 242         vou_inf_disable(VOU_HDMI, encoder->crtc);
 243 
 244         zx_hdmi_hw_disable(hdmi);
 245 
 246         clk_disable_unprepare(hdmi->xclk);
 247         clk_disable_unprepare(hdmi->osc_clk);
 248         clk_disable_unprepare(hdmi->cec_clk);
 249 }
 250 
 251 static const struct drm_encoder_helper_funcs zx_hdmi_encoder_helper_funcs = {
 252         .enable = zx_hdmi_encoder_enable,
 253         .disable = zx_hdmi_encoder_disable,
 254         .mode_set = zx_hdmi_encoder_mode_set,
 255 };
 256 
 257 static const struct drm_encoder_funcs zx_hdmi_encoder_funcs = {
 258         .destroy = drm_encoder_cleanup,
 259 };
 260 
 261 static int zx_hdmi_connector_get_modes(struct drm_connector *connector)
 262 {
 263         struct zx_hdmi *hdmi = to_zx_hdmi(connector);
 264         struct edid *edid;
 265         int ret;
 266 
 267         edid = drm_get_edid(connector, &hdmi->ddc->adap);
 268         if (!edid)
 269                 return 0;
 270 
 271         hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
 272         hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
 273         drm_connector_update_edid_property(connector, edid);
 274         ret = drm_add_edid_modes(connector, edid);
 275         kfree(edid);
 276 
 277         return ret;
 278 }
 279 
 280 static enum drm_mode_status
 281 zx_hdmi_connector_mode_valid(struct drm_connector *connector,
 282                              struct drm_display_mode *mode)
 283 {
 284         return MODE_OK;
 285 }
 286 
 287 static struct drm_connector_helper_funcs zx_hdmi_connector_helper_funcs = {
 288         .get_modes = zx_hdmi_connector_get_modes,
 289         .mode_valid = zx_hdmi_connector_mode_valid,
 290 };
 291 
 292 static enum drm_connector_status
 293 zx_hdmi_connector_detect(struct drm_connector *connector, bool force)
 294 {
 295         struct zx_hdmi *hdmi = to_zx_hdmi(connector);
 296 
 297         return (hdmi_readb(hdmi, TPI_HPD_RSEN) & TPI_HPD_CONNECTION) ?
 298                 connector_status_connected : connector_status_disconnected;
 299 }
 300 
 301 static const struct drm_connector_funcs zx_hdmi_connector_funcs = {
 302         .fill_modes = drm_helper_probe_single_connector_modes,
 303         .detect = zx_hdmi_connector_detect,
 304         .destroy = drm_connector_cleanup,
 305         .reset = drm_atomic_helper_connector_reset,
 306         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 307         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 308 };
 309 
 310 static int zx_hdmi_register(struct drm_device *drm, struct zx_hdmi *hdmi)
 311 {
 312         struct drm_encoder *encoder = &hdmi->encoder;
 313 
 314         encoder->possible_crtcs = VOU_CRTC_MASK;
 315 
 316         drm_encoder_init(drm, encoder, &zx_hdmi_encoder_funcs,
 317                          DRM_MODE_ENCODER_TMDS, NULL);
 318         drm_encoder_helper_add(encoder, &zx_hdmi_encoder_helper_funcs);
 319 
 320         hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
 321 
 322         drm_connector_init(drm, &hdmi->connector, &zx_hdmi_connector_funcs,
 323                            DRM_MODE_CONNECTOR_HDMIA);
 324         drm_connector_helper_add(&hdmi->connector,
 325                                  &zx_hdmi_connector_helper_funcs);
 326 
 327         drm_connector_attach_encoder(&hdmi->connector, encoder);
 328 
 329         return 0;
 330 }
 331 
 332 static irqreturn_t zx_hdmi_irq_thread(int irq, void *dev_id)
 333 {
 334         struct zx_hdmi *hdmi = dev_id;
 335 
 336         drm_helper_hpd_irq_event(hdmi->connector.dev);
 337 
 338         return IRQ_HANDLED;
 339 }
 340 
 341 static irqreturn_t zx_hdmi_irq_handler(int irq, void *dev_id)
 342 {
 343         struct zx_hdmi *hdmi = dev_id;
 344         u8 lstat;
 345 
 346         lstat = hdmi_readb(hdmi, L1_INTR_STAT);
 347 
 348         /* Monitor detect/HPD interrupt */
 349         if (lstat & L1_INTR_STAT_INTR1) {
 350                 u8 stat;
 351 
 352                 stat = hdmi_readb(hdmi, INTR1_STAT);
 353                 hdmi_writeb(hdmi, INTR1_STAT, stat);
 354 
 355                 if (stat & INTR1_MONITOR_DETECT)
 356                         return IRQ_WAKE_THREAD;
 357         }
 358 
 359         return IRQ_NONE;
 360 }
 361 
 362 static int zx_hdmi_audio_startup(struct device *dev, void *data)
 363 {
 364         struct zx_hdmi *hdmi = dev_get_drvdata(dev);
 365         struct drm_encoder *encoder = &hdmi->encoder;
 366 
 367         vou_inf_hdmi_audio_sel(encoder->crtc, VOU_HDMI_AUD_SPDIF);
 368 
 369         return 0;
 370 }
 371 
 372 static void zx_hdmi_audio_shutdown(struct device *dev, void *data)
 373 {
 374         struct zx_hdmi *hdmi = dev_get_drvdata(dev);
 375 
 376         /* Disable audio input */
 377         hdmi_writeb_mask(hdmi, AUD_EN, AUD_IN_EN, 0);
 378 }
 379 
 380 static inline int zx_hdmi_audio_get_n(unsigned int fs)
 381 {
 382         unsigned int n;
 383 
 384         if (fs && (fs % 44100) == 0)
 385                 n = 6272 * (fs / 44100);
 386         else
 387                 n = fs * 128 / 1000;
 388 
 389         return n;
 390 }
 391 
 392 static int zx_hdmi_audio_hw_params(struct device *dev,
 393                                    void *data,
 394                                    struct hdmi_codec_daifmt *daifmt,
 395                                    struct hdmi_codec_params *params)
 396 {
 397         struct zx_hdmi *hdmi = dev_get_drvdata(dev);
 398         struct hdmi_audio_infoframe *cea = &params->cea;
 399         union hdmi_infoframe frame;
 400         int n;
 401 
 402         /* We only support spdif for now */
 403         if (daifmt->fmt != HDMI_SPDIF) {
 404                 DRM_DEV_ERROR(hdmi->dev, "invalid daifmt %d\n", daifmt->fmt);
 405                 return -EINVAL;
 406         }
 407 
 408         switch (params->sample_width) {
 409         case 16:
 410                 hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK,
 411                                  SPDIF_SAMPLE_SIZE_16BIT);
 412                 break;
 413         case 20:
 414                 hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK,
 415                                  SPDIF_SAMPLE_SIZE_20BIT);
 416                 break;
 417         case 24:
 418                 hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK,
 419                                  SPDIF_SAMPLE_SIZE_24BIT);
 420                 break;
 421         default:
 422                 DRM_DEV_ERROR(hdmi->dev, "invalid sample width %d\n",
 423                               params->sample_width);
 424                 return -EINVAL;
 425         }
 426 
 427         /* CTS is calculated by hardware, and we only need to take care of N */
 428         n = zx_hdmi_audio_get_n(params->sample_rate);
 429         hdmi_writeb(hdmi, N_SVAL1, n & 0xff);
 430         hdmi_writeb(hdmi, N_SVAL2, (n >> 8) & 0xff);
 431         hdmi_writeb(hdmi, N_SVAL3, (n >> 16) & 0xf);
 432 
 433         /* Enable spdif mode */
 434         hdmi_writeb_mask(hdmi, AUD_MODE, SPDIF_EN, SPDIF_EN);
 435 
 436         /* Enable audio input */
 437         hdmi_writeb_mask(hdmi, AUD_EN, AUD_IN_EN, AUD_IN_EN);
 438 
 439         memcpy(&frame.audio, cea, sizeof(*cea));
 440 
 441         return zx_hdmi_infoframe_trans(hdmi, &frame, FSEL_AUDIO);
 442 }
 443 
 444 static int zx_hdmi_audio_digital_mute(struct device *dev, void *data,
 445                                       bool enable)
 446 {
 447         struct zx_hdmi *hdmi = dev_get_drvdata(dev);
 448 
 449         if (enable)
 450                 hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, TPI_AUD_MUTE,
 451                                  TPI_AUD_MUTE);
 452         else
 453                 hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, TPI_AUD_MUTE, 0);
 454 
 455         return 0;
 456 }
 457 
 458 static int zx_hdmi_audio_get_eld(struct device *dev, void *data,
 459                                  uint8_t *buf, size_t len)
 460 {
 461         struct zx_hdmi *hdmi = dev_get_drvdata(dev);
 462         struct drm_connector *connector = &hdmi->connector;
 463 
 464         memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
 465 
 466         return 0;
 467 }
 468 
 469 static const struct hdmi_codec_ops zx_hdmi_codec_ops = {
 470         .audio_startup = zx_hdmi_audio_startup,
 471         .hw_params = zx_hdmi_audio_hw_params,
 472         .audio_shutdown = zx_hdmi_audio_shutdown,
 473         .digital_mute = zx_hdmi_audio_digital_mute,
 474         .get_eld = zx_hdmi_audio_get_eld,
 475 };
 476 
 477 static struct hdmi_codec_pdata zx_hdmi_codec_pdata = {
 478         .ops = &zx_hdmi_codec_ops,
 479         .spdif = 1,
 480 };
 481 
 482 static int zx_hdmi_audio_register(struct zx_hdmi *hdmi)
 483 {
 484         struct platform_device *pdev;
 485 
 486         pdev = platform_device_register_data(hdmi->dev, HDMI_CODEC_DRV_NAME,
 487                                              PLATFORM_DEVID_AUTO,
 488                                              &zx_hdmi_codec_pdata,
 489                                              sizeof(zx_hdmi_codec_pdata));
 490         if (IS_ERR(pdev))
 491                 return PTR_ERR(pdev);
 492 
 493         hdmi->audio_pdev = pdev;
 494 
 495         return 0;
 496 }
 497 
 498 static int zx_hdmi_i2c_read(struct zx_hdmi *hdmi, struct i2c_msg *msg)
 499 {
 500         int len = msg->len;
 501         u8 *buf = msg->buf;
 502         int retry = 0;
 503         int ret = 0;
 504 
 505         /* Bits [9:8] of bytes */
 506         hdmi_writeb(hdmi, ZX_DDC_DIN_CNT2, (len >> 8) & 0xff);
 507         /* Bits [7:0] of bytes */
 508         hdmi_writeb(hdmi, ZX_DDC_DIN_CNT1, len & 0xff);
 509 
 510         /* Clear FIFO */
 511         hdmi_writeb_mask(hdmi, ZX_DDC_CMD, DDC_CMD_MASK, DDC_CMD_CLEAR_FIFO);
 512 
 513         /* Kick off the read */
 514         hdmi_writeb_mask(hdmi, ZX_DDC_CMD, DDC_CMD_MASK,
 515                          DDC_CMD_SEQUENTIAL_READ);
 516 
 517         while (len > 0) {
 518                 int cnt, i;
 519 
 520                 /* FIFO needs some time to get ready */
 521                 usleep_range(500, 1000);
 522 
 523                 cnt = hdmi_readb(hdmi, ZX_DDC_DOUT_CNT) & DDC_DOUT_CNT_MASK;
 524                 if (cnt == 0) {
 525                         if (++retry > 5) {
 526                                 DRM_DEV_ERROR(hdmi->dev,
 527                                               "DDC FIFO read timed out!");
 528                                 return -ETIMEDOUT;
 529                         }
 530                         continue;
 531                 }
 532 
 533                 for (i = 0; i < cnt; i++)
 534                         *buf++ = hdmi_readb(hdmi, ZX_DDC_DATA);
 535                 len -= cnt;
 536         }
 537 
 538         return ret;
 539 }
 540 
 541 static int zx_hdmi_i2c_write(struct zx_hdmi *hdmi, struct i2c_msg *msg)
 542 {
 543         /*
 544          * The DDC I2C adapter is only for reading EDID data, so we assume
 545          * that the write to this adapter must be the EDID data offset.
 546          */
 547         if ((msg->len != 1) ||
 548             ((msg->addr != DDC_ADDR) && (msg->addr != DDC_SEGMENT_ADDR)))
 549                 return -EINVAL;
 550 
 551         if (msg->addr == DDC_SEGMENT_ADDR)
 552                 hdmi_writeb(hdmi, ZX_DDC_SEGM, msg->addr << 1);
 553         else if (msg->addr == DDC_ADDR)
 554                 hdmi_writeb(hdmi, ZX_DDC_ADDR, msg->addr << 1);
 555 
 556         hdmi_writeb(hdmi, ZX_DDC_OFFSET, msg->buf[0]);
 557 
 558         return 0;
 559 }
 560 
 561 static int zx_hdmi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 562                             int num)
 563 {
 564         struct zx_hdmi *hdmi = i2c_get_adapdata(adap);
 565         struct zx_hdmi_i2c *ddc = hdmi->ddc;
 566         int i, ret = 0;
 567 
 568         mutex_lock(&ddc->lock);
 569 
 570         /* Enable DDC master access */
 571         hdmi_writeb_mask(hdmi, TPI_DDC_MASTER_EN, HW_DDC_MASTER, HW_DDC_MASTER);
 572 
 573         for (i = 0; i < num; i++) {
 574                 DRM_DEV_DEBUG(hdmi->dev,
 575                               "xfer: num: %d/%d, len: %d, flags: %#x\n",
 576                               i + 1, num, msgs[i].len, msgs[i].flags);
 577 
 578                 if (msgs[i].flags & I2C_M_RD)
 579                         ret = zx_hdmi_i2c_read(hdmi, &msgs[i]);
 580                 else
 581                         ret = zx_hdmi_i2c_write(hdmi, &msgs[i]);
 582 
 583                 if (ret < 0)
 584                         break;
 585         }
 586 
 587         if (!ret)
 588                 ret = num;
 589 
 590         /* Disable DDC master access */
 591         hdmi_writeb_mask(hdmi, TPI_DDC_MASTER_EN, HW_DDC_MASTER, 0);
 592 
 593         mutex_unlock(&ddc->lock);
 594 
 595         return ret;
 596 }
 597 
 598 static u32 zx_hdmi_i2c_func(struct i2c_adapter *adapter)
 599 {
 600         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 601 }
 602 
 603 static const struct i2c_algorithm zx_hdmi_algorithm = {
 604         .master_xfer    = zx_hdmi_i2c_xfer,
 605         .functionality  = zx_hdmi_i2c_func,
 606 };
 607 
 608 static int zx_hdmi_ddc_register(struct zx_hdmi *hdmi)
 609 {
 610         struct i2c_adapter *adap;
 611         struct zx_hdmi_i2c *ddc;
 612         int ret;
 613 
 614         ddc = devm_kzalloc(hdmi->dev, sizeof(*ddc), GFP_KERNEL);
 615         if (!ddc)
 616                 return -ENOMEM;
 617 
 618         hdmi->ddc = ddc;
 619         mutex_init(&ddc->lock);
 620 
 621         adap = &ddc->adap;
 622         adap->owner = THIS_MODULE;
 623         adap->class = I2C_CLASS_DDC;
 624         adap->dev.parent = hdmi->dev;
 625         adap->algo = &zx_hdmi_algorithm;
 626         snprintf(adap->name, sizeof(adap->name), "zx hdmi i2c");
 627 
 628         ret = i2c_add_adapter(adap);
 629         if (ret) {
 630                 DRM_DEV_ERROR(hdmi->dev, "failed to add I2C adapter: %d\n",
 631                               ret);
 632                 return ret;
 633         }
 634 
 635         i2c_set_adapdata(adap, hdmi);
 636 
 637         return 0;
 638 }
 639 
 640 static int zx_hdmi_bind(struct device *dev, struct device *master, void *data)
 641 {
 642         struct platform_device *pdev = to_platform_device(dev);
 643         struct drm_device *drm = data;
 644         struct resource *res;
 645         struct zx_hdmi *hdmi;
 646         int irq;
 647         int ret;
 648 
 649         hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
 650         if (!hdmi)
 651                 return -ENOMEM;
 652 
 653         hdmi->dev = dev;
 654         hdmi->drm = drm;
 655 
 656         dev_set_drvdata(dev, hdmi);
 657 
 658         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 659         hdmi->mmio = devm_ioremap_resource(dev, res);
 660         if (IS_ERR(hdmi->mmio)) {
 661                 ret = PTR_ERR(hdmi->mmio);
 662                 DRM_DEV_ERROR(dev, "failed to remap hdmi region: %d\n", ret);
 663                 return ret;
 664         }
 665 
 666         irq = platform_get_irq(pdev, 0);
 667         if (irq < 0)
 668                 return irq;
 669 
 670         hdmi->cec_clk = devm_clk_get(hdmi->dev, "osc_cec");
 671         if (IS_ERR(hdmi->cec_clk)) {
 672                 ret = PTR_ERR(hdmi->cec_clk);
 673                 DRM_DEV_ERROR(dev, "failed to get cec_clk: %d\n", ret);
 674                 return ret;
 675         }
 676 
 677         hdmi->osc_clk = devm_clk_get(hdmi->dev, "osc_clk");
 678         if (IS_ERR(hdmi->osc_clk)) {
 679                 ret = PTR_ERR(hdmi->osc_clk);
 680                 DRM_DEV_ERROR(dev, "failed to get osc_clk: %d\n", ret);
 681                 return ret;
 682         }
 683 
 684         hdmi->xclk = devm_clk_get(hdmi->dev, "xclk");
 685         if (IS_ERR(hdmi->xclk)) {
 686                 ret = PTR_ERR(hdmi->xclk);
 687                 DRM_DEV_ERROR(dev, "failed to get xclk: %d\n", ret);
 688                 return ret;
 689         }
 690 
 691         ret = zx_hdmi_ddc_register(hdmi);
 692         if (ret) {
 693                 DRM_DEV_ERROR(dev, "failed to register ddc: %d\n", ret);
 694                 return ret;
 695         }
 696 
 697         ret = zx_hdmi_audio_register(hdmi);
 698         if (ret) {
 699                 DRM_DEV_ERROR(dev, "failed to register audio: %d\n", ret);
 700                 return ret;
 701         }
 702 
 703         ret = zx_hdmi_register(drm, hdmi);
 704         if (ret) {
 705                 DRM_DEV_ERROR(dev, "failed to register hdmi: %d\n", ret);
 706                 return ret;
 707         }
 708 
 709         ret = devm_request_threaded_irq(dev, irq, zx_hdmi_irq_handler,
 710                                         zx_hdmi_irq_thread, IRQF_SHARED,
 711                                         dev_name(dev), hdmi);
 712         if (ret) {
 713                 DRM_DEV_ERROR(dev, "failed to request threaded irq: %d\n", ret);
 714                 return ret;
 715         }
 716 
 717         return 0;
 718 }
 719 
 720 static void zx_hdmi_unbind(struct device *dev, struct device *master,
 721                            void *data)
 722 {
 723         struct zx_hdmi *hdmi = dev_get_drvdata(dev);
 724 
 725         hdmi->connector.funcs->destroy(&hdmi->connector);
 726         hdmi->encoder.funcs->destroy(&hdmi->encoder);
 727 
 728         if (hdmi->audio_pdev)
 729                 platform_device_unregister(hdmi->audio_pdev);
 730 }
 731 
 732 static const struct component_ops zx_hdmi_component_ops = {
 733         .bind = zx_hdmi_bind,
 734         .unbind = zx_hdmi_unbind,
 735 };
 736 
 737 static int zx_hdmi_probe(struct platform_device *pdev)
 738 {
 739         return component_add(&pdev->dev, &zx_hdmi_component_ops);
 740 }
 741 
 742 static int zx_hdmi_remove(struct platform_device *pdev)
 743 {
 744         component_del(&pdev->dev, &zx_hdmi_component_ops);
 745         return 0;
 746 }
 747 
 748 static const struct of_device_id zx_hdmi_of_match[] = {
 749         { .compatible = "zte,zx296718-hdmi", },
 750         { /* end */ },
 751 };
 752 MODULE_DEVICE_TABLE(of, zx_hdmi_of_match);
 753 
 754 struct platform_driver zx_hdmi_driver = {
 755         .probe = zx_hdmi_probe,
 756         .remove = zx_hdmi_remove,
 757         .driver = {
 758                 .name = "zx-hdmi",
 759                 .of_match_table = zx_hdmi_of_match,
 760         },
 761 };

/* [<][>][^][v][top][bottom][index][help] */