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
f57019aa
Commit
f57019aa
authored
Jun 17, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/wm8962' into asoc-next
parents
7daf390b
384b8345
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
105 additions
and
30 deletions
+105
-30
Documentation/devicetree/bindings/sound/wm8962.txt
Documentation/devicetree/bindings/sound/wm8962.txt
+23
-0
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8962.c
+82
-30
No files found.
Documentation/devicetree/bindings/sound/wm8962.txt
View file @
f57019aa
...
...
@@ -8,9 +8,32 @@ Required properties:
- reg : the I2C address of the device.
Optional properties:
- spk-mono: This is a boolean property. If present, the SPK_MONO bit
of R51 (Class D Control 2) gets set, indicating that the speaker is
in mono mode.
- mic-cfg : Default register value for R48 (Additional Control 4).
If absent, the default should be the register default.
- gpio-cfg : A list of GPIO configuration register values. The list must
be 6 entries long. If absent, no configuration of these registers is
performed. And note that only the value within [0x0, 0xffff] is valid.
Any other value is regarded as setting the GPIO register by its reset
value 0x0.
Example:
codec: wm8962@1a {
compatible = "wlf,wm8962";
reg = <0x1a>;
gpio-cfg = <
0x0000 /* 0:Default */
0x0000 /* 1:Default */
0x0013 /* 2:FN_DMICCLK */
0x0000 /* 3:Default */
0x8014 /* 4:FN_DMICCDAT */
0x0000 /* 5:Default */
>;
};
sound/soc/codecs/wm8962.c
View file @
f57019aa
...
...
@@ -51,6 +51,7 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
/* codec private data */
struct
wm8962_priv
{
struct
wm8962_pdata
pdata
;
struct
regmap
*
regmap
;
struct
snd_soc_codec
*
codec
;
...
...
@@ -2347,12 +2348,13 @@ static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = {
static
int
wm8962_add_widgets
(
struct
snd_soc_codec
*
codec
)
{
struct
wm8962_pdata
*
pdata
=
dev_get_platdata
(
codec
->
dev
);
struct
wm8962_priv
*
wm8962
=
snd_soc_codec_get_drvdata
(
codec
);
struct
wm8962_pdata
*
pdata
=
&
wm8962
->
pdata
;
struct
snd_soc_dapm_context
*
dapm
=
&
codec
->
dapm
;
snd_soc_add_codec_controls
(
codec
,
wm8962_snd_controls
,
ARRAY_SIZE
(
wm8962_snd_controls
));
if
(
pdata
&&
pdata
->
spk_mono
)
if
(
pdata
->
spk_mono
)
snd_soc_add_codec_controls
(
codec
,
wm8962_spk_mono_controls
,
ARRAY_SIZE
(
wm8962_spk_mono_controls
));
else
...
...
@@ -2362,7 +2364,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
snd_soc_dapm_new_controls
(
dapm
,
wm8962_dapm_widgets
,
ARRAY_SIZE
(
wm8962_dapm_widgets
));
if
(
pdata
&&
pdata
->
spk_mono
)
if
(
pdata
->
spk_mono
)
snd_soc_dapm_new_controls
(
dapm
,
wm8962_dapm_spk_mono_widgets
,
ARRAY_SIZE
(
wm8962_dapm_spk_mono_widgets
));
else
...
...
@@ -2371,7 +2373,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
snd_soc_dapm_add_routes
(
dapm
,
wm8962_intercon
,
ARRAY_SIZE
(
wm8962_intercon
));
if
(
pdata
&&
pdata
->
spk_mono
)
if
(
pdata
->
spk_mono
)
snd_soc_dapm_add_routes
(
dapm
,
wm8962_spk_mono_intercon
,
ARRAY_SIZE
(
wm8962_spk_mono_intercon
));
else
...
...
@@ -3335,14 +3337,14 @@ static struct gpio_chip wm8962_template_chip = {
static
void
wm8962_init_gpio
(
struct
snd_soc_codec
*
codec
)
{
struct
wm8962_priv
*
wm8962
=
snd_soc_codec_get_drvdata
(
codec
);
struct
wm8962_pdata
*
pdata
=
dev_get_platdata
(
codec
->
dev
)
;
struct
wm8962_pdata
*
pdata
=
&
wm8962
->
pdata
;
int
ret
;
wm8962
->
gpio_chip
=
wm8962_template_chip
;
wm8962
->
gpio_chip
.
ngpio
=
WM8962_MAX_GPIO
;
wm8962
->
gpio_chip
.
dev
=
codec
->
dev
;
if
(
pdata
&&
pdata
->
gpio_base
)
if
(
pdata
->
gpio_base
)
wm8962
->
gpio_chip
.
base
=
pdata
->
gpio_base
;
else
wm8962
->
gpio_chip
.
base
=
-
1
;
...
...
@@ -3422,31 +3424,29 @@ static int wm8962_probe(struct snd_soc_codec *codec)
WM8962_OSC_ENA
|
WM8962_PLL2_ENA
|
WM8962_PLL3_ENA
,
0
);
if
(
pdata
)
{
/* Apply static configuration for GPIOs */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
pdata
->
gpio_init
);
i
++
)
if
(
pdata
->
gpio_init
[
i
])
{
wm8962_set_gpio_mode
(
codec
,
i
+
1
);
snd_soc_write
(
codec
,
0x200
+
i
,
pdata
->
gpio_init
[
i
]
&
0xffff
);
}
/* Apply static configuration for GPIOs */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
pdata
->
gpio_init
);
i
++
)
if
(
pdata
->
gpio_init
[
i
])
{
wm8962_set_gpio_mode
(
codec
,
i
+
1
);
snd_soc_write
(
codec
,
0x200
+
i
,
pdata
->
gpio_init
[
i
]
&
0xffff
);
}
/* Put the speakers into mono mode? */
if
(
pdata
->
spk_mono
)
snd_soc_update_bits
(
codec
,
WM8962_CLASS_D_CONTROL_2
,
/* Put the speakers into mono mode? */
if
(
pdata
->
spk_mono
)
snd_soc_update_bits
(
codec
,
WM8962_CLASS_D_CONTROL_2
,
WM8962_SPK_MONO_MASK
,
WM8962_SPK_MONO
);
/* Micbias setup, detection enable and detection
* threasholds. */
if
(
pdata
->
mic_cfg
)
snd_soc_update_bits
(
codec
,
WM8962_ADDITIONAL_CONTROL_4
,
WM8962_MICDET_ENA
|
WM8962_MICDET_THR_MASK
|
WM8962_MICSHORT_THR_MASK
|
WM8962_MICBIAS_LVL
,
pdata
->
mic_cfg
);
}
/* Micbias setup, detection enable and detection
* threasholds. */
if
(
pdata
->
mic_cfg
)
snd_soc_update_bits
(
codec
,
WM8962_ADDITIONAL_CONTROL_4
,
WM8962_MICDET_ENA
|
WM8962_MICDET_THR_MASK
|
WM8962_MICSHORT_THR_MASK
|
WM8962_MICBIAS_LVL
,
pdata
->
mic_cfg
);
/* Latch volume update bits */
snd_soc_update_bits
(
codec
,
WM8962_LEFT_INPUT_VOLUME
,
...
...
@@ -3508,7 +3508,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
wm8962_init_gpio
(
codec
);
if
(
wm8962
->
irq
)
{
if
(
pdata
&&
pdata
->
irq_active_low
)
{
if
(
pdata
->
irq_active_low
)
{
trigger
=
IRQF_TRIGGER_LOW
;
irq_pol
=
WM8962_IRQ_POL
;
}
else
{
...
...
@@ -3586,6 +3586,34 @@ static const struct regmap_config wm8962_regmap = {
.
cache_type
=
REGCACHE_RBTREE
,
};
static
int
wm8962_set_pdata_from_of
(
struct
i2c_client
*
i2c
,
struct
wm8962_pdata
*
pdata
)
{
const
struct
device_node
*
np
=
i2c
->
dev
.
of_node
;
u32
val32
;
int
i
;
if
(
of_property_read_bool
(
np
,
"spk-mono"
))
pdata
->
spk_mono
=
true
;
if
(
of_property_read_u32
(
np
,
"mic-cfg"
,
&
val32
)
>=
0
)
pdata
->
mic_cfg
=
val32
;
if
(
of_property_read_u32_array
(
np
,
"gpio-cfg"
,
pdata
->
gpio_init
,
ARRAY_SIZE
(
pdata
->
gpio_init
))
>=
0
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
pdata
->
gpio_init
);
i
++
)
{
/*
* The range of GPIO register value is [0x0, 0xffff]
* While the default value of each register is 0x0
* Any other value will be regarded as default value
*/
if
(
pdata
->
gpio_init
[
i
]
>
0xffff
)
pdata
->
gpio_init
[
i
]
=
0x0
;
}
return
0
;
}
static
int
wm8962_i2c_probe
(
struct
i2c_client
*
i2c
,
const
struct
i2c_device_id
*
id
)
{
...
...
@@ -3605,6 +3633,15 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
init_completion
(
&
wm8962
->
fll_lock
);
wm8962
->
irq
=
i2c
->
irq
;
/* If platform data was supplied, update the default data in priv */
if
(
pdata
)
{
memcpy
(
&
wm8962
->
pdata
,
pdata
,
sizeof
(
struct
wm8962_pdata
));
}
else
if
(
i2c
->
dev
.
of_node
)
{
ret
=
wm8962_set_pdata_from_of
(
i2c
,
&
wm8962
->
pdata
);
if
(
ret
!=
0
)
return
ret
;
}
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
wm8962
->
supplies
);
i
++
)
wm8962
->
supplies
[
i
].
supply
=
wm8962_supply_names
[
i
];
...
...
@@ -3668,7 +3705,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
goto
err_enable
;
}
if
(
pdata
&&
pdata
->
in4_dc_measure
)
{
if
(
wm8962
->
pdata
.
in4_dc_measure
)
{
ret
=
regmap_register_patch
(
wm8962
->
regmap
,
wm8962_dc_measure
,
ARRAY_SIZE
(
wm8962_dc_measure
));
...
...
@@ -3721,6 +3758,21 @@ static int wm8962_runtime_resume(struct device *dev)
wm8962_reset
(
wm8962
);
/* SYSCLK defaults to on; make sure it is off so we can safely
* write to registers if the device is declocked.
*/
regmap_update_bits
(
wm8962
->
regmap
,
WM8962_CLOCKING2
,
WM8962_SYSCLK_ENA
,
0
);
/* Ensure we have soft control over all registers */
regmap_update_bits
(
wm8962
->
regmap
,
WM8962_CLOCKING2
,
WM8962_CLKREG_OVD
,
WM8962_CLKREG_OVD
);
/* Ensure that the oscillator and PLLs are disabled */
regmap_update_bits
(
wm8962
->
regmap
,
WM8962_PLL2
,
WM8962_OSC_ENA
|
WM8962_PLL2_ENA
|
WM8962_PLL3_ENA
,
0
);
regcache_sync
(
wm8962
->
regmap
);
regmap_update_bits
(
wm8962
->
regmap
,
WM8962_ANTI_POP
,
...
...
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