aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolin Chen <b42378@freescale.com>2013-08-23 07:55:00 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:01:32 -0400
commita80597788c18a800efbee9ec7fc9c8e5dbb550e2 (patch)
treec860d80cdb95eccb86d8c946fb5bcbdc78c93d6a
parent23e369b88b546d7b699ca9ec46e195a05c61b717 (diff)
ENGR00276567-7 ASoC: fsl: Add si476x machine driver
Add si476x machine dirver for i.MX series SoC and binding doc. Signed-off-by: Nicolin Chen <b42378@freescale.com>
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-si476x.txt24
-rw-r--r--sound/soc/fsl/Kconfig12
-rw-r--r--sound/soc/fsl/Makefile2
-rw-r--r--sound/soc/fsl/imx-si476x.c164
4 files changed, 202 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-si476x.txt b/Documentation/devicetree/bindings/sound/imx-audio-si476x.txt
new file mode 100644
index 000000000000..53cd34afe6b8
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-si476x.txt
@@ -0,0 +1,24 @@
1Freescale i.MX audio complex with si476x codec
2
3Required properties:
4- compatible : "fsl,imx-audio-si476x"
5- model : The user-visible name of this sound complex
6- ssi-controller : The phandle of the i.MX SSI controller
7
8- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
9- mux-ext-port : The external port of the i.MX audio muxer
10
11Note: The AUDMUX port numbering should start at 1, which is consistent with
12hardware manual.
13
14Example:
15
16sound {
17 compatible = "fsl,imx-audio-si476x",
18 "fsl,imx-tuner-si476x";
19 model = "imx-radio-si476x";
20
21 ssi-controller = <&ssi1>;
22 mux-int-port = <2>;
23 mux-ext-port = <5>;
24};
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index d3d54e565d64..0c9f147da49f 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -221,4 +221,16 @@ config SND_SOC_IMX_MC13783
221 select SND_SOC_MC13783 221 select SND_SOC_MC13783
222 select SND_SOC_IMX_PCM_DMA 222 select SND_SOC_IMX_PCM_DMA
223 223
224config SND_SOC_IMX_SI476X
225 tristate "SoC Audio support for i.MX boards with si476x"
226 select SND_SOC_IMX_PCM_DMA
227 select SND_SOC_IMX_AUDMUX
228 select SND_SOC_FSL_SSI
229 select SND_SOC_FSL_UTILS
230 select SND_SOC_SI476X
231 help
232 SoC Audio support for i.MX boards with SI476x
233 Say Y if you want to add support for Soc audio for the AMFM Tuner chip
234 SI476x module.
235
224endif # SND_IMX_SOC 236endif # SND_IMX_SOC
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 79a6858bb61d..72f812e8cdb6 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -53,6 +53,7 @@ snd-soc-imx-cs42888-objs := imx-cs42888.o
53snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o 53snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
54snd-soc-imx-wm8962-objs := imx-wm8962.o 54snd-soc-imx-wm8962-objs := imx-wm8962.o
55snd-soc-imx-mc13783-objs := imx-mc13783.o 55snd-soc-imx-mc13783-objs := imx-mc13783.o
56snd-soc-imx-si476x-objs := imx-si476x.o
56 57
57obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o 58obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
58obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o 59obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
@@ -62,3 +63,4 @@ obj-$(CONFIG_SND_SOC_IMX_CS42888) += snd-soc-imx-cs42888.o
62obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o 63obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
63obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o 64obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
64obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o 65obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
66obj-$(CONFIG_SND_SOC_IMX_SI476X) += snd-soc-imx-si476x.o
diff --git a/sound/soc/fsl/imx-si476x.c b/sound/soc/fsl/imx-si476x.c
new file mode 100644
index 000000000000..d3febf80af59
--- /dev/null
+++ b/sound/soc/fsl/imx-si476x.c
@@ -0,0 +1,164 @@
1/*
2 * Copyright (C) 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5/*
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14#include <linux/module.h>
15#include <linux/of_platform.h>
16#include <sound/soc.h>
17
18#include "imx-audmux.h"
19
20static int imx_audmux_config(int slave, int master)
21{
22 unsigned int ptcr, pdcr;
23 slave = slave - 1;
24 master = master - 1;
25
26 ptcr = IMX_AUDMUX_V2_PTCR_SYN |
27 IMX_AUDMUX_V2_PTCR_TFSDIR |
28 IMX_AUDMUX_V2_PTCR_TFSEL(slave) |
29 IMX_AUDMUX_V2_PTCR_TCLKDIR |
30 IMX_AUDMUX_V2_PTCR_TCSEL(slave);
31 pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(slave);
32 imx_audmux_v2_configure_port(master, ptcr, pdcr);
33
34 ptcr = IMX_AUDMUX_V2_PTCR_SYN;
35 pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(master);
36 imx_audmux_v2_configure_port(slave, ptcr, pdcr);
37
38 return 0;
39}
40
41static int imx_si476x_hw_params(struct snd_pcm_substream *substream,
42 struct snd_pcm_hw_params *params)
43{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
46 u32 channels = params_channels(params);
47 u32 rate = params_rate(params);
48 u32 bclk = rate * channels * 32;
49 int ret = 0;
50
51 /* set cpu DAI configuration */
52 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
53 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
54 if (ret) {
55 dev_err(cpu_dai->dev, "failed to set dai fmt\n");
56 return ret;
57 }
58
59 ret = snd_soc_dai_set_sysclk(cpu_dai, 0, bclk, SND_SOC_CLOCK_OUT);
60 if (ret)
61 dev_err(cpu_dai->dev, "failed to set sysclk\n");
62
63 return ret;
64}
65
66static struct snd_soc_ops imx_si476x_ops = {
67 .hw_params = imx_si476x_hw_params,
68};
69
70static struct snd_soc_dai_link imx_dai = {
71 .name = "imx-si476x",
72 .stream_name = "imx-si476x",
73 .codec_dai_name = "si476x-codec",
74 .codec_name = "si476x-codec.99",
75 .ops = &imx_si476x_ops,
76};
77
78static struct snd_soc_card snd_soc_card_imx_3stack = {
79 .name = "imx-audio-si476x",
80 .dai_link = &imx_dai,
81 .num_links = 1,
82};
83
84static int imx_si476x_probe(struct platform_device *pdev)
85{
86 struct snd_soc_card *card = &snd_soc_card_imx_3stack;
87 struct device_node *ssi_np, *np = pdev->dev.of_node;
88 struct platform_device *ssi_pdev;
89 int int_port, ext_port, ret;
90
91 ret = of_property_read_u32(np, "mux-int-port", &int_port);
92 if (ret) {
93 dev_err(&pdev->dev, "mux-int-port missing or invalid\n");
94 return ret;
95 }
96
97 ret = of_property_read_u32(np, "mux-ext-port", &ext_port);
98 if (ret) {
99 dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");
100 return ret;
101 }
102
103 imx_audmux_config(int_port, ext_port);
104
105 ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0);
106 if (!ssi_np) {
107 dev_err(&pdev->dev, "phandle missing or invalid\n");
108 return -EINVAL;
109 }
110
111 ssi_pdev = of_find_device_by_node(ssi_np);
112 if (!ssi_pdev) {
113 dev_err(&pdev->dev, "failed to find SSI platform device\n");
114 ret = -EINVAL;
115 goto end;
116 }
117
118 card->dev = &pdev->dev;
119 card->dai_link->cpu_dai_name = dev_name(&ssi_pdev->dev);
120 card->dai_link->platform_of_node = ssi_np;
121
122 ret = snd_soc_register_card(card);
123 if (ret)
124 dev_err(&pdev->dev, "Failed to register card: %d\n", ret);
125
126end:
127 if (ssi_np)
128 of_node_put(ssi_np);
129
130 return ret;
131}
132
133static int imx_si476x_remove(struct platform_device *pdev)
134{
135 struct snd_soc_card *card = &snd_soc_card_imx_3stack;
136
137 snd_soc_unregister_card(card);
138
139 return 0;
140}
141
142static const struct of_device_id imx_si476x_dt_ids[] = {
143 { .compatible = "fsl,imx-audio-si476x", },
144 { /* sentinel */ }
145};
146MODULE_DEVICE_TABLE(of, imx_si476x_dt_ids);
147
148static struct platform_driver imx_si476x_driver = {
149 .driver = {
150 .name = "imx-tuner-si476x",
151 .owner = THIS_MODULE,
152 .of_match_table = imx_si476x_dt_ids,
153 },
154 .probe = imx_si476x_probe,
155 .remove = imx_si476x_remove,
156};
157
158module_platform_driver(imx_si476x_driver);
159
160/* Module information */
161MODULE_AUTHOR("Freescale Semiconductor, Inc.");
162MODULE_DESCRIPTION("ALSA SoC i.MX si476x");
163MODULE_LICENSE("GPL");
164MODULE_ALIAS("platform:imx-tuner-si476x");