Skip to content

Commit 0f27008

Browse files
committed
Merge branch 'at91-4.14-trunk/base_i2s' into linux-4.14-at91
2 parents e2e1c4e + 9708e52 commit 0f27008

5 files changed

Lines changed: 202 additions & 0 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Mikroe-PROTO audio board
2+
3+
Required properties:
4+
- compatible: "mikroe,mikroe-proto"
5+
- dai-format: Must be "i2s".
6+
- i2s-controller: The phandle of the I2S controller.
7+
- audio-codec: The phandle of the WM8731 audio codec.
8+
Optional properties:
9+
- model: The user-visible name of this sound complex.
10+
- bitclock-master: Indicates dai-link bit clock master; for details see simple-card.txt (1).
11+
- frame-master: Indicates dai-link frame master; for details see simple-card.txt (1).
12+
13+
(1) : There must be the same master for both bit and frame clocks.
14+
15+
Example:
16+
sound {
17+
compatible = "mikroe,mikroe-proto";
18+
model = "wm8731 @ sama5d2_xplained";
19+
i2s-controller = <&i2s0>;
20+
audio-codec = <&wm8731>;
21+
dai-format = "i2s";
22+
};
23+
};

Documentation/devicetree/bindings/vendor-prefixes.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ micrel Micrel Inc.
207207
microchip Microchip Technology Inc.
208208
microcrystal Micro Crystal AG
209209
micron Micron Technology Inc.
210+
mikroe MikroElektronika d.o.o.
210211
minix MINIX Technology Ltd.
211212
miramems MiraMEMS Sensing Technology Co., Ltd.
212213
mitsubishi Mitsubishi Electric Corporation

sound/soc/atmel/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,15 @@ config SND_ATMEL_SOC_I2S
9797
help
9898
Say Y or M if you want to add support for Atmel ASoc driver for boards
9999
using I2S.
100+
101+
config SND_SOC_MIKROE_PROTO
102+
tristate "Support for Mikroe-PROTO board"
103+
depends on OF
104+
select SND_SOC_WM8731
105+
help
106+
Say Y or M if you want to add support for MikroElektronika PROTO Audio
107+
Board. This board contains the WM8731 codec, which can be configured
108+
using I2C over SDA (MPU Data Input) and SCL (MPU Clock Input) pins.
109+
Both playback and capture are supported.
110+
100111
endif

sound/soc/atmel/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ snd-soc-sam9x5-wm8731-objs := sam9x5_wm8731.o
1717
snd-atmel-soc-classd-objs := atmel-classd.o
1818
snd-atmel-soc-pdmic-objs := atmel-pdmic.o
1919
snd-atmel-soc-tse850-pcm5142-objs := tse850-pcm5142.o
20+
snd-soc-mikroe-proto-objs := mikroe-proto.o
2021

2122
obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
2223
obj-$(CONFIG_SND_ATMEL_SOC_WM8904) += snd-atmel-soc-wm8904.o
2324
obj-$(CONFIG_SND_AT91_SOC_SAM9X5_WM8731) += snd-soc-sam9x5-wm8731.o
2425
obj-$(CONFIG_SND_ATMEL_SOC_CLASSD) += snd-atmel-soc-classd.o
2526
obj-$(CONFIG_SND_ATMEL_SOC_PDMIC) += snd-atmel-soc-pdmic.o
2627
obj-$(CONFIG_SND_ATMEL_SOC_TSE850_PCM5142) += snd-atmel-soc-tse850-pcm5142.o
28+
obj-$(CONFIG_SND_SOC_MIKROE_PROTO) += snd-soc-mikroe-proto.o

