Skip to content

Commit fb4587d

Browse files
committed
Merge remote-tracking branches 'asoc/topic/wm8580', 'asoc/topic/wm8753', 'asoc/topic/wm8978', 'asoc/topic/wm9081' and 'asoc/topic/wm9705' into asoc-next
6 parents dc42c6c + 60bc617 + 68b24a2 + fbd972d + e2d5759 + d41a5b4 commit fb4587d

File tree

10 files changed

+159
-130
lines changed

10 files changed

+159
-130
lines changed

Documentation/devicetree/bindings/sound/wm8580.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
WM8580 audio CODEC
1+
WM8580 and WM8581 audio CODEC
22

33
This device supports I2C only.
44

55
Required properties:
66

7-
- compatible : "wlf,wm8580"
7+
- compatible : "wlf,wm8580", "wlf,wm8581"
88

99
- reg : the I2C address of the device.
1010

sound/soc/codecs/Kconfig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,7 @@ config SND_SOC_WM8523
938938
depends on I2C
939939

940940
config SND_SOC_WM8580
941-
tristate "Wolfson Microelectronics WM8523 CODEC"
941+
tristate "Wolfson Microelectronics WM8580 and WM8581 CODECs"
942942
depends on I2C
943943

944944
config SND_SOC_WM8711
@@ -1072,12 +1072,14 @@ config SND_SOC_WM8998
10721072

10731073
config SND_SOC_WM9081
10741074
tristate
1075+
depends on I2C
10751076

10761077
config SND_SOC_WM9090
10771078
tristate
10781079

10791080
config SND_SOC_WM9705
10801081
tristate
1082+
select REGMAP_AC97
10811083

10821084
config SND_SOC_WM9712
10831085
tristate

sound/soc/codecs/wm8580.c

Lines changed: 90 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* wm8580.c -- WM8580 ALSA Soc Audio driver
2+
* wm8580.c -- WM8580 and WM8581 ALSA Soc Audio driver
33
*
44
* Copyright 2008-12 Wolfson Microelectronics PLC.
55
*
@@ -12,6 +12,9 @@
1212
* The WM8580 is a multichannel codec with S/PDIF support, featuring six
1313
* DAC channels and two ADC channels.
1414
*
15+
* The WM8581 is a multichannel codec with S/PDIF support, featuring eight
16+
* DAC channels and two ADC channels.
17+
*
1518
* Currently only the primary audio interface is supported - S/PDIF and
1619
* the secondary audio interfaces are not.
1720
*/
@@ -65,6 +68,8 @@
6568
#define WM8580_DIGITAL_ATTENUATION_DACR2 0x17
6669
#define WM8580_DIGITAL_ATTENUATION_DACL3 0x18
6770
#define WM8580_DIGITAL_ATTENUATION_DACR3 0x19
71+
#define WM8581_DIGITAL_ATTENUATION_DACL4 0x1A
72+
#define WM8581_DIGITAL_ATTENUATION_DACR4 0x1B
6873
#define WM8580_MASTER_DIGITAL_ATTENUATION 0x1C
6974
#define WM8580_ADC_CONTROL1 0x1D
7075
#define WM8580_SPDTXCHAN0 0x1E
@@ -236,12 +241,17 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
236241
"PVDD",
237242
};
238243

244+
struct wm8580_driver_data {
245+
int num_dacs;
246+
};
247+
239248
/* codec private data */
240249
struct wm8580_priv {
241250
struct regmap *regmap;
242251
struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
243252
struct pll_state a;
244253
struct pll_state b;
254+
const struct wm8580_driver_data *drvdata;
245255
int sysclk[2];
246256
};
247257

@@ -306,6 +316,19 @@ SOC_DOUBLE("Capture Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 1),
306316
SOC_SINGLE("Capture High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
307317
};
308318

319+
static const struct snd_kcontrol_new wm8581_snd_controls[] = {
320+
SOC_DOUBLE_R_EXT_TLV("DAC4 Playback Volume",
321+
WM8581_DIGITAL_ATTENUATION_DACL4,
322+
WM8581_DIGITAL_ATTENUATION_DACR4,
323+
0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
324+
325+
SOC_SINGLE("DAC4 Deemphasis Switch", WM8580_DAC_CONTROL3, 3, 1, 0),
326+
327+
SOC_DOUBLE("DAC4 Invert Switch", WM8580_DAC_CONTROL4, 8, 7, 1, 0),
328+
329+
SOC_SINGLE("DAC4 Switch", WM8580_DAC_CONTROL5, 3, 1, 1),
330+
};
331+
309332
static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {
310333
SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1),
311334
SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1),
@@ -324,6 +347,13 @@ SND_SOC_DAPM_INPUT("AINL"),
324347
SND_SOC_DAPM_INPUT("AINR"),
325348
};
326349

