* NONE,
* TDMIN_LB, 6
* LOOPBACK, 7
+ * FRHDMIRX, 8
*/
- resample_module = <3>;
+ resample_module = <8>;
status = "okay";
};
* NONE,
* TDMIN_LB, 6
* LOOPBACK, 7
+ * FRHDMIRX, 8
*/
- resample_module = <3>;
+ resample_module = <8>;
status = "okay";
};
* NONE,
* TDMIN_LB, 6
* LOOPBACK, 7
+ * FRHDMIRX, 8
*/
- resample_module = <3>;
+ resample_module = <8>;
status = "okay";
};
* NONE,
* TDMIN_LB, 6
* LOOPBACK, 7
+ * FRHDMIRX, 8
*/
- resample_module = <3>;
+ resample_module = <8>;
status = "okay";
};
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);
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(
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;
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;
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;
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"
};
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];
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;
}
* 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 {
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;
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
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 */
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);
#include "ddr_mngr.h"
#include "audio_utils.h"
#include "frhdmirx_hw.h"
+#include "resample.h"
#include <linux/amlogic/media/sound/misc.h>
struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
+ resample_set_inner_rate(RESAMPLE_A);
return 0;
}
struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
+ //resample_set(RESAMPLE_A, RATE_OFF);
}
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)
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:
#include <sound/tlv.h>
#include "resample.h"
-#include "resample_hw.h"
-#include "ddr_mngr.h"
#include "regs.h"
#include "iomap.h"
/*#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;
};
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;
};
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");
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;
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;
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);
ret);
return -EINVAL;
}
+#endif
pr_info("%s, resample_pll:%lu, sclk:%lu, clk:%lu\n",
__func__,
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;
"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;
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]);
-
- if (audio_resample_set(p_resample, (bool)index, resample_rate))
- return 0;
+ resample_rate = resample_idx2rate(index);
+ ret = audio_resample_set(p_resample, (bool)index, resample_rate);
+ if (ret)
+ return ret;
- 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)
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;
}
"FRHDMIRX", /* from tl1 chipset*/
"LOOPBACK_B",
"SPDIFIN_LB",
+ "RESERVED_0",
+ "RESERVED_1",
+ "RESERVED_2",
+ "RESERVED_3",
"VAD",
};
return 0;
}
-
static const struct snd_kcontrol_new asrc_a_controls[] = {
SOC_ENUM_EXT("Hardware resample enable",
auge_resample_enum,
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)
#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
{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;
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;
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;
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;
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;
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;
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;
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;
#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);
+#include "ddr_mngr.h"
+
+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(int id, int src);
-extern void resample_format_set(int id, int ch_num, int bits);
+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(int id);
-extern void resample_ctrl_write(int id, int value);
+extern int resample_ctrl_read(enum resample_idx id);
+extern void resample_ctrl_write(enum resample_idx id, int value);
#endif
/*
* 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;
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);
#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
}
#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);