aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/hdmi/hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/hdmi/hdmi.c')
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.c117
1 files changed, 116 insertions, 1 deletions
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 51b9ea552f97..973720792236 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -19,6 +19,7 @@
19#include <linux/of_irq.h> 19#include <linux/of_irq.h>
20#include <linux/of_gpio.h> 20#include <linux/of_gpio.h>
21 21
22#include <sound/hdmi-codec.h>
22#include "hdmi.h" 23#include "hdmi.h"
23 24
24void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on) 25void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on)
@@ -434,6 +435,111 @@ static int msm_hdmi_get_gpio(struct device_node *of_node, const char *name)
434 return gpio; 435 return gpio;
435} 436}
436 437
438/*
439 * HDMI audio codec callbacks
440 */
441static int msm_hdmi_audio_hw_params(struct device *dev, void *data,
442 struct hdmi_codec_daifmt *daifmt,
443 struct hdmi_codec_params *params)
444{
445 struct hdmi *hdmi = dev_get_drvdata(dev);
446 unsigned int chan;
447 unsigned int channel_allocation = 0;
448 unsigned int rate;
449 unsigned int level_shift = 0; /* 0dB */
450 bool down_mix = false;
451
452 dev_dbg(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate,
453 params->sample_width, params->cea.channels);
454
455 switch (params->cea.channels) {
456 case 2:
457 /* FR and FL speakers */
458 channel_allocation = 0;
459 chan = MSM_HDMI_AUDIO_CHANNEL_2;
460 break;
461 case 4:
462 /* FC, LFE, FR and FL speakers */
463 channel_allocation = 0x3;
464 chan = MSM_HDMI_AUDIO_CHANNEL_4;
465 break;
466 case 6:
467 /* RR, RL, FC, LFE, FR and FL speakers */
468 channel_allocation = 0x0B;
469 chan = MSM_HDMI_AUDIO_CHANNEL_6;
470 break;
471 case 8:
472 /* FRC, FLC, RR, RL, FC, LFE, FR and FL speakers */
473 channel_allocation = 0x1F;
474 chan = MSM_HDMI_AUDIO_CHANNEL_8;
475 break;
476 default:
477 return -EINVAL;
478 }
479
480 switch (params->sample_rate) {
481 case 32000:
482 rate = HDMI_SAMPLE_RATE_32KHZ;
483 break;
484 case 44100:
485 rate = HDMI_SAMPLE_RATE_44_1KHZ;
486 break;
487 case 48000:
488 rate = HDMI_SAMPLE_RATE_48KHZ;
489 break;
490 case 88200:
491 rate = HDMI_SAMPLE_RATE_88_2KHZ;
492 break;
493 case 96000:
494 rate = HDMI_SAMPLE_RATE_96KHZ;
495 break;
496 case 176400:
497 rate = HDMI_SAMPLE_RATE_176_4KHZ;
498 break;
499 case 192000:
500 rate = HDMI_SAMPLE_RATE_192KHZ;
501 break;
502 default:
503 dev_err(dev, "rate[%d] not supported!\n",
504 params->sample_rate);
505 return -EINVAL;
506 }
507
508 msm_hdmi_audio_set_sample_rate(hdmi, rate);
509 msm_hdmi_audio_info_setup(hdmi, 1, chan, channel_allocation,
510 level_shift, down_mix);
511
512 return 0;
513}
514
515static void msm_hdmi_audio_shutdown(struct device *dev, void *data)
516{
517 struct hdmi *hdmi = dev_get_drvdata(dev);
518
519 msm_hdmi_audio_info_setup(hdmi, 0, 0, 0, 0, 0);
520}
521
522static const struct hdmi_codec_ops msm_hdmi_audio_codec_ops = {
523 .hw_params = msm_hdmi_audio_hw_params,
524 .audio_shutdown = msm_hdmi_audio_shutdown,
525};
526
527static struct hdmi_codec_pdata codec_data = {
528 .ops = &msm_hdmi_audio_codec_ops,
529 .max_i2s_channels = 8,
530 .i2s = 1,
531};
532
533static int msm_hdmi_register_audio_driver(struct hdmi *hdmi, struct device *dev)
534{
535 hdmi->audio_pdev = platform_device_register_data(dev,
536 HDMI_CODEC_DRV_NAME,
537 PLATFORM_DEVID_AUTO,
538 &codec_data,
539 sizeof(codec_data));
540 return PTR_ERR_OR_ZERO(hdmi->audio_pdev);
541}
542
437static int msm_hdmi_bind(struct device *dev, struct device *master, void *data) 543static int msm_hdmi_bind(struct device *dev, struct device *master, void *data)
438{ 544{
439 struct drm_device *drm = dev_get_drvdata(master); 545 struct drm_device *drm = dev_get_drvdata(master);
@@ -441,7 +547,7 @@ static int msm_hdmi_bind(struct device *dev, struct device *master, void *data)
441 static struct hdmi_platform_config *hdmi_cfg; 547 static struct hdmi_platform_config *hdmi_cfg;
442 struct hdmi *hdmi; 548 struct hdmi *hdmi;
443 struct device_node *of_node = dev->of_node; 549 struct device_node *of_node = dev->of_node;
444 int i; 550 int i, err;
445 551
446 hdmi_cfg = (struct hdmi_platform_config *) 552 hdmi_cfg = (struct hdmi_platform_config *)
447 of_device_get_match_data(dev); 553 of_device_get_match_data(dev);
@@ -468,6 +574,12 @@ static int msm_hdmi_bind(struct device *dev, struct device *master, void *data)
468 return PTR_ERR(hdmi); 574 return PTR_ERR(hdmi);
469 priv->hdmi = hdmi; 575 priv->hdmi = hdmi;
470 576
577 err = msm_hdmi_register_audio_driver(hdmi, dev);
578 if (err) {
579 DRM_ERROR("Failed to attach an audio codec %d\n", err);
580 hdmi->audio_pdev = NULL;
581 }
582
471 return 0; 583 return 0;
472} 584}
473 585
@@ -477,6 +589,9 @@ static void msm_hdmi_unbind(struct device *dev, struct device *master,
477 struct drm_device *drm = dev_get_drvdata(master); 589 struct drm_device *drm = dev_get_drvdata(master);
478 struct msm_drm_private *priv = drm->dev_private; 590 struct msm_drm_private *priv = drm->dev_private;
479 if (priv->hdmi) { 591 if (priv->hdmi) {
592 if (priv->hdmi->audio_pdev)
593 platform_device_unregister(priv->hdmi->audio_pdev);
594
480 msm_hdmi_destroy(priv->hdmi); 595 msm_hdmi_destroy(priv->hdmi);
481 priv->hdmi = NULL; 596 priv->hdmi = NULL;
482 } 597 }