Skip to content

Commit

Permalink
WIP: cdn_dp hdmi audio switch
Browse files Browse the repository at this point in the history
  • Loading branch information
ayufan committed Jan 2, 2021
1 parent 8c6aae9 commit ab09e25
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 36 deletions.
35 changes: 26 additions & 9 deletions arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,32 @@
reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
};

hdmi-sound {
status = "okay";
compatible = "rockchip,rk3399-hdmi-dp";
rockchip,cpu = <&i2s2>;
rockchip,codec = <&hdmi>, <&cdn_dp>;
cdn_dp_hdmi_sound: cdn-dp-hdmi-sound {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,name = "cdn-dp-hdmi-sound";

simple-audio-card,dai-link@0 {
format = "i2s";
cpu {
sound-dai = <&i2s2>;
};

codec {
sound-dai = <&hdmi 0>;
};
};
simple-audio-card,dai-link@1 {
format = "i2s";
cpu {
sound-dai = <&i2s2>;
};

codec {
sound-dai = <&cdn_dp 1>;
};
};
};

sound {
Expand Down Expand Up @@ -264,10 +285,6 @@
status = "okay";
};

&hdmi_sound {
status = "okay";
};

&gpu {
mali-supply = <&vdd_gpu>;
status = "okay";
Expand Down
84 changes: 57 additions & 27 deletions sound/soc/rockchip/rockchip_hdmi_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@
#define DRV_NAME "rk-hdmi-dp-sound"
#define MAX_CODECS 2

static const struct snd_soc_dapm_widget rk_dapm_widgets[] = {
SND_SOC_DAPM_LINE("HDMI", NULL),
};

static const struct snd_soc_dapm_route rk_dapm_routes[] = {
{"HDMI", NULL, "TX"},
};

static const struct snd_kcontrol_new rk_mc_controls[] = {
SOC_DAPM_PIN_SWITCH("HDMI"),
};

static int rk_hdmi_dp_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
Expand Down Expand Up @@ -142,32 +154,43 @@ static struct snd_soc_ops rockchip_sound_hdmidp_ops = {
.hw_params = rk_hdmi_dp_hw_params,
};

SND_SOC_DAILINK_DEFS(audio,
DAILINK_COMP_ARRAY(COMP_CPU(NULL)),
DAILINK_COMP_ARRAY(COMP_CODEC(NULL, NULL), COMP_CODEC(NULL, NULL)),
DAILINK_COMP_ARRAY(COMP_PLATFORM(NULL)));

static struct snd_soc_dai_link rk_dailink = {
.name = "HDMI-DP",
.stream_name = "HDMI-DP",
.init = rockchip_sound_hdmi_dp_init,
.ops = &rockchip_sound_hdmidp_ops,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
SND_SOC_DAILINK_REG(audio),
};

static struct snd_soc_card snd_soc_card_rk = {
.name = "rk-hdmi-dp-sound",
.dai_link = &rk_dailink,
.num_links = 1,
.num_aux_devs = 0,
.dapm_widgets = rk_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(rk_dapm_widgets),
.dapm_routes = rk_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(rk_dapm_routes),
.controls = rk_mc_controls,
.num_controls = ARRAY_SIZE(rk_mc_controls),
};

static int rk_hdmi_dp_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &snd_soc_card_rk;
struct device_node *np = pdev->dev.of_node;
struct snd_soc_dai_link *link = card->dai_link;
struct snd_soc_dai_link_component *codecs;
struct snd_soc_dai_link_component *codec;
struct of_phandle_args args;
struct device_node *node;
int count;
int ret = 0, i = 0, idx = 0;
int ret = 0, i = 0;

card->dev = &pdev->dev;

Expand All @@ -176,44 +199,51 @@ static int rk_hdmi_dp_probe(struct platform_device *pdev)
return -EINVAL;

/* refine codecs, remove unavailable node */
for (i = 0; i < count; i++) {
node = of_parse_phandle(np, "rockchip,codec", i);
if (!node)
return -ENODEV;
if (of_device_is_available(node))
idx++;
}

if (!idx)
return -ENODEV;
link->num_codecs = 0;

codecs = devm_kcalloc(&pdev->dev, idx,
sizeof(*codecs), GFP_KERNEL);
link->codecs = codecs;
link->num_codecs = idx;
idx = 0;
for (i = 0; i < count; i++) {
node = of_parse_phandle(np, "rockchip,codec", i);
if (!node)
return -ENODEV;
if (!of_device_is_available(node))
codec = &link->codecs[link->num_codecs];

codec->of_node = of_parse_phandle(np, "rockchip,codec", i);
if (!codec->of_node) {
dev_err(&pdev->dev,
"Property 'rockchip,codec' missing or invalid\n");
return -EINVAL;
}

if (!of_device_is_available(codec->of_node)) {
dev_err(&pdev->dev,
"Property 'rockchip,codec' is not available\n");
continue;
}

ret = of_parse_phandle_with_fixed_args(np, "rockchip,codec",
0, i, &args);
if (ret)
if (ret) {
dev_err(&pdev->dev,
"Unable to parse property 'rockchip,codec'\n");
return ret;
}

codecs[idx].of_node = node;
ret = snd_soc_get_dai_name(&args, &codecs[idx].dai_name);
ret = snd_soc_get_dai_name(&args, &codec->dai_name);
if (ret)
return ret;
idx++;

link->num_codecs++;
}

if (!link->num_codecs) {
dev_err(&pdev->dev,
"Property 'rockchip,cpu' missing or invalid\n");
return -ENODEV;
}

link->cpus->of_node = of_parse_phandle(np, "rockchip,cpu", 0);
if (!link->cpus->of_node)
if (!link->cpus->of_node) {
dev_err(&pdev->dev,
"Property 'rockchip,cpu' missing or invalid\n");
return -ENODEV;
}
link->platforms->of_node = link->cpus->of_node;

ret = devm_snd_soc_register_card(&pdev->dev, card);
Expand Down

0 comments on commit ab09e25

Please sign in to comment.