mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
audio: auge: fix audio locker, resample, tdm format, eq/drc, share buffer
PD#156734: audio: auge: fix audio locker, resample, tdm format, eq/drc, share buffer Change-Id: I03750c34310bdbc32eddc51f64cf4b91a95325bc Signed-off-by: Xing Wang <xing.wang@amlogic.com>
This commit is contained in:
@@ -14355,3 +14355,7 @@ AMLOGIC THERMAL DRIVER
|
||||
M: Huan Biao <huan.biao@amlogic.com>
|
||||
F: drivers/amlgoic/thermal/meson_tsensor.c
|
||||
F: drivers/amlogic/thermal/meson_cooldev.c
|
||||
|
||||
AMLOGIC G12A Audio DRIVER
|
||||
M: Xing Wang <xing.wang@amlogic.com>
|
||||
F: sound/soc/amlogic/auge/*
|
||||
|
||||
@@ -944,14 +944,35 @@
|
||||
tdmout_index = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
audio_effect:eqdrc{
|
||||
/*eq_enable = <1>;*/
|
||||
/*drc_enable = <1>;*/
|
||||
/*
|
||||
* 0:tdmout_a
|
||||
* 1:tdmout_b
|
||||
* 2:tdmout_c
|
||||
* 3:spdifout
|
||||
* 4:spdifout_b
|
||||
*/
|
||||
eqdrc_module = <1>;
|
||||
/* max 0xf, each bit for one lane, usually one lane */
|
||||
lane_mask = <0x1>;
|
||||
/* max 0xff, each bit for one channel */
|
||||
channel_mask = <0x3>;
|
||||
};
|
||||
auge_sound {
|
||||
compatible = "amlogic, g12a-sound-card";
|
||||
aml-audio-card,name = "AML-AUGESOUND";
|
||||
|
||||
aml-audio-card,loopback = <&aml_loopback>;
|
||||
|
||||
aml-audio-card,aux-devs = <&amlogic_codec>;
|
||||
/*avout mute gpio*/
|
||||
avout_mute-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
/*for audio effect ,eqdrc */
|
||||
aml-audio-card,effect = <&audio_effect>;
|
||||
|
||||
aml-audio-card,dai-link@0 {
|
||||
format = "dsp_a";
|
||||
mclk-fs = <512>;
|
||||
@@ -976,38 +997,42 @@
|
||||
};
|
||||
|
||||
aml-audio-card,dai-link@1 {
|
||||
format = "i2s"; /*"dsp_a";*/
|
||||
format = "i2s";// "dsp_a";
|
||||
mclk-fs = <256>;
|
||||
//continuous-clock;
|
||||
//bitclock-inversion;
|
||||
//frame-inversion;
|
||||
bitclock-master = <&aml_tdmb>;
|
||||
frame-master = <&aml_tdmb>;
|
||||
//bitclock-master = <&tdmbcodec>;
|
||||
//frame-master = <&tdmbcodec>;
|
||||
cpu {
|
||||
sound-dai = <&aml_tdmb>;
|
||||
|
||||
dai-tdm-slot-tx-mask = <1 1>;
|
||||
dai-tdm-slot-rx-mask = <1 1>;
|
||||
dai-tdm-slot-num = <2>;
|
||||
/*
|
||||
* dai-tdm-slot-tx-mask =
|
||||
* <1 1 1 1 1 1 1 1>;
|
||||
* dai-tdm-slot-rx-mask =
|
||||
* <1 1 1 1 1 1 1 1>;
|
||||
* dai-tdm-slot-num = <8>;
|
||||
*/
|
||||
|
||||
/*
|
||||
* dai-tdm-slot-tx-mask =
|
||||
* <1 1 1 1 1 1 1 1>;
|
||||
* dai-tdm-slot-rx-mask =
|
||||
* <1 1 1 1 1 1 1 1>;
|
||||
* dai-tdm-slot-num = <8>;
|
||||
*/
|
||||
dai-tdm-slot-width = <32>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec &amlogic_codec
|
||||
/*&ad82584f_62*/>;
|
||||
tdmbcodec: codec {
|
||||
sound-dai = <&dummy_codec &dummy_codec
|
||||
&amlogic_codec /*&ad82584f_62*/>;
|
||||
};
|
||||
};
|
||||
|
||||
aml-audio-card,dai-link@2 {
|
||||
format = "i2s";
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
//continuous-clock;
|
||||
//bitclock-inversion;
|
||||
//frame-inversion;
|
||||
bitclock-master = <&aml_tdmc>;
|
||||
@@ -1070,7 +1095,7 @@
|
||||
interrupt-names = "irq";
|
||||
frequency = <49000000>; /* pll */
|
||||
dividor = <49>; /* locker's parent */
|
||||
status = "disabled";
|
||||
status = "okay";
|
||||
};
|
||||
/* Audio Related end */
|
||||
|
||||
@@ -1336,8 +1361,8 @@
|
||||
aml_tdma: tdma {
|
||||
compatible = "amlogic, g12a-snd-tdma";
|
||||
#sound-dai-cells = <0>;
|
||||
dai-tdm-lane-slot-mask-in = <1 0>;
|
||||
dai-tdm-lane-slot-mask-out = <0 1>;
|
||||
dai-tdm-lane-slot-mask-in = <0 1>;
|
||||
dai-tdm-oe-lane-slot-mask-out = <1 0>;
|
||||
dai-tdm-clk-sel = <0>;
|
||||
clocks = <&clkaudio CLKID_AUDIO_MCLK_A
|
||||
&clkc CLKID_MPLL0>;
|
||||
@@ -1357,6 +1382,14 @@
|
||||
clock-names = "mclk", "clk_srcpll";
|
||||
pinctrl-names = "tdm_pins";
|
||||
pinctrl-0 = <&tdmb_mclk &tdmout_b &tdmin_b>;
|
||||
/*
|
||||
* 0: tdmout_a;
|
||||
* 1: tdmout_b;
|
||||
* 2: tdmout_c;
|
||||
* 3: spdifout;
|
||||
* 4: spdifout_b;
|
||||
*/
|
||||
samesource_sel = <4>;
|
||||
};
|
||||
|
||||
aml_tdmc: tdmc {
|
||||
@@ -1401,8 +1434,6 @@
|
||||
&clkaudio CLKID_AUDIO_SPDIFOUTB_CTRL>;
|
||||
clock-names = "sysclk",
|
||||
"gate_spdifout", "clk_spdifout";
|
||||
//pinctrl-names = "spdif_pins";
|
||||
//pinctrl-0 = <&spdifout>;
|
||||
status = "okay";
|
||||
};
|
||||
aml_pdm: pdm {
|
||||
@@ -1423,6 +1454,59 @@
|
||||
filter_mode = <1>; /* mode 0~4, defalut:1 */
|
||||
status = "okay";
|
||||
};
|
||||
aml_loopback: loopback {
|
||||
compatible = "amlogic, snd-loopback";
|
||||
/*
|
||||
* 0: out rate = in data rate;
|
||||
* 1: out rate = loopback data rate;
|
||||
*/
|
||||
lb_mode = <0>;
|
||||
|
||||
/* datain src
|
||||
* 0: tdmin_a;
|
||||
* 1: tdmin_b;
|
||||
* 2: tdmin_c;
|
||||
* 3: spdifin;
|
||||
* 4: pdmin;
|
||||
*/
|
||||
datain_src = <4>;
|
||||
datain_chnum = <8>;
|
||||
datain_chmask = <0x3f>;
|
||||
|
||||
/* tdmin_lb src
|
||||
* 0: tdmoutA
|
||||
* 1: tdmoutB
|
||||
* 2: tdmoutC
|
||||
* 3: PAD_tdminA
|
||||
* 4: PAD_tdminB
|
||||
* 5: PAD_tdminC
|
||||
*/
|
||||
datalb_src = <2>;
|
||||
datalb_chnum = <8>;
|
||||
datalb_chmask = <0x3>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
audioresample: resample {
|
||||
compatible = "amlogic, g12a-resample";
|
||||
clocks = <&clkc CLKID_MPLL3
|
||||
&clkaudio CLKID_AUDIO_MCLK_F
|
||||
&clkaudio CLKID_AUDIO_RESAMPLE_CTRL>;
|
||||
clock-names = "resample_pll", "resample_src", "resample_clk";
|
||||
/*same with toddr_src
|
||||
* TDMIN_A, 0
|
||||
* TDMIN_B, 1
|
||||
* TDMIN_C, 2
|
||||
* SPDIFIN, 3
|
||||
* PDMIN, 4
|
||||
* NONE,
|
||||
* TDMIN_LB, 6
|
||||
* LOOPBACK, 7
|
||||
*/
|
||||
resample_module = <4>;
|
||||
status = "okay";
|
||||
};
|
||||
aml_pwrdet: pwrdet {
|
||||
compatible = "amlogic, g12a-power-detect";
|
||||
|
||||
@@ -1444,7 +1528,7 @@
|
||||
hi_th = <0x70000>;
|
||||
lo_th = <0x16000>;
|
||||
|
||||
status = "disabled";
|
||||
status = "okay";
|
||||
};
|
||||
}; /* end of audiobus */
|
||||
|
||||
@@ -1469,6 +1553,7 @@
|
||||
mux {
|
||||
groups = "mclk0_a";
|
||||
function = "mclk0";
|
||||
drive-strength = <2>;
|
||||
};
|
||||
};
|
||||
tdmout_b: tdmout_b {
|
||||
@@ -1477,13 +1562,16 @@
|
||||
"tdmb_fs",
|
||||
"tdmb_dout0";
|
||||
function = "tdmb_out";
|
||||
drive-strength = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
tdmin_b:tdmin_b {
|
||||
mux { /* GPIOA_4 */
|
||||
groups = "tdmb_din1";
|
||||
groups = "tdmb_din1"
|
||||
/*,"tdmb_slv_sclk", "tdmb_slv_fs"*/;
|
||||
function = "tdmb_in";
|
||||
drive-strength = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1535,7 +1623,7 @@
|
||||
groups = "pdm_din0_a",
|
||||
/*"pdm_din1_a",*/
|
||||
"pdm_din2_a",
|
||||
"pdm_din3_a",
|
||||
/*"pdm_din3_a",*/
|
||||
"pdm_dclk_a";
|
||||
function = "pdm";
|
||||
};
|
||||
|
||||
@@ -18,6 +18,24 @@
|
||||
#ifndef _AML_NOTIFY_H
|
||||
#define _AML_NOTIFY_H
|
||||
#include <linux/notifier.h>
|
||||
|
||||
/* HDMI audio stream type ID */
|
||||
#define AOUT_EVENT_IEC_60958_PCM 0x1
|
||||
#define AOUT_EVENT_RAWDATA_AC_3 0x2
|
||||
#define AOUT_EVENT_RAWDATA_MPEG1 0x3
|
||||
#define AOUT_EVENT_RAWDATA_MP3 0x4
|
||||
#define AOUT_EVENT_RAWDATA_MPEG2 0x5
|
||||
#define AOUT_EVENT_RAWDATA_AAC 0x6
|
||||
#define AOUT_EVENT_RAWDATA_DTS 0x7
|
||||
#define AOUT_EVENT_RAWDATA_ATRAC 0x8
|
||||
#define AOUT_EVENT_RAWDATA_ONE_BIT_AUDIO 0x9
|
||||
#define AOUT_EVENT_RAWDATA_DOBLY_DIGITAL_PLUS 0xA
|
||||
#define AOUT_EVENT_RAWDATA_DTS_HD 0xB
|
||||
#define AOUT_EVENT_RAWDATA_MAT_MLP 0xC
|
||||
#define AOUT_EVENT_RAWDATA_DST 0xD
|
||||
#define AOUT_EVENT_RAWDATA_WMA_PRO 0xE
|
||||
#define AOUT_EVENT_RAWDATA_DTS_HD_MA (AOUT_EVENT_RAWDATA_DTS_HD|(1<<8))
|
||||
|
||||
int aout_notifier_call_chain(unsigned long val, void *v);
|
||||
int aout_unregister_client(struct notifier_block *p);
|
||||
int aout_register_client(struct notifier_block *p);
|
||||
|
||||
@@ -23,4 +23,5 @@ obj-$(CONFIG_AMLOGIC_SND_SOC_AUGE) += audio_controller.o \
|
||||
effects.o \
|
||||
effects_hw.o \
|
||||
pwrdet.o \
|
||||
pwrdet_hw.o
|
||||
pwrdet_hw.o \
|
||||
sharebuffer.o
|
||||
|
||||
@@ -959,7 +959,7 @@ static int aml_card_probe(struct platform_device *pdev)
|
||||
|
||||
if (priv->chipinfo && priv->chipinfo->eqdrc_fn) {
|
||||
pr_info("eq/drc function enable\n");
|
||||
ret = card_add_eqdrc_kcontrols(&priv->snd_card);
|
||||
ret = card_add_effects_init(&priv->snd_card);
|
||||
if (ret < 0)
|
||||
pr_warn_once("Failed to add audio effects controls\n");
|
||||
} else
|
||||
|
||||
@@ -136,7 +136,7 @@ static void aml_check_pwrdet(bool enable);
|
||||
|
||||
/* Audio EQ DRC */
|
||||
static struct frddr_attach attach_aed;
|
||||
static void aml_check_aed(bool enable);
|
||||
static void aml_check_aed(bool enable, int dst);
|
||||
|
||||
/* to DDRS */
|
||||
static struct toddr *register_toddr_l(struct device *dev,
|
||||
@@ -716,7 +716,7 @@ void aml_frddr_enable(struct frddr *fr, bool enable)
|
||||
aml_audiobus_update_bits(actrl, reg, 1<<31, enable<<31);
|
||||
|
||||
/* check for Audio EQ/DRC */
|
||||
aml_check_aed(enable);
|
||||
aml_check_aed(enable, fr->dest);
|
||||
}
|
||||
|
||||
void aml_frddr_select_dst(struct frddr *fr, enum frddr_dest dst)
|
||||
@@ -737,6 +737,42 @@ void aml_frddr_select_dst(struct frddr *fr, enum frddr_dest dst)
|
||||
}
|
||||
}
|
||||
|
||||
/* select dst for same source
|
||||
* sel: share buffer req_sel 1~2
|
||||
* sel 0 is aleardy used for reg_frddr_src_sel1
|
||||
* sel 1 is for reg_frddr_src_sel2
|
||||
* sel 2 is for reg_frddr_src_sel3
|
||||
*/
|
||||
void aml_frddr_select_dst_ss(struct frddr *fr, enum frddr_dest dst, int sel)
|
||||
{
|
||||
struct aml_audio_controller *actrl = fr->actrl;
|
||||
unsigned int reg_base = fr->reg_base;
|
||||
unsigned int reg;
|
||||
|
||||
if (dst == fr->dest) {
|
||||
pr_warn_once("same source sel is same with frddr->dest\r");
|
||||
return;
|
||||
}
|
||||
|
||||
reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL0, reg_base);
|
||||
/* same source en */
|
||||
if (fr->chipinfo
|
||||
&& fr->chipinfo->same_src_fn) {
|
||||
|
||||
if (sel == 1)
|
||||
aml_audiobus_update_bits(actrl, reg,
|
||||
0xf << 4,
|
||||
dst << 4 | 1 << 7);
|
||||
else if (sel == 2)
|
||||
aml_audiobus_update_bits(actrl, reg,
|
||||
0xf << 8,
|
||||
dst << 8 | 1 << 11);
|
||||
else
|
||||
pr_warn_once("sel :%d is not supported for same source\n",
|
||||
sel);
|
||||
}
|
||||
}
|
||||
|
||||
void aml_frddr_set_fifos(struct frddr *fr,
|
||||
unsigned int depth, unsigned int thresh)
|
||||
{
|
||||
@@ -795,8 +831,12 @@ void aml_aed_enable(bool enable, int aed_module)
|
||||
}
|
||||
}
|
||||
|
||||
static void aml_check_aed(bool enable)
|
||||
static void aml_check_aed(bool enable, int dst)
|
||||
{
|
||||
/* check effect module is sync with crruent frddr dst */
|
||||
if (attach_aed.attach_module != dst)
|
||||
return;
|
||||
|
||||
/* AED in enable */
|
||||
if (attach_aed.enable) {
|
||||
if (enable) {
|
||||
|
||||
@@ -92,6 +92,8 @@ int aml_frddr_set_intrpt(struct frddr *fr, unsigned int intrpt);
|
||||
unsigned int aml_frddr_get_position(struct frddr *fr);
|
||||
void aml_frddr_enable(struct frddr *fr, bool enable);
|
||||
void aml_frddr_select_dst(struct frddr *fr, enum frddr_dest);
|
||||
extern void aml_frddr_select_dst_ss(struct frddr *fr,
|
||||
enum frddr_dest dst, int sel);
|
||||
void aml_frddr_set_fifos(struct frddr *fr,
|
||||
unsigned int depth, unsigned int thresh);
|
||||
unsigned int aml_frddr_get_fifo_id(struct frddr *fr);
|
||||
|
||||
@@ -131,7 +131,7 @@ static int mixer_set_AED_req_ctrl(struct snd_kcontrol *kcontrol,
|
||||
pr_info("AED req_sel0 module:%s\n", aed_req_module_texts[value]);
|
||||
|
||||
/* REQ_SEL0 */
|
||||
aed_req_sel(0, value);
|
||||
aed_req_sel(false, 0, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -140,9 +140,13 @@ static int mixer_set_EQ(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
unsigned int value = ucontrol->value.integer.value[0];
|
||||
int eqdrc_module;
|
||||
|
||||
aed_set_eq(value, aml_EQ_param_length, &aml_EQ_param[0]);
|
||||
|
||||
eqdrc_module = aed_get_req_sel(0);
|
||||
aml_aed_enable(value, eqdrc_module);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -150,10 +154,14 @@ static int mixer_set_DRC_params(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
unsigned int value = ucontrol->value.integer.value[0];
|
||||
int eqdrc_module;
|
||||
|
||||
aed_set_drc(value, aml_DRC_param_length, &aml_drc_table[0],
|
||||
aml_DRC_param_length, &aml_drc_tko_table[0]);
|
||||
|
||||
eqdrc_module = aed_get_req_sel(0);
|
||||
aml_aed_enable(value, eqdrc_module);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -185,59 +193,99 @@ static const struct snd_kcontrol_new snd_eqdrc_controls[] = {
|
||||
mixer_eqdrc_read, mixer_eqdrc_write,
|
||||
chvol_tlv),
|
||||
|
||||
SOC_SINGLE_EXT_TLV("EQ master volume mute",
|
||||
SOC_SINGLE_EXT("EQ master volume mute",
|
||||
AED_MUTE, 31, 0x1, 0,
|
||||
mixer_eqdrc_read, mixer_eqdrc_write,
|
||||
NULL),
|
||||
mixer_eqdrc_read, mixer_eqdrc_write),
|
||||
|
||||
SOC_SINGLE_EXT_TLV("EQ/DRC Channel Mask",
|
||||
SOC_SINGLE_EXT("EQ/DRC Channel Mask",
|
||||
AED_TOP_CTL, 18, 0xff, 0,
|
||||
mixer_eqdrc_read, mixer_eqdrc_write,
|
||||
NULL),
|
||||
mixer_eqdrc_read, mixer_eqdrc_write),
|
||||
|
||||
SOC_SINGLE_EXT_TLV("EQ/DRC Lane Mask",
|
||||
SOC_SINGLE_EXT("EQ/DRC Lane Mask",
|
||||
AED_TOP_CTL, 14, 0xf, 0,
|
||||
mixer_eqdrc_read, mixer_eqdrc_write,
|
||||
NULL),
|
||||
mixer_eqdrc_read, mixer_eqdrc_write),
|
||||
|
||||
SOC_SINGLE_EXT_TLV("EQ/DRC Req Module",
|
||||
SOC_SINGLE_EXT("EQ/DRC Req Module",
|
||||
AED_TOP_REQ_CTL, 0, 0x7, 0,
|
||||
mixer_eqdrc_read, mixer_set_AED_req_ctrl,
|
||||
NULL),
|
||||
mixer_eqdrc_read, mixer_set_AED_req_ctrl),
|
||||
|
||||
SOC_SINGLE_EXT_TLV("EQ enable",
|
||||
SOC_SINGLE_EXT("EQ enable",
|
||||
AED_EQ_EN, 0, 0x1, 0,
|
||||
mixer_eqdrc_read, mixer_set_EQ,
|
||||
NULL),
|
||||
mixer_eqdrc_read, mixer_set_EQ),
|
||||
|
||||
SOC_SINGLE_EXT_TLV("DRC enable",
|
||||
SOC_SINGLE_EXT("DRC enable",
|
||||
AED_DRC_EN, 0, 0x1, 0,
|
||||
mixer_eqdrc_read, mixer_set_DRC_params,
|
||||
NULL),
|
||||
mixer_eqdrc_read, mixer_set_DRC_params),
|
||||
|
||||
SOC_SINGLE_EXT_TLV("NG enable",
|
||||
SOC_SINGLE_EXT("NG enable",
|
||||
AED_NG_CTL, 0, 0x1, 0,
|
||||
mixer_eqdrc_read, mixer_eqdrc_write,
|
||||
NULL),
|
||||
mixer_eqdrc_read, mixer_eqdrc_write),
|
||||
|
||||
SOC_SINGLE_EXT_TLV("NG noise thd",
|
||||
SOC_SINGLE_EXT("NG noise thd",
|
||||
AED_NG_THD0, 8, 0x7FFF, 0,
|
||||
mixer_eqdrc_read, mixer_eqdrc_write,
|
||||
NULL),
|
||||
mixer_eqdrc_read, mixer_eqdrc_write),
|
||||
|
||||
SOC_SINGLE_EXT_TLV("NG signal thd",
|
||||
SOC_SINGLE_EXT("NG signal thd",
|
||||
AED_NG_THD1, 8, 0x7FFF, 0,
|
||||
mixer_eqdrc_read, mixer_eqdrc_write,
|
||||
NULL),
|
||||
mixer_eqdrc_read, mixer_eqdrc_write),
|
||||
|
||||
SOC_SINGLE_EXT_TLV("NG counter thd",
|
||||
SOC_SINGLE_EXT("NG counter thd",
|
||||
AED_NG_CNT_THD, 0, 0xFFFF, 0,
|
||||
mixer_eqdrc_read, mixer_eqdrc_write,
|
||||
NULL),
|
||||
mixer_eqdrc_read, mixer_eqdrc_write),
|
||||
};
|
||||
|
||||
int card_add_eqdrc_kcontrols(struct snd_soc_card *card)
|
||||
int card_add_effects_init(struct snd_soc_card *card)
|
||||
{
|
||||
struct device_node *audio_effect_np;
|
||||
int eq_enable = -1, drc_enable = -1, eqdrc_module = -1;
|
||||
int lane_mask = -1, channel_mask = -1;
|
||||
|
||||
audio_effect_np = of_parse_phandle(card->dev->of_node,
|
||||
"aml-audio-card,effect", 0);
|
||||
if (audio_effect_np == NULL) {
|
||||
pr_err("error: failed to find node %s for eq/drc info!\n",
|
||||
"audio_effect");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
of_property_read_u32(audio_effect_np,
|
||||
"eq_enable",
|
||||
&eq_enable);
|
||||
of_property_read_u32(audio_effect_np,
|
||||
"drc_enable",
|
||||
&drc_enable);
|
||||
of_property_read_u32(audio_effect_np,
|
||||
"eqdrc_module",
|
||||
&eqdrc_module);
|
||||
of_property_read_u32(audio_effect_np,
|
||||
"lane_mask",
|
||||
&lane_mask);
|
||||
of_property_read_u32(audio_effect_np,
|
||||
"channel_mask",
|
||||
&channel_mask);
|
||||
|
||||
init_EQ_DRC_module();
|
||||
|
||||
if (eq_enable >= 0)
|
||||
aed_set_eq(1, aml_EQ_param_length, &aml_EQ_param[0]);
|
||||
|
||||
if (drc_enable >= 0)
|
||||
aed_set_drc(1, aml_DRC_param_length, &aml_drc_table[0],
|
||||
aml_DRC_param_length, &aml_drc_tko_table[0]);
|
||||
|
||||
/* sel 0 in default */
|
||||
if (eqdrc_module >= 0)
|
||||
aed_req_sel(false, 0, eqdrc_module);
|
||||
|
||||
if (lane_mask >= 0)
|
||||
aed_set_lane(lane_mask);
|
||||
if (channel_mask >= 0)
|
||||
aed_set_channel(channel_mask);
|
||||
|
||||
/* init eq/drc in defalut */
|
||||
set_internal_EQ_volume(0xc0, 0x30, 0x30);
|
||||
|
||||
/* eq/drc mixer controls */
|
||||
return snd_soc_add_card_controls(card,
|
||||
snd_eqdrc_controls, ARRAY_SIZE(snd_eqdrc_controls));
|
||||
}
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
#ifndef __AML_AUDIO_EFFECTS_H__
|
||||
#define __AML_AUDIO_EFFECTS_H__
|
||||
|
||||
extern int card_add_eqdrc_kcontrols(struct snd_soc_card *card);
|
||||
extern int card_add_effects_init(struct snd_soc_card *card);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,12 +35,10 @@ int DRC0_enable(int enable, int thd0, int k0)
|
||||
|
||||
int init_EQ_DRC_module(void)
|
||||
{
|
||||
eqdrc_write(AED_TOP_CTL, (1 << 31)); /* fifo init */
|
||||
eqdrc_write(AED_ED_CTL, 1); /* soft reset*/
|
||||
msleep(20);
|
||||
eqdrc_write(AED_ED_CTL, 0); /* soft reset*/
|
||||
eqdrc_write(AED_TOP_CTL, (0 << 1) /*i2s in sel*/
|
||||
| (1 << 0)); /*module enable*/
|
||||
|
||||
eqdrc_write(AED_NG_CTL, (3 << 30)); /* disable noise gate*/
|
||||
|
||||
return 0;
|
||||
@@ -62,22 +60,22 @@ int set_internal_EQ_volume(
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aed_req_sel(int sel, int req_module)
|
||||
void aed_req_sel(bool enable, int sel, int req_module)
|
||||
{
|
||||
int mask_offset, val_offset;
|
||||
|
||||
switch (sel) {
|
||||
case 0: /* REQ_SEL0 */
|
||||
mask_offset = 0x1 << 3 | 0x7 << 0;
|
||||
val_offset = 0x1 << 3 | req_module << 0;
|
||||
val_offset = enable << 3 | req_module << 0;
|
||||
break;
|
||||
case 1: /* REQ_SEL1 */
|
||||
mask_offset = 0x1 << 7 | 0x7 << 4;
|
||||
val_offset = 0x1 << 7 | req_module << 4;
|
||||
val_offset = enable << 7 | req_module << 4;
|
||||
break;
|
||||
case 2: /* REQ_SEL0 */
|
||||
case 2: /* REQ_SEL2 */
|
||||
mask_offset = 0x1 << 11 | 0x7 << 8;
|
||||
val_offset = 0x1 << 11 | req_module << 8;
|
||||
val_offset = enable << 11 | req_module << 8;
|
||||
break;
|
||||
default:
|
||||
pr_err("unknown AED req_sel:%d\n", sel);
|
||||
@@ -87,6 +85,30 @@ void aed_req_sel(int sel, int req_module)
|
||||
eqdrc_update_bits(AED_TOP_REQ_CTL, mask_offset, val_offset);
|
||||
}
|
||||
|
||||
/* get eq/drc module */
|
||||
int aed_get_req_sel(int sel)
|
||||
{
|
||||
int val = eqdrc_read(AED_TOP_REQ_CTL);
|
||||
int mask_off;
|
||||
|
||||
switch (sel) {
|
||||
case 0: /* REQ_SEL0 */
|
||||
mask_off = 0;
|
||||
break;
|
||||
case 1: /* REQ_SEL1 */
|
||||
mask_off = 4;
|
||||
break;
|
||||
case 2: /* REQ_SEL2 */
|
||||
mask_off = 8;
|
||||
break;
|
||||
default:
|
||||
pr_err("unknown AED req_sel:%d\n", sel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return (val >> mask_off) & 0x7;
|
||||
}
|
||||
|
||||
void aed_set_eq(int enable, int params_len, unsigned int *params)
|
||||
{
|
||||
if (enable) {
|
||||
@@ -156,17 +178,31 @@ int aml_aed_format_set(int frddr_dst)
|
||||
|
||||
void aed_src_select(bool enable, int frddr_dst, int fifo_id)
|
||||
{
|
||||
if (enable) {
|
||||
if (frddr_dst >= 3) {
|
||||
/* SPDIFOUT A/B */
|
||||
aml_spdifout_select_aed(enable, frddr_dst - 3);
|
||||
} else if (frddr_dst < 3 && frddr_dst >= 0) {
|
||||
/* TDMOUT A/B/C */
|
||||
aml_tdmout_select_aed(enable, frddr_dst);
|
||||
} else
|
||||
pr_err("unknown function for AED\n");
|
||||
}
|
||||
/* Effect Module */
|
||||
if (frddr_dst >= 3) {
|
||||
/* SPDIFOUT A/B */
|
||||
aml_spdifout_select_aed(enable, frddr_dst - 3);
|
||||
} else if (frddr_dst < 3 && frddr_dst >= 0) {
|
||||
/* TDMOUT A/B/C */
|
||||
aml_tdmout_select_aed(enable, frddr_dst);
|
||||
} else
|
||||
pr_err("unknown function for AED\n");
|
||||
|
||||
/* AED module, req */
|
||||
aed_req_sel(enable, 0, frddr_dst);
|
||||
|
||||
/* AED module, sel & enable */
|
||||
eqdrc_update_bits(AED_TOP_CTL,
|
||||
0x3 << 4 | 0x1 << 0,
|
||||
fifo_id << 4 | enable << 0);
|
||||
}
|
||||
|
||||
void aed_set_lane(int lane_mask)
|
||||
{
|
||||
eqdrc_update_bits(AED_TOP_CTL, 0xf << 14, lane_mask << 14);
|
||||
}
|
||||
|
||||
void aed_set_channel(int channel_mask)
|
||||
{
|
||||
eqdrc_update_bits(AED_TOP_CTL, 0xff << 18, channel_mask << 18);
|
||||
}
|
||||
|
||||
@@ -29,11 +29,14 @@ extern int set_internal_EQ_volume(
|
||||
unsigned int channel_1_volume,
|
||||
unsigned int channel_2_volume);
|
||||
|
||||
extern void aed_req_sel(int sel, int req_module);
|
||||
extern void aed_req_sel(bool enable, int sel, int req_module);
|
||||
extern int aed_get_req_sel(int sel);
|
||||
extern void aed_set_eq(int enable, int params_len, unsigned int *params);
|
||||
extern void aed_set_drc(int enable,
|
||||
int drc_len, unsigned int *drc_params,
|
||||
int drc_tko_len, unsigned int *drc_tko_params);
|
||||
extern int aml_aed_format_set(int frddr_dst);
|
||||
extern void aed_src_select(bool enable, int frddr_dst, int fifo_id);
|
||||
extern void aed_set_lane(int lane_mask);
|
||||
extern void aed_set_channel(int channel_mask);
|
||||
#endif
|
||||
|
||||
@@ -182,9 +182,9 @@ CLOCK_COM_MUX(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 8);
|
||||
CLOCK_COM_DIV(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0, 8);
|
||||
CLOCK_COM_GATE(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 15);
|
||||
/* audio resample */
|
||||
CLOCK_COM_MUX(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 24);
|
||||
CLOCK_COM_DIV(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0, 0xff);
|
||||
CLOCK_COM_GATE(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 31);
|
||||
CLOCK_COM_MUX(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLE_CTRL), 0xf, 24);
|
||||
CLOCK_COM_DIV(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLE_CTRL), 0, 8);
|
||||
CLOCK_COM_GATE(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLE_CTRL), 31);
|
||||
|
||||
static int g12a_clks_init(struct clk **clks, void __iomem *iobase)
|
||||
{
|
||||
@@ -233,7 +233,7 @@ static int g12a_clks_init(struct clk **clks, void __iomem *iobase)
|
||||
WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFOUTB_CTRL]));
|
||||
|
||||
IOMAP_COM_CLK(locker_out, iobase);
|
||||
clks[CLKID_AUDIO_LOCKER_OUT] = REGISTER_CLK_COM(locker_out);
|
||||
clks[CLKID_AUDIO_LOCKER_OUT] = REGISTER_AUDIOCLK_COM(locker_out);
|
||||
WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_LOCKER_OUT]));
|
||||
|
||||
IOMAP_COM_CLK(locker_in, iobase);
|
||||
|
||||
@@ -55,16 +55,16 @@ void audiolocker_update_clks(struct clk *clk_calc, struct clk *clk_ref)
|
||||
|
||||
in_count = audiolocker_read(RO_REF2IMCLK_CNT_L);
|
||||
out_count = audiolocker_read(RO_REF2OMCLK_CNT_L);
|
||||
/*pr_info("\tin count:%d, out count:%d\n", in_count, out_count);*/
|
||||
pr_info("\tin count:%d, out count:%d\n", in_count, out_count);
|
||||
|
||||
if (in_count < out_count) {
|
||||
add_cnt++;
|
||||
mpll1_rate = clk_get_rate(clk_calc);
|
||||
mpll2_rate = clk_get_rate(clk_ref);
|
||||
/* if ( !(add_cnt % 1000))
|
||||
* pr_info("\t add cnt:%d, mpll1_rate:%d mpll2 rate:%d\n",
|
||||
* add_cnt,mpll1_rate, mpll2_rate);
|
||||
*/
|
||||
|
||||
pr_info("\t add cnt:%d, mpll1_rate:%d mpll2 rate:%d\n",
|
||||
add_cnt, mpll1_rate, mpll2_rate);
|
||||
|
||||
clk_set_rate(clk_ref, mpll2_rate + 600);
|
||||
/*udelay(1);*/
|
||||
audiolocker_reset();
|
||||
@@ -72,10 +72,10 @@ void audiolocker_update_clks(struct clk *clk_calc, struct clk *clk_ref)
|
||||
reduce_cnt++;
|
||||
mpll1_rate = clk_get_rate(clk_calc);
|
||||
mpll2_rate = clk_get_rate(clk_ref);
|
||||
/* if (!(reduce_cnt % 1000))
|
||||
* pr_info("\t reduce cnt:%d, mpll1_rate:%d, mpll2 rate:%d\n",
|
||||
* reduce_cnt,mpll1_rate, mpll2_rate);
|
||||
*/
|
||||
|
||||
pr_info("\t reduce cnt:%d, mpll1_rate:%d, mpll2 rate:%d\n",
|
||||
reduce_cnt, mpll1_rate, mpll2_rate);
|
||||
|
||||
clk_set_rate(clk_ref, mpll2_rate - 600);
|
||||
/*udelay(1);*/
|
||||
audiolocker_reset();
|
||||
|
||||
@@ -71,11 +71,16 @@ static int resample_clk_set(struct audioresample *p_resample)
|
||||
pr_err("Can't enable resample_src clock: %d\n", ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (p_resample->out_rate)
|
||||
if (p_resample->out_rate) {
|
||||
clk_set_rate(p_resample->sclk,
|
||||
p_resample->out_rate * 256);
|
||||
else
|
||||
clk_set_rate(p_resample->clk,
|
||||
p_resample->out_rate * 256);
|
||||
} else {
|
||||
/* defaule resample clk */
|
||||
clk_set_rate(p_resample->sclk, 48000 * 256);
|
||||
clk_set_rate(p_resample->clk, 48000 * 256);
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(p_resample->pll);
|
||||
if (ret) {
|
||||
|
||||
100
sound/soc/amlogic/auge/sharebuffer.c
Normal file
100
sound/soc/amlogic/auge/sharebuffer.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* sound/soc/amlogic/auge/sharebuffer.c
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include <sound/pcm.h>
|
||||
|
||||
#include <linux/amlogic/media/sound/aout_notify.h>
|
||||
|
||||
#include "sharebuffer.h"
|
||||
#include "ddr_mngr.h"
|
||||
|
||||
#include "spdif_hw.h"
|
||||
|
||||
int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream,
|
||||
struct frddr *fr, int spdif_id)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
int bit_depth;
|
||||
|
||||
bit_depth = snd_pcm_format_width(runtime->format);
|
||||
|
||||
spdifout_samesource_set(spdif_id,
|
||||
aml_frddr_get_fifo_id(fr),
|
||||
bit_depth, true);
|
||||
|
||||
/* spdif b, notify hdmitx audio */
|
||||
if (spdif_id == 1) {
|
||||
spdifoutb_to_hdmitx_ctrl();
|
||||
aout_notifier_call_chain(0x1, substream);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sharebuffer_enable(int sel, bool enable)
|
||||
{
|
||||
if (sel < 0) {
|
||||
pr_err("Not support same source\n");
|
||||
return;
|
||||
} else if (sel < 3) {
|
||||
// TODO: same with tdm
|
||||
} else if (sel < 5) {
|
||||
/* same source with spdif a/b */
|
||||
spdifout_enable(sel - 3, enable);
|
||||
}
|
||||
}
|
||||
|
||||
int sharebuffer_prepare(struct snd_pcm_substream *substream,
|
||||
void *pfrddr, int samesource_sel)
|
||||
{
|
||||
struct frddr *fr = (struct frddr *)pfrddr;
|
||||
|
||||
/* each module prepare, clocks and controls */
|
||||
if (samesource_sel < 0) {
|
||||
pr_err("Not support same source\n");
|
||||
return -EINVAL;
|
||||
} else if (samesource_sel < 3) {
|
||||
// TODO: same with tdm
|
||||
} else if (samesource_sel < 5) {
|
||||
/* same source with spdif a/b */
|
||||
sharebuffer_spdifout_prepare(substream, fr, samesource_sel - 3);
|
||||
}
|
||||
|
||||
/* frddr, share buffer, src_sel1 */
|
||||
aml_frddr_select_dst_ss(fr, samesource_sel, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sharebuffer_trigger(int cmd, int samesource_sel)
|
||||
{
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
sharebuffer_enable(samesource_sel, true);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
sharebuffer_enable(samesource_sel, false);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
24
sound/soc/amlogic/auge/sharebuffer.h
Normal file
24
sound/soc/amlogic/auge/sharebuffer.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* sound/soc/amlogic/auge/sharebuffer.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 __AML_AUDIO_SHAREBUFFER_H__
|
||||
#define __AML_AUDIO_SHAREBUFFER_H__
|
||||
|
||||
extern int sharebuffer_prepare(struct snd_pcm_substream *substream,
|
||||
void *pfrddr, int samesource_sel);
|
||||
extern int sharebuffer_trigger(int cmd, int samesource_sel);
|
||||
|
||||
#endif
|
||||
@@ -416,11 +416,8 @@ static int aml_dai_spdif_prepare(
|
||||
aml_frddr_select_dst(fr, dst);
|
||||
aml_frddr_set_fifos(fr, 0x40, 0x20);
|
||||
|
||||
// TODO: TOHDMITX_CTRL0
|
||||
/* TOHDMITX_CTRL0 */
|
||||
if (p_spdif->id == 1) {
|
||||
/* HDMI audio stream type ID */
|
||||
#define AOUT_EVENT_IEC_60958_PCM 0x1
|
||||
|
||||
spdifoutb_to_hdmitx_ctrl();
|
||||
aout_notifier_call_chain(AOUT_EVENT_IEC_60958_PCM,
|
||||
substream);
|
||||
|
||||
@@ -280,3 +280,90 @@ void spdifoutb_to_hdmitx_ctrl(void)
|
||||
| 1 << 0 /* spdif_clk_b */
|
||||
);
|
||||
}
|
||||
|
||||
void spdifout_clk_ctrl(int spdif_id, bool is_enable)
|
||||
{
|
||||
unsigned int offset, reg;
|
||||
|
||||
offset = EE_AUDIO_CLK_SPDIFOUT_B_CTRL - EE_AUDIO_CLK_SPDIFOUT_CTRL;
|
||||
reg = EE_AUDIO_CLK_SPDIFOUT_CTRL + offset * spdif_id;
|
||||
|
||||
/* select : mpll 0, 24m, so spdif clk:6m */
|
||||
audiobus_write(reg, is_enable << 31 | 0x0 << 24 | 0x3 << 0);
|
||||
}
|
||||
|
||||
void spdifout_fifo_ctrl(int spdif_id, int fifo_id, int bitwidth)
|
||||
{
|
||||
unsigned int frddr_type;
|
||||
unsigned int offset, reg;
|
||||
|
||||
switch (bitwidth) {
|
||||
case 8:
|
||||
frddr_type = 0;
|
||||
break;
|
||||
case 16:
|
||||
frddr_type = 1;
|
||||
break;
|
||||
case 24:
|
||||
frddr_type = 4;
|
||||
break;
|
||||
case 32:
|
||||
frddr_type = 3;
|
||||
break;
|
||||
default:
|
||||
pr_err("runtime format invalid bitwidth: %d\n",
|
||||
bitwidth);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_info("%s, bit depth:%d, frddr type:%d\n",
|
||||
__func__, bitwidth, frddr_type);
|
||||
|
||||
/* 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);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL1 - EE_AUDIO_SPDIFOUT_CTRL1;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * spdif_id;
|
||||
audiobus_update_bits(reg,
|
||||
0x3 << 24 | 0x1f << 8 | 0x7 << 4,
|
||||
fifo_id << 24 | (bitwidth - 1) << 8 | frddr_type<<4);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_SWAP - EE_AUDIO_SPDIFOUT_SWAP;
|
||||
reg = EE_AUDIO_SPDIFOUT_SWAP + offset * spdif_id;
|
||||
audiobus_write(reg, 1<<4);
|
||||
|
||||
/* reset afifo */
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
|
||||
audiobus_update_bits(reg, 3<<28, 0);
|
||||
audiobus_update_bits(reg, 1<<29, 1<<29);
|
||||
audiobus_update_bits(reg, 1<<28, 1<<28);
|
||||
|
||||
}
|
||||
|
||||
void spdifout_enable(int spdif_id, bool is_enable)
|
||||
{
|
||||
unsigned int offset, reg;
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
|
||||
audiobus_update_bits(reg, 1<<31, is_enable<<31);
|
||||
}
|
||||
|
||||
void spdifout_samesource_set(int spdif_index, int fifo_id,
|
||||
int bitwidth, bool is_enable)
|
||||
{
|
||||
int spdif_id;
|
||||
|
||||
if (spdif_index == 1)
|
||||
spdif_id = 1;
|
||||
else
|
||||
spdif_id = 0;
|
||||
|
||||
spdifout_clk_ctrl(spdif_id, true);
|
||||
spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth);
|
||||
}
|
||||
|
||||
@@ -54,4 +54,8 @@ extern void aml_spdifout_get_aed_info(int spdifout_id,
|
||||
int *bitwidth, int *frddrtype);
|
||||
|
||||
extern void spdifoutb_to_hdmitx_ctrl(void);
|
||||
|
||||
extern void spdifout_samesource_set(int spdif_index, int fifo_id,
|
||||
int bitwidth, bool is_enable);
|
||||
extern void spdifout_enable(int spdif_id, bool is_enable);
|
||||
#endif
|
||||
|
||||
@@ -37,6 +37,10 @@
|
||||
#include "ddr_mngr.h"
|
||||
#include "tdm_hw.h"
|
||||
|
||||
/*#define G12A_PTM*/
|
||||
|
||||
#include "sharebuffer.h"
|
||||
|
||||
#define DRV_NAME "aml_tdm"
|
||||
|
||||
#define TDM_A 0
|
||||
@@ -79,6 +83,9 @@ struct tdm_chipinfo {
|
||||
|
||||
/* clk pad */
|
||||
bool clk_pad_ctl;
|
||||
|
||||
/* same source */
|
||||
bool same_src_fn;
|
||||
};
|
||||
|
||||
struct aml_tdm {
|
||||
@@ -97,6 +104,8 @@ struct aml_tdm {
|
||||
struct frddr *fddr;
|
||||
|
||||
struct tdm_chipinfo *chipinfo;
|
||||
/* share buffer with module */
|
||||
int samesource_sel;
|
||||
};
|
||||
|
||||
static const struct snd_pcm_hardware aml_tdm_hardware = {
|
||||
@@ -116,7 +125,7 @@ static const struct snd_pcm_hardware aml_tdm_hardware = {
|
||||
.buffer_bytes_max = 512 * 1024,
|
||||
|
||||
.rate_min = 8000,
|
||||
.rate_max = 48000,
|
||||
.rate_max = 192000,
|
||||
.channels_min = 1,
|
||||
.channels_max = 32,
|
||||
};
|
||||
@@ -383,6 +392,14 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream,
|
||||
enum frddr_dest dst;
|
||||
unsigned int fifo_id;
|
||||
|
||||
/* share buffer prepare */
|
||||
if (p_tdm->chipinfo &&
|
||||
p_tdm->chipinfo->same_src_fn) {
|
||||
if (p_tdm->samesource_sel >= 0)
|
||||
sharebuffer_prepare(substream,
|
||||
fr, p_tdm->samesource_sel);
|
||||
}
|
||||
|
||||
fifo_id = aml_frddr_get_fifo_id(fr);
|
||||
aml_tdm_fifo_ctrl(p_tdm->actrl,
|
||||
bit_depth,
|
||||
@@ -460,6 +477,13 @@ static int aml_dai_tdm_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
{
|
||||
struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
|
||||
/* share buffer trigger */
|
||||
if (p_tdm->chipinfo &&
|
||||
p_tdm->chipinfo->same_src_fn) {
|
||||
if (p_tdm->samesource_sel >= 0)
|
||||
sharebuffer_trigger(cmd, p_tdm->samesource_sel);
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
@@ -476,7 +500,6 @@ static int aml_dai_tdm_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
dev_info(substream->pcm->card->dev, "tdm capture enable\n");
|
||||
aml_toddr_enable(p_tdm->tddr, 1);
|
||||
}
|
||||
|
||||
aml_tdm_enable(p_tdm->actrl,
|
||||
substream->stream, p_tdm->id, true);
|
||||
|
||||
@@ -486,6 +509,7 @@ static int aml_dai_tdm_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
aml_tdm_enable(p_tdm->actrl,
|
||||
substream->stream, p_tdm->id, false);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
dev_info(substream->pcm->card->dev, "tdm playback stop\n");
|
||||
aml_frddr_enable(p_tdm->fddr, 0);
|
||||
@@ -697,8 +721,6 @@ static unsigned int aml_mpll_mclk_ratio(unsigned int freq)
|
||||
return ratio;
|
||||
}
|
||||
|
||||
/*#define G12A_PTM*/
|
||||
|
||||
static int aml_dai_set_tdm_sysclk(struct snd_soc_dai *cpu_dai,
|
||||
int clk_id, unsigned int freq, int dir)
|
||||
{
|
||||
@@ -983,6 +1005,7 @@ struct tdm_chipinfo g12a_tdma_chipinfo = {
|
||||
.sclk_ws_inv = true,
|
||||
.oe_fn = true,
|
||||
.clk_pad_ctl = true,
|
||||
.same_src_fn = true,
|
||||
};
|
||||
|
||||
struct tdm_chipinfo g12a_tdmb_chipinfo = {
|
||||
@@ -990,6 +1013,7 @@ struct tdm_chipinfo g12a_tdmb_chipinfo = {
|
||||
.sclk_ws_inv = true,
|
||||
.oe_fn = true,
|
||||
.clk_pad_ctl = true,
|
||||
.same_src_fn = true,
|
||||
};
|
||||
|
||||
struct tdm_chipinfo g12a_tdmc_chipinfo = {
|
||||
@@ -997,6 +1021,7 @@ struct tdm_chipinfo g12a_tdmc_chipinfo = {
|
||||
.sclk_ws_inv = true,
|
||||
.oe_fn = true,
|
||||
.clk_pad_ctl = true,
|
||||
.same_src_fn = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id aml_tdm_device_id[] = {
|
||||
@@ -1072,6 +1097,19 @@ static int aml_tdm_platform_probe(struct platform_device *pdev)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* default no same source */
|
||||
if (p_tdm->chipinfo &&
|
||||
p_tdm->chipinfo->same_src_fn) {
|
||||
ret = of_property_read_u32(node, "samesource_sel",
|
||||
&p_tdm->samesource_sel);
|
||||
if (ret < 0)
|
||||
p_tdm->samesource_sel = -1;
|
||||
|
||||
pr_info("TDM id %d samesource_sel:%d\n",
|
||||
p_tdm->id,
|
||||
p_tdm->samesource_sel);
|
||||
}
|
||||
|
||||
/* get tdm lanes info. if not, set to default 1 */
|
||||
ret = of_parse_tdm_lane_slot_in(node,
|
||||
&p_tdm->setting.lane_mask_in);
|
||||
|
||||
@@ -237,9 +237,12 @@ void aml_tdm_set_format(
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
if (p_config->sclk_ws_inv)
|
||||
bclkout_skew = 2;
|
||||
else
|
||||
if (p_config->sclk_ws_inv) {
|
||||
if (master_mode)
|
||||
bclkout_skew = 2;
|
||||
else
|
||||
bclkout_skew = 3;
|
||||
} else
|
||||
bclkout_skew = 1;
|
||||
bclkin_skew = 3;
|
||||
|
||||
@@ -264,9 +267,12 @@ void aml_tdm_set_format(
|
||||
* that is, together with the last bit of the previous
|
||||
* data word.
|
||||
*/
|
||||
if (p_config->sclk_ws_inv)
|
||||
bclkout_skew = 2;
|
||||
else
|
||||
if (p_config->sclk_ws_inv) {
|
||||
if (master_mode)
|
||||
bclkout_skew = 2;
|
||||
else
|
||||
bclkout_skew = 3;
|
||||
} else
|
||||
bclkout_skew = 1;
|
||||
bclkin_skew = 3;
|
||||
|
||||
@@ -279,7 +285,13 @@ void aml_tdm_set_format(
|
||||
* Frame high, one bit for frame sync,
|
||||
* frame sync asserts with the first bit of the frame.
|
||||
*/
|
||||
bclkout_skew = 2;
|
||||
if (p_config->sclk_ws_inv) {
|
||||
if (master_mode)
|
||||
bclkout_skew = 3;
|
||||
else
|
||||
bclkout_skew = 4;
|
||||
} else
|
||||
bclkout_skew = 2;
|
||||
bclkin_skew = 2;
|
||||
|
||||
if (capture_active)
|
||||
@@ -343,7 +355,7 @@ void aml_tdm_set_format(
|
||||
aml_audiobus_update_bits(actrl, reg_out,
|
||||
0x3<<30, 0x3<<30);
|
||||
|
||||
if (p_config->sclk_ws_inv)
|
||||
if (p_config->sclk_ws_inv && master_mode)
|
||||
aml_audiobus_update_bits(actrl, reg_out,
|
||||
0x1 << 28,
|
||||
0x1 << 28);
|
||||
|
||||
@@ -49,8 +49,6 @@
|
||||
#include "spdif_dai.h"
|
||||
#include "dmic.h"
|
||||
|
||||
#define AOUT_EVENT_IEC_60958_PCM 0x1
|
||||
|
||||
/* extern int set_i2s_iec958_samesource(int enable);
|
||||
*
|
||||
* the I2S hw and IEC958 PCM output initiation,958 initiation here,
|
||||
|
||||
@@ -18,22 +18,6 @@
|
||||
#ifndef _AML_SPDIF_DAI_H
|
||||
#define _AML_SPDIF_DAI_H
|
||||
|
||||
/* HDMI audio stream type ID */
|
||||
#define AOUT_EVENT_IEC_60958_PCM 0x1
|
||||
#define AOUT_EVENT_RAWDATA_AC_3 0x2
|
||||
#define AOUT_EVENT_RAWDATA_MPEG1 0x3
|
||||
#define AOUT_EVENT_RAWDATA_MP3 0x4
|
||||
#define AOUT_EVENT_RAWDATA_MPEG2 0x5
|
||||
#define AOUT_EVENT_RAWDATA_AAC 0x6
|
||||
#define AOUT_EVENT_RAWDATA_DTS 0x7
|
||||
#define AOUT_EVENT_RAWDATA_ATRAC 0x8
|
||||
#define AOUT_EVENT_RAWDATA_ONE_BIT_AUDIO 0x9
|
||||
#define AOUT_EVENT_RAWDATA_DOBLY_DIGITAL_PLUS 0xA
|
||||
#define AOUT_EVENT_RAWDATA_DTS_HD 0xB
|
||||
#define AOUT_EVENT_RAWDATA_MAT_MLP 0xC
|
||||
#define AOUT_EVENT_RAWDATA_DST 0xD
|
||||
#define AOUT_EVENT_RAWDATA_WMA_PRO 0xE
|
||||
#define AOUT_EVENT_RAWDATA_DTS_HD_MA (AOUT_EVENT_RAWDATA_DTS_HD|(1<<8))
|
||||
extern unsigned int IEC958_mode_codec;
|
||||
|
||||
/*
|
||||
|
||||
@@ -255,20 +255,23 @@ static const struct snd_soc_dapm_route T9015_audio_dapm_routes[] = {
|
||||
static int aml_T9015_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
u32 val = snd_soc_read(codec, AUDIO_CONFIG_BLOCK_ENABLE);
|
||||
|
||||
pr_debug("%s, format:%x, codec = %p\n", __func__, fmt, codec);
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
snd_soc_update_bits(codec, AUDIO_CONFIG_BLOCK_ENABLE,
|
||||
I2S_MODE, 1);
|
||||
val |= (0x1 << I2S_MODE);
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
snd_soc_update_bits(codec, AUDIO_CONFIG_BLOCK_ENABLE,
|
||||
I2S_MODE, 0);
|
||||
val &= ~(0x1 << I2S_MODE);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snd_soc_write(codec, AUDIO_CONFIG_BLOCK_ENABLE, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -328,19 +328,23 @@ static const struct snd_soc_dapm_route T9015S_audio_dapm_routes[] = {
|
||||
static int aml_T9015S_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
u32 val = snd_soc_read(codec, AUDIO_CONFIG_BLOCK_ENABLE);
|
||||
|
||||
pr_debug("%s, format:%x, codec = %p\n", __func__, fmt, codec);
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
snd_soc_update_bits(codec, AUDIO_CONFIG_BLOCK_ENABLE,
|
||||
I2S_MODE, 1);
|
||||
val |= (0x1 << I2S_MODE);
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
snd_soc_update_bits(codec, AUDIO_CONFIG_BLOCK_ENABLE,
|
||||
I2S_MODE, 0);
|
||||
val &= ~(0x1 << I2S_MODE);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snd_soc_write(codec, AUDIO_CONFIG_BLOCK_ENABLE, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user