Skip to content

Commit da644e2

Browse files
committed
Merge remote-tracking branches 'asoc/topic/stac9766', 'asoc/topic/sti', 'asoc/topic/sti-codec', 'asoc/topic/sunxi' and 'asoc/topic/tegra' into asoc-next
6 parents f617134 + 7aacbc7 + 4db61af + 92591ef + 4a15b24 + 8a7a282 commit da644e2

23 files changed

+1816
-463
lines changed

Documentation/devicetree/bindings/sound/sun4i-codec.txt

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
* Allwinner A10 Codec
22

33
Required properties:
4-
- compatible: must be either "allwinner,sun4i-a10-codec" or
5-
"allwinner,sun7i-a20-codec"
4+
- compatible: must be one of the following compatibles:
5+
- "allwinner,sun4i-a10-codec"
6+
- "allwinner,sun6i-a31-codec"
7+
- "allwinner,sun7i-a20-codec"
8+
- "allwinner,sun8i-a23-codec"
9+
- "allwinner,sun8i-h3-codec"
610
- reg: must contain the registers location and length
711
- interrupts: must contain the codec interrupt
812
- dmas: DMA channels for tx and rx dma. See the DMA client binding,
@@ -17,6 +21,43 @@ Required properties:
1721
Optional properties:
1822
- allwinner,pa-gpios: gpio to enable external amplifier
1923

