#include <linux/clk.h>
#include <linux/io.h>
#include <linux/of_gpio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include "i2s.h"
#include "s3c-i2s-v2.h"
#include "../codecs/max98095.h"
+#include "codec_plugin.h"
#define DRV_NAME "daisy-snd-max98095"
SND_SOC_DAPM_HP("Headphone Jack", NULL),
};
+static int get_hdmi(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct audio_codec_plugin *plugin;
+ int ret = 0, state = 0;
+
+ plugin = (struct audio_codec_plugin *)kcontrol->private_value;
+
+ if (!plugin)
+ return 0;
+
+ if (!plugin->ops.hw_params)
+ return 0;
+
+ ret = plugin->ops.get_state(plugin->dev, &state);
+ if (ret < 0)
+ return 0;
+
+ ucontrol->value.integer.value[0] = (long int)state;
+ return 1;
+}
+
+static int put_hdmi(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct audio_codec_plugin *plugin;
+ int ret = 0, state;
+
+ plugin = (struct audio_codec_plugin *)kcontrol->private_value;
+
+ if (!plugin)
+ return 0;
+
+ if (!plugin->ops.hw_params)
+ return 0;
+
+ state = (int)ucontrol->value.integer.value[0];
+ ret = plugin->ops.set_state(plugin->dev,
+ ucontrol->value.integer.value[0]);
+
+ if (ret < 0)
+ return 0;
+ return 1;
+}
+
+static struct snd_kcontrol_new daisy_dapm_controls[] = {
+ SOC_SINGLE_BOOL_EXT("HDMI Playback Switch", 0, get_hdmi, put_hdmi),
+};
+
static int daisy_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
.name = "DAISY-I2S",
.dai_link = daisy_dai,
.num_links = ARRAY_SIZE(daisy_dai),
+ .controls = daisy_dapm_controls,
+ .num_controls = ARRAY_SIZE(daisy_dapm_controls),
.dapm_widgets = daisy_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(daisy_dapm_widgets),
.dapm_routes = daisy_audio_map,
.num_dapm_routes = ARRAY_SIZE(daisy_audio_map),
};
+static int plugin_init(struct audio_codec_plugin **pplugin)
+{
+ struct device_node *plugin_node = NULL;
+ struct platform_device *plugin_pdev;
+ struct audio_codec_plugin *plugin;
+
+ plugin_node = of_find_node_by_name(NULL, "hdmi-audio");
+ if (!plugin_node)
+ return -EFAULT;
+
+ plugin_pdev = of_find_device_by_node(plugin_node);
+ if (!plugin_node)
+ return -EFAULT;
+
+ plugin = dev_get_drvdata(&plugin_pdev->dev);
+ if (!plugin)
+ return -EFAULT;
+ else
+ *pplugin = plugin;
+ return 0;
+}
+
static __devinit int daisy_max98095_driver_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &daisy_snd;
struct device_node *dn;
struct daisy_max98095 *machine;
+ struct audio_codec_plugin *plugin = NULL;
int i, ret;
if (!pdev->dev.platform_data && !pdev->dev.of_node) {
return -ENOMEM;
}
+ plugin_init(&plugin);
+ daisy_dapm_controls[0].private_value = (unsigned long)plugin;
+
card->dev = &pdev->dev;
platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, machine);
if (mod & HDMI_DVI_MODE_EN)
onoff = false;
+ ctx->enabled = onoff;
hdmi_reg_writeb(ctx, HDMI_AUI_CON, onoff ? 2 : 0);
hdmi_reg_writemask(ctx, HDMI_CON_0, onoff ?
HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
return ret;
}
+static int hdmi_set_state(struct device *dev, int enable)
+{
+ struct hdmi_audio_context *ctx = NULL;
+ struct audio_codec_plugin *plugin;
+ int ret = 0;
+
+ if (!dev) {
+ dev_err(dev, "invalid device.\n");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ plugin = dev_get_drvdata(dev);
+ ctx = container_of(plugin, struct hdmi_audio_context, plugin);
+
+ if (enable)
+ hdmi_audio_control(ctx, true);
+ else
+ hdmi_audio_control(ctx, false);
+ return ret;
+}
+
+static int hdmi_get_state(struct device *dev, int *is_enabled)
+{
+ struct hdmi_audio_context *ctx = NULL;
+ struct audio_codec_plugin *plugin;
+ int ret = 0;
+
+ if (!dev) {
+ dev_err(dev, "invalid device.\n");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ plugin = dev_get_drvdata(dev);
+ ctx = container_of(plugin, struct hdmi_audio_context, plugin);
+
+ if (is_enabled && ctx)
+ *is_enabled = ctx->enabled;
+ else
+ return -EINVAL;
+ return 0;
+}
+
static __devinit int hdmi_audio_probe(struct platform_device *pdev)
{
}
ctx->pdev = pdev;
+ ctx->enabled = true;
ctx->plugin.dev = &pdev->dev;
ctx->plugin.ops.hw_params = hdmi_audio_hw_params;
ctx->plugin.ops.trigger = hdmi_audio_trigger;
+ ctx->plugin.ops.get_state = hdmi_get_state;
+ ctx->plugin.ops.set_state = hdmi_set_state;
ctx->params.sample_rate = DEFAULT_RATE;
ctx->params.bits_per_sample = DEFAULT_BPS;