*/
#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+
#include <sound/hdmi-codec.h>
-#include <sound/msm_hdmi_audio.h>
#include "hdmi.h"
void hdmi_set_mode(struct hdmi *hdmi, bool power_on)
}
#endif
-static void msm_hdmi_register_audio_driver(struct hdmi *hdmi, struct device *dev);
+/*
+ * HDMI audio codec callbacks
+ */
+static int msm_hdmi_audio_hw_params(struct device *dev,
+ struct hdmi_codec_daifmt *daifmt,
+ struct hdmi_codec_params *params)
+{
+ struct hdmi *hdmi = dev_get_drvdata(dev);
+ unsigned int chan;
+ unsigned int channel_allocation = 0;
+ unsigned int rate;
+ unsigned int level_shift = 0; /* 0dB */
+ bool down_mix = false;
+
+ dev_dbg(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate,
+ params->sample_width, params->cea.channels);
+
+ switch (params->cea.channels) {
+ case 2:
+ /* FR and FL speakers */
+ channel_allocation = 0;
+ chan = MSM_HDMI_AUDIO_CHANNEL_2;
+ break;
+ case 4:
+ /* FC, LFE, FR and FL speakers */
+ channel_allocation = 0x3;
+ chan = MSM_HDMI_AUDIO_CHANNEL_4;
+ break;
+ case 6:
+ /* RR, RL, FC, LFE, FR and FL speakers */
+ channel_allocation = 0x0B;
+ chan = MSM_HDMI_AUDIO_CHANNEL_6;
+ break;
+ case 8:
+ /* FRC, FLC, RR, RL, FC, LFE, FR and FL speakers */
+ channel_allocation = 0x1F;
+ chan = MSM_HDMI_AUDIO_CHANNEL_8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (params->sample_rate) {
+ case 32000:
+ rate = HDMI_SAMPLE_RATE_32KHZ;
+ break;
+ case 44100:
+ rate = HDMI_SAMPLE_RATE_44_1KHZ;
+ break;
+ case 48000:
+ rate = HDMI_SAMPLE_RATE_48KHZ;
+ break;
+ case 88200:
+ rate = HDMI_SAMPLE_RATE_88_2KHZ;
+ break;
+ case 96000:
+ rate = HDMI_SAMPLE_RATE_96KHZ;
+ break;
+ case 176400:
+ rate = HDMI_SAMPLE_RATE_176_4KHZ;
+ break;
+ case 192000:
+ rate = HDMI_SAMPLE_RATE_192KHZ;
+ break;
+ default:
+ dev_err(dev, "rate[%d] not supported!\n",
+ params->sample_rate);
+ return -EINVAL;
+ }
+
+ hdmi_audio_set_sample_rate(hdmi, rate);
+ hdmi_audio_info_setup(hdmi, 1, chan, channel_allocation,
+ level_shift, down_mix);
+
+ return 0;
+}
+
+static void msm_hdmi_audio_shutdown(struct device *dev)
+{
+ struct hdmi *hdmi = dev_get_drvdata(dev);
+
+ hdmi_audio_info_setup(hdmi, 0, 0, 0, 0, 0);
+}
+
+static const struct hdmi_codec_ops msm_hdmi_audio_codec_ops = {
+ .hw_params = msm_hdmi_audio_hw_params,
+ .audio_shutdown = msm_hdmi_audio_shutdown,
+};
+
+static struct hdmi_codec_pdata codec_data = {
+ .ops = &msm_hdmi_audio_codec_ops,
+ .max_i2s_channels = 8,
+ .i2s = 1,
+};
+
+static int msm_hdmi_register_audio_driver(struct hdmi *hdmi, struct device *dev)
+{
+ hdmi->audio_pdev = platform_device_register_data(dev,
+ HDMI_CODEC_DRV_NAME,
+ PLATFORM_DEVID_AUTO,
+ &codec_data,
+ sizeof(codec_data));
+ if (IS_ERR(hdmi->audio_pdev))
+ return PTR_ERR(hdmi->audio_pdev);
+
+ return 0;
+}
+
static int hdmi_bind(struct device *dev, struct device *master, void *data)
{
struct drm_device *drm = dev_get_drvdata(master);
#ifdef CONFIG_OF
struct device_node *of_node = dev->of_node;
const struct of_device_id *match;
+ int err;
match = of_match_node(dt_match, of_node);
if (match && match->data) {
if (IS_ERR(hdmi))
return PTR_ERR(hdmi);
priv->hdmi = hdmi;
- msm_hdmi_register_audio_driver(hdmi, dev);
+
+ err = msm_hdmi_register_audio_driver(hdmi, dev);
+ if (err) {
+ DRM_ERROR("Failed to attach an audio codec %d\n", err);
+ hdmi->audio_pdev = NULL;
+ }
return 0;
}
struct drm_device *drm = dev_get_drvdata(master);
struct msm_drm_private *priv = drm->dev_private;
if (priv->hdmi) {
- DRM_INFO("%s driver unbound to HDMI\n", HDMI_CODEC_DRV_NAME);
- platform_device_unregister(priv->hdmi->audio_pdev);
hdmi_destroy(priv->hdmi);
+ if (priv->hdmi->audio_pdev)
+ platform_device_unregister(priv->hdmi->audio_pdev);
+
priv->hdmi = NULL;
}
}
.bind = hdmi_bind,
.unbind = hdmi_unbind,
};
-/*
- * HDMI audio codec callbacks
- */
-
-static int msm_hdmi_audio_hw_params(struct device *dev,
- struct hdmi_codec_daifmt *daifmt,
- struct hdmi_codec_params *params)
-{
- struct hdmi *hdmi = dev_get_drvdata(dev);
- unsigned int chan;// = params->cea.channels;
- unsigned int channel_allocation = 0;
- unsigned int rate;//
- unsigned int level_shift = 0; /* 0dB */
- bool down_mix = false;
- dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__,
- params->sample_rate, params->sample_width, chan);
-
- switch (params->cea.channels) {
- case 2:
- channel_allocation = 0;
- chan = MSM_HDMI_AUDIO_CHANNEL_2;
- break;
- case 4:
- channel_allocation = 0;
- chan = MSM_HDMI_AUDIO_CHANNEL_4;
- break;
- case 6:
- channel_allocation = 0x0B;
- chan = MSM_HDMI_AUDIO_CHANNEL_6;
- break;
- case 8:
- channel_allocation = 0x1F;
- chan = MSM_HDMI_AUDIO_CHANNEL_8;
- break;
- default:
- //dev_err(hdmi->dev, "channel[%d] not supported!\n", chan);
- return -EINVAL;
- }
-
- switch (params->sample_rate) {
- case 32000:
- rate = HDMI_SAMPLE_RATE_32KHZ;
- case 44100:
- rate = HDMI_SAMPLE_RATE_48KHZ;
- case 48000:
- rate = HDMI_SAMPLE_RATE_48KHZ;
- case 88200:
- rate = HDMI_SAMPLE_RATE_88_2KHZ;
- case 96000:
- rate = HDMI_SAMPLE_RATE_96KHZ;
- case 176400:
- rate = HDMI_SAMPLE_RATE_176_4KHZ;
- case 192000:
- rate = HDMI_SAMPLE_RATE_192KHZ;
- break;
- default:
- dev_err(dev, "rate[%d] not supported!\n",
- params->sample_rate);
- return -EINVAL;
- }
- rate = HDMI_SAMPLE_RATE_48KHZ;
- channel_allocation = 0;
-
- //FIXME..
- hdmi_audio_set_sample_rate(hdmi, rate);
-
- hdmi_audio_info_setup(hdmi, 1, chan,
- channel_allocation, level_shift, down_mix);
-
-
-
- return 0;
-}
-
-static int msm_hdmi_audio_startup(struct device *dev,
- void (*abort_cb)(struct device *dev))
-{
- struct hdmi *hdmi = dev_get_drvdata(dev);
-
- dev_dbg(dev, "%s\n", __func__);
-
- //msm_hdmi_audio_enable(hdmi);
-
- return 0;
-}
-
-static void msm_hdmi_audio_shutdown(struct device *dev)
-{
- struct hdmi *hdmi = dev_get_drvdata(dev);
-
- dev_dbg(dev, "%s\n", __func__);
-
- hdmi_audio_info_setup(hdmi, 0, 0, 0, 0, 0);
-}
-
-static const struct hdmi_codec_ops msm_hdmi_audio_codec_ops = {
- .hw_params = msm_hdmi_audio_hw_params,
- .audio_startup = msm_hdmi_audio_startup,
- .audio_shutdown = msm_hdmi_audio_shutdown,
-};
-
-static void msm_hdmi_register_audio_driver(struct hdmi *hdmi, struct device *dev)
-{
- struct hdmi_codec_pdata codec_data = {
- .ops = &msm_hdmi_audio_codec_ops,
- .max_i2s_channels = 2,
- .i2s = 1,
- };
- //struct platform_device *pdev;
-
- hdmi->audio_pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
- PLATFORM_DEVID_AUTO, &codec_data,
- sizeof(codec_data));
- if (IS_ERR(hdmi->audio_pdev))
- return;
-
- DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
-}
static int hdmi_dev_probe(struct platform_device *pdev)
{