sound/soc/atmel/mikroe-proto.c

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*
2+
* ASoC driver for PROTO AudioCODEC (with a WM8731)
3+
*
4+
* Author: Florian Meier, <koalo@koalo.de>
5+
* Copyright 2013
6+
*
7+
* This program is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License version 2 as
9+
* published by the Free Software Foundation.
10+
*/
11+
12+
#include <linux/module.h>
13+
#include <linux/platform_device.h>
14+
15+
#include <sound/core.h>
16+
#include <sound/pcm.h>
17+
#include <sound/soc.h>
18+
#include <sound/jack.h>
19+
20+
#include "../codecs/wm8731.h"
21+
22+
#define XTAL_RATE 12288000 /* This is fixed on this board */
23+
24+
static int snd_proto_init(struct snd_soc_pcm_runtime *rtd)
25+
{
26+
struct snd_soc_card *card = rtd->card;
27+
struct snd_soc_dai *codec_dai = rtd->codec_dai;
28+
29+
/* Set proto sysclk */
30+
int ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
31+
XTAL_RATE, SND_SOC_CLOCK_IN);
32+
if (ret < 0) {
33+
dev_err(card->dev, "Failed to set WM8731 SYSCLK: %d\n",
34+
ret);
35+
return ret;
36+
}
37+
38+
return 0;
39+
}
40+
41+
static const struct snd_soc_dapm_widget snd_proto_widget[] = {
42+
SND_SOC_DAPM_MIC("Microphone Jack", NULL),
43+
SND_SOC_DAPM_HP("Headphone Jack", NULL),
44+
};
45+
46+
static const struct snd_soc_dapm_route snd_proto_route[] = {
47+
/* speaker connected to LHPOUT/RHPOUT */
48+
{"Headphone Jack", NULL, "LHPOUT"},
49+
{"Headphone Jack", NULL, "RHPOUT"},
50+
51+
/* mic is connected to Mic Jack, with WM8731 Mic Bias */
52+
{"MICIN", NULL, "Mic Bias"},
53+
{"Mic Bias", NULL, "Microphone Jack"},
54+
};
55+
56+
/* audio machine driver */
57+
static struct snd_soc_card snd_proto = {
58+
.name = "snd_mikroe_proto",
59+
.owner = THIS_MODULE,
60+
.dapm_widgets = snd_proto_widget,
61+
.num_dapm_widgets = ARRAY_SIZE(snd_proto_widget),
62+
.dapm_routes = snd_proto_route,
63+
.num_dapm_routes = ARRAY_SIZE(snd_proto_route),
64+
};
65+
66+
static int snd_proto_probe(struct platform_device *pdev)
67+
{
68+
struct snd_soc_dai_link *dai;
69+
struct device_node *np = pdev->dev.of_node;
70+
struct device_node *codec_np, *cpu_np;
71+
struct device_node *bitclkmaster = NULL;
72+
struct device_node *framemaster = NULL;
73+
unsigned int dai_fmt;
74+
int ret = 0;
75+
76+
if (!np) {
77+
dev_err(&pdev->dev, "No device node supplied\n");
78+
return -EINVAL;
79+
}
80+
81+
snd_proto.dev = &pdev->dev;
82+
ret = snd_soc_of_parse_card_name(&snd_proto, "model");
83+
if (ret)
84+
return ret;
85+
86+
dai = devm_kzalloc(&pdev->dev, sizeof(*dai), GFP_KERNEL);
87+
if (!dai)
88+
return -ENOMEM;
89+
90+
snd_proto.dai_link = dai;
91+
snd_proto.num_links = 1;
92+
93+
dai->name = "WM8731";
94+
dai->stream_name = "WM8731 HiFi";
95+
dai->codec_dai_name = "wm8731-hifi";
96+
dai->init = &snd_proto_init;
97+
98+
codec_np = of_parse_phandle(np, "audio-codec", 0);
99+
if (!codec_np) {
100+
dev_err(&pdev->dev, "audio-codec node missing\n");
101+
return -EINVAL;
102+
}
103+
dai->codec_of_node = codec_np;
104+
105+
cpu_np = of_parse_phandle(np, "i2s-controller", 0);
106+
if (!cpu_np) {
107+
dev_err(&pdev->dev, "i2s-controller missing\n");
108+
return -EINVAL;
109+
}
110+
dai->cpu_of_node = cpu_np;
111+
dai->platform_of_node = cpu_np;
112+
113+
dai_fmt = snd_soc_of_parse_daifmt(np, NULL,
114+
&bitclkmaster, &framemaster);
115+
if (bitclkmaster != framemaster) {
116+
dev_err(&pdev->dev, "Must be the same bitclock and frame master\n");
117+
return -EINVAL;
118+
}
119+
if (bitclkmaster) {
120+
dai_fmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
121+
if (codec_np == bitclkmaster)
122+
dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
123+
else
124+
dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
125+
}
126+
of_node_put(bitclkmaster);
127+
of_node_put(framemaster);
128+
dai->dai_fmt = dai_fmt;
129+
130+
of_node_put(codec_np);
131+
of_node_put(cpu_np);
132+
133+
ret = snd_soc_register_card(&snd_proto);
134+
if (ret && ret != -EPROBE_DEFER)
135+
dev_err(&pdev->dev,
136+
"snd_soc_register_card() failed: %d\n", ret);
137+
138+
return ret;
139+
}
140+
141+
static int snd_proto_remove(struct platform_device *pdev)
142+
{
143+
return snd_soc_unregister_card(&snd_proto);
144+
}
145+
146+
static const struct of_device_id snd_proto_of_match[] = {
147+
{ .compatible = "mikroe,mikroe-proto", },
148+
{},
149+
};
150+
MODULE_DEVICE_TABLE(of, snd_proto_of_match);
151+
152+
static struct platform_driver snd_proto_driver = {
153+
.driver = {
154+
.name = "snd-mikroe-proto",
155+
.of_match_table = snd_proto_of_match,
156+
},
157+
.probe = snd_proto_probe,
158+
.remove = snd_proto_remove,
159+
};
160+
161+
module_platform_driver(snd_proto_driver);
162+
163+
MODULE_AUTHOR("Florian Meier");
164+
MODULE_DESCRIPTION("ASoC Driver for PROTO board (WM8731)");
165+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)