mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
audio: auge: init spdif_b when bootup and add channel status
PD#165171: audio: auge: init spdif_b when bootup and add channel status Change-Id: I001d74a0f21fb3f02edf741bd3b87d45dfddcd5f Signed-off-by: Xing Wang <xing.wang@amlogic.com>
This commit is contained in:
10
MAINTAINERS
10
MAINTAINERS
@@ -14454,3 +14454,13 @@ F: drivers/amlogic/media/dtv_demod/*
|
||||
AMLOGIC DEFENDKEY DRIVER
|
||||
M: Zhongfu Luo <zhongfu.luo@amlogic.com>
|
||||
F: drivers/amlogic/defendkey/*
|
||||
|
||||
AMLOGIC DEBUG
|
||||
M: Jianxin Pan <jianxin.pan@amlogic.com>
|
||||
F: drivers/amlogic/debug/
|
||||
|
||||
AMLOGIC G12A spdif channel status
|
||||
M: xing wang<xing.wang@amlogic.com>
|
||||
F: arch/arm64/boot/dts/amlogic/g12a_*
|
||||
F: include/linux/amlogic/media/sound/spdif_info.h
|
||||
F: sound/soc/amlogic/auge*
|
||||
|
||||
@@ -587,6 +587,7 @@
|
||||
|
||||
aml-audio-card,dai-link@4 {
|
||||
mclk-fs = <128>;
|
||||
//continuous-clock;
|
||||
/* suffix-name, sync with android audio hal
|
||||
* what's the dai link used for
|
||||
*/
|
||||
@@ -602,6 +603,7 @@
|
||||
/* spdif_b to hdmi, only playback */
|
||||
aml-audio-card,dai-link@5 {
|
||||
mclk-fs = <128>;
|
||||
continuous-clock;
|
||||
/* suffix-name, sync with android audio hal
|
||||
* what's the dai link used for
|
||||
*/
|
||||
|
||||
@@ -670,6 +670,7 @@
|
||||
/* spdif_b to hdmi, only playback */
|
||||
aml-audio-card,dai-link@5 {
|
||||
mclk-fs = <128>;
|
||||
continuous-clock;
|
||||
/* suffix-name, sync with android audio hal
|
||||
* what's the dai link used for
|
||||
*/
|
||||
|
||||
@@ -671,6 +671,7 @@
|
||||
/* spdif_b to hdmi, only playback */
|
||||
aml-audio-card,dai-link@5 {
|
||||
mclk-fs = <128>;
|
||||
continuous-clock;
|
||||
/* suffix-name, sync with android audio hal
|
||||
* what's the dai link used for
|
||||
*/
|
||||
|
||||
@@ -589,6 +589,7 @@
|
||||
/* spdif_b to hdmi, only playback */
|
||||
aml-audio-card,dai-link@5 {
|
||||
mclk-fs = <128>;
|
||||
continuous-clock;
|
||||
/* suffix-name, sync with android audio hal
|
||||
* what's the dai link used for
|
||||
*/
|
||||
|
||||
@@ -603,6 +603,7 @@
|
||||
/* spdif_b to hdmi, only playback */
|
||||
aml-audio-card,dai-link@5 {
|
||||
mclk-fs = <128>;
|
||||
continuous-clock;
|
||||
/* suffix-name, sync with android audio hal
|
||||
* what's the dai link used for
|
||||
*/
|
||||
|
||||
@@ -700,6 +700,7 @@
|
||||
/* spdif_b to hdmi, only playback */
|
||||
aml-audio-card,dai-link@5 {
|
||||
mclk-fs = <128>;
|
||||
continuous-clock;
|
||||
/* suffix-name, sync with android audio hal
|
||||
* what's the dai link used for
|
||||
*/
|
||||
|
||||
@@ -563,6 +563,7 @@
|
||||
/* spdif_b to hdmi, only playback */
|
||||
aml-audio-card,dai-link@5 {
|
||||
mclk-fs = <128>;
|
||||
continuous-clock;
|
||||
/* suffix-name, sync with android audio hal
|
||||
* what's the dai link used for
|
||||
*/
|
||||
|
||||
37
include/linux/amlogic/media/sound/spdif_info.h
Normal file
37
include/linux/amlogic/media/sound/spdif_info.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* include/linux/amlogic/media/sound/spdif_info.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SPDIF_INFO_H__
|
||||
#define __SPDIF_INFO_H__
|
||||
|
||||
#include <sound/pcm.h>
|
||||
|
||||
struct iec958_chsts {
|
||||
unsigned short chstat0_l;
|
||||
unsigned short chstat1_l;
|
||||
unsigned short chstat0_r;
|
||||
unsigned short chstat1_r;
|
||||
};
|
||||
|
||||
extern bool spdif_is_4x_clk(void);
|
||||
|
||||
extern void spdif_get_channel_status_info(struct iec958_chsts *chsts,
|
||||
unsigned int rate);
|
||||
|
||||
extern void spdif_notify_to_hdmitx(struct snd_pcm_substream *substream);
|
||||
|
||||
#endif
|
||||
@@ -510,15 +510,18 @@ static int aml_card_dai_init(struct snd_soc_pcm_runtime *rtd)
|
||||
bool idle_clk = false;
|
||||
int ret, i;
|
||||
|
||||
/* enable dai-link mclk when CONTINUOUS clk setted */
|
||||
idle_clk = !!(rtd->dai_link->dai_fmt & SND_SOC_DAIFMT_CONT);
|
||||
|
||||
for (i = 0; i < rtd->num_codecs; i++) {
|
||||
codec = rtd->codec_dais[i];
|
||||
|
||||
ret = aml_card_init_dai(codec, &dai_props->codec_dai);
|
||||
ret = aml_card_init_dai(codec, &dai_props->codec_dai, idle_clk);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = aml_card_init_dai(cpu, &dai_props->cpu_dai);
|
||||
ret = aml_card_init_dai(cpu, &dai_props->cpu_dai, idle_clk);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -527,14 +530,6 @@ static int aml_card_dai_init(struct snd_soc_pcm_runtime *rtd)
|
||||
aml_card_init_mic(rtd->card, &priv->mic_jack, PREFIX);
|
||||
hp_mic_detect_cnt = 1;
|
||||
}
|
||||
/* enable dai-link mclk when CONTINUOUS clk setted */
|
||||
idle_clk = !!(rtd->dai_link->dai_fmt & SND_SOC_DAIFMT_CONT);
|
||||
if (idle_clk && dai_props->cpu_dai.clk) {
|
||||
clk_set_rate(dai_props->cpu_dai.clk, dai_props->cpu_dai.sysclk);
|
||||
ret = clk_prepare_enable(dai_props->cpu_dai.clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -242,11 +242,11 @@ codec_confs_end:
|
||||
}
|
||||
|
||||
int aml_card_init_dai(struct snd_soc_dai *dai,
|
||||
struct aml_dai *aml_dai)
|
||||
struct aml_dai *aml_dai, bool cont_clk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (aml_dai->sysclk) {
|
||||
if (aml_dai->sysclk && cont_clk) {
|
||||
ret = snd_soc_dai_set_sysclk(dai, 0, aml_dai->sysclk, 0);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(dai->dev, "aml-card: set_sysclk error\n");
|
||||
|
||||
@@ -71,7 +71,7 @@ int aml_card_parse_codec_confs(struct device_node *codec_np,
|
||||
struct snd_soc_card *card);
|
||||
|
||||
int aml_card_init_dai(struct snd_soc_dai *dai,
|
||||
struct aml_dai *aml_dai);
|
||||
struct aml_dai *aml_dai, bool cont_clk);
|
||||
|
||||
int aml_card_canonicalize_dailink(struct snd_soc_dai_link *dai_link);
|
||||
void aml_card_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
|
||||
|
||||
@@ -854,6 +854,49 @@ static void aml_check_aed(bool enable, int dst)
|
||||
}
|
||||
}
|
||||
|
||||
void frddr_init_default(unsigned int frddr_index, unsigned int src0_sel)
|
||||
{
|
||||
unsigned int offset, reg;
|
||||
unsigned int start_addr, end_addr, int_addr;
|
||||
static int buf[256];
|
||||
|
||||
memset(buf, 0x0, sizeof(buf));
|
||||
start_addr = virt_to_phys(buf);
|
||||
end_addr = start_addr + sizeof(buf) - 1;
|
||||
int_addr = sizeof(buf) / 64;
|
||||
|
||||
offset = EE_AUDIO_FRDDR_B_START_ADDR - EE_AUDIO_FRDDR_A_START_ADDR;
|
||||
reg = EE_AUDIO_FRDDR_A_START_ADDR + offset * frddr_index;
|
||||
audiobus_write(reg, start_addr);
|
||||
|
||||
offset = EE_AUDIO_FRDDR_B_INIT_ADDR - EE_AUDIO_FRDDR_A_INIT_ADDR;
|
||||
reg = EE_AUDIO_FRDDR_A_INIT_ADDR + offset * frddr_index;
|
||||
audiobus_write(reg, start_addr);
|
||||
|
||||
offset = EE_AUDIO_FRDDR_B_FINISH_ADDR - EE_AUDIO_FRDDR_A_FINISH_ADDR;
|
||||
reg = EE_AUDIO_FRDDR_A_FINISH_ADDR + offset * frddr_index;
|
||||
audiobus_write(reg, end_addr);
|
||||
|
||||
offset = EE_AUDIO_FRDDR_B_INT_ADDR - EE_AUDIO_FRDDR_A_INT_ADDR;
|
||||
reg = EE_AUDIO_FRDDR_A_INT_ADDR + offset * frddr_index;
|
||||
audiobus_write(reg, int_addr);
|
||||
|
||||
offset = EE_AUDIO_FRDDR_B_CTRL1 - EE_AUDIO_FRDDR_A_CTRL1;
|
||||
reg = EE_AUDIO_FRDDR_A_CTRL1 + offset * frddr_index;
|
||||
audiobus_write(reg,
|
||||
(0x40 - 1) << 24 | (0x20 - 1) << 16 | 2 << 8 | 0 << 0);
|
||||
|
||||
offset = EE_AUDIO_FRDDR_B_CTRL0 - EE_AUDIO_FRDDR_A_CTRL0;
|
||||
reg = EE_AUDIO_FRDDR_A_CTRL0 + offset * frddr_index;
|
||||
audiobus_write(reg,
|
||||
1 << 31
|
||||
| 0 << 24
|
||||
| 4 << 16
|
||||
| 1 << 3 /* src0 enable */
|
||||
| src0_sel << 0 /* src0 sel */
|
||||
);
|
||||
}
|
||||
|
||||
static struct ddr_chipinfo g12a_ddr_chipinfo = {
|
||||
.addr_separated = true,
|
||||
.same_src_fn = true,
|
||||
|
||||
@@ -99,5 +99,7 @@ void aml_frddr_set_fifos(struct frddr *fr,
|
||||
unsigned int aml_frddr_get_fifo_id(struct frddr *fr);
|
||||
/* audio eq drc */
|
||||
void aml_aed_enable(bool enable, int aed_module);
|
||||
|
||||
void frddr_init_default(unsigned int frddr_index, unsigned int src0_sel);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ static int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream,
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
int bit_depth;
|
||||
struct iec958_chsts chsts;
|
||||
|
||||
bit_depth = snd_pcm_format_width(runtime->format);
|
||||
|
||||
@@ -35,11 +36,13 @@ static int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream,
|
||||
aml_frddr_get_fifo_id(fr),
|
||||
bit_depth, true);
|
||||
|
||||
/* spdif b, notify hdmitx audio */
|
||||
if (spdif_id == 1) {
|
||||
spdifoutb_to_hdmitx_ctrl(spdif_id);
|
||||
aout_notifier_call_chain(0x1, substream);
|
||||
}
|
||||
/* spdif to hdmitx */
|
||||
spdifoutb_to_hdmitx_ctrl(spdif_id);
|
||||
/* check and set channel status */
|
||||
spdif_get_channel_status_info(&chsts, runtime->rate);
|
||||
spdif_set_channel_status_info(&chsts, spdif_id);
|
||||
/* notify hdmitx audio */
|
||||
aout_notifier_call_chain(0x1, substream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -52,9 +55,11 @@ static int sharebuffer_spdifout_free(struct snd_pcm_substream *substream,
|
||||
|
||||
bit_depth = snd_pcm_format_width(runtime->format);
|
||||
|
||||
spdifout_samesource_set(spdif_id,
|
||||
aml_frddr_get_fifo_id(fr),
|
||||
bit_depth, false);
|
||||
/* spdif b is always on */
|
||||
if (spdif_id != 1)
|
||||
spdifout_samesource_set(spdif_id,
|
||||
aml_frddr_get_fifo_id(fr),
|
||||
bit_depth, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,8 +38,6 @@
|
||||
#include "spdif_hw.h"
|
||||
#include "audio_utils.h"
|
||||
|
||||
#include <linux/amlogic/media/sound/aout_notify.h>
|
||||
|
||||
#define DRV_NAME "aml_spdif"
|
||||
|
||||
#define SPDIF_A 0
|
||||
@@ -81,6 +79,7 @@ struct aml_spdif {
|
||||
|
||||
unsigned int id;
|
||||
struct spdif_chipinfo *chipinfo;
|
||||
unsigned int clk_cont; /* CONTINUOUS CLOCK */
|
||||
};
|
||||
|
||||
static const struct snd_pcm_hardware aml_spdif_hardware = {
|
||||
@@ -276,6 +275,9 @@ static irqreturn_t aml_spdif_ddr_isr(int irq, void *devid)
|
||||
struct snd_pcm_substream *substream =
|
||||
(struct snd_pcm_substream *)devid;
|
||||
|
||||
if (!snd_pcm_running(substream))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
snd_pcm_period_elapsed(substream);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -389,8 +391,6 @@ static int aml_spdif_prepare(struct snd_pcm_substream *substream)
|
||||
end_addr = start_addr + runtime->dma_bytes - 8;
|
||||
int_addr = frames_to_bytes(runtime, runtime->period_size) / 8;
|
||||
|
||||
pr_info("asoc debug: %s-%d\n", __func__, __LINE__);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
struct frddr *fr = p_spdif->fddr;
|
||||
|
||||
@@ -411,6 +411,7 @@ static snd_pcm_uframes_t aml_spdif_pointer(struct snd_pcm_substream *substream)
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct aml_spdif *p_spdif = runtime->private_data;
|
||||
unsigned int addr, start_addr;
|
||||
snd_pcm_uframes_t frames;
|
||||
|
||||
start_addr = runtime->dma_addr;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
@@ -418,7 +419,11 @@ static snd_pcm_uframes_t aml_spdif_pointer(struct snd_pcm_substream *substream)
|
||||
else
|
||||
addr = aml_toddr_get_position(p_spdif->tddr);
|
||||
|
||||
return bytes_to_frames(runtime, addr - start_addr);
|
||||
frames = bytes_to_frames(runtime, addr - start_addr);
|
||||
if (frames > runtime->buffer_size)
|
||||
frames = 0;
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
int aml_spdif_silence(struct snd_pcm_substream *substream, int channel,
|
||||
@@ -502,14 +507,29 @@ static int aml_dai_spdif_startup(
|
||||
|
||||
pr_info("asoc debug: %s-%d\n", __func__, __LINE__);
|
||||
|
||||
aml_spdif_fifo_reset(p_spdif->actrl,
|
||||
substream->stream,
|
||||
p_spdif->id);
|
||||
if (!p_spdif->clk_cont)
|
||||
aml_spdif_fifo_reset(p_spdif->actrl,
|
||||
substream->stream,
|
||||
p_spdif->id);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
/* enable clock gate */
|
||||
|
||||
if (p_spdif->clk_cont) {
|
||||
pr_info("spdif_%s keep clk continuous\n",
|
||||
(p_spdif->id == 0) ? "a":"b");
|
||||
return 0;
|
||||
}
|
||||
/* enable clock gate */
|
||||
ret = clk_prepare_enable(p_spdif->gate_spdifout);
|
||||
|
||||
/* clock parent */
|
||||
ret = clk_set_parent(p_spdif->clk_spdifout, p_spdif->sysclk);
|
||||
if (ret) {
|
||||
pr_err("Can't set clk_spdifout parent clock\n");
|
||||
ret = PTR_ERR(p_spdif->clk_spdifout);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* enable clock */
|
||||
ret = clk_prepare_enable(p_spdif->sysclk);
|
||||
if (ret) {
|
||||
@@ -522,10 +542,18 @@ static int aml_dai_spdif_startup(
|
||||
ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* enable clock gate */
|
||||
ret = clk_prepare_enable(p_spdif->gate_spdifin);
|
||||
|
||||
/* clock parent */
|
||||
ret = clk_set_parent(p_spdif->clk_spdifin, p_spdif->fixed_clk);
|
||||
if (ret) {
|
||||
pr_err("Can't set clk_spdifin parent clock\n");
|
||||
ret = PTR_ERR(p_spdif->clk_spdifin);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* enable clock */
|
||||
ret = clk_prepare_enable(p_spdif->fixed_clk);
|
||||
if (ret) {
|
||||
@@ -553,6 +581,12 @@ static void aml_dai_spdif_shutdown(
|
||||
|
||||
/* disable clock and gate */
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
if (p_spdif->clk_cont) {
|
||||
pr_info("spdif_%s keep clk continuous\n",
|
||||
(p_spdif->id == 0) ? "a":"b");
|
||||
return;
|
||||
}
|
||||
|
||||
clk_disable_unprepare(p_spdif->clk_spdifout);
|
||||
clk_disable_unprepare(p_spdif->sysclk);
|
||||
clk_disable_unprepare(p_spdif->gate_spdifout);
|
||||
@@ -573,13 +607,12 @@ static int aml_dai_spdif_prepare(
|
||||
unsigned int bit_depth = 0;
|
||||
unsigned int fifo_id = 0;
|
||||
|
||||
pr_info("%s stream:%d\n", __func__, substream->stream);
|
||||
|
||||
bit_depth = snd_pcm_format_width(runtime->format);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
struct frddr *fr = p_spdif->fddr;
|
||||
enum frddr_dest dst;
|
||||
struct iec958_chsts chsts;
|
||||
|
||||
switch (p_spdif->id) {
|
||||
case 0:
|
||||
@@ -597,47 +630,17 @@ static int aml_dai_spdif_prepare(
|
||||
aml_frddr_select_dst(fr, dst);
|
||||
aml_frddr_set_fifos(fr, 0x40, 0x20);
|
||||
|
||||
/* check channel status info, and set them */
|
||||
spdif_get_channel_status_info(&chsts, runtime->rate);
|
||||
spdif_set_channel_status_info(&chsts, p_spdif->id);
|
||||
|
||||
/* TOHDMITX_CTRL0 */
|
||||
if (p_spdif->id == 1) {
|
||||
spdifoutb_to_hdmitx_ctrl(p_spdif->id);
|
||||
if (IEC958_mode_codec == 2) {
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_AC_3,
|
||||
substream);
|
||||
} else if (IEC958_mode_codec == 3) {
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_DTS,
|
||||
substream);
|
||||
} else if (IEC958_mode_codec == 4) {
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_DOBLY_DIGITAL_PLUS,
|
||||
substream);
|
||||
} else if (IEC958_mode_codec == 5) {
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_DTS_HD,
|
||||
substream);
|
||||
} else if (IEC958_mode_codec == 7 ||
|
||||
IEC958_mode_codec == 8) {
|
||||
//aml_aiu_write(AIU_958_CHSTAT_L0, 0x1902);
|
||||
//aml_aiu_write(AIU_958_CHSTAT_L1, 0x900);
|
||||
//aml_aiu_write(AIU_958_CHSTAT_R0, 0x1902);
|
||||
//aml_aiu_write(AIU_958_CHSTAT_R1, 0x900);
|
||||
if (IEC958_mode_codec == 8)
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_DTS_HD_MA,
|
||||
substream);
|
||||
else
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_MAT_MLP,
|
||||
substream);
|
||||
} else {
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_IEC_60958_PCM,
|
||||
substream);
|
||||
}
|
||||
|
||||
/* notify to hdmitx */
|
||||
spdif_notify_to_hdmitx(substream);
|
||||
}
|
||||
|
||||
} else {
|
||||
struct toddr *to = p_spdif->tddr;
|
||||
unsigned int msb, lsb, toddr_type;
|
||||
@@ -729,8 +732,9 @@ static int aml_dai_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
dev_info(substream->pcm->card->dev, "spdif capture disable\n");
|
||||
aml_toddr_enable(p_spdif->tddr, 0);
|
||||
}
|
||||
aml_spdif_enable(p_spdif->actrl,
|
||||
substream->stream, p_spdif->id, false);
|
||||
if (!p_spdif->clk_cont)
|
||||
aml_spdif_enable(p_spdif->actrl,
|
||||
substream->stream, p_spdif->id, false);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@@ -779,13 +783,14 @@ static void aml_set_spdifclk(struct aml_spdif *p_spdif)
|
||||
p_spdif->sysclk_freq);
|
||||
if (p_spdif->sysclk_freq) {
|
||||
unsigned int mul = 4;
|
||||
if (IEC958_mode_codec == 4 || IEC958_mode_codec == 5 ||
|
||||
IEC958_mode_codec == 7 || IEC958_mode_codec == 8) {
|
||||
pr_info("set 4x audio clk for 958\n");
|
||||
p_spdif->sysclk_freq = p_spdif->sysclk_freq * 4;
|
||||
} else {
|
||||
pr_info("set normal 512 fs /4 fs\n");
|
||||
}
|
||||
int ret;
|
||||
|
||||
if (spdif_is_4x_clk()) {
|
||||
pr_info("set 4x audio clk for 958\n");
|
||||
p_spdif->sysclk_freq *= 4;
|
||||
} else {
|
||||
pr_info("set normal 512 fs /4 fs\n");
|
||||
}
|
||||
mpll_freq = p_spdif->sysclk_freq * mul;
|
||||
|
||||
#ifdef G12A_PTM
|
||||
@@ -794,6 +799,17 @@ static void aml_set_spdifclk(struct aml_spdif *p_spdif)
|
||||
clk_set_rate(p_spdif->sysclk, mpll_freq);
|
||||
clk_set_rate(p_spdif->clk_spdifout,
|
||||
p_spdif->sysclk_freq);
|
||||
|
||||
ret = clk_prepare_enable(p_spdif->sysclk);
|
||||
if (ret) {
|
||||
pr_err("Can't enable pcm sysclk clock: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
ret = clk_prepare_enable(p_spdif->clk_spdifout);
|
||||
if (ret) {
|
||||
pr_err("Can't enable clk_spdifout clock: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -933,13 +949,6 @@ static int aml_spdif_parse_of(struct platform_device *pdev)
|
||||
dev_err(dev, "Can't retrieve spdifout clock\n");
|
||||
return PTR_ERR(p_spdif->clk_spdifout);
|
||||
}
|
||||
ret = clk_set_parent(p_spdif->clk_spdifout, p_spdif->sysclk);
|
||||
if (ret) {
|
||||
dev_err(dev,
|
||||
"Can't set clk_spdifout parent clock\n");
|
||||
ret = PTR_ERR(p_spdif->clk_spdifout);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1007,6 +1016,15 @@ static int aml_spdif_platform_probe(struct platform_device *pdev)
|
||||
of_device_get_match_data(dev);
|
||||
if (p_spdif_chipinfo) {
|
||||
aml_spdif->id = p_spdif_chipinfo->id;
|
||||
/* for spdif_b, clk be continuous,
|
||||
* and keep silence when no valid data
|
||||
*/
|
||||
if (aml_spdif->id == 1)
|
||||
aml_spdif->clk_cont = 1;
|
||||
|
||||
if (aml_spdif->clk_cont)
|
||||
spdifout_play_with_zerodata(aml_spdif->id);
|
||||
|
||||
aml_spdif->chipinfo = p_spdif_chipinfo;
|
||||
} else
|
||||
dev_warn_once(dev,
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
#include "iomap.h"
|
||||
#include "spdif_hw.h"
|
||||
#include "ddr_mngr.h"
|
||||
|
||||
#include <linux/amlogic/media/sound/aout_notify.h>
|
||||
|
||||
/*#define G12A_PTM*/
|
||||
/*#define G12A_PTM_LB_INTERNAL*/
|
||||
@@ -29,8 +32,6 @@ void aml_spdif_enable(
|
||||
int index,
|
||||
bool is_enable)
|
||||
{
|
||||
pr_info("spdif stream :%d is_enable:%d\n", stream, is_enable);
|
||||
|
||||
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
unsigned int offset, reg;
|
||||
|
||||
@@ -146,8 +147,8 @@ void aml_spdif_fifo_ctrl(
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
|
||||
aml_audiobus_update_bits(actrl,
|
||||
reg,
|
||||
0x1<<29|0x1<<28|0x1<<20|0x1<<19|0xff<<4,
|
||||
1<<29|1<<28|0<<20|0<<19|0x3<<4);
|
||||
0x1<<29|0x1<<28|0x3<<21|0x1<<20|0x1<<19|0xff<<4,
|
||||
1<<29|1<<28|0x0<<21|0<<20|0<<19|0x3<<4);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL1 - EE_AUDIO_SPDIFOUT_CTRL1;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * index;
|
||||
@@ -319,15 +320,18 @@ void spdifout_fifo_ctrl(int spdif_id, int fifo_id, int bitwidth)
|
||||
return;
|
||||
}
|
||||
|
||||
pr_info("%s, bit depth:%d, frddr type:%d\n",
|
||||
__func__, bitwidth, frddr_type);
|
||||
pr_info("spdif_%s fifo ctrl, frddr:%d type:%d, %d bits\n",
|
||||
(spdif_id == 0) ? "a":"b",
|
||||
fifo_id,
|
||||
frddr_type,
|
||||
bitwidth);
|
||||
|
||||
/* mask lane 0 L/R channels */
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
|
||||
audiobus_update_bits(reg,
|
||||
0x1<<29|0x1<<28|0x1<<20|0x1<<19|0xff<<4,
|
||||
1<<29|1<<28|0<<20|0<<19|0x3<<4);
|
||||
0x3<<21|0x1<<20|0x1<<19|0xff<<4,
|
||||
0x0<<21|0<<20|0<<19|0x3<<4);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL1 - EE_AUDIO_SPDIFOUT_CTRL1;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * spdif_id;
|
||||
@@ -345,15 +349,46 @@ void spdifout_fifo_ctrl(int spdif_id, int fifo_id, int bitwidth)
|
||||
audiobus_update_bits(reg, 3<<28, 0);
|
||||
audiobus_update_bits(reg, 1<<29, 1<<29);
|
||||
audiobus_update_bits(reg, 1<<28, 1<<28);
|
||||
}
|
||||
|
||||
static void spdifout_mute(int spdif_id)
|
||||
{
|
||||
unsigned int offset, reg;
|
||||
|
||||
/* mute */
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
|
||||
audiobus_update_bits(reg, 0x3 << 21, 0x3 << 21);
|
||||
}
|
||||
|
||||
static bool spdifout_is_enable(int spdif_id)
|
||||
{
|
||||
unsigned int offset, reg, val;
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
|
||||
val = audiobus_read(reg);
|
||||
|
||||
return ((val >> 31) == 1);
|
||||
}
|
||||
|
||||
void spdifout_enable(int spdif_id, bool is_enable)
|
||||
{
|
||||
unsigned int offset, reg;
|
||||
|
||||
pr_info("spdif_%s is set to %s\n",
|
||||
(spdif_id == 0) ? "a":"b",
|
||||
is_enable ? "enable":"disable");
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
|
||||
|
||||
if (!is_enable) {
|
||||
/* share buffer, spdif should be active, so mute it */
|
||||
audiobus_update_bits(reg, 0x3 << 21, 0x3 << 21);
|
||||
return;
|
||||
}
|
||||
|
||||
audiobus_update_bits(reg, 1<<31, is_enable<<31);
|
||||
}
|
||||
|
||||
@@ -367,11 +402,12 @@ void spdifout_samesource_set(int spdif_index, int fifo_id,
|
||||
else
|
||||
spdif_id = 0;
|
||||
|
||||
if (is_enable) {
|
||||
spdifout_clk_ctrl(spdif_id, true);
|
||||
/* clk for spdif_b is always on */
|
||||
if (!spdif_id)
|
||||
spdifout_clk_ctrl(spdif_id, is_enable);
|
||||
|
||||
if (is_enable)
|
||||
spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth);
|
||||
} else
|
||||
spdifout_clk_ctrl(spdif_id, false);
|
||||
}
|
||||
|
||||
int spdifin_get_sample_rate(void)
|
||||
@@ -394,3 +430,107 @@ int spdifin_get_audio_type(void)
|
||||
|
||||
return (val >> 16) & 0xff;
|
||||
}
|
||||
|
||||
void spdif_set_channel_status_info(
|
||||
struct iec958_chsts *chsts, int spdif_id)
|
||||
{
|
||||
unsigned int offset, reg;
|
||||
|
||||
/* "ch status" = reg_chsts0~B */
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
|
||||
audiobus_update_bits(reg, 0x1 << 24, 0x0 << 24);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTS0 - EE_AUDIO_SPDIFOUT_CHSTS0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTS0 + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTS1 - EE_AUDIO_SPDIFOUT_CHSTS1;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTS1 + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTS2 - EE_AUDIO_SPDIFOUT_CHSTS2;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTS2 + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTS3 - EE_AUDIO_SPDIFOUT_CHSTS3;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTS3 + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTS4 - EE_AUDIO_SPDIFOUT_CHSTS4;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTS4 + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTS5 - EE_AUDIO_SPDIFOUT_CHSTS5;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTS5 + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_l << 16 | chsts->chstat0_l);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTS6 - EE_AUDIO_SPDIFOUT_CHSTS6;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTS6 + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTS7 - EE_AUDIO_SPDIFOUT_CHSTS7;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTS7 + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTS8 - EE_AUDIO_SPDIFOUT_CHSTS8;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTS8 + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTS9 - EE_AUDIO_SPDIFOUT_CHSTS9;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTS9 + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTSA - EE_AUDIO_SPDIFOUT_CHSTSA;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTSA + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CHSTSB - EE_AUDIO_SPDIFOUT_CHSTSB;
|
||||
reg = EE_AUDIO_SPDIFOUT_CHSTSB + offset * spdif_id;
|
||||
audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
|
||||
}
|
||||
|
||||
void spdifout_play_with_zerodata(unsigned int spdif_id)
|
||||
{
|
||||
pr_info("%s, spdif id:%d enable:%d\n",
|
||||
__func__,
|
||||
spdif_id,
|
||||
spdifout_is_enable(spdif_id));
|
||||
|
||||
if (!spdifout_is_enable(spdif_id)) {
|
||||
unsigned int frddr_index = 0;
|
||||
unsigned int bitwidth = 32;
|
||||
unsigned int sample_rate = 48000;
|
||||
unsigned int src0_sel = 4; /* spdif b */
|
||||
struct iec958_chsts chsts;
|
||||
struct snd_pcm_substream substream;
|
||||
struct snd_pcm_runtime runtime;
|
||||
|
||||
substream.runtime = &runtime;
|
||||
runtime.rate = 48000;
|
||||
runtime.format = SNDRV_PCM_FORMAT_S16_LE;
|
||||
runtime.channels = 2;
|
||||
runtime.sample_bits = 16;
|
||||
|
||||
/* check whether fix to spdif a */
|
||||
if (spdif_id == 0)
|
||||
src0_sel = 3;
|
||||
|
||||
/* spdif ctrl */
|
||||
spdifout_fifo_ctrl(spdif_id, frddr_index, bitwidth);
|
||||
|
||||
/* channel status info */
|
||||
spdif_get_channel_status_info(&chsts, sample_rate);
|
||||
spdif_set_channel_status_info(&chsts, spdif_id);
|
||||
|
||||
/* notify hdmitx audio */
|
||||
spdifoutb_to_hdmitx_ctrl(spdif_id);
|
||||
aout_notifier_call_chain(0x1, &substream);
|
||||
|
||||
frddr_init_default(frddr_index, src0_sel);
|
||||
|
||||
spdifout_enable(spdif_id, true);
|
||||
|
||||
spdifout_mute(spdif_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,8 @@
|
||||
#define __AML_SPDIF_HW_H__
|
||||
#include "audio_io.h"
|
||||
#include "regs.h"
|
||||
/*
|
||||
* 0 -- other formats except(DD,DD+,DTS)
|
||||
* 1 -- DTS
|
||||
* 2 -- DD
|
||||
* 3 -- DTS with 958 PCM RAW package mode
|
||||
* 4 -- DD+
|
||||
*/
|
||||
|
||||
extern unsigned int IEC958_mode_codec;
|
||||
#include <linux/amlogic/media/sound/spdif_info.h>
|
||||
|
||||
extern void aml_spdif_enable(
|
||||
struct aml_audio_controller *actrl,
|
||||
@@ -71,4 +64,9 @@ extern void spdifout_enable(int spdif_id, bool is_enable);
|
||||
extern int spdifin_get_sample_rate(void);
|
||||
|
||||
extern int spdifin_get_audio_type(void);
|
||||
|
||||
extern void spdif_set_channel_status_info(
|
||||
struct iec958_chsts *chsts, int spdif_id);
|
||||
|
||||
extern void spdifout_play_with_zerodata(unsigned int spdif_id);
|
||||
#endif
|
||||
|
||||
@@ -139,6 +139,9 @@ static irqreturn_t aml_tdm_ddr_isr(int irq, void *devid)
|
||||
{
|
||||
struct snd_pcm_substream *substream = (struct snd_pcm_substream *)devid;
|
||||
|
||||
if (!snd_pcm_running(substream))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
snd_pcm_period_elapsed(substream);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -314,6 +317,7 @@ static snd_pcm_uframes_t aml_tdm_pointer(struct snd_pcm_substream *substream)
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct aml_tdm *p_tdm = runtime->private_data;
|
||||
unsigned int addr, start_addr;
|
||||
snd_pcm_uframes_t frames;
|
||||
|
||||
start_addr = runtime->dma_addr;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
@@ -321,7 +325,11 @@ static snd_pcm_uframes_t aml_tdm_pointer(struct snd_pcm_substream *substream)
|
||||
else
|
||||
addr = aml_toddr_get_position(p_tdm->tddr);
|
||||
|
||||
return bytes_to_frames(runtime, addr - start_addr);
|
||||
frames = bytes_to_frames(runtime, addr - start_addr);
|
||||
if (frames > runtime->buffer_size)
|
||||
frames = 0;
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
static int aml_tdm_mmap(struct snd_pcm_substream *substream,
|
||||
|
||||
@@ -1 +1 @@
|
||||
obj-y += notify.o
|
||||
obj-y += notify.o spdif_info.o
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* sound/soc/amlogic/meson/notify.c
|
||||
* sound/soc/amlogic/common/notify.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
|
||||
160
sound/soc/amlogic/common/spdif_info.c
Normal file
160
sound/soc/amlogic/common/spdif_info.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* sound/soc/amlogic/common/spdif_info.c
|
||||
*
|
||||
* Copyright (C) 2018 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
*/
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "spdif_info: " fmt
|
||||
|
||||
#include <linux/amlogic/media/sound/aout_notify.h>
|
||||
#include <linux/amlogic/media/sound/spdif_info.h>
|
||||
|
||||
/*
|
||||
* 0 -- other formats except(DD,DD+,DTS)
|
||||
* 1 -- DTS
|
||||
* 2 -- DD
|
||||
* 3 -- DTS with 958 PCM RAW package mode
|
||||
* 4 -- DD+
|
||||
*/
|
||||
unsigned int IEC958_mode_codec;
|
||||
EXPORT_SYMBOL(IEC958_mode_codec);
|
||||
|
||||
bool spdif_is_4x_clk(void)
|
||||
{
|
||||
bool is_4x = false;
|
||||
|
||||
if (IEC958_mode_codec == 4 || IEC958_mode_codec == 5 ||
|
||||
IEC958_mode_codec == 7 || IEC958_mode_codec == 8) {
|
||||
is_4x = true;
|
||||
}
|
||||
|
||||
return is_4x;
|
||||
}
|
||||
|
||||
void spdif_get_channel_status_info(
|
||||
struct iec958_chsts *chsts,
|
||||
unsigned int rate)
|
||||
{
|
||||
int rate_bit = snd_pcm_rate_to_rate_bit(rate);
|
||||
|
||||
if (rate_bit == SNDRV_PCM_RATE_KNOT) {
|
||||
pr_err("Unsupport sample rate\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IEC958_mode_codec && IEC958_mode_codec != 9) {
|
||||
if (IEC958_mode_codec == 1) {
|
||||
/* dts, use raw sync-word mode */
|
||||
pr_info("iec958 mode RAW\n");
|
||||
} else {
|
||||
/* ac3,use the same pcm mode as i2s */
|
||||
}
|
||||
|
||||
chsts->chstat0_l = 0x1902;
|
||||
chsts->chstat0_r = 0x1902;
|
||||
if (IEC958_mode_codec == 4 || IEC958_mode_codec == 5) {
|
||||
/* DD+ */
|
||||
if (rate_bit == SNDRV_PCM_RATE_32000) {
|
||||
chsts->chstat1_l = 0x300;
|
||||
chsts->chstat1_r = 0x300;
|
||||
} else if (rate_bit == SNDRV_PCM_RATE_44100) {
|
||||
chsts->chstat1_l = 0xc00;
|
||||
chsts->chstat1_r = 0xc00;
|
||||
} else {
|
||||
chsts->chstat1_l = 0Xe00;
|
||||
chsts->chstat1_r = 0Xe00;
|
||||
}
|
||||
} else {
|
||||
/* DTS,DD */
|
||||
if (rate_bit == SNDRV_PCM_RATE_32000) {
|
||||
chsts->chstat1_l = 0x300;
|
||||
chsts->chstat1_r = 0x300;
|
||||
} else if (rate_bit == SNDRV_PCM_RATE_44100) {
|
||||
chsts->chstat1_l = 0;
|
||||
chsts->chstat1_r = 0;
|
||||
} else {
|
||||
chsts->chstat1_l = 0x200;
|
||||
chsts->chstat1_r = 0x200;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
chsts->chstat0_l = 0x0100;
|
||||
chsts->chstat0_r = 0x0100;
|
||||
chsts->chstat1_l = 0x200;
|
||||
chsts->chstat1_r = 0x200;
|
||||
|
||||
if (rate_bit == SNDRV_PCM_RATE_44100) {
|
||||
chsts->chstat1_l = 0;
|
||||
chsts->chstat1_r = 0;
|
||||
} else if (rate_bit == SNDRV_PCM_RATE_88200) {
|
||||
chsts->chstat1_l = 0x800;
|
||||
chsts->chstat1_r = 0x800;
|
||||
} else if (rate_bit == SNDRV_PCM_RATE_96000) {
|
||||
chsts->chstat1_l = 0xa00;
|
||||
chsts->chstat1_r = 0xa00;
|
||||
} else if (rate_bit == SNDRV_PCM_RATE_176400) {
|
||||
chsts->chstat1_l = 0xc00;
|
||||
chsts->chstat1_r = 0xc00;
|
||||
} else if (rate_bit == SNDRV_PCM_RATE_192000) {
|
||||
chsts->chstat1_l = 0xe00;
|
||||
chsts->chstat1_r = 0xe00;
|
||||
}
|
||||
}
|
||||
pr_info("rate: %d, channel status ch0_l:0x%x, ch0_r:0x%x, ch1_l:0x%x, ch1_r:0x%x\n",
|
||||
rate,
|
||||
chsts->chstat0_l,
|
||||
chsts->chstat0_r,
|
||||
chsts->chstat1_l,
|
||||
chsts->chstat1_r);
|
||||
}
|
||||
|
||||
|
||||
void spdif_notify_to_hdmitx(struct snd_pcm_substream *substream)
|
||||
{
|
||||
if (IEC958_mode_codec == 2) {
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_AC_3,
|
||||
substream);
|
||||
} else if (IEC958_mode_codec == 3) {
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_DTS,
|
||||
substream);
|
||||
} else if (IEC958_mode_codec == 4) {
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_DOBLY_DIGITAL_PLUS,
|
||||
substream);
|
||||
} else if (IEC958_mode_codec == 5) {
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_DTS_HD,
|
||||
substream);
|
||||
} else if (IEC958_mode_codec == 7 ||
|
||||
IEC958_mode_codec == 8) {
|
||||
//aml_aiu_write(AIU_958_CHSTAT_L0, 0x1902);
|
||||
//aml_aiu_write(AIU_958_CHSTAT_L1, 0x900);
|
||||
//aml_aiu_write(AIU_958_CHSTAT_R0, 0x1902);
|
||||
//aml_aiu_write(AIU_958_CHSTAT_R1, 0x900);
|
||||
if (IEC958_mode_codec == 8)
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_DTS_HD_MA,
|
||||
substream);
|
||||
else
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_RAWDATA_MAT_MLP,
|
||||
substream);
|
||||
} else {
|
||||
aout_notifier_call_chain(
|
||||
AOUT_EVENT_IEC_60958_PCM,
|
||||
substream);
|
||||
}
|
||||
}
|
||||
@@ -1011,7 +1011,7 @@ void audio_hw_958_raw(void)
|
||||
|
||||
}
|
||||
|
||||
void set_958_channel_status(struct _aiu_958_channel_status_t *set)
|
||||
void set_958_channel_status(struct iec958_chsts *set)
|
||||
{
|
||||
if (set) {
|
||||
aml_aiu_write(AIU_958_CHSTAT_L0, set->chstat0_l);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define __AML_AUDIO_HW_H__
|
||||
|
||||
#include "sound/asound.h"
|
||||
#include <linux/amlogic/media/sound/spdif_info.h>
|
||||
|
||||
#define AUDIO_CLK_GATE_ON(a) CLK_GATE_ON(a)
|
||||
#define AUDIO_CLK_GATE_OFF(a) CLK_GATE_OFF(a)
|
||||
@@ -29,13 +30,6 @@ struct _aiu_clk_setting_t {
|
||||
unsigned short devisor;
|
||||
};
|
||||
|
||||
struct _aiu_958_channel_status_t {
|
||||
unsigned short chstat0_l;
|
||||
unsigned short chstat1_l;
|
||||
unsigned short chstat0_r;
|
||||
unsigned short chstat1_r;
|
||||
};
|
||||
|
||||
struct audio_output_config_t {
|
||||
/* audio clock */
|
||||
unsigned short clock;
|
||||
@@ -55,7 +49,7 @@ struct audio_output_config_t {
|
||||
unsigned short brst;
|
||||
unsigned short length;
|
||||
unsigned short paddsize;
|
||||
struct _aiu_958_channel_status_t chan_status;
|
||||
struct iec958_chsts chan_status;
|
||||
};
|
||||
|
||||
struct _aiu_958_raw_setting_t {
|
||||
@@ -64,7 +58,7 @@ struct _aiu_958_raw_setting_t {
|
||||
unsigned short brst;
|
||||
unsigned short length;
|
||||
unsigned short paddsize;
|
||||
struct _aiu_958_channel_status_t *chan_stat;
|
||||
struct iec958_chsts *chan_stat;
|
||||
};
|
||||
|
||||
struct aml_chipset_info {
|
||||
|
||||
@@ -50,16 +50,6 @@
|
||||
#include <linux/amlogic/media/sound/audin_regs.h>
|
||||
#include <linux/amlogic/media/sound/audio_iomap.h>
|
||||
|
||||
/*
|
||||
* 0 -- other formats except(DD,DD+,DTS)
|
||||
* 1 -- DTS
|
||||
* 2 -- DD
|
||||
* 3 -- DTS with 958 PCM RAW package mode
|
||||
* 4 -- DD+
|
||||
*/
|
||||
unsigned int IEC958_mode_codec;
|
||||
EXPORT_SYMBOL(IEC958_mode_codec);
|
||||
|
||||
struct aml_spdif {
|
||||
struct clk *clk_mpl1;
|
||||
struct clk *clk_i958;
|
||||
@@ -99,7 +89,7 @@ void aml_spdif_play(int samesrc)
|
||||
uint div = 0;
|
||||
static int iec958buf[DEFAULT_PLAYBACK_SIZE];
|
||||
struct _aiu_958_raw_setting_t set;
|
||||
struct _aiu_958_channel_status_t chstat;
|
||||
struct iec958_chsts chstat;
|
||||
struct snd_pcm_substream substream;
|
||||
struct snd_pcm_runtime runtime;
|
||||
int size = DEFAULT_PLAYBACK_SIZE;
|
||||
@@ -203,7 +193,7 @@ static int aml_dai_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
void aml_hw_iec958_init(struct snd_pcm_substream *substream, int samesrc)
|
||||
{
|
||||
struct _aiu_958_raw_setting_t set;
|
||||
struct _aiu_958_channel_status_t chstat;
|
||||
struct iec958_chsts chstat;
|
||||
unsigned int i2s_mode, iec958_mode;
|
||||
unsigned int start, size;
|
||||
int sample_rate;
|
||||
|
||||
Reference in New Issue
Block a user