硬件环境:i.MX8QM Bumblebeee-MB_V1.0
软件环境:Linux 4.14.98_2.0.0_ga
目标:在 i.MX8QM 上完成 TAS2505 驱动移植,实现音频播放及音量调节功能
一、硬件电路调整
查看 TAS2505 数据手册可知,TAS2505 有两种供电模式:① 外部 LDO 供电;② 内部 LDO 供电;
① 外部 LDO 供电
② 内部 LDO 供电
硬件电路修改:
① 查看 i.MX8QM Bumblebeee-MB_V1.0 原理图,可以发现 LDO_SEL 引脚上拉,但是却是使用外部 LDO 供电,需要修改供电模式为内部 LDO 供电;
② BCLK 与 WCLK 需要修改连接,分别是接到 i.MX8QM 上的 ESAI SCKT 和 FST;
③ 输出端两个接地电容需去掉。
TAS2505 连接电路 ①
TAS2505 连接电路 ②
TAS2505 连接电路 ③
电路修改
二、驱动代码移植
首先了解 TAS2505 内部寄存器的工作机制
如上图所示,TAS2505 内部寄存器是以 Page 的方式进行功能划分,通过修改 0x00 寄存器的值进行 Page 切换,默认 0x00 = 0,表示当前寄存器操作为对第 0 页进行操作,要对第一页操作只需修改 0x00 = 1 即可。我们这里也只需修改到第 0 页及第 1 页的寄存器。
i.MX8QM 默认使用的是 Audio ALSA 架构,通信接口使用的是 ESAI0,TAS2505 作为主设备同步模式,驱动代码移植可以参考 CS42888 驱动进行移植,如下图为所需修改及添加的代码文件。
① 首先将 tas2505.c 及 tas2505.h 放到 codec 目录底下,修改 Makefile 添加编译到内核中
Makefile
snd-soc-tas2505-objs := tas2505.o
obj-y += snd-soc-tas2505.o
tas2505.c
/* 省略部分代码 */
static const struct regmap_range_cfg tas2505_ranges[] = {
{
.range_min = 0,
.range_max = 2 * 128,
.selector_reg = 0x03,//TAS2505_PAGECTL, /*这里改为 0x03 才可以正常工作,否则第一页寄存器无法写入,原因不详*/
.selector_mask = 0xff,
.selector_shift = 0,
.window_start = 0,
.window_len = 128,
},
};
/* 初始化时钟 */
static void tas2505_clk_on(struct snd_soc_codec *codec)
{
int i;
uint8_t lBuf[2] = {0};
printk("[pual_audio] Enter %s - %d -- \n",__func__,__LINE__);
for (i = 0; i < sizeof(ts2505_Clk_Table); i += 2)
{
lBuf[0] = ts2505_Clk_Table[i];
lBuf[1] = ts2505_Clk_Table[i + 1];
snd_soc_write(codec, lBuf[0], lBuf[1]);
}
}
/* 初始化 tas2505 */
static void tas2505_power_on(struct snd_soc_codec *codec)
{
int i;
uint8_t lBuf[2] = {0};
printk("[pual_audio] Enter %s - %d -- \n",__func__,__LINE__);
for (i = 0; i < sizeof(ts2505_Init_Table); i += 2)
{
lBuf[0] = ts2505_Init_Table[i];
lBuf[1] = ts2505_Init_Table[i + 1];
snd_soc_write(codec, lBuf[0], lBuf[1]);
}
}
static int tas2505_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
/* 省略部分代码 */
/* Enable SPKVDD Power */
printk("[pual] Enable SPKVDD_EN %s - %d -- \n",__func__,__LINE__);
//GPIO0_IO31
ret = gpio_request(511, "SPKVDD_EN");
gpio_direction_output(511, 0);
gpio_set_value(511, 1);
tas2505 = devm_kzalloc(&i2c->dev, sizeof(*tas2505), GFP_KERNEL);
if (tas2505 == NULL)
return -ENOMEM;
/* 获取 mclk 时钟 */
tas2505->mclk = devm_clk_get(&i2c->dev, "mclk");
if (IS_ERR(tas2505->mclk)) {
if (PTR_ERR(tas2505->mclk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
}
/* 使能 mclk 时钟 */
ret = clk_prepare_enable(tas2505->mclk);
if (ret) {
dev_err(tas2505->dev, "Failed to enable MCLK: %d\n", ret);
return ret;
}
/* 初始化 regmap i2c */
tas2505->regmap = devm_regmap_init_i2c(i2c, regmap_config);
if (IS_ERR(tas2505->regmap)) {
ret = PTR_ERR(tas2505->regmap);
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
ret);
return ret;
}
tas2505->dev = &i2c->dev;
dev_set_drvdata(tas2505->dev, tas2505);
return snd_soc_register_codec( &i2c->dev, &soc_codec_driver_tas2505,
tas2505_dai_driver, ARRAY_SIZE(tas2505_dai_driver));
}
tas2505.h
/* 省略部分代码 */
#define TAS2505_RATES SNDRV_PCM_RATE_8000_96000
#define TAS2505_FORMATS SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE
/* 经过验证,无法通过 page * 128 的方式操作对应 page */
/* 这里是通过每次写对应 page 的寄存器时,先写 0x00 选择 page */
//#define TAS2505_REG(page, reg) ((page * 128) + reg)
#define TAS2505_REG(page, reg) (reg)
#define TAS2505_PAGECTL TAS2505_REG(0, 0)
#define TAS2505_RESET TAS2505_REG(0, 1)
#define TAS2505_DACFLAG2 TAS2505_REG(0, 38)
#define TAS2505_STICKYFLAG1 TAS2505_REG(0, 42)
#define TAS2505_INTFLAG1 TAS2505_REG(0, 43)
/* 省略部分代码 */
#define TAS2505_STICKYFLAG2 TAS2505_REG(0, 44)
#define TAS2505_INTFLAG2 TAS2505_REG(0, 46)
#define TAS2505_DACINSTRSET TAS2505_REG(0, 60)
#define TAS2505_DACSETUP1 TAS2505_REG(0, 63)
#define TAS2505_DACSETUP2 TAS2505_REG(0, 64)
static const uint8_t ts2505_Init_Table[] ={
0x00, 0x00, //Page switch to Page 0
0x01, 0x01, //Assert Software reset
0x00, 0x01, //Page Switch to Page 1
0x02, 0x00, //LDO output programmed as 1.8V and Level shifters powered up
0x00, 0x00, //Page switch to Page 0
0x3c, 0x01, //Dac Instruction programming PRB #1 for Mono routing. Type interpolation (x8) and 3 programmable Biquads
0x1c, 0x00, //Data slot offset 00
0x3f, 0xB0, //DAC powered up, Soft step 1 per Fs,Mono Mix of Left and Right
0x40, 0x04, //DAC volume not muted
0x41, 0x00, //DAC digital gain 0dB
0x00, 0x01, //Page Switch to Page 1
0x01, 0x10, //Master Reference Powered on
0x0a, 0x00, //Output common mode for DAC set to 0.9V (default)
0x03, 0x00, //DAC is enabled with low power mode
//0x2E, 0x00, //Speaker Volume Control
0x30, 0x30, //SPK driver Gain=18 dB
0x2D, 0x02, //SPK powered up
};
static const uint8_t ts2505_Clk_Table[] ={
0x00, 0x00, //Page switch to Page 0
0x1e, 0x84, //BCLK N-divider powered up,BCLK divider N = 4
0x1b, 0x0c, // Codec Interface control Word length = 16bits, BCLK&WCLK outputs, I2S mode
0x04, 0x00, //CODEC_CLKIN=MCLK, MCLK should be 12.288MHz
0x0b, 0x81, //DAC NDAC Powered up, NDAC=1
0x0c, 0x82, //DAC MDAC Powered up, MDAC=2
0x0d, 0x00, //DAC OSR(9:0)-> DOSR=128
0x0e, 0x80, //DAC OSR(9:0)-> DOSR=128
};
② 参考 imx-cs42888.c 在 fsl 目录底下添加 imx-tas2505.c 文件
imx-tas2505.c
/* 省略部分代码 */
static int imx_tas2505_surround_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
/* 省略部分代码 */
priv->is_stream_tdm[tx] = channels > 1 && channels % 2;
dai_format = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
priv->mclk_freq = clk_get_rate(priv->codec_clk);
priv->esai_freq = clk_get_rate(priv->esai_clk);
if (priv->is_codec_master) {
printk("[pual_imx_audio] Enter %s - %d -- \n",__func__,__LINE__);
/* TDM is not supported by codec in master mode */
dai_format |= SND_SOC_DAIFMT_CBM_CFM;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKT_EXTAL,
priv->mclk_freq, SND_SOC_CLOCK_IN);
else
ret = snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKR_EXTAL,
priv->mclk_freq, SND_SOC_CLOCK_IN);
ret = snd_soc_dai_set_sysclk(codec_dai, 0,
priv->mclk_freq, SND_SOC_CLOCK_OUT);
} else {
printk("[pual_imx_audio] Enter %s - %d -- \n",__func__,__LINE__);
dai_format |= SND_SOC_DAIFMT_CBS_CFS;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKT_EXTAL,
priv->mclk_freq, SND_SOC_CLOCK_OUT);
else
ret = snd_soc_dai_set_sysclk(cpu_dai, ESAI_HCKR_EXTAL,
priv->mclk_freq, SND_SOC_CLOCK_OUT);
ret = snd_soc_dai_set_sysclk(codec_dai, 0,
priv->mclk_freq, SND_SOC_CLOCK_IN);
}
/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
return 0;
}
static int imx_tas2505_surround_startup(struct snd_pcm_substream *substream)
{
priv->mclk_freq = clk_get_rate(priv->codec_clk);
if (priv->mclk_freq % 12288000 == 0) {
support_rates[0] = 8000;
support_rates[1] = 44100;
support_rates[2] = 48000;
support_rates[3] = 96000;
support_rates[4] = 192000;
constraint_rates.list = support_rates;
constraint_rates.count = 5;
ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
&constraint_rates);
} else
dev_warn(dev, "mclk may be not supported %d\n", priv->mclk_freq);
return 0;
}
static const struct snd_soc_dapm_widget imx_tas2505_dapm_widgets[] = {
SND_SOC_DAPM_SPK("Ext Spk", NULL),
};
static struct snd_soc_dai_link imx_tas2505_dai[] = {
{
.name = "HiFi",
.stream_name = "HiFi",
.codec_dai_name = "tas2505-hifi",
.ops = &imx_tas2505_surround_ops,
.ignore_pmdown_time = 1,
},
};
static struct snd_soc_card snd_soc_card_imx_tas2505 = {
.name = "tas2505-audio",
.dai_link = imx_tas2505_dai,
.dapm_widgets = imx_tas2505_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(imx_tas2505_dapm_widgets),
.owner = THIS_MODULE,
};
static int imx_tas2505_probe(struct platform_device *pdev)
{
if (!asrc_pdev) {
printk("[pual_imx_audio] Enter %s - %d -- \n",__func__,__LINE__);
imx_tas2505_dai[0].cpu_dai_name = dev_name(&esai_pdev->dev);
imx_tas2505_dai[0].platform_of_node = esai_np;
snd_soc_card_imx_tas2505.num_links = 1;
} else {
printk("[pual_imx_audio] Enter %s - %d -- \n",__func__,__LINE__);
imx_tas2505_dai[0].cpu_dai_name = dev_name(&esai_pdev->dev);
imx_tas2505_dai[0].platform_of_node = esai_np;
imx_tas2505_dai[1].cpu_of_node = asrc_np;
imx_tas2505_dai[1].platform_of_node = asrc_np;
imx_tas2505_dai[2].cpu_dai_name = dev_name(&esai_pdev->dev);
snd_soc_card_imx_tas2505.num_links = 3;
if (priv->is_codec_rpmsg) {
printk("[pual_imx_audio] Enter %s - %d -- \n",__func__,__LINE__);
imx_tas2505_dai[2].codec_name = "rpmsg-audio-codec-tas2505";
imx_tas2505_dai[2].codec_dai_name = "tas2505-hifi";
} else {
printk("[pual_imx_audio] Enter %s - %d -- \n",__func__,__LINE__);
imx_tas2505_dai[2].codec_of_node = codec_np;
}
ret = snd_soc_of_parse_audio_routing(&snd_soc_card_imx_tas2505, "audio-routing");
③ 修改 fsl 目录下 Makefile 将 imx-tas2505.c 编译进内核
Makefile
snd-soc-imx-tas2505-objs := imx-tas2505.o
obj-y += snd-soc-imx-tas2505.o
④ 添加 TAS2505 相关配置到 DTS 中
fsl-imx8qm-mek.dtsi
/ {
sound: sound {
compatible = "fsl,imx7d-evk-tas2505",
"fsl,imx-audio-tas2505";
model = "tas2505-audio";
cpu-dai = <&esai0>;
audio-codec = <&tas2505>;
codec-master;
audio-routing =
"Ext Spk", "Speaker";
};
};
&iomuxc {
pinctrl_esai0: esai0grp {
fsl,pins = <
SC_P_ESAI0_FSR_AUD_ESAI0_FSR 0xc6000040
SC_P_ESAI0_FST_AUD_ESAI0_FST 0xc6000040
SC_P_ESAI0_SCKR_AUD_ESAI0_SCKR 0xc6000040
SC_P_ESAI0_SCKT_AUD_ESAI0_SCKT 0xc6000040
SC_P_ESAI0_TX0_AUD_ESAI0_TX0 0xc6000040
SC_P_ESAI0_TX1_AUD_ESAI0_TX1 0xc6000040
SC_P_ESAI0_TX2_RX3_AUD_ESAI0_TX2_RX3 0xc6000040
SC_P_ESAI0_TX3_RX2_AUD_ESAI0_TX3_RX2 0xc6000040
SC_P_ESAI0_TX4_RX1_AUD_ESAI0_TX4_RX1 0xc6000040
SC_P_ESAI0_TX5_RX0_AUD_ESAI0_TX5_RX0 0xc6000040
SC_P_SCU_GPIO0_03_LSIO_GPIO0_IO31 0x0600004c
>;
};
};
&esai0 {
compatible = "fsl,imx8qm-esai";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_esai0>;
assigned-clocks = <&clk IMX8QM_ACM_ESAI0_MCLK_SEL>,
<&clk IMX8QM_AUD_PLL0_DIV>,
<&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
<&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
<&clk IMX8QM_AUD_ESAI_0_EXTAL_IPG>;
assigned-clock-parents = <&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_CLK>;
assigned-clock-rates = <0>, <786432000>, <49152000>, <12288000>, <49152000>;
fsl,esai-synchronous;
status = "okay";
};
&i2c1 {
tas2505: tas2505@18{
compatible = "ti,tas2505";
reg = <0x18>;
clocks = <&clk IMX8QM_AUD_MCLKOUT0>;
clock-names = "mclk";
power-domains = <&pd_mclk_out0>;
assigned-clocks = <&clk IMX8QM_AUD_PLL0_DIV>,
<&clk IMX8QM_AUD_ACM_AUD_PLL_CLK0_DIV>,
<&clk IMX8QM_AUD_ACM_AUD_REC_CLK0_DIV>,
<&clk IMX8QM_AUD_MCLKOUT0>;
assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
};
};
以上,就完成了 TAS2505 驱动的移植,然后进行编译,再将生成的镜像烧录到 i.MX8。
三、音频功能调试分析
1、I2C 通信
首先先确保 TAS2505 I2C 通信正常,执行如下操作,可以看到 I2C 设备从机地址为 0x18
root@imx8qmmek:/unit_tests/I2C# i2cdetect -y 5
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
执行如下命令,查看设备寄存器内容
root@imx8qmmek:/unit_tests/I2C# i2cdump -y -f 5 0x18
No size specified (using byte-data access)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 00 00 10 00 00 11 04 00 00 00 00 01 02 00 80 02 ..?..??....??.??
10: 00 08 00 00 00 00 00 00 00 00 01 0c 00 00 04 00 .?........??..?.
20: 00 00 00 00 00 00 11 00 00 00 00 00 00 00 00 00 ......?.........
30: 00 00 00 00 00 12 03 02 02 00 00 00 01 00 00 30 .....????...?..0
40: 0c 00 00 00 6f 38 00 00 00 00 00 ee 10 d8 7e e3 ?...o8.....???~?
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
写寄存器 0x00 的值为 1,切换 Page 1 后,再查看寄存器内容
root@imx8qmmek:/unit_tests/I2C# i2cset -y -f 5 0x18 0x00 0x01
root@imx8qmmek:/unit_tests/I2C#
root@imx8qmmek:/unit_tests/I2C# i2cdump -y -f 5 0x18
No size specified (using byte-data access)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 01 10 05 00 00 00 00 00 00 00 00 10 00 00 00 00 ???........?....
10: 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 @...............
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 .............?..
30: 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0...............
40: 08 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ?.?.............
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
确认 I2C 通信正常后,还需要确保时钟可以正确输出,TAS2505 作为主设备,MCLK 时钟由 i.MX8 发出,BCLK 和 WCLK 由 TAS2505 发出。
2、时钟及数据输出
设备初始化完成后就应该会有 MCLK = 12.28MHz 时钟输出,测量波形如下,
接下来需要测量 BCLK 和 WCLK,由于这两个时钟是在播放音频时才开启,执行如下命令播放音频文件,
root@imx8qmmek:/unit_tests# aplay audio8k16S.wav
[ 1537.022371] [pual_imx_audio] Enter imx_tas2505_surround_startup - 187 --
[ 1537.029572] [pual_imx_audio] Enter imx_tas2505_surround_hw_params - 64 --
[ 1537.036517] [pual_imx_audio] Enter imx_tas2505_surround_hw_params - 81 --
[ 1537.043443] [pual_imx_audio] Enter imx_tas2505_surround_hw_params - 165 --
[ 1537.050455] [pual_audio] Enter tas2505_hw_params - 155 --
[ 1537.056366] [pual_audio] Enter tas2505_set_bias_level - 270 --
[ 1537.062337] [pual_audio] Enter tas2505_clk_on - 215 --
[ 1537.070868] [pual_audio] Enter tas2505_set_bias_level - 270 --
[ 1537.076859] [pual_audio] Enter tas2505_dac_mute - 186 --
Playing WAVE 'audio8k16S.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Stereo
[ 1541.775728] [pual_audio] Enter tas2505_dac_mute - 186 --
[ 1541.781911] [pual_imx_audio] Enter imx_tas2505_surround_hw_free - 173 --
[ 1541.789119] [pual_audio] Enter tas2505_set_bias_level - 270 --
[ 1541.795943] [pual_audio] Enter tas2505_set_bias_level - 270 --
[ 1541.801899] [pual_audio] Enter tas2505_clk_off - 228 --
测量波形如下,BCLK = 3.072MHz,WCLK = 48KHz
此时测量 DATA 信号波形如下,
3、音量调节
接下来需要使用音量控件调节音频播放的音量,tas2505.c 中有如下定义
static const struct snd_kcontrol_new tas2505_snd_controls[] = {
SOC_SINGLE_TLV("DAC Playback Volume", TAS2505_DACVOL,
-127, 48,0, dac_vol_tlv),
SOC_SINGLE_EXT_TLV("Speaker Driver Volume", TAS2505_SPKVOL1,
0, 117, 1,
tas2505_spkdrv_getvol, tas2505_spkdrv_putvol, spk_drv_vol_tlv),
SOC_SINGLE_TLV("Speaker Amplifer Volume", TAS2505_SPKVOL2,
4, 5, 0, spk_amp_vol_tlv),
};
执行如下命令,可以看到驱动中定义的控件属性
root@imx8qmmek:/unit_tests# amixer contents
numid=1,iface=MIXER,name='DAC Playback Volume'[ 665.815864] [pual_audio] Enter tas2505_spkdrv_getvol - 30 --
; type=INTEGER,access=rw---R--,values=1,min=0,max=48,step=0
: values=48
| dBscale-min=-63.50dB,step=0.50dB,mute=0
numid=3,iface=MIXER,name='Speaker Amplifer Volume'
; type=INTEGER,access=rw---R--,values=1,min=0,max=5,step=0
: values=1
| dBscale-min=0.00dB,step=6.00dB,mute=1
numid=2,iface=MIXER,name='Speaker Driver Volume'
; type=INTEGER,access=rw---R--,values=1,min=0,max=117,step=0
: values=117
| dBlinear-min=-99999.99dB,max=0.00dB
使用 amixer cset 进行音频音量调节,命令如下,
root@imx8qmmek:/unit_tests# amixer cset numid=3,iface=MIXER,name='Speaker Amplifer Volume' 1
numid=3,iface=MIXER,name='Speaker Amplifer Volume'
; type=INTEGER,access=rw---R--,values=1,min=0,max=5,step=0
: values=1
| dBscale-min=0.00dB,step=6.00dB,mute=1
root@imx8qmmek:/unit_tests# amixer cset numid=2,iface=MIXER,name='Speaker Driver Volume' 60
[ 837.180499] [pual_audio] Enter tas2505_spkdrv_getvol - 30 --
[ 837.186754] [pual_audio] Enter tas2505_spkdrv_putvol - 48 --
numid=2,iface=MIXER,name='Speaker Driver Volume'[ 837.193570] [pual_audio] Enter tas2505_spkdrv_getvol - 30 --
; type=INTEGER,access=rw---R--,values=1,min=0,max=117,step=0
: values=60
| dBlinear-min=-99999.99dB,max=0.00dB
以上便完成了 TAS2505 在 i.MX8QM 平台上的驱动移植,实现了播放音频文件的功能,并进行音量调节。
四、参考文献
【1】 《TAS2505 application reference guide》
评论