350+
static const struct snd_soc_dapm_widget wm8581_dapm_widgets[] = {
351+
SND_SOC_DAPM_DAC("DAC4", "Playback", WM8580_PWRDN1, 5, 1),
352+
353+
SND_SOC_DAPM_OUTPUT("VOUT4L"),
354+
SND_SOC_DAPM_OUTPUT("VOUT4R"),
355+
};
356+
327357
static const struct snd_soc_dapm_route wm8580_dapm_routes[] = {
328358
{ "VOUT1L", NULL, "DAC1" },
329359
{ "VOUT1R", NULL, "DAC1" },
@@ -338,6 +368,11 @@ static const struct snd_soc_dapm_route wm8580_dapm_routes[] = {
338368
{ "ADC", NULL, "AINR" },
339369
};
340370

371+
static const struct snd_soc_dapm_route wm8581_dapm_routes[] = {
372+
{ "VOUT4L", NULL, "DAC4" },
373+
{ "VOUT4R", NULL, "DAC4" },
374+
};
375+
341376
/* PLL divisors */
342377
struct _pll_div {
343378
u32 prescale:1;
@@ -815,10 +850,21 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
815850
return 0;
816851
}
817852

853+
static int wm8580_playback_startup(struct snd_pcm_substream *substream,
854+
struct snd_soc_dai *dai)
855+
{
856+
struct snd_soc_codec *codec = dai->codec;
857+
struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
858+
859+
return snd_pcm_hw_constraint_minmax(substream->runtime,
860+
SNDRV_PCM_HW_PARAM_CHANNELS, 1, wm8580->drvdata->num_dacs * 2);
861+
}
862+
818863
#define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
819864
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
820865

821866
static const struct snd_soc_dai_ops wm8580_dai_ops_playback = {
867+
.startup = wm8580_playback_startup,
822868
.set_sysclk = wm8580_set_sysclk,
823869
.hw_params = wm8580_paif_hw_params,
824870
.set_fmt = wm8580_set_paif_dai_fmt,
@@ -842,7 +888,6 @@ static struct snd_soc_dai_driver wm8580_dai[] = {
842888
.playback = {
843889
.stream_name = "Playback",
844890
.channels_min = 1,
845-
.channels_max = 6,
846891
.rates = SNDRV_PCM_RATE_8000_192000,
847892
.formats = WM8580_FORMATS,
848893
},
@@ -865,8 +910,22 @@ static struct snd_soc_dai_driver wm8580_dai[] = {
865910
static int wm8580_probe(struct snd_soc_codec *codec)
866911
{
867912
struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
913+
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
868914
int ret = 0;
869915

916+
switch (wm8580->drvdata->num_dacs) {
917+
case 4:
918+
snd_soc_add_codec_controls(codec, wm8581_snd_controls,
919+
ARRAY_SIZE(wm8581_snd_controls));
920+
snd_soc_dapm_new_controls(dapm, wm8581_dapm_widgets,
921+
ARRAY_SIZE(wm8581_dapm_widgets));
922+
snd_soc_dapm_add_routes(dapm, wm8581_dapm_routes,
923+
ARRAY_SIZE(wm8581_dapm_routes));
924+
break;
925+
default:
926+
break;
927+
}
928+
870929
ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
871930
wm8580->supplies);
872931
if (ret != 0) {
@@ -914,12 +973,6 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
914973
},
915974
};
916975

917-
static const struct of_device_id wm8580_of_match[] = {
918-
{ .compatible = "wlf,wm8580" },
919-
{ },
920-
};
921-
MODULE_DEVICE_TABLE(of, wm8580_of_match);
922-
923976
static const struct regmap_config wm8580_regmap = {
924977
.reg_bits = 7,
925978
.val_bits = 9,
@@ -932,10 +985,25 @@ static const struct regmap_config wm8580_regmap = {
932985
.volatile_reg = wm8580_volatile,
933986
};
934987

935-
#if IS_ENABLED(CONFIG_I2C)
988+
static const struct wm8580_driver_data wm8580_data = {
989+
.num_dacs = 3,
990+
};
991+
992+
static const struct wm8580_driver_data wm8581_data = {
993+
.num_dacs = 4,
994+
};
995+
996+
static const struct of_device_id wm8580_of_match[] = {
997+
{ .compatible = "wlf,wm8580", .data = &wm8580_data },
998+
{ .compatible = "wlf,wm8581", .data = &wm8581_data },
999+
{ },
1000+
};
1001+
MODULE_DEVICE_TABLE(of, wm8580_of_match);
1002+
9361003
static int wm8580_i2c_probe(struct i2c_client *i2c,
9371004
const struct i2c_device_id *id)
9381005
{
1006+
const struct of_device_id *of_id;
9391007
struct wm8580_priv *wm8580;
9401008
int ret, i;
9411009

@@ -960,6 +1028,15 @@ static int wm8580_i2c_probe(struct i2c_client *i2c,
9601028

9611029
i2c_set_clientdata(i2c, wm8580);
9621030

1031+
of_id = of_match_device(wm8580_of_match, &i2c->dev);
1032+
if (of_id)
1033+
wm8580->drvdata = of_id->data;
1034+
1035+
if (!wm8580->drvdata) {
1036+
dev_err(&i2c->dev, "failed to find driver data\n");
1037+
return -EINVAL;
1038+
}
1039+
9631040
ret = snd_soc_register_codec(&i2c->dev,
9641041
&soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
9651042

@@ -973,7 +1050,8 @@ static int wm8580_i2c_remove(struct i2c_client *client)
9731050
}
9741051

9751052
static const struct i2c_device_id wm8580_i2c_id[] = {
976-
{ "wm8580", 0 },
1053+
{ "wm8580", (kernel_ulong_t)&wm8580_data },
1054+
{ "wm8581", (kernel_ulong_t)&wm8581_data },
9771055
{ }
9781056
};
9791057
MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
@@ -987,31 +1065,10 @@ static struct i2c_driver wm8580_i2c_driver = {
9871065
.remove = wm8580_i2c_remove,
9881066
.id_table = wm8580_i2c_id,
9891067
};
990-
#endif
9911068

992-
static int __init wm8580_modinit(void)
993-
{
994-
int ret = 0;
995-
996-
#if IS_ENABLED(CONFIG_I2C)
997-
ret = i2c_add_driver(&wm8580_i2c_driver);
998-
if (ret != 0) {
999-
pr_err("Failed to register WM8580 I2C driver: %d\n", ret);
1000-
}
1001-
#endif
1002-
1003-
return ret;
1004-
}
1005-
module_init(wm8580_modinit);
1006-
1007-
static void __exit wm8580_exit(void)
1008-
{
1009-
#if IS_ENABLED(CONFIG_I2C)
1010-
i2c_del_driver(&wm8580_i2c_driver);
1011-
#endif
1012-
}
1013-
module_exit(wm8580_exit);
1069+
module_i2c_driver(wm8580_i2c_driver);
10141070

10151071
MODULE_DESCRIPTION("ASoC WM8580 driver");
10161072
MODULE_AUTHOR("Mark Brown <[email protected]>");
1073+
MODULE_AUTHOR("Matt Flax <[email protected]>");
10171074
MODULE_LICENSE("GPL");

sound/soc/codecs/wm8753.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,4 @@
112112
#define WM8753_VXCLK_DIV_8 (3 << 6)
113113
#define WM8753_VXCLK_DIV_16 (4 << 6)
114114

115-
#define WM8753_DAI_HIFI 0
116-
#define WM8753_DAI_VOICE 1
117-
118115
#endif

sound/soc/codecs/wm8978.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ enum wm8978_clk_id {
7878
};
7979

8080
enum wm8978_sysclk_src {
81+
WM8978_MCLK = 0,
8182
WM8978_PLL,
82-
WM8978_MCLK
8383
};
8484

8585
#endif /* __WM8978_H__ */

sound/soc/codecs/wm9081.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,6 @@ static const struct regmap_config wm9081_regmap = {
13041304
.cache_type = REGCACHE_RBTREE,
13051305
};
13061306

1307-
#if IS_ENABLED(CONFIG_I2C)
13081307
static int wm9081_i2c_probe(struct i2c_client *i2c,
13091308
const struct i2c_device_id *id)
13101309
{
@@ -1384,7 +1383,6 @@ static struct i2c_driver wm9081_i2c_driver = {
13841383
.remove = wm9081_i2c_remove,
13851384
.id_table = wm9081_i2c_id,
13861385
};
1387-
#endif
13881386

13891387
module_i2c_driver(wm9081_i2c_driver);
13901388

0 commit comments

Comments
 (0)