mirror of
https://github.com/hardkernel/linux.git
synced 2026-04-01 18:53:02 +09:00
audio: add HW resample for HDMIRX [1/1]
PD#SWPL-6118 Problem: No resample will cause mismatch between input and output if they are not at same samplerate. Solution: Add resample for hdmirx case Verify: Local tested. Change-Id: I298e401578bf49484d6b75fd736d2a74c38508e4 Signed-off-by: Shuai Li <shuai.li@amlogic.com>
This commit is contained in:
@@ -1458,8 +1458,9 @@
|
||||
* NONE,
|
||||
* TDMIN_LB, 6
|
||||
* LOOPBACK, 7
|
||||
* FRHDMIRX, 8
|
||||
*/
|
||||
resample_module = <3>;
|
||||
resample_module = <8>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1518,8 +1518,9 @@
|
||||
* NONE,
|
||||
* TDMIN_LB, 6
|
||||
* LOOPBACK, 7
|
||||
* FRHDMIRX, 8
|
||||
*/
|
||||
resample_module = <3>;
|
||||
resample_module = <8>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1455,8 +1455,9 @@
|
||||
* NONE,
|
||||
* TDMIN_LB, 6
|
||||
* LOOPBACK, 7
|
||||
* FRHDMIRX, 8
|
||||
*/
|
||||
resample_module = <3>;
|
||||
resample_module = <8>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1512,8 +1512,9 @@
|
||||
* NONE,
|
||||
* TDMIN_LB, 6
|
||||
* LOOPBACK, 7
|
||||
* FRHDMIRX, 8
|
||||
*/
|
||||
resample_module = <3>;
|
||||
resample_module = <8>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -388,10 +388,10 @@ void aml_toddr_set_fifos(struct toddr *to, unsigned int thresh)
|
||||
if (to->chipinfo
|
||||
&& to->chipinfo->src_sel_ctrl) {
|
||||
mask = 0xfff << 12 | 0xf << 8;
|
||||
val = (thresh-1) << 12 | 2 << 8;
|
||||
val = (thresh-2) << 12 | 2 << 8;
|
||||
} else {
|
||||
mask = 0xff << 16 | 0xf << 8;
|
||||
val = (thresh-1) << 16 | 2 << 8;
|
||||
val = (thresh-2) << 16 | 2 << 8;
|
||||
}
|
||||
|
||||
aml_audiobus_update_bits(actrl, reg, mask, val);
|
||||
@@ -479,28 +479,29 @@ void aml_toddr_write(struct toddr *to, unsigned int val)
|
||||
|
||||
aml_audiobus_write(actrl, reg, val);
|
||||
}
|
||||
|
||||
void aml_toddr_set_resample(struct toddr *to, bool enable)
|
||||
/* not for tl1 */
|
||||
static void aml_toddr_set_resample(struct toddr *to, bool enable)
|
||||
{
|
||||
struct aml_audio_controller *actrl = to->actrl;
|
||||
unsigned int reg_base = to->reg_base;
|
||||
unsigned int reg;
|
||||
|
||||
reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL0, reg_base);
|
||||
aml_audiobus_update_bits(actrl, reg, 1<<30, enable<<30);
|
||||
aml_audiobus_update_bits(actrl, reg, 1<<30, !!enable<<30);
|
||||
}
|
||||
|
||||
void aml_toddr_set_resample_ab(struct toddr *to, int asrc_src_sel, bool enable)
|
||||
/* tl1 after */
|
||||
static void aml_toddr_set_resample_ab(struct toddr *to,
|
||||
enum resample_idx index, bool enable)
|
||||
{
|
||||
struct aml_audio_controller *actrl = to->actrl;
|
||||
unsigned int reg_base = to->reg_base;
|
||||
unsigned int reg;
|
||||
|
||||
reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base);
|
||||
if (asrc_src_sel == 0)
|
||||
aml_audiobus_update_bits(actrl, reg, 1 << 27, enable << 27);
|
||||
else
|
||||
aml_audiobus_update_bits(actrl, reg, 1 << 26, enable << 26);
|
||||
if (index == RESAMPLE_A)
|
||||
aml_audiobus_update_bits(actrl, reg, 1 << 27, !!enable << 27);
|
||||
else if (index == RESAMPLE_B)
|
||||
aml_audiobus_update_bits(actrl, reg, 1 << 26, !!enable << 26);
|
||||
}
|
||||
|
||||
static void aml_resample_enable(
|
||||
@@ -508,12 +509,15 @@ static void aml_resample_enable(
|
||||
struct toddr_attach *p_attach_resample,
|
||||
bool enable)
|
||||
{
|
||||
if (!to)
|
||||
if (!to || !p_attach_resample) {
|
||||
pr_err("%s(), NULL pointer.", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (to->chipinfo
|
||||
&& to->chipinfo->asrc_src_sel_ctrl) {
|
||||
/* fix asrc_src_sel */
|
||||
/*
|
||||
switch (p_attach_resample->attach_module) {
|
||||
case LOOPBACK_A:
|
||||
to->asrc_src_sel = ASRC_LOOPBACK_A;
|
||||
@@ -525,21 +529,24 @@ static void aml_resample_enable(
|
||||
to->asrc_src_sel = to->fifo_id;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
to->asrc_src_sel = p_attach_resample->attach_module;
|
||||
}
|
||||
|
||||
pr_info("toddr %d selects data to %s resample_%c for module:%s\n",
|
||||
to->fifo_id,
|
||||
enable ? "enable" : "disable",
|
||||
(p_attach_resample->id == 0) ? 'a' : 'b',
|
||||
(p_attach_resample->id == RESAMPLE_A) ? 'a' : 'b',
|
||||
toddr_src_get_str(p_attach_resample->attach_module)
|
||||
);
|
||||
|
||||
if (enable) {
|
||||
int bitwidth = to->bitdepth;
|
||||
/* channels and bit depth for resample */
|
||||
|
||||
if (to->chipinfo
|
||||
&& to->chipinfo->asrc_only_left_j
|
||||
&& (to->src == SPDIFIN)
|
||||
/*&& (to->src == SPDIFIN)*/
|
||||
&& (bitwidth == 32)) {
|
||||
struct aml_audio_controller *actrl = to->actrl;
|
||||
unsigned int reg_base = to->reg_base;
|
||||
@@ -583,13 +590,14 @@ static void aml_resample_enable(
|
||||
aml_toddr_set_resample(to, enable);
|
||||
}
|
||||
|
||||
void aml_set_resample(int id, bool enable, int resample_module)
|
||||
void aml_set_resample(enum resample_idx id,
|
||||
bool enable, enum toddr_src resample_module)
|
||||
{
|
||||
struct toddr_attach *p_attach_resample;
|
||||
struct toddr *to;
|
||||
bool update_running = false;
|
||||
|
||||
if (id == 0)
|
||||
if (id == RESAMPLE_A)
|
||||
p_attach_resample = &attach_resample_a;
|
||||
else
|
||||
p_attach_resample = &attach_resample_b;
|
||||
@@ -1370,13 +1378,13 @@ void frddr_deinit_without_mngr(unsigned int frddr_index)
|
||||
audiobus_write(reg, 0x0);
|
||||
}
|
||||
|
||||
static int toddr_src_idx = -1;
|
||||
static enum toddr_src toddr_src_idx = TODDR_INVAL;
|
||||
|
||||
static const char *const toddr_src_sel_texts[] = {
|
||||
"TDMIN_A", "TDMIN_B", "TDMIN_C", "SPDIFIN",
|
||||
"PDMIN", "FRATV", "TDMIN_LB", "LOOPBACK_A",
|
||||
"FRHDMIRX", "LOOPBACK_B", "SPDIFIN_LB",
|
||||
"EARCRX_DMAC", "RESERVED", "RESERVED", "RESERVED",
|
||||
"EARCRX_DMAC", "RESERVED_0", "RESERVED_1", "RESERVED_2",
|
||||
"VAD"
|
||||
};
|
||||
|
||||
@@ -1384,14 +1392,14 @@ static const struct soc_enum toddr_input_source_enum =
|
||||
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(toddr_src_sel_texts),
|
||||
toddr_src_sel_texts);
|
||||
|
||||
int toddr_src_get(void)
|
||||
enum toddr_src toddr_src_get(void)
|
||||
{
|
||||
return toddr_src_idx;
|
||||
}
|
||||
|
||||
const char *toddr_src_get_str(int idx)
|
||||
const char *toddr_src_get_str(enum toddr_src idx)
|
||||
{
|
||||
if (idx < 0 || idx > 15)
|
||||
if (idx < TDMIN_A || idx > VAD)
|
||||
return NULL;
|
||||
|
||||
return toddr_src_sel_texts[idx];
|
||||
@@ -1409,6 +1417,8 @@ static int toddr_src_enum_set(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
toddr_src_idx = ucontrol->value.enumerated.item[0];
|
||||
/* also update to resample src */
|
||||
//set_resample_source(toddr_src_idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -42,19 +42,29 @@ enum ddr_types {
|
||||
* from tl1, add new source FRATV, FRHDMIRX, LOOPBACK_B, SPDIFIN_LB, VAD
|
||||
*/
|
||||
enum toddr_src {
|
||||
TDMIN_A,
|
||||
TDMIN_B,
|
||||
TDMIN_C,
|
||||
SPDIFIN,
|
||||
PDMIN,
|
||||
FRATV, /* NONE for axg, g12a, g12b */
|
||||
TDMIN_LB,
|
||||
LOOPBACK_A,
|
||||
FRHDMIRX, /* from tl1 chipset*/
|
||||
LOOPBACK_B,
|
||||
SPDIFIN_LB,
|
||||
EARCRX_DMAC, /* from sm1 chipset */
|
||||
VAD,
|
||||
TODDR_INVAL = -1,
|
||||
TDMIN_A = 0,
|
||||
TDMIN_B = 1,
|
||||
TDMIN_C = 2,
|
||||
SPDIFIN = 3,
|
||||
PDMIN = 4,
|
||||
FRATV = 5, /* NONE for axg, g12a, g12b */
|
||||
TDMIN_LB = 6,
|
||||
LOOPBACK_A = 7,
|
||||
FRHDMIRX = 8, /* from tl1 chipset*/
|
||||
LOOPBACK_B = 9,
|
||||
SPDIFIN_LB = 10,
|
||||
EARCRX_DMAC = 11,/* from sm1 chipset */
|
||||
RESERVED_0 = 12,
|
||||
RESERVED_1 = 13,
|
||||
RESERVED_2 = 14,
|
||||
VAD = 15,
|
||||
TODDR_SRC_MAX = 16
|
||||
};
|
||||
|
||||
enum resample_idx {
|
||||
RESAMPLE_A,
|
||||
RESAMPLE_B
|
||||
};
|
||||
|
||||
enum resample_src {
|
||||
@@ -177,7 +187,7 @@ struct toddr {
|
||||
enum toddr_src src;
|
||||
unsigned int fifo_id;
|
||||
|
||||
unsigned int asrc_src_sel;
|
||||
enum toddr_src asrc_src_sel;
|
||||
|
||||
int is_lb; /* check whether for loopback */
|
||||
int irq;
|
||||
@@ -194,7 +204,7 @@ enum status {
|
||||
|
||||
struct toddr_attach {
|
||||
bool enable;
|
||||
int id;
|
||||
enum resample_idx id;
|
||||
int status;
|
||||
/* which module should be attached,
|
||||
* check which toddr in use should be attached
|
||||
@@ -259,7 +269,8 @@ unsigned int aml_toddr_read(struct toddr *to);
|
||||
void aml_toddr_write(struct toddr *to, unsigned int val);
|
||||
|
||||
/* resample */
|
||||
void aml_set_resample(int id, bool enable, int resample_module);
|
||||
void aml_set_resample(enum resample_idx id,
|
||||
bool enable, enum toddr_src resample_module);
|
||||
/* power detect */
|
||||
void aml_pwrdet_enable(bool enable, int pwrdet_module);
|
||||
/* Voice Activity Detection */
|
||||
@@ -297,8 +308,8 @@ void aml_set_aed(bool enable, int aed_module);
|
||||
void frddr_init_without_mngr(unsigned int frddr_index, unsigned int src0_sel);
|
||||
void frddr_deinit_without_mngr(unsigned int frddr_index);
|
||||
|
||||
int toddr_src_get(void);
|
||||
const char *toddr_src_get_str(int idx);
|
||||
enum toddr_src toddr_src_get(void);
|
||||
const char *toddr_src_get_str(enum toddr_src idx);
|
||||
int frddr_src_get(void);
|
||||
const char *frddr_src_get_str(int idx);
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "ddr_mngr.h"
|
||||
#include "audio_utils.h"
|
||||
#include "frhdmirx_hw.h"
|
||||
#include "resample.h"
|
||||
|
||||
#include <linux/amlogic/media/sound/misc.h>
|
||||
|
||||
@@ -371,6 +372,7 @@ static int extn_dai_startup(
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
resample_set_inner_rate(RESAMPLE_A);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -378,6 +380,7 @@ static void extn_dai_shutdown(
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
//resample_set(RESAMPLE_A, RATE_OFF);
|
||||
}
|
||||
|
||||
static int extn_dai_prepare(
|
||||
@@ -401,7 +404,7 @@ static int extn_dai_prepare(
|
||||
} else {
|
||||
struct toddr *to = p_extn->tddr;
|
||||
unsigned int msb = 0, lsb = 0, toddr_type = 0;
|
||||
unsigned int src = toddr_src_get();
|
||||
enum toddr_src src = toddr_src_get();
|
||||
struct toddr_fmt fmt;
|
||||
|
||||
if (bit_depth == 24)
|
||||
@@ -472,7 +475,7 @@ static int extn_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
struct extn *p_extn = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
unsigned int src = toddr_src_get();
|
||||
enum toddr_src src = toddr_src_get();
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
#include <sound/tlv.h>
|
||||
|
||||
#include "resample.h"
|
||||
#include "resample_hw.h"
|
||||
#include "ddr_mngr.h"
|
||||
#include "regs.h"
|
||||
#include "iomap.h"
|
||||
|
||||
@@ -38,12 +36,12 @@
|
||||
|
||||
/*#define __PTM_RESAMPLE_CLK__*/
|
||||
|
||||
#define RESAMPLE_A 0
|
||||
#define RESAMPLE_B 1
|
||||
//#define RESAMPLE_A 0
|
||||
//#define RESAMPLE_B 1
|
||||
|
||||
struct resample_chipinfo {
|
||||
int num; /* support resample a/b */
|
||||
int id;
|
||||
enum resample_idx id;
|
||||
|
||||
bool dividor_fn;
|
||||
};
|
||||
@@ -60,15 +58,15 @@ struct audioresample {
|
||||
|
||||
struct resample_chipinfo *chipinfo;
|
||||
|
||||
int id;
|
||||
enum resample_idx id;
|
||||
|
||||
/*which module should be resampled */
|
||||
int resample_module;
|
||||
enum toddr_src resample_module;
|
||||
/* resample to the rate */
|
||||
int out_rate;
|
||||
|
||||
/* sync with auge_resample_texts */
|
||||
int asrc_rate_idx;
|
||||
enum samplerate_index asrc_rate_idx;
|
||||
|
||||
bool enable;
|
||||
};
|
||||
@@ -77,11 +75,11 @@ struct audioresample *s_resample_a;
|
||||
|
||||
struct audioresample *s_resample_b;
|
||||
|
||||
static struct audioresample *get_audioresample(int id)
|
||||
static struct audioresample *get_audioresample(enum resample_idx id)
|
||||
{
|
||||
struct audioresample *p_resample;
|
||||
|
||||
p_resample = ((id == 0) ? s_resample_a : s_resample_b);
|
||||
p_resample = ((id == RESAMPLE_A) ? s_resample_a : s_resample_b);
|
||||
|
||||
if (!p_resample) {
|
||||
pr_debug("Not init audio resample\n");
|
||||
@@ -93,7 +91,7 @@ static struct audioresample *get_audioresample(int id)
|
||||
|
||||
int get_resample_module_num(void)
|
||||
{
|
||||
struct audioresample *p_resample = get_audioresample(0);
|
||||
struct audioresample *p_resample = get_audioresample(RESAMPLE_A);
|
||||
|
||||
if (p_resample && p_resample->chipinfo)
|
||||
return p_resample->chipinfo->num;
|
||||
@@ -101,6 +99,32 @@ int get_resample_module_num(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int set_resample_source(enum resample_idx id, enum toddr_src src)
|
||||
{
|
||||
struct audioresample *p_resample = get_audioresample(id);
|
||||
(void)p_resample;
|
||||
(void)src;
|
||||
//p_resample->resample_module = src;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_resample_rate_index(
|
||||
enum resample_idx id, enum samplerate_index index)
|
||||
{
|
||||
struct audioresample *p_resample = get_audioresample(id);
|
||||
|
||||
p_resample->asrc_rate_idx = index;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum samplerate_index get_resample_rate_index(
|
||||
enum resample_idx id)
|
||||
{
|
||||
struct audioresample *p_resample = get_audioresample(id);
|
||||
|
||||
return p_resample->asrc_rate_idx;
|
||||
}
|
||||
|
||||
static int resample_clk_set(struct audioresample *p_resample)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -126,7 +150,7 @@ static int resample_clk_set(struct audioresample *p_resample)
|
||||
clk_set_rate(p_resample->sclk, 48000 * CLK_RATIO);
|
||||
clk_set_rate(p_resample->clk, 48000 * CLK_RATIO);
|
||||
}
|
||||
|
||||
#if 0
|
||||
ret = clk_prepare_enable(p_resample->pll);
|
||||
if (ret) {
|
||||
pr_err("Can't enable pll clock: %d\n", ret);
|
||||
@@ -146,6 +170,7 @@ static int resample_clk_set(struct audioresample *p_resample)
|
||||
ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
pr_info("%s, resample_pll:%lu, sclk:%lu, clk:%lu\n",
|
||||
__func__,
|
||||
@@ -153,9 +178,11 @@ static int resample_clk_set(struct audioresample *p_resample)
|
||||
clk_get_rate(p_resample->sclk),
|
||||
clk_get_rate(p_resample->clk));
|
||||
} else {
|
||||
#if 0
|
||||
clk_disable_unprepare(p_resample->clk);
|
||||
clk_disable_unprepare(p_resample->sclk);
|
||||
clk_disable_unprepare(p_resample->pll);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -194,25 +221,25 @@ static const char *const auge_resample_texts[] = {
|
||||
"Enable:192K",
|
||||
};
|
||||
|
||||
static int resample_idx2rate(int index)
|
||||
static int resample_idx2rate(enum samplerate_index index)
|
||||
{
|
||||
int rate = 0;
|
||||
|
||||
if (index == 0)
|
||||
if (index == RATE_OFF)
|
||||
rate = 0;
|
||||
else if (index == 1)
|
||||
else if (index == RATE_32K)
|
||||
rate = 32000;
|
||||
else if (index == 2)
|
||||
else if (index == RATE_44K)
|
||||
rate = 44100;
|
||||
else if (index == 3)
|
||||
else if (index == RATE_48K)
|
||||
rate = 48000;
|
||||
else if (index == 4)
|
||||
else if (index == RATE_88K)
|
||||
rate = 88200;
|
||||
else if (index == 5)
|
||||
else if (index == RATE_96K)
|
||||
rate = 96000;
|
||||
else if (index == 6)
|
||||
else if (index == RATE_176K)
|
||||
rate = 176400;
|
||||
else if (index == 7)
|
||||
else if (index == RATE_192K)
|
||||
rate = 192000;
|
||||
|
||||
return rate;
|
||||
@@ -238,38 +265,51 @@ static int resample_get_enum(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int resample_set(int id, int index)
|
||||
int resample_set(enum resample_idx id, enum samplerate_index index)
|
||||
{
|
||||
int resample_rate = resample_idx2rate(index);
|
||||
int resample_rate = 0;
|
||||
struct audioresample *p_resample = get_audioresample(id);
|
||||
int ret = 0;
|
||||
|
||||
pr_info("%s resample_%c to %s, last %s\n",
|
||||
__func__,
|
||||
(id == RESAMPLE_A) ? 'a' : 'b',
|
||||
auge_resample_texts[index],
|
||||
auge_resample_texts[p_resample->asrc_rate_idx]);
|
||||
|
||||
if (!p_resample)
|
||||
return 0;
|
||||
|
||||
if (index == p_resample->asrc_rate_idx)
|
||||
return 0;
|
||||
//if (index == p_resample->asrc_rate_idx)
|
||||
// return 0;
|
||||
|
||||
p_resample->asrc_rate_idx = index;
|
||||
|
||||
pr_info("%s resample_%c %s\n",
|
||||
__func__,
|
||||
(id == 0) ? 'a' : 'b',
|
||||
auge_resample_texts[index]);
|
||||
resample_rate = resample_idx2rate(index);
|
||||
ret = audio_resample_set(p_resample, (bool)index, resample_rate);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (audio_resample_set(p_resample, (bool)index, resample_rate))
|
||||
return 0;
|
||||
|
||||
if ((index == 0) || (resample_rate == 0))
|
||||
if (index == RATE_OFF)
|
||||
resample_disable(p_resample->id);
|
||||
else {
|
||||
resample_init(p_resample->id, resample_rate);
|
||||
|
||||
resample_set_hw_param(p_resample->id, index - 1);
|
||||
resample_set_hw_param(p_resample->id, index);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int resample_set_inner_rate(enum resample_idx id)
|
||||
{
|
||||
enum samplerate_index index = get_resample_rate_index(id);
|
||||
|
||||
pr_debug("%s() index %d\n", __func__, id);
|
||||
|
||||
return resample_set(id, index);
|
||||
}
|
||||
|
||||
static int resample_set_enum(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
@@ -282,7 +322,8 @@ static int resample_set_enum(
|
||||
return 0;
|
||||
}
|
||||
|
||||
resample_set(p_resample->id, index);
|
||||
set_resample_rate_index(p_resample->id, index);
|
||||
resample_set_inner_rate(p_resample->id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -345,6 +386,10 @@ static const char *const auge_resample_module_texts[] = {
|
||||
"FRHDMIRX", /* from tl1 chipset*/
|
||||
"LOOPBACK_B",
|
||||
"SPDIFIN_LB",
|
||||
"RESERVED_0",
|
||||
"RESERVED_1",
|
||||
"RESERVED_2",
|
||||
"RESERVED_3",
|
||||
"VAD",
|
||||
};
|
||||
|
||||
@@ -388,7 +433,6 @@ static int resample_module_set_enum(
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new asrc_a_controls[] = {
|
||||
SOC_ENUM_EXT("Hardware resample enable",
|
||||
auge_resample_enum,
|
||||
@@ -566,6 +610,13 @@ static int resample_platform_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(p_resample->clk);
|
||||
if (ret) {
|
||||
pr_err("Can't enable resample_clk clock: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
p_resample->dev = dev;
|
||||
|
||||
if (p_chipinfo && p_chipinfo->id == 1)
|
||||
|
||||
@@ -17,10 +17,16 @@
|
||||
#ifndef __AML_AUDIO_RESAMPLE_H__
|
||||
#define __AML_AUDIO_RESAMPLE_H__
|
||||
|
||||
#include "resample_hw.h"
|
||||
|
||||
extern int card_add_resample_kcontrols(struct snd_soc_card *card);
|
||||
|
||||
extern int resample_set(int id, int index);
|
||||
extern int resample_set(enum resample_idx id, enum samplerate_index index);
|
||||
|
||||
extern int get_resample_module_num(void);
|
||||
|
||||
int set_resample_source(enum resample_idx id, enum toddr_src src);
|
||||
|
||||
int resample_set_inner_rate(enum resample_idx id);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -40,7 +40,7 @@ static u32 resample_coef_parameters_table[7][5] = {
|
||||
{0x00800000, 0x0, 0x0, 0x0, 0x0},
|
||||
};
|
||||
|
||||
void resample_enable(int id, bool enable)
|
||||
void resample_enable(enum resample_idx id, bool enable)
|
||||
{
|
||||
int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
|
||||
int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
|
||||
@@ -58,7 +58,7 @@ void resample_enable(int id, bool enable)
|
||||
enable << 28);
|
||||
}
|
||||
|
||||
int resample_init(int id, int input_sr)
|
||||
int resample_init(enum resample_idx id, int input_sr)
|
||||
{
|
||||
u16 Avg_cnt_init = 0;
|
||||
unsigned int clk_rate = 167000000;//clk81;
|
||||
@@ -77,15 +77,15 @@ int resample_init(int id, int input_sr)
|
||||
Avg_cnt_init);
|
||||
|
||||
audiobus_update_bits(reg,
|
||||
0x3 << 26 | 0x3ff << 16 | 0xffff << 0,
|
||||
0x3 << 26 | 0x3ff << 16 | 0xffff,
|
||||
0x0 << 26 | /* method0 */
|
||||
RESAMPLE_CNT_CONTROL << 16 |
|
||||
Avg_cnt_init << 0);
|
||||
Avg_cnt_init);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int resample_disable(int id)
|
||||
int resample_disable(enum resample_idx id)
|
||||
{
|
||||
int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
|
||||
int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
|
||||
@@ -95,15 +95,20 @@ int resample_disable(int id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int resample_set_hw_param(int id, int index)
|
||||
int resample_set_hw_param(enum resample_idx id,
|
||||
enum samplerate_index rate_index)
|
||||
{
|
||||
int i, reg, offset;
|
||||
|
||||
if (rate_index < RATE_32K) {
|
||||
pr_info("%s(), inval index %d", __func__, rate_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
offset = EE_AUDIO_RESAMPLEB_COEF0 - EE_AUDIO_RESAMPLEA_COEF0;
|
||||
reg = EE_AUDIO_RESAMPLEA_COEF0 + offset * id;
|
||||
for (i = 0; i < 5; i++) {
|
||||
audiobus_write((reg + i),
|
||||
resample_coef_parameters_table[index][i]);
|
||||
resample_coef_parameters_table[rate_index - 1][i]);
|
||||
}
|
||||
|
||||
offset = EE_AUDIO_RESAMPLEB_CTRL2 - EE_AUDIO_RESAMPLEA_CTRL2;
|
||||
@@ -113,15 +118,15 @@ int resample_set_hw_param(int id, int index)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* not avail for tl1 */
|
||||
void resample_src_select(int src)
|
||||
{
|
||||
audiobus_update_bits(EE_AUDIO_RESAMPLEA_CTRL0,
|
||||
0x3 << 29,
|
||||
src << 29);
|
||||
}
|
||||
|
||||
void resample_src_select_ab(int id, int src)
|
||||
/* for tl1 and after */
|
||||
void resample_src_select_ab(enum resample_idx id, enum toddr_src src)
|
||||
{
|
||||
int offset = EE_AUDIO_RESAMPLEB_CTRL3 - EE_AUDIO_RESAMPLEA_CTRL3;
|
||||
int reg = EE_AUDIO_RESAMPLEA_CTRL3 + offset * id;
|
||||
@@ -131,7 +136,7 @@ void resample_src_select_ab(int id, int src)
|
||||
src << 16);
|
||||
}
|
||||
|
||||
void resample_format_set(int id, int ch_num, int bits)
|
||||
void resample_format_set(enum resample_idx id, int ch_num, int bits)
|
||||
{
|
||||
int offset = EE_AUDIO_RESAMPLEB_CTRL3 - EE_AUDIO_RESAMPLEA_CTRL3;
|
||||
int reg = EE_AUDIO_RESAMPLEA_CTRL3 + offset * id;
|
||||
@@ -140,7 +145,7 @@ void resample_format_set(int id, int ch_num, int bits)
|
||||
ch_num << 8 | (bits - 1) << 0);
|
||||
}
|
||||
|
||||
int resample_ctrl_read(int id)
|
||||
int resample_ctrl_read(enum resample_idx id)
|
||||
{
|
||||
int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
|
||||
int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
|
||||
@@ -148,7 +153,7 @@ int resample_ctrl_read(int id)
|
||||
return audiobus_read(reg);
|
||||
}
|
||||
|
||||
void resample_ctrl_write(int id, int value)
|
||||
void resample_ctrl_write(enum resample_idx id, int value)
|
||||
{
|
||||
int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0;
|
||||
int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id;
|
||||
|
||||
@@ -17,15 +17,29 @@
|
||||
#ifndef __AML_AUDIO_RESAMPLE_HW_H__
|
||||
#define __AML_AUDIO_RESAMPLE_HW_H__
|
||||
|
||||
extern void resample_enable(int id, bool enable);
|
||||
extern int resample_init(int id, int input_sr);
|
||||
extern int resample_disable(int id);
|
||||
extern int resample_set_hw_param(int id, int index);
|
||||
extern void resample_src_select(int src);
|
||||
extern void resample_src_select_ab(int id, int src);
|
||||
extern void resample_format_set(int id, int ch_num, int bits);
|
||||
#include "ddr_mngr.h"
|
||||
|
||||
extern int resample_ctrl_read(int id);
|
||||
extern void resample_ctrl_write(int id, int value);
|
||||
enum samplerate_index {
|
||||
RATE_OFF,
|
||||
RATE_32K,
|
||||
RATE_44K,
|
||||
RATE_48K,
|
||||
RATE_88K,
|
||||
RATE_96K,
|
||||
RATE_176K,
|
||||
RATE_192K,
|
||||
};
|
||||
|
||||
extern void resample_enable(enum resample_idx id, bool enable);
|
||||
extern int resample_init(enum resample_idx id, int input_sr);
|
||||
extern int resample_disable(enum resample_idx id);
|
||||
extern int resample_set_hw_param(enum resample_idx id,
|
||||
enum samplerate_index rate_index);
|
||||
extern void resample_src_select(int src);
|
||||
extern void resample_src_select_ab(enum resample_idx id, enum toddr_src src);
|
||||
extern void resample_format_set(enum resample_idx id, int ch_num, int bits);
|
||||
|
||||
extern int resample_ctrl_read(enum resample_idx id);
|
||||
extern void resample_ctrl_write(enum resample_idx id, int value);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -86,11 +86,11 @@ struct aml_spdif {
|
||||
/*
|
||||
* resample a/b do asrc for spdif in
|
||||
*/
|
||||
unsigned int asrc_id;
|
||||
enum resample_idx asrc_id;
|
||||
/* spdif in do asrc for pcm,
|
||||
* if raw data, disable it automatically.
|
||||
*/
|
||||
unsigned int auto_asrc;
|
||||
enum samplerate_index auto_asrc;
|
||||
|
||||
/* check spdifin channel status for pcm or nonpcm */
|
||||
struct timer_list timer;
|
||||
@@ -441,7 +441,7 @@ static void spdifin_audio_type_work_func(struct work_struct *work)
|
||||
|
||||
if (val & 0x2)
|
||||
/* nonpcm, resample disable */
|
||||
resample_set(p_spdif->asrc_id, 0);
|
||||
resample_set(p_spdif->asrc_id, RATE_OFF);
|
||||
else
|
||||
/* pcm, resample which rate ? */
|
||||
resample_set(p_spdif->asrc_id, p_spdif->auto_asrc);
|
||||
@@ -652,7 +652,7 @@ static void spdifin_status_event(struct aml_spdif *p_spdif)
|
||||
#ifdef __SPDIFIN_AUDIO_TYPE_HW__
|
||||
/* resample disable, by hw */
|
||||
if (!spdifin_check_audiotype_by_sw(p_spdif))
|
||||
resample_set(p_spdif->asrc_id, 0);
|
||||
resample_set(p_spdif->asrc_id, RATE_OFF);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -1075,7 +1075,7 @@ static void aml_dai_spdif_shutdown(
|
||||
#ifdef __SPDIFIN_AUDIO_TYPE_HW__
|
||||
/* resample disabled, by hw */
|
||||
if (!spdifin_check_audiotype_by_sw(p_spdif))
|
||||
resample_set(p_spdif->asrc_id, 0);
|
||||
resample_set(p_spdif->asrc_id, RATE_OFF);
|
||||
#endif
|
||||
clk_disable_unprepare(p_spdif->clk_spdifin);
|
||||
clk_disable_unprepare(p_spdif->fixed_clk);
|
||||
|
||||
Reference in New Issue
Block a user