diff options
Diffstat (limited to 'sound/soc/fsl/imx-mc13783.c')
-rw-r--r-- | sound/soc/fsl/imx-mc13783.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c new file mode 100644 index 000000000000..549b31fdc9dd --- /dev/null +++ b/sound/soc/fsl/imx-mc13783.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | * imx-mc13783.c -- SoC audio for imx based boards with mc13783 codec | ||
3 | * | ||
4 | * Copyright 2012 Philippe Retornaz, <philippe.retornaz@epfl.ch> | ||
5 | * | ||
6 | * Heavly based on phycore-mc13783: | ||
7 | * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/moduleparam.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <sound/core.h> | ||
20 | #include <sound/pcm.h> | ||
21 | #include <sound/soc.h> | ||
22 | #include <sound/soc-dapm.h> | ||
23 | #include <asm/mach-types.h> | ||
24 | |||
25 | #include "../codecs/mc13783.h" | ||
26 | #include "imx-ssi.h" | ||
27 | #include "imx-audmux.h" | ||
28 | |||
29 | #define FMT_SSI (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | \ | ||
30 | SND_SOC_DAIFMT_CBM_CFM) | ||
31 | |||
32 | static int imx_mc13783_hifi_hw_params(struct snd_pcm_substream *substream, | ||
33 | struct snd_pcm_hw_params *params) | ||
34 | { | ||
35 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
36 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
37 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
38 | int ret; | ||
39 | |||
40 | ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xfffffffc, 0xfffffffc, | ||
41 | 4, 16); | ||
42 | if (ret) | ||
43 | return ret; | ||
44 | |||
45 | ret = snd_soc_dai_set_sysclk(codec_dai, MC13783_CLK_CLIA, 26000000, 0); | ||
46 | if (ret) | ||
47 | return ret; | ||
48 | |||
49 | ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x0, 0xfffffffc, 2, 16); | ||
50 | if (ret) | ||
51 | return ret; | ||
52 | |||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static struct snd_soc_ops imx_mc13783_hifi_ops = { | ||
57 | .hw_params = imx_mc13783_hifi_hw_params, | ||
58 | }; | ||
59 | |||
60 | static struct snd_soc_dai_link imx_mc13783_dai_mc13783[] = { | ||
61 | { | ||
62 | .name = "MC13783", | ||
63 | .stream_name = "Sound", | ||
64 | .codec_dai_name = "mc13783-hifi", | ||
65 | .codec_name = "mc13783-codec", | ||
66 | .cpu_dai_name = "imx-ssi.0", | ||
67 | .platform_name = "imx-pcm-audio.0", | ||
68 | .ops = &imx_mc13783_hifi_ops, | ||
69 | .symmetric_rates = 1, | ||
70 | .dai_fmt = FMT_SSI, | ||
71 | }, | ||
72 | }; | ||
73 | |||
74 | static const struct snd_soc_dapm_widget imx_mc13783_widget[] = { | ||
75 | SND_SOC_DAPM_MIC("Mic", NULL), | ||
76 | SND_SOC_DAPM_HP("Headphone", NULL), | ||
77 | SND_SOC_DAPM_SPK("Speaker", NULL), | ||
78 | }; | ||
79 | |||
80 | static const struct snd_soc_dapm_route imx_mc13783_routes[] = { | ||
81 | {"Speaker", NULL, "LSP"}, | ||
82 | {"Headphone", NULL, "HSL"}, | ||
83 | {"Headphone", NULL, "HSR"}, | ||
84 | |||
85 | {"MC1LIN", NULL, "MC1 Bias"}, | ||
86 | {"MC2IN", NULL, "MC2 Bias"}, | ||
87 | {"MC1 Bias", NULL, "Mic"}, | ||
88 | {"MC2 Bias", NULL, "Mic"}, | ||
89 | }; | ||
90 | |||
91 | static struct snd_soc_card imx_mc13783 = { | ||
92 | .name = "imx_mc13783", | ||
93 | .dai_link = imx_mc13783_dai_mc13783, | ||
94 | .num_links = ARRAY_SIZE(imx_mc13783_dai_mc13783), | ||
95 | .dapm_widgets = imx_mc13783_widget, | ||
96 | .num_dapm_widgets = ARRAY_SIZE(imx_mc13783_widget), | ||
97 | .dapm_routes = imx_mc13783_routes, | ||
98 | .num_dapm_routes = ARRAY_SIZE(imx_mc13783_routes), | ||
99 | }; | ||
100 | |||
101 | static int __devinit imx_mc13783_probe(struct platform_device *pdev) | ||
102 | { | ||
103 | int ret; | ||
104 | |||
105 | imx_mc13783.dev = &pdev->dev; | ||
106 | |||
107 | ret = snd_soc_register_card(&imx_mc13783); | ||
108 | if (ret) { | ||
109 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", | ||
110 | ret); | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | if (machine_is_mx31_3ds()) { | ||
115 | imx_audmux_v2_configure_port(MX31_AUDMUX_PORT4_SSI_PINS_4, | ||
116 | IMX_AUDMUX_V2_PTCR_SYN, | ||
117 | IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0) | | ||
118 | IMX_AUDMUX_V2_PDCR_MODE(1) | | ||
119 | IMX_AUDMUX_V2_PDCR_INMMASK(0xfc)); | ||
120 | imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, | ||
121 | IMX_AUDMUX_V2_PTCR_SYN | | ||
122 | IMX_AUDMUX_V2_PTCR_TFSDIR | | ||
123 | IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) | | ||
124 | IMX_AUDMUX_V2_PTCR_TCLKDIR | | ||
125 | IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) | | ||
126 | IMX_AUDMUX_V2_PTCR_RFSDIR | | ||
127 | IMX_AUDMUX_V2_PTCR_RFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) | | ||
128 | IMX_AUDMUX_V2_PTCR_RCLKDIR | | ||
129 | IMX_AUDMUX_V2_PTCR_RCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4), | ||
130 | IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT4_SSI_PINS_4)); | ||
131 | } else if (machine_is_mx27_3ds()) { | ||
132 | imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, | ||
133 | IMX_AUDMUX_V1_PCR_SYN | | ||
134 | IMX_AUDMUX_V1_PCR_TFSDIR | | ||
135 | IMX_AUDMUX_V1_PCR_TCLKDIR | | ||
136 | IMX_AUDMUX_V1_PCR_RFSDIR | | ||
137 | IMX_AUDMUX_V1_PCR_RCLKDIR | | ||
138 | IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) | | ||
139 | IMX_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) | | ||
140 | IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) | ||
141 | ); | ||
142 | imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4, | ||
143 | IMX_AUDMUX_V1_PCR_SYN | | ||
144 | IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) | ||
145 | ); | ||
146 | } | ||
147 | |||
148 | return ret; | ||
149 | } | ||
150 | |||
151 | static int __devexit imx_mc13783_remove(struct platform_device *pdev) | ||
152 | { | ||
153 | snd_soc_unregister_card(&imx_mc13783); | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static struct platform_driver imx_mc13783_audio_driver = { | ||
159 | .driver = { | ||
160 | .name = "imx_mc13783", | ||
161 | .owner = THIS_MODULE, | ||
162 | }, | ||
163 | .probe = imx_mc13783_probe, | ||
164 | .remove = __devexit_p(imx_mc13783_remove) | ||
165 | }; | ||
166 | |||
167 | module_platform_driver(imx_mc13783_audio_driver); | ||
168 | |||
169 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | ||
170 | MODULE_AUTHOR("Philippe Retornaz <philippe.retornaz@epfl.ch"); | ||
171 | MODULE_DESCRIPTION("imx with mc13783 codec ALSA SoC driver"); | ||
172 | MODULE_LICENSE("GPL"); | ||
173 | MODULE_ALIAS("platform:imx_mc13783"); | ||