Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
5439e726
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
5439e726
编写于
16年前
作者:
T
Takashi Iwai
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/asoc' into for-linus
上级
238c6d54
2f423577
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
447 addition
and
78 deletion
+447
-78
include/sound/soc-dapm.h
include/sound/soc-dapm.h
+15
-0
include/sound/soc.h
include/sound/soc.h
+30
-0
sound/arm/pxa2xx-ac97-lib.c
sound/arm/pxa2xx-ac97-lib.c
+16
-9
sound/soc/codecs/twl4030.c
sound/soc/codecs/twl4030.c
+55
-63
sound/soc/davinci/davinci-evm.c
sound/soc/davinci/davinci-evm.c
+16
-3
sound/soc/omap/Kconfig
sound/soc/omap/Kconfig
+1
-0
sound/soc/omap/omap3pandora.c
sound/soc/omap/omap3pandora.c
+13
-0
sound/soc/soc-core.c
sound/soc/soc-core.c
+107
-0
sound/soc/soc-dapm.c
sound/soc/soc-dapm.c
+194
-3
未找到文件。
include/sound/soc-dapm.h
浏览文件 @
5439e726
...
...
@@ -85,6 +85,10 @@
#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \
.invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1}
#define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \
{ .id = snd_soc_dapm_value_mux, .name = wname, .reg = wreg, \
.shift = wshift, .invert = winvert, .kcontrols = wcontrols, \
.num_kcontrols = 1}
/* path domain with event - event handler must return 0 for success */
#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \
...
...
@@ -172,6 +176,12 @@
.get = snd_soc_dapm_get_enum_double, \
.put = snd_soc_dapm_put_enum_double, \
.private_value = (unsigned long)&xenum }
#define SOC_DAPM_VALUE_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_value_enum_double, \
.get = snd_soc_dapm_get_value_enum_double, \
.put = snd_soc_dapm_put_value_enum_double, \
.private_value = (unsigned long)&xenum }
/* dapm stream operations */
#define SND_SOC_DAPM_STREAM_NOP 0x0
...
...
@@ -214,6 +224,10 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
struct
snd_ctl_elem_value
*
ucontrol
);
int
snd_soc_dapm_put_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
);
int
snd_soc_dapm_get_value_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
);
int
snd_soc_dapm_put_value_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
);
int
snd_soc_dapm_new_control
(
struct
snd_soc_codec
*
codec
,
const
struct
snd_soc_dapm_widget
*
widget
);
int
snd_soc_dapm_new_controls
(
struct
snd_soc_codec
*
codec
,
...
...
@@ -247,6 +261,7 @@ enum snd_soc_dapm_type {
snd_soc_dapm_input
=
0
,
/* input pin */
snd_soc_dapm_output
,
/* output pin */
snd_soc_dapm_mux
,
/* selects 1 analog signal from many inputs */
snd_soc_dapm_value_mux
,
/* selects 1 analog signal from many inputs */
snd_soc_dapm_mixer
,
/* mixes several analog signals together */
snd_soc_dapm_pga
,
/* programmable gain/attenuation (volume) */
snd_soc_dapm_adc
,
/* analog to digital converter */
...
...
This diff is collapsed.
Click to expand it.
include/sound/soc.h
浏览文件 @
5439e726
...
...
@@ -94,11 +94,22 @@
SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts)
#define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \
{ .max = xmax, .texts = xtexts }
#define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xmax, xtexts, xvalues) \
{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
.mask = xmask, .max = xmax, .texts = xtexts, .values = xvalues}
#define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xmax, xtexts, xvalues) \
SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xmax, xtexts, xvalues)
#define SOC_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
.info = snd_soc_info_enum_double, \
.get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \
.private_value = (unsigned long)&xenum }
#define SOC_VALUE_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
.info = snd_soc_info_value_enum_double, \
.get = snd_soc_get_value_enum_double, \
.put = snd_soc_put_value_enum_double, \
.private_value = (unsigned long)&xenum }
#define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\
xhandler_get, xhandler_put) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
...
...
@@ -200,6 +211,12 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
struct
snd_ctl_elem_value
*
ucontrol
);
int
snd_soc_put_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
);
int
snd_soc_info_value_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_info
*
uinfo
);
int
snd_soc_get_value_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
);
int
snd_soc_put_value_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
);
int
snd_soc_info_volsw
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_info
*
uinfo
);
int
snd_soc_info_volsw_ext
(
struct
snd_kcontrol
*
kcontrol
,
...
...
@@ -406,6 +423,19 @@ struct soc_enum {
void
*
dapm
;
};
/* semi enumerated kcontrol */
struct
soc_value_enum
{
unsigned
short
reg
;
unsigned
short
reg2
;
unsigned
char
shift_l
;
unsigned
char
shift_r
;
unsigned
int
max
;
unsigned
int
mask
;
const
char
**
texts
;
const
unsigned
int
*
values
;
void
*
dapm
;
};
#include <sound/soc-dai.h>
#endif
This diff is collapsed.
Click to expand it.
sound/arm/pxa2xx-ac97-lib.c
浏览文件 @
5439e726
...
...
@@ -321,10 +321,6 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
{
int
ret
;
ret
=
request_irq
(
IRQ_AC97
,
pxa2xx_ac97_irq
,
0
,
"AC97"
,
NULL
);
if
(
ret
<
0
)
goto
err
;
if
(
cpu_is_pxa25x
()
||
cpu_is_pxa27x
())
{
pxa_gpio_mode
(
GPIO31_SYNC_AC97_MD
);
pxa_gpio_mode
(
GPIO30_SDATA_OUT_AC97_MD
);
...
...
@@ -339,7 +335,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
if
(
IS_ERR
(
ac97conf_clk
))
{
ret
=
PTR_ERR
(
ac97conf_clk
);
ac97conf_clk
=
NULL
;
goto
err_
irq
;
goto
err_
conf
;
}
}
...
...
@@ -347,19 +343,30 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
if
(
IS_ERR
(
ac97_clk
))
{
ret
=
PTR_ERR
(
ac97_clk
);
ac97_clk
=
NULL
;
goto
err_
irq
;
goto
err_
clk
;
}
return
clk_enable
(
ac97_clk
);
ret
=
clk_enable
(
ac97_clk
);
if
(
ret
)
goto
err_clk2
;
ret
=
request_irq
(
IRQ_AC97
,
pxa2xx_ac97_irq
,
IRQF_DISABLED
,
"AC97"
,
NULL
);
if
(
ret
<
0
)
goto
err_irq
;
return
0
;
err_irq:
GCR
|=
GCR_ACLINK_OFF
;
err_clk2:
clk_put
(
ac97_clk
);
ac97_clk
=
NULL
;
err_clk:
if
(
ac97conf_clk
)
{
clk_put
(
ac97conf_clk
);
ac97conf_clk
=
NULL
;
}
free_irq
(
IRQ_AC97
,
NULL
);
err:
err_conf:
return
ret
;
}
EXPORT_SYMBOL_GPL
(
pxa2xx_ac97_hw_probe
);
...
...
This diff is collapsed.
Click to expand it.
sound/soc/codecs/twl4030.c
浏览文件 @
5439e726
...
...
@@ -192,39 +192,51 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
/* Earpiece */
static
const
char
*
twl4030_earpiece_texts
[]
=
{
"Off"
,
"DACL1"
,
"DACL2"
,
"
Invalid"
,
"
DACR1"
};
{
"Off"
,
"DACL1"
,
"DACL2"
,
"DACR1"
};
static
const
struct
soc_enum
twl4030_earpiece_enum
=
SOC_ENUM_SINGLE
(
TWL4030_REG_EAR_CTL
,
1
,
static
const
unsigned
int
twl4030_earpiece_values
[]
=
{
0x0
,
0x1
,
0x2
,
0x4
};
static
const
struct
soc_value_enum
twl4030_earpiece_enum
=
SOC_VALUE_ENUM_SINGLE
(
TWL4030_REG_EAR_CTL
,
1
,
0x7
,
ARRAY_SIZE
(
twl4030_earpiece_texts
),
twl4030_earpiece_texts
);
twl4030_earpiece_texts
,
twl4030_earpiece_values
);
static
const
struct
snd_kcontrol_new
twl4030_dapm_earpiece_control
=
SOC_DAPM_ENUM
(
"Route"
,
twl4030_earpiece_enum
);
SOC_DAPM_
VALUE_
ENUM
(
"Route"
,
twl4030_earpiece_enum
);
/* PreDrive Left */
static
const
char
*
twl4030_predrivel_texts
[]
=
{
"Off"
,
"DACL1"
,
"DACL2"
,
"Invalid"
,
"DACR2"
};
{
"Off"
,
"DACL1"
,
"DACL2"
,
"DACR2"
};
static
const
unsigned
int
twl4030_predrivel_values
[]
=
{
0x0
,
0x1
,
0x2
,
0x4
};
static
const
struct
soc_enum
twl4030_predrivel_enum
=
SOC_
ENUM_SINGLE
(
TWL4030_REG_PREDL_CTL
,
1
,
static
const
struct
soc_
value_
enum
twl4030_predrivel_enum
=
SOC_
VALUE_ENUM_SINGLE
(
TWL4030_REG_PREDL_CTL
,
1
,
0x7
,
ARRAY_SIZE
(
twl4030_predrivel_texts
),
twl4030_predrivel_texts
);
twl4030_predrivel_texts
,
twl4030_predrivel_values
);
static
const
struct
snd_kcontrol_new
twl4030_dapm_predrivel_control
=
SOC_DAPM_ENUM
(
"Route"
,
twl4030_predrivel_enum
);
SOC_DAPM_
VALUE_
ENUM
(
"Route"
,
twl4030_predrivel_enum
);
/* PreDrive Right */
static
const
char
*
twl4030_predriver_texts
[]
=
{
"Off"
,
"DACR1"
,
"DACR2"
,
"
Invalid"
,
"
DACL2"
};
{
"Off"
,
"DACR1"
,
"DACR2"
,
"DACL2"
};
static
const
struct
soc_enum
twl4030_predriver_enum
=
SOC_ENUM_SINGLE
(
TWL4030_REG_PREDR_CTL
,
1
,
static
const
unsigned
int
twl4030_predriver_values
[]
=
{
0x0
,
0x1
,
0x2
,
0x4
};
static
const
struct
soc_value_enum
twl4030_predriver_enum
=
SOC_VALUE_ENUM_SINGLE
(
TWL4030_REG_PREDR_CTL
,
1
,
0x7
,
ARRAY_SIZE
(
twl4030_predriver_texts
),
twl4030_predriver_texts
);
twl4030_predriver_texts
,
twl4030_predriver_values
);
static
const
struct
snd_kcontrol_new
twl4030_dapm_predriver_control
=
SOC_DAPM_ENUM
(
"Route"
,
twl4030_predriver_enum
);
SOC_DAPM_
VALUE_
ENUM
(
"Route"
,
twl4030_predriver_enum
);
/* Headset Left */
static
const
char
*
twl4030_hsol_texts
[]
=
...
...
@@ -300,28 +312,35 @@ SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
/* Left analog microphone selection */
static
const
char
*
twl4030_analoglmic_texts
[]
=
{
"Off"
,
"Main mic"
,
"Headset mic"
,
"Invalid"
,
"AUXL"
,
"Invalid"
,
"Invalid"
,
"Invalid"
,
"Carkit mic"
};
{
"Off"
,
"Main mic"
,
"Headset mic"
,
"AUXL"
,
"Carkit mic"
};
static
const
unsigned
int
twl4030_analoglmic_values
[]
=
{
0x0
,
0x1
,
0x2
,
0x4
,
0x8
};
static
const
struct
soc_enum
twl4030_analoglmic_enum
=
SOC_
ENUM_SINGLE
(
TWL4030_REG_ANAMICL
,
0
,
static
const
struct
soc_
value_
enum
twl4030_analoglmic_enum
=
SOC_
VALUE_ENUM_SINGLE
(
TWL4030_REG_ANAMICL
,
0
,
0xf
,
ARRAY_SIZE
(
twl4030_analoglmic_texts
),
twl4030_analoglmic_texts
);
twl4030_analoglmic_texts
,
twl4030_analoglmic_values
);
static
const
struct
snd_kcontrol_new
twl4030_dapm_analoglmic_control
=
SOC_DAPM_ENUM
(
"Route"
,
twl4030_analoglmic_enum
);
SOC_DAPM_
VALUE_
ENUM
(
"Route"
,
twl4030_analoglmic_enum
);
/* Right analog microphone selection */
static
const
char
*
twl4030_analogrmic_texts
[]
=
{
"Off"
,
"Sub mic"
,
"
Invalid"
,
"Invalid"
,
"
AUXR"
};
{
"Off"
,
"Sub mic"
,
"AUXR"
};
static
const
struct
soc_enum
twl4030_analogrmic_enum
=
SOC_ENUM_SINGLE
(
TWL4030_REG_ANAMICR
,
0
,
static
const
unsigned
int
twl4030_analogrmic_values
[]
=
{
0x0
,
0x1
,
0x4
};
static
const
struct
soc_value_enum
twl4030_analogrmic_enum
=
SOC_VALUE_ENUM_SINGLE
(
TWL4030_REG_ANAMICR
,
0
,
0x5
,
ARRAY_SIZE
(
twl4030_analogrmic_texts
),
twl4030_analogrmic_texts
);
twl4030_analogrmic_texts
,
twl4030_analogrmic_values
);
static
const
struct
snd_kcontrol_new
twl4030_dapm_analogrmic_control
=
SOC_DAPM_ENUM
(
"Route"
,
twl4030_analogrmic_enum
);
SOC_DAPM_
VALUE_
ENUM
(
"Route"
,
twl4030_analogrmic_enum
);
/* TX1 L/R Analog/Digital microphone selection */
static
const
char
*
twl4030_micpathtx1_texts
[]
=
...
...
@@ -347,28 +366,6 @@ static const struct soc_enum twl4030_micpathtx2_enum =
static
const
struct
snd_kcontrol_new
twl4030_dapm_micpathtx2_control
=
SOC_DAPM_ENUM
(
"Route"
,
twl4030_micpathtx2_enum
);
/*
* This function filters out the non valid mux settings, named as "Invalid"
* in the enum texts.
* Just refuse to set an invalid mux mode.
*/
static
int
twl4030_enum_event
(
struct
snd_soc_dapm_widget
*
w
,
struct
snd_kcontrol
*
kcontrol
,
int
event
)
{
struct
soc_enum
*
e
=
(
struct
soc_enum
*
)
kcontrol
->
private_value
;
int
ret
=
0
;
int
val
;
val
=
w
->
value
>>
e
->
shift_l
;
if
(
!
strcmp
(
"Invalid"
,
e
->
texts
[
val
]))
{
printk
(
KERN_WARNING
"Invalid MUX setting on 0x%02x (%d)
\n
"
,
e
->
reg
,
val
);
ret
=
-
1
;
}
return
ret
;
}
static
int
micpath_event
(
struct
snd_soc_dapm_widget
*
w
,
struct
snd_kcontrol
*
kcontrol
,
int
event
)
{
...
...
@@ -737,16 +734,13 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
/* Output MUX controls */
/* Earpiece */
SND_SOC_DAPM_MUX_E
(
"Earpiece Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
twl4030_dapm_earpiece_control
,
twl4030_enum_event
,
SND_SOC_DAPM_PRE_REG
),
SND_SOC_DAPM_VALUE_MUX
(
"Earpiece Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
twl4030_dapm_earpiece_control
),
/* PreDrivL/R */
SND_SOC_DAPM_MUX_E
(
"PredriveL Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
twl4030_dapm_predrivel_control
,
twl4030_enum_event
,
SND_SOC_DAPM_PRE_REG
),
SND_SOC_DAPM_MUX_E
(
"PredriveR Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
twl4030_dapm_predriver_control
,
twl4030_enum_event
,
SND_SOC_DAPM_PRE_REG
),
SND_SOC_DAPM_VALUE_MUX
(
"PredriveL Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
twl4030_dapm_predrivel_control
),
SND_SOC_DAPM_VALUE_MUX
(
"PredriveR Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
twl4030_dapm_predriver_control
),
/* HeadsetL/R */
SND_SOC_DAPM_MUX
(
"HeadsetL Mux"
,
SND_SOC_NOPM
,
0
,
0
,
&
twl4030_dapm_hsol_control
),
...
...
@@ -789,12 +783,10 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_POST_REG
),
/* Analog input muxes with power switch for the physical ADCL/R */
SND_SOC_DAPM_MUX_E
(
"Analog Left Capture Route"
,
TWL4030_REG_AVADC_CTL
,
3
,
0
,
&
twl4030_dapm_analoglmic_control
,
twl4030_enum_event
,
SND_SOC_DAPM_PRE_REG
),
SND_SOC_DAPM_MUX_E
(
"Analog Right Capture Route"
,
TWL4030_REG_AVADC_CTL
,
1
,
0
,
&
twl4030_dapm_analogrmic_control
,
twl4030_enum_event
,
SND_SOC_DAPM_PRE_REG
),
SND_SOC_DAPM_VALUE_MUX
(
"Analog Left Capture Route"
,
TWL4030_REG_AVADC_CTL
,
3
,
0
,
&
twl4030_dapm_analoglmic_control
),
SND_SOC_DAPM_VALUE_MUX
(
"Analog Right Capture Route"
,
TWL4030_REG_AVADC_CTL
,
1
,
0
,
&
twl4030_dapm_analogrmic_control
),
SND_SOC_DAPM_PGA
(
"Analog Left Amplifier"
,
TWL4030_REG_ANAMICL
,
4
,
0
,
NULL
,
0
),
...
...
This diff is collapsed.
Click to expand it.
sound/soc/davinci/davinci-evm.c
浏览文件 @
5439e726
...
...
@@ -26,7 +26,6 @@
#include "davinci-pcm.h"
#include "davinci-i2s.h"
#define EVM_CODEC_CLOCK 22579200
#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
...
...
@@ -37,6 +36,21 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
struct
snd_soc_dai
*
codec_dai
=
rtd
->
dai
->
codec_dai
;
struct
snd_soc_dai
*
cpu_dai
=
rtd
->
dai
->
cpu_dai
;
int
ret
=
0
;
unsigned
sysclk
;
/* ASP1 on DM355 EVM is clocked by an external oscillator */
if
(
machine_is_davinci_dm355_evm
())
sysclk
=
27000000
;
/* ASP0 in DM6446 EVM is clocked by U55, as configured by
* board-dm644x-evm.c using GPIOs from U18. There are six
* options; here we "know" we use a 48 KHz sample rate.
*/
else
if
(
machine_is_davinci_evm
())
sysclk
=
12288000
;
else
return
-
EINVAL
;
/* set codec DAI configuration */
ret
=
snd_soc_dai_set_fmt
(
codec_dai
,
AUDIO_FORMAT
);
...
...
@@ -49,8 +63,7 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
return
ret
;
/* set the codec system clock */
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
0
,
EVM_CODEC_CLOCK
,
SND_SOC_CLOCK_OUT
);
ret
=
snd_soc_dai_set_sysclk
(
codec_dai
,
0
,
sysclk
,
SND_SOC_CLOCK_OUT
);
if
(
ret
<
0
)
return
ret
;
...
...
This diff is collapsed.
Click to expand it.
sound/soc/omap/Kconfig
浏览文件 @
5439e726
...
...
@@ -10,6 +10,7 @@ config SND_OMAP_SOC_N810
tristate "SoC Audio support for Nokia N810"
depends on SND_OMAP_SOC && MACH_NOKIA_N810
select SND_OMAP_SOC_MCBSP
select OMAP_MUX
select SND_SOC_TLV320AIC3X
help
Say Y if you want to add support for SoC audio on Nokia N810.
...
...
This diff is collapsed.
Click to expand it.
sound/soc/omap/omap3pandora.c
浏览文件 @
5439e726
...
...
@@ -180,6 +180,19 @@ static int omap3pandora_in_init(struct snd_soc_codec *codec)
{
int
ret
;
/* All TWL4030 output pins are floating */
snd_soc_dapm_nc_pin
(
codec
,
"OUTL"
),
snd_soc_dapm_nc_pin
(
codec
,
"OUTR"
),
snd_soc_dapm_nc_pin
(
codec
,
"EARPIECE"
),
snd_soc_dapm_nc_pin
(
codec
,
"PREDRIVEL"
),
snd_soc_dapm_nc_pin
(
codec
,
"PREDRIVER"
),
snd_soc_dapm_nc_pin
(
codec
,
"HSOL"
),
snd_soc_dapm_nc_pin
(
codec
,
"HSOR"
),
snd_soc_dapm_nc_pin
(
codec
,
"CARKITL"
),
snd_soc_dapm_nc_pin
(
codec
,
"CARKITR"
),
snd_soc_dapm_nc_pin
(
codec
,
"HFL"
),
snd_soc_dapm_nc_pin
(
codec
,
"HFR"
),
ret
=
snd_soc_dapm_new_controls
(
codec
,
omap3pandora_in_dapm_widgets
,
ARRAY_SIZE
(
omap3pandora_in_dapm_widgets
));
if
(
ret
<
0
)
...
...
This diff is collapsed.
Click to expand it.
sound/soc/soc-core.c
浏览文件 @
5439e726
...
...
@@ -1584,6 +1584,113 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
}
EXPORT_SYMBOL_GPL
(
snd_soc_put_enum_double
);
/**
* snd_soc_info_value_enum_double - semi enumerated double mixer info callback
* @kcontrol: mixer control
* @uinfo: control element information
*
* Callback to provide information about a double semi enumerated
* mixer control.
*
* Semi enumerated mixer: the enumerated items are referred as values. Can be
* used for handling bitfield coded enumeration for example.
*
* Returns 0 for success.
*/
int
snd_soc_info_value_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_info
*
uinfo
)
{
struct
soc_value_enum
*
e
=
(
struct
soc_value_enum
*
)
kcontrol
->
private_value
;
uinfo
->
type
=
SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
uinfo
->
count
=
e
->
shift_l
==
e
->
shift_r
?
1
:
2
;
uinfo
->
value
.
enumerated
.
items
=
e
->
max
;
if
(
uinfo
->
value
.
enumerated
.
item
>
e
->
max
-
1
)
uinfo
->
value
.
enumerated
.
item
=
e
->
max
-
1
;
strcpy
(
uinfo
->
value
.
enumerated
.
name
,
e
->
texts
[
uinfo
->
value
.
enumerated
.
item
]);
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_soc_info_value_enum_double
);
/**
* snd_soc_get_value_enum_double - semi enumerated double mixer get callback
* @kcontrol: mixer control
* @ucontrol: control element information
*
* Callback to get the value of a double semi enumerated mixer.
*
* Semi enumerated mixer: the enumerated items are referred as values. Can be
* used for handling bitfield coded enumeration for example.
*
* Returns 0 for success.
*/
int
snd_soc_get_value_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_soc_codec
*
codec
=
snd_kcontrol_chip
(
kcontrol
);
struct
soc_value_enum
*
e
=
(
struct
soc_value_enum
*
)
kcontrol
->
private_value
;
unsigned
short
reg_val
,
val
,
mux
;
reg_val
=
snd_soc_read
(
codec
,
e
->
reg
);
val
=
(
reg_val
>>
e
->
shift_l
)
&
e
->
mask
;
for
(
mux
=
0
;
mux
<
e
->
max
;
mux
++
)
{
if
(
val
==
e
->
values
[
mux
])
break
;
}
ucontrol
->
value
.
enumerated
.
item
[
0
]
=
mux
;
if
(
e
->
shift_l
!=
e
->
shift_r
)
{
val
=
(
reg_val
>>
e
->
shift_r
)
&
e
->
mask
;
for
(
mux
=
0
;
mux
<
e
->
max
;
mux
++
)
{
if
(
val
==
e
->
values
[
mux
])
break
;
}
ucontrol
->
value
.
enumerated
.
item
[
1
]
=
mux
;
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_soc_get_value_enum_double
);
/**
* snd_soc_put_value_enum_double - semi enumerated double mixer put callback
* @kcontrol: mixer control
* @ucontrol: control element information
*
* Callback to set the value of a double semi enumerated mixer.
*
* Semi enumerated mixer: the enumerated items are referred as values. Can be
* used for handling bitfield coded enumeration for example.
*
* Returns 0 for success.
*/
int
snd_soc_put_value_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_soc_codec
*
codec
=
snd_kcontrol_chip
(
kcontrol
);
struct
soc_value_enum
*
e
=
(
struct
soc_value_enum
*
)
kcontrol
->
private_value
;
unsigned
short
val
;
unsigned
short
mask
;
if
(
ucontrol
->
value
.
enumerated
.
item
[
0
]
>
e
->
max
-
1
)
return
-
EINVAL
;
val
=
e
->
values
[
ucontrol
->
value
.
enumerated
.
item
[
0
]]
<<
e
->
shift_l
;
mask
=
e
->
mask
<<
e
->
shift_l
;
if
(
e
->
shift_l
!=
e
->
shift_r
)
{
if
(
ucontrol
->
value
.
enumerated
.
item
[
1
]
>
e
->
max
-
1
)
return
-
EINVAL
;
val
|=
e
->
values
[
ucontrol
->
value
.
enumerated
.
item
[
1
]]
<<
e
->
shift_r
;
mask
|=
e
->
mask
<<
e
->
shift_r
;
}
return
snd_soc_update_bits
(
codec
,
e
->
reg
,
mask
,
val
);
}
EXPORT_SYMBOL_GPL
(
snd_soc_put_value_enum_double
);
/**
* snd_soc_info_enum_ext - external enumerated single mixer info callback
* @kcontrol: mixer control
...
...
This diff is collapsed.
Click to expand it.
sound/soc/soc-dapm.c
浏览文件 @
5439e726
...
...
@@ -53,13 +53,15 @@
/* dapm power sequences - make this per codec in the future */
static
int
dapm_up_seq
[]
=
{
snd_soc_dapm_pre
,
snd_soc_dapm_micbias
,
snd_soc_dapm_mic
,
snd_soc_dapm_mux
,
snd_soc_dapm_dac
,
snd_soc_dapm_mixer
,
snd_soc_dapm_pga
,
snd_soc_dapm_adc
,
snd_soc_dapm_hp
,
snd_soc_dapm_spk
,
snd_soc_dapm_post
snd_soc_dapm_mux
,
snd_soc_dapm_value_mux
,
snd_soc_dapm_dac
,
snd_soc_dapm_mixer
,
snd_soc_dapm_pga
,
snd_soc_dapm_adc
,
snd_soc_dapm_hp
,
snd_soc_dapm_spk
,
snd_soc_dapm_post
};
static
int
dapm_down_seq
[]
=
{
snd_soc_dapm_pre
,
snd_soc_dapm_adc
,
snd_soc_dapm_hp
,
snd_soc_dapm_spk
,
snd_soc_dapm_pga
,
snd_soc_dapm_mixer
,
snd_soc_dapm_dac
,
snd_soc_dapm_mic
,
snd_soc_dapm_micbias
,
snd_soc_dapm_mux
,
snd_soc_dapm_post
snd_soc_dapm_micbias
,
snd_soc_dapm_mux
,
snd_soc_dapm_value_mux
,
snd_soc_dapm_post
};
static
int
dapm_status
=
1
;
...
...
@@ -134,6 +136,25 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
}
}
break
;
case
snd_soc_dapm_value_mux
:
{
struct
soc_value_enum
*
e
=
(
struct
soc_value_enum
*
)
w
->
kcontrols
[
i
].
private_value
;
int
val
,
item
;
val
=
snd_soc_read
(
w
->
codec
,
e
->
reg
);
val
=
(
val
>>
e
->
shift_l
)
&
e
->
mask
;
for
(
item
=
0
;
item
<
e
->
max
;
item
++
)
{
if
(
val
==
e
->
values
[
item
])
break
;
}
p
->
connect
=
0
;
for
(
i
=
0
;
i
<
e
->
max
;
i
++
)
{
if
(
!
(
strcmp
(
p
->
name
,
e
->
texts
[
i
]))
&&
item
==
i
)
p
->
connect
=
1
;
}
}
break
;
/* does not effect routing - always connected */
case
snd_soc_dapm_pga
:
case
snd_soc_dapm_output
:
...
...
@@ -179,6 +200,30 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
return
-
ENODEV
;
}
/* connect value_mux widget to it's interconnecting audio paths */
static
int
dapm_connect_value_mux
(
struct
snd_soc_codec
*
codec
,
struct
snd_soc_dapm_widget
*
src
,
struct
snd_soc_dapm_widget
*
dest
,
struct
snd_soc_dapm_path
*
path
,
const
char
*
control_name
,
const
struct
snd_kcontrol_new
*
kcontrol
)
{
struct
soc_value_enum
*
e
=
(
struct
soc_value_enum
*
)
kcontrol
->
private_value
;
int
i
;
for
(
i
=
0
;
i
<
e
->
max
;
i
++
)
{
if
(
!
(
strcmp
(
control_name
,
e
->
texts
[
i
])))
{
list_add
(
&
path
->
list
,
&
codec
->
dapm_paths
);
list_add
(
&
path
->
list_sink
,
&
dest
->
sources
);
list_add
(
&
path
->
list_source
,
&
src
->
sinks
);
path
->
name
=
(
char
*
)
e
->
texts
[
i
];
dapm_set_path_status
(
dest
,
path
,
0
);
return
0
;
}
}
return
-
ENODEV
;
}
/* connect mixer widget to it's interconnecting audio paths */
static
int
dapm_connect_mixer
(
struct
snd_soc_codec
*
codec
,
struct
snd_soc_dapm_widget
*
src
,
struct
snd_soc_dapm_widget
*
dest
,
...
...
@@ -653,6 +698,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
case
snd_soc_dapm_vmid
:
continue
;
case
snd_soc_dapm_mux
:
case
snd_soc_dapm_value_mux
:
case
snd_soc_dapm_output
:
case
snd_soc_dapm_input
:
case
snd_soc_dapm_switch
:
...
...
@@ -728,6 +774,45 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
return
0
;
}
/* test and update the power status of a value_mux widget */
static
int
dapm_value_mux_update_power
(
struct
snd_soc_dapm_widget
*
widget
,
struct
snd_kcontrol
*
kcontrol
,
int
mask
,
int
mux
,
int
val
,
struct
soc_value_enum
*
e
)
{
struct
snd_soc_dapm_path
*
path
;
int
found
=
0
;
if
(
widget
->
id
!=
snd_soc_dapm_value_mux
)
return
-
ENODEV
;
if
(
!
snd_soc_test_bits
(
widget
->
codec
,
e
->
reg
,
mask
,
val
))
return
0
;
/* find dapm widget path assoc with kcontrol */
list_for_each_entry
(
path
,
&
widget
->
codec
->
dapm_paths
,
list
)
{
if
(
path
->
kcontrol
!=
kcontrol
)
continue
;
if
(
!
path
->
name
||
!
e
->
texts
[
mux
])
continue
;
found
=
1
;
/* we now need to match the string in the enum to the path */
if
(
!
(
strcmp
(
path
->
name
,
e
->
texts
[
mux
])))
path
->
connect
=
1
;
/* new connection */
else
path
->
connect
=
0
;
/* old connection must be
powered down */
}
if
(
found
)
{
dapm_power_widgets
(
widget
->
codec
,
SND_SOC_DAPM_STREAM_NOP
);
dump_dapm
(
widget
->
codec
,
"mux power update"
);
}
return
0
;
}
/* test and update the power status of a mixer or switch widget */
static
int
dapm_mixer_update_power
(
struct
snd_soc_dapm_widget
*
widget
,
struct
snd_kcontrol
*
kcontrol
,
int
reg
,
...
...
@@ -965,6 +1050,12 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
if
(
ret
!=
0
)
goto
err
;
break
;
case
snd_soc_dapm_value_mux
:
ret
=
dapm_connect_value_mux
(
codec
,
wsource
,
wsink
,
path
,
control
,
&
wsink
->
kcontrols
[
0
]);
if
(
ret
!=
0
)
goto
err
;
break
;
case
snd_soc_dapm_switch
:
case
snd_soc_dapm_mixer
:
ret
=
dapm_connect_mixer
(
codec
,
wsource
,
wsink
,
path
,
control
);
...
...
@@ -1047,6 +1138,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
dapm_new_mixer
(
codec
,
w
);
break
;
case
snd_soc_dapm_mux
:
case
snd_soc_dapm_value_mux
:
dapm_new_mux
(
codec
,
w
);
break
;
case
snd_soc_dapm_adc
:
...
...
@@ -1273,6 +1365,105 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
}
EXPORT_SYMBOL_GPL
(
snd_soc_dapm_put_enum_double
);
/**
* snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
* callback
* @kcontrol: mixer control
* @ucontrol: control element information
*
* Callback to get the value of a dapm semi enumerated double mixer control.
*
* Semi enumerated mixer: the enumerated items are referred as values. Can be
* used for handling bitfield coded enumeration for example.
*
* Returns 0 for success.
*/
int
snd_soc_dapm_get_value_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_soc_dapm_widget
*
widget
=
snd_kcontrol_chip
(
kcontrol
);
struct
soc_value_enum
*
e
=
(
struct
soc_value_enum
*
)
kcontrol
->
private_value
;
unsigned
short
reg_val
,
val
,
mux
;
reg_val
=
snd_soc_read
(
widget
->
codec
,
e
->
reg
);
val
=
(
reg_val
>>
e
->
shift_l
)
&
e
->
mask
;
for
(
mux
=
0
;
mux
<
e
->
max
;
mux
++
)
{
if
(
val
==
e
->
values
[
mux
])
break
;
}
ucontrol
->
value
.
enumerated
.
item
[
0
]
=
mux
;
if
(
e
->
shift_l
!=
e
->
shift_r
)
{
val
=
(
reg_val
>>
e
->
shift_r
)
&
e
->
mask
;
for
(
mux
=
0
;
mux
<
e
->
max
;
mux
++
)
{
if
(
val
==
e
->
values
[
mux
])
break
;
}
ucontrol
->
value
.
enumerated
.
item
[
1
]
=
mux
;
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_soc_dapm_get_value_enum_double
);
/**
* snd_soc_dapm_put_value_enum_double - dapm semi enumerated double mixer set
* callback
* @kcontrol: mixer control
* @ucontrol: control element information
*
* Callback to set the value of a dapm semi enumerated double mixer control.
*
* Semi enumerated mixer: the enumerated items are referred as values. Can be
* used for handling bitfield coded enumeration for example.
*
* Returns 0 for success.
*/
int
snd_soc_dapm_put_value_enum_double
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_soc_dapm_widget
*
widget
=
snd_kcontrol_chip
(
kcontrol
);
struct
soc_value_enum
*
e
=
(
struct
soc_value_enum
*
)
kcontrol
->
private_value
;
unsigned
short
val
,
mux
;
unsigned
short
mask
;
int
ret
=
0
;
if
(
ucontrol
->
value
.
enumerated
.
item
[
0
]
>
e
->
max
-
1
)
return
-
EINVAL
;
mux
=
ucontrol
->
value
.
enumerated
.
item
[
0
];
val
=
e
->
values
[
ucontrol
->
value
.
enumerated
.
item
[
0
]]
<<
e
->
shift_l
;
mask
=
e
->
mask
<<
e
->
shift_l
;
if
(
e
->
shift_l
!=
e
->
shift_r
)
{
if
(
ucontrol
->
value
.
enumerated
.
item
[
1
]
>
e
->
max
-
1
)
return
-
EINVAL
;
val
|=
e
->
values
[
ucontrol
->
value
.
enumerated
.
item
[
1
]]
<<
e
->
shift_r
;
mask
|=
e
->
mask
<<
e
->
shift_r
;
}
mutex_lock
(
&
widget
->
codec
->
mutex
);
widget
->
value
=
val
;
dapm_value_mux_update_power
(
widget
,
kcontrol
,
mask
,
mux
,
val
,
e
);
if
(
widget
->
event
)
{
if
(
widget
->
event_flags
&
SND_SOC_DAPM_PRE_REG
)
{
ret
=
widget
->
event
(
widget
,
kcontrol
,
SND_SOC_DAPM_PRE_REG
);
if
(
ret
<
0
)
goto
out
;
}
ret
=
snd_soc_update_bits
(
widget
->
codec
,
e
->
reg
,
mask
,
val
);
if
(
widget
->
event_flags
&
SND_SOC_DAPM_POST_REG
)
ret
=
widget
->
event
(
widget
,
kcontrol
,
SND_SOC_DAPM_POST_REG
);
}
else
ret
=
snd_soc_update_bits
(
widget
->
codec
,
e
->
reg
,
mask
,
val
);
out:
mutex_unlock
(
&
widget
->
codec
->
mutex
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
snd_soc_dapm_put_value_enum_double
);
/**
* snd_soc_dapm_new_control - create new dapm control
* @codec: audio codec
...
...
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录