Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
5439e726
Commit
5439e726
authored
Jan 06, 2009
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/asoc' into for-linus
parents
238c6d54
2f423577
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
447 additions
and
78 deletions
+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
No files found.
include/sound/soc-dapm.h
View file @
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 */
...
...
include/sound/soc.h
View file @
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
sound/arm/pxa2xx-ac97-lib.c
View file @
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
);
...
...
sound/soc/codecs/twl4030.c
View file @
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
),
...
...
sound/soc/davinci/davinci-evm.c
View file @
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
;
...
...
sound/soc/omap/Kconfig
View file @
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.
...
...
sound/soc/omap/omap3pandora.c
View file @
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
)
...
...
sound/soc/soc-core.c
View file @
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
...
...
sound/soc/soc-dapm.c
View file @
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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment