diff options
author | Rongjun Ying <rongjun.ying@csr.com> | 2014-03-05 03:34:36 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-03-06 04:21:56 -0500 |
commit | af12a31f054f55b75c8cf4a459c7bd9d1c7726a9 (patch) | |
tree | e1904713b5516fdaf14fa88235634c4b0ee7ceb1 | |
parent | a731e217df3a2ee3ef9413153ed7b45e578d8687 (diff) |
ASoC: sirf: Add SiRF audio card
This connects platform DAI, SiRF internal audio codec DAI and
SiRF auido port DAI together and works as a mach driver.
Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | Documentation/devicetree/bindings/sound/sirf-audio.txt | 41 | ||||
-rw-r--r-- | sound/soc/sirf/Kconfig | 6 | ||||
-rw-r--r-- | sound/soc/sirf/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/sirf/sirf-audio.c | 156 |
4 files changed, 205 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/sirf-audio.txt b/Documentation/devicetree/bindings/sound/sirf-audio.txt new file mode 100644 index 000000000000..c88882ca3704 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/sirf-audio.txt | |||
@@ -0,0 +1,41 @@ | |||
1 | * SiRF atlas6 and prima2 internal audio codec and port based audio setups | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "sirf,sirf-audio-card" | ||
5 | - sirf,audio-platform: phandle for the platform node | ||
6 | - sirf,audio-codec: phandle for the SiRF internal codec node | ||
7 | |||
8 | Optional properties: | ||
9 | - hp-pa-gpios: Need to be present if the board need control external | ||
10 | headphone amplifier. | ||
11 | - spk-pa-gpios: Need to be present if the board need control external | ||
12 | speaker amplifier. | ||
13 | - hp-switch-gpios: Need to be present if the board capable to detect jack | ||
14 | insertion, removal. | ||
15 | |||
16 | Available audio endpoints for the audio-routing table: | ||
17 | |||
18 | Board connectors: | ||
19 | * Headset Stereophone | ||
20 | * Ext Spk | ||
21 | * Line In | ||
22 | * Mic | ||
23 | |||
24 | SiRF internal audio codec pins: | ||
25 | * HPOUTL | ||
26 | * HPOUTR | ||
27 | * SPKOUT | ||
28 | * Ext Mic | ||
29 | * Mic Bias | ||
30 | |||
31 | Example: | ||
32 | |||
33 | sound { | ||
34 | compatible = "sirf,sirf-audio-card"; | ||
35 | sirf,audio-codec = <&audiocodec>; | ||
36 | sirf,audio-platform = <&audioport>; | ||
37 | hp-pa-gpios = <&gpio 44 0>; | ||
38 | spk-pa-gpios = <&gpio 46 0>; | ||
39 | hp-switch-gpios = <&gpio 45 0>; | ||
40 | }; | ||
41 | |||
diff --git a/sound/soc/sirf/Kconfig b/sound/soc/sirf/Kconfig index 75b0344d2151..89e89429b04a 100644 --- a/sound/soc/sirf/Kconfig +++ b/sound/soc/sirf/Kconfig | |||
@@ -3,6 +3,12 @@ config SND_SOC_SIRF | |||
3 | depends on ARCH_SIRF || COMPILE_TEST | 3 | depends on ARCH_SIRF || COMPILE_TEST |
4 | select SND_SOC_GENERIC_DMAENGINE_PCM | 4 | select SND_SOC_GENERIC_DMAENGINE_PCM |
5 | 5 | ||
6 | config SND_SOC_SIRF_AUDIO | ||
7 | tristate "SoC Audio support for SiRF internal audio codec" | ||
8 | depends on SND_SOC_SIRF | ||
9 | select SND_SOC_SIRF_AUDIO_CODEC | ||
10 | select SND_SOC_SIRF_AUDIO_PORT | ||
11 | |||
6 | config SND_SOC_SIRF_AUDIO_PORT | 12 | config SND_SOC_SIRF_AUDIO_PORT |
7 | select REGMAP_MMIO | 13 | select REGMAP_MMIO |
8 | tristate | 14 | tristate |
diff --git a/sound/soc/sirf/Makefile b/sound/soc/sirf/Makefile index fb012c852b28..913b93231d4e 100644 --- a/sound/soc/sirf/Makefile +++ b/sound/soc/sirf/Makefile | |||
@@ -1,3 +1,5 @@ | |||
1 | snd-soc-sirf-audio-objs := sirf-audio.o | ||
1 | snd-soc-sirf-audio-port-objs := sirf-audio-port.o | 2 | snd-soc-sirf-audio-port-objs := sirf-audio-port.o |
2 | 3 | ||
4 | obj-$(CONFIG_SND_SOC_SIRF_AUDIO) += snd-soc-sirf-audio.o | ||
3 | obj-$(CONFIG_SND_SOC_SIRF_AUDIO_PORT) += snd-soc-sirf-audio-port.o | 5 | obj-$(CONFIG_SND_SOC_SIRF_AUDIO_PORT) += snd-soc-sirf-audio-port.o |
diff --git a/sound/soc/sirf/sirf-audio.c b/sound/soc/sirf/sirf-audio.c new file mode 100644 index 000000000000..ecef51021653 --- /dev/null +++ b/sound/soc/sirf/sirf-audio.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /* | ||
2 | * SiRF audio card driver | ||
3 | * | ||
4 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/platform_device.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/of.h> | ||
12 | #include <linux/gpio.h> | ||
13 | #include <linux/of_gpio.h> | ||
14 | #include <sound/core.h> | ||
15 | #include <sound/pcm.h> | ||
16 | #include <sound/soc.h> | ||
17 | |||
18 | struct sirf_audio_card { | ||
19 | unsigned int gpio_hp_pa; | ||
20 | unsigned int gpio_spk_pa; | ||
21 | }; | ||
22 | |||
23 | static int sirf_audio_hp_event(struct snd_soc_dapm_widget *w, | ||
24 | struct snd_kcontrol *ctrl, int event) | ||
25 | { | ||
26 | struct snd_soc_dapm_context *dapm = w->dapm; | ||
27 | struct snd_soc_card *card = dapm->card; | ||
28 | struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); | ||
29 | int on = !SND_SOC_DAPM_EVENT_OFF(event); | ||
30 | if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) | ||
31 | gpio_set_value(sirf_audio_card->gpio_hp_pa, on); | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | static int sirf_audio_spk_event(struct snd_soc_dapm_widget *w, | ||
36 | struct snd_kcontrol *ctrl, int event) | ||
37 | { | ||
38 | struct snd_soc_dapm_context *dapm = w->dapm; | ||
39 | struct snd_soc_card *card = dapm->card; | ||
40 | struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); | ||
41 | int on = !SND_SOC_DAPM_EVENT_OFF(event); | ||
42 | |||
43 | if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) | ||
44 | gpio_set_value(sirf_audio_card->gpio_spk_pa, on); | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | static const struct snd_soc_dapm_widget sirf_audio_dapm_widgets[] = { | ||
49 | SND_SOC_DAPM_HP("Hp", sirf_audio_hp_event), | ||
50 | SND_SOC_DAPM_SPK("Ext Spk", sirf_audio_spk_event), | ||
51 | SND_SOC_DAPM_MIC("Ext Mic", NULL), | ||
52 | }; | ||
53 | |||
54 | static const struct snd_soc_dapm_route intercon[] = { | ||
55 | {"Hp", NULL, "HPOUTL"}, | ||
56 | {"Hp", NULL, "HPOUTR"}, | ||
57 | {"Ext Spk", NULL, "SPKOUT"}, | ||
58 | {"MICIN1", NULL, "Mic Bias"}, | ||
59 | {"Mic Bias", NULL, "Ext Mic"}, | ||
60 | }; | ||
61 | |||
62 | /* Digital audio interface glue - connects codec <--> CPU */ | ||
63 | static struct snd_soc_dai_link sirf_audio_dai_link[] = { | ||
64 | { | ||
65 | .name = "SiRF audio card", | ||
66 | .stream_name = "SiRF audio HiFi", | ||
67 | .codec_dai_name = "sirf-audio-codec", | ||
68 | }, | ||
69 | }; | ||
70 | |||
71 | /* Audio machine driver */ | ||
72 | static struct snd_soc_card snd_soc_sirf_audio_card = { | ||
73 | .name = "SiRF audio card", | ||
74 | .owner = THIS_MODULE, | ||
75 | .dai_link = sirf_audio_dai_link, | ||
76 | .num_links = ARRAY_SIZE(sirf_audio_dai_link), | ||
77 | .dapm_widgets = sirf_audio_dapm_widgets, | ||
78 | .num_dapm_widgets = ARRAY_SIZE(sirf_audio_dapm_widgets), | ||
79 | .dapm_routes = intercon, | ||
80 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
81 | }; | ||
82 | |||
83 | static int sirf_audio_probe(struct platform_device *pdev) | ||
84 | { | ||
85 | struct snd_soc_card *card = &snd_soc_sirf_audio_card; | ||
86 | struct sirf_audio_card *sirf_audio_card; | ||
87 | int ret; | ||
88 | |||
89 | sirf_audio_card = devm_kzalloc(&pdev->dev, sizeof(struct sirf_audio_card), | ||
90 | GFP_KERNEL); | ||
91 | if (sirf_audio_card == NULL) | ||
92 | return -ENOMEM; | ||
93 | |||
94 | sirf_audio_dai_link[0].cpu_of_node = | ||
95 | of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0); | ||
96 | sirf_audio_dai_link[0].platform_of_node = | ||
97 | of_parse_phandle(pdev->dev.of_node, "sirf,audio-platform", 0); | ||
98 | sirf_audio_dai_link[0].codec_of_node = | ||
99 | of_parse_phandle(pdev->dev.of_node, "sirf,audio-codec", 0); | ||
100 | sirf_audio_card->gpio_spk_pa = of_get_named_gpio(pdev->dev.of_node, | ||
101 | "spk-pa-gpios", 0); | ||
102 | sirf_audio_card->gpio_hp_pa = of_get_named_gpio(pdev->dev.of_node, | ||
103 | "hp-pa-gpios", 0); | ||
104 | if (gpio_is_valid(sirf_audio_card->gpio_spk_pa)) { | ||
105 | ret = devm_gpio_request_one(&pdev->dev, | ||
106 | sirf_audio_card->gpio_spk_pa, | ||
107 | GPIOF_OUT_INIT_LOW, "SPA_PA_SD"); | ||
108 | if (ret) { | ||
109 | dev_err(&pdev->dev, | ||
110 | "Failed to request GPIO_%d for reset: %d\n", | ||
111 | sirf_audio_card->gpio_spk_pa, ret); | ||
112 | return ret; | ||
113 | } | ||
114 | } | ||
115 | if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) { | ||
116 | ret = devm_gpio_request_one(&pdev->dev, | ||
117 | sirf_audio_card->gpio_hp_pa, | ||
118 | GPIOF_OUT_INIT_LOW, "HP_PA_SD"); | ||
119 | if (ret) { | ||
120 | dev_err(&pdev->dev, | ||
121 | "Failed to request GPIO_%d for reset: %d\n", | ||
122 | sirf_audio_card->gpio_hp_pa, ret); | ||
123 | return ret; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | card->dev = &pdev->dev; | ||
128 | snd_soc_card_set_drvdata(card, sirf_audio_card); | ||
129 | |||
130 | ret = devm_snd_soc_register_card(&pdev->dev, card); | ||
131 | if (ret) | ||
132 | dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret); | ||
133 | |||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | static const struct of_device_id sirf_audio_of_match[] = { | ||
138 | {.compatible = "sirf,sirf-audio-card", }, | ||
139 | { }, | ||
140 | }; | ||
141 | MODULE_DEVICE_TABLE(of, sirf_audio_of_match); | ||
142 | |||
143 | static struct platform_driver sirf_audio_driver = { | ||
144 | .driver = { | ||
145 | .name = "sirf-audio-card", | ||
146 | .owner = THIS_MODULE, | ||
147 | .pm = &snd_soc_pm_ops, | ||
148 | .of_match_table = sirf_audio_of_match, | ||
149 | }, | ||
150 | .probe = sirf_audio_probe, | ||
151 | }; | ||
152 | module_platform_driver(sirf_audio_driver); | ||
153 | |||
154 | MODULE_AUTHOR("RongJun Ying <RongJun.Ying@csr.com>"); | ||
155 | MODULE_DESCRIPTION("ALSA SoC SIRF audio card driver"); | ||
156 | MODULE_LICENSE("GPL v2"); | ||