24+
Required properties for the following compatibles:
25+
- "allwinner,sun6i-a31-codec"
26+
- "allwinner,sun8i-a23-codec"
27+
- "allwinner,sun8i-h3-codec"
28+
- resets: phandle to the reset control for this device
29+
- allwinner,audio-routing: A list of the connections between audio components.
30+
Each entry is a pair of strings, the first being the
31+
connection's sink, the second being the connection's
32+
source. Valid names include:
33+
34+
Audio pins on the SoC:
35+
"HP"
36+
"HPCOM"
37+
"LINEIN"
38+
"LINEOUT" (not on sun8i-a23)
39+
"MIC1"
40+
"MIC2"
41+
"MIC3" (sun6i-a31 only)
42+
43+
Microphone biases from the SoC:
44+
"HBIAS"
45+
"MBIAS"
46+
47+
Board connectors:
48+
"Headphone"
49+
"Headset Mic"
50+
"Line In"
51+
"Line Out"
52+
"Mic"
53+
"Speaker"
54+
55+
Required properties for the following compatibles:
56+
- "allwinner,sun8i-a23-codec"
57+
- "allwinner,sun8i-h3-codec"
58+
- allwinner,codec-analog-controls: A phandle to the codec analog controls
59+
block in the PRCM.
60+
2061
Example:
2162
codec: codec@01c22c00 {
2263
#sound-dai-cells = <0>;
@@ -28,3 +69,23 @@ codec: codec@01c22c00 {
2869
dmas = <&dma 0 19>, <&dma 0 19>;
2970
dma-names = "rx", "tx";
3071
};
72+
73+
codec: codec@01c22c00 {
74+
#sound-dai-cells = <0>;
75+
compatible = "allwinner,sun6i-a31-codec";
76+
reg = <0x01c22c00 0x98>;
77+
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
78+
clocks = <&ccu CLK_APB1_CODEC>, <&ccu CLK_CODEC>;
79+
clock-names = "apb", "codec";
80+
resets = <&ccu RST_APB1_CODEC>;
81+
dmas = <&dma 15>, <&dma 15>;
82+
dma-names = "rx", "tx";
83+
allwinner,audio-routing =
84+
"Headphone", "HP",
85+
"Speaker", "LINEOUT",
86+
"LINEIN", "Line In",
87+
"MIC1", "MBIAS",
88+
"MIC1", "Mic",
89+
"MIC2", "HBIAS",
90+
"MIC2", "Headset Mic";
91+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
* Allwinner Codec Analog Controls
2+
3+
Required properties:
4+
- compatible: must be one of the following compatibles:
5+
- "allwinner,sun8i-a23-codec-analog"
6+
- "allwinner,sun8i-h3-codec-analog"
7+
8+
Required properties if not a sub-node of the PRCM node:
9+
- reg: must contain the registers location and length
10+
11+
Example:
12+
prcm: prcm@01f01400 {
13+
codec_analog: codec-analog {
14+
compatible = "allwinner,sun8i-a23-codec-analog";
15+
};
16+
};

sound/soc/codecs/stac9766.c

Lines changed: 72 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/slab.h>
1919
#include <linux/module.h>
2020
#include <linux/device.h>
21+
#include <linux/regmap.h>
2122
#include <sound/core.h>
2223
#include <sound/pcm.h>
2324
#include <sound/ac97_codec.h>
@@ -26,31 +27,56 @@
2627
#include <sound/soc.h>
2728
#include <sound/tlv.h>
2829

29-
#include "stac9766.h"
30-
3130
#define STAC9766_VENDOR_ID 0x83847666
3231
#define STAC9766_VENDOR_ID_MASK 0xffffffff
3332

34-
/*
35-
* STAC9766 register cache
36-
*/
37-
static const u16 stac9766_reg[] = {
38-
0x6A90, 0x8000, 0x8000, 0x8000, /* 6 */
39-
0x0000, 0x0000, 0x8008, 0x8008, /* e */
40-
0x8808, 0x8808, 0x8808, 0x8808, /* 16 */
41-
0x8808, 0x0000, 0x8000, 0x0000, /* 1e */
42-
0x0000, 0x0000, 0x0000, 0x000f, /* 26 */
43-
0x0a05, 0x0400, 0xbb80, 0x0000, /* 2e */
44-
0x0000, 0xbb80, 0x0000, 0x0000, /* 36 */
45-
0x0000, 0x2000, 0x0000, 0x0100, /* 3e */
46-
0x0000, 0x0000, 0x0080, 0x0000, /* 46 */
47-
0x0000, 0x0000, 0x0003, 0xffff, /* 4e */
48-
0x0000, 0x0000, 0x0000, 0x0000, /* 56 */
49-
0x4000, 0x0000, 0x0000, 0x0000, /* 5e */
50-
0x1201, 0xFFFF, 0xFFFF, 0x0000, /* 66 */
51-
0x0000, 0x0000, 0x0000, 0x0000, /* 6e */
52-
0x0000, 0x0000, 0x0000, 0x0006, /* 76 */
53-
0x0000, 0x0000, 0x0000, 0x0000, /* 7e */
33+
#define AC97_STAC_DA_CONTROL 0x6A
34+
#define AC97_STAC_ANALOG_SPECIAL 0x6E
35+
#define AC97_STAC_STEREO_MIC 0x78
36+
37+
static const struct reg_default stac9766_reg_defaults[] = {
38+
{ 0x02, 0x8000 },
39+
{ 0x04, 0x8000 },
40+
{ 0x06, 0x8000 },
41+
{ 0x0a, 0x0000 },
42+
{ 0x0c, 0x8008 },
43+
{ 0x0e, 0x8008 },
44+
{ 0x10, 0x8808 },
45+
{ 0x12, 0x8808 },
46+
{ 0x14, 0x8808 },
47+
{ 0x16, 0x8808 },
48+
{ 0x18, 0x8808 },
49+
{ 0x1a, 0x0000 },
50+
{ 0x1c, 0x8000 },
51+
{ 0x20, 0x0000 },
52+
{ 0x22, 0x0000 },
53+
{ 0x28, 0x0a05 },
54+
{ 0x2c, 0xbb80 },
55+
{ 0x32, 0xbb80 },
56+
{ 0x3a, 0x2000 },
57+
{ 0x3e, 0x0100 },
58+
{ 0x4c, 0x0300 },
59+
{ 0x4e, 0xffff },
60+
{ 0x50, 0x0000 },
61+
{ 0x52, 0x0000 },
62+
{ 0x54, 0x0000 },
63+
{ 0x6a, 0x0000 },
64+
{ 0x6e, 0x1000 },
65+
{ 0x72, 0x0000 },
66+
{ 0x78, 0x0000 },
67+
};
68+
69+
static const struct regmap_config stac9766_regmap_config = {
70+
.reg_bits = 16,
71+
.reg_stride = 2,
72+
.val_bits = 16,
73+
.max_register = 0x78,
74+
.cache_type = REGCACHE_RBTREE,
75+
76+
.volatile_reg = regmap_ac97_default_volatile,
77+
78+
.reg_defaults = stac9766_reg_defaults,
79+
.num_reg_defaults = ARRAY_SIZE(stac9766_reg_defaults),
5480
};
5581

5682
static const char *stac9766_record_mux[] = {"Mic", "CD", "Video", "AUX",
@@ -139,90 +165,39 @@ static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = {
139165
SOC_ENUM("Pop Bypass Mux", stac9766_popbypass_enum),
140166
};
141167

142-
static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,
143-
unsigned int val)
144-
{
145-
struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
146-
u16 *cache = codec->reg_cache;
147-
148-
if (reg > AC97_STAC_PAGE0) {
149-
stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
150-
soc_ac97_ops->write(ac97, reg, val);
151-
stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
152-
return 0;
153-
}
154-
if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
155-
return -EIO;
156-
157-
soc_ac97_ops->write(ac97, reg, val);
158-
cache[reg / 2] = val;
159-
return 0;
160-
}
161-
162-
static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
163-
unsigned int reg)
164-
{
165-
struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
166-
u16 val = 0, *cache = codec->reg_cache;
167-
168-
if (reg > AC97_STAC_PAGE0) {
169-
stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
170-
val = soc_ac97_ops->read(ac97, reg - AC97_STAC_PAGE0);
171-
stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
172-
return val;
173-
}
174-
if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
175-
return -EIO;
176-
177-
if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
178-
reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||
179-
reg == AC97_VENDOR_ID2) {
180-
181-
val = soc_ac97_ops->read(ac97, reg);
182-
return val;
183-
}
184-
return cache[reg / 2];
185-
}
186-
187168
static int ac97_analog_prepare(struct snd_pcm_substream *substream,
188169
struct snd_soc_dai *dai)
189170
{
190171
struct snd_soc_codec *codec = dai->codec;
191172
struct snd_pcm_runtime *runtime = substream->runtime;
192-
unsigned short reg, vra;
193-
194-
vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
173+
unsigned short reg;
195174

196-
vra |= 0x1; /* enable variable rate audio */
197-
vra &= ~0x4; /* disable SPDIF output */
198-
199-
stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
175+
/* enable variable rate audio, disable SPDIF output */
176+
snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x5, 0x1);
200177

201178
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
202179
reg = AC97_PCM_FRONT_DAC_RATE;
203180
else
204181
reg = AC97_PCM_LR_ADC_RATE;
205182

206-
return stac9766_ac97_write(codec, reg, runtime->rate);
183+
return snd_soc_write(codec, reg, runtime->rate);
207184
}
208185

209186
static int ac97_digital_prepare(struct snd_pcm_substream *substream,
210187
struct snd_soc_dai *dai)
211188
{
212189
struct snd_soc_codec *codec = dai->codec;
213190
struct snd_pcm_runtime *runtime = substream->runtime;
214-
unsigned short reg, vra;
215-
216-
stac9766_ac97_write(codec, AC97_SPDIF, 0x2002);
191+
unsigned short reg;
217192

218-
vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
219-
vra |= 0x5; /* Enable VRA and SPDIF out */
193+
snd_soc_write(codec, AC97_SPDIF, 0x2002);
220194

221-
stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
195+
/* Enable VRA and SPDIF out */
196+
snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x5, 0x5);
222197

223198
reg = AC97_PCM_FRONT_DAC_RATE;
224199

225-
return stac9766_ac97_write(codec, reg, runtime->rate);
200+
return snd_soc_write(codec, reg, runtime->rate);
226201
}
227202

228203
static int stac9766_set_bias_level(struct snd_soc_codec *codec,
@@ -232,11 +207,11 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
232207
case SND_SOC_BIAS_ON: /* full On */
233208
case SND_SOC_BIAS_PREPARE: /* partial On */
234209
case SND_SOC_BIAS_STANDBY: /* Off, with power */
235-
stac9766_ac97_write(codec, AC97_POWERDOWN, 0x0000);
210+
snd_soc_write(codec, AC97_POWERDOWN, 0x0000);
236211
break;
237212
case SND_SOC_BIAS_OFF: /* Off, without power */
238213
/* disable everything including AC link */
239-
stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff);
214+
snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
240215
break;
241216
}
242217
return 0;
@@ -300,21 +275,34 @@ static struct snd_soc_dai_driver stac9766_dai[] = {
300275
static int stac9766_codec_probe(struct snd_soc_codec *codec)
301276
{
302277
struct snd_ac97 *ac97;
278+
struct regmap *regmap;
279+
int ret;
303280

304281
ac97 = snd_soc_new_ac97_codec(codec, STAC9766_VENDOR_ID,
305282
STAC9766_VENDOR_ID_MASK);
306283
if (IS_ERR(ac97))
307284
return PTR_ERR(ac97);
308285

286+
regmap = regmap_init_ac97(ac97, &stac9766_regmap_config);
287+
if (IS_ERR(regmap)) {
288+
ret = PTR_ERR(regmap);
289+
goto err_free_ac97;
290+
}
291+
292+
snd_soc_codec_init_regmap(codec, regmap);
309293
snd_soc_codec_set_drvdata(codec, ac97);
310294

311295
return 0;
296+
err_free_ac97:
297+
snd_soc_free_ac97_codec(ac97);
298+
return ret;
312299
}
313300

314301
static int stac9766_codec_remove(struct snd_soc_codec *codec)
315302
{
316303
struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
317304

305+
snd_soc_codec_exit_regmap(codec);
318306
snd_soc_free_ac97_codec(ac97);
319307
return 0;
320308
}
@@ -324,17 +312,11 @@ static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
324312
.controls = stac9766_snd_ac97_controls,
325313
.num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls),
326314
},
327-
.write = stac9766_ac97_write,
328-
.read = stac9766_ac97_read,
329315
.set_bias_level = stac9766_set_bias_level,
330316
.suspend_bias_off = true,
331317
.probe = stac9766_codec_probe,
332318
.remove = stac9766_codec_remove,
333319
.resume = stac9766_codec_resume,
334-
.reg_cache_size = ARRAY_SIZE(stac9766_reg),
335-
.reg_word_size = sizeof(u16),
336-
.reg_cache_step = 2,
337-
.reg_cache_default = stac9766_reg,
338320
};
339321

340322
static int stac9766_probe(struct platform_device *pdev)

sound/soc/codecs/stac9766.h

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)