diff options
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/Kconfig | 12 | ||||
-rw-r--r-- | sound/soc/fsl/eukrea-tlv320.c | 108 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_esai.c | 36 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_esai.h | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 332 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.h | 48 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_spdif.c | 9 | ||||
-rw-r--r-- | sound/soc/fsl/imx-mc13783.c | 1 | ||||
-rw-r--r-- | sound/soc/fsl/imx-pcm-fiq.c | 7 | ||||
-rw-r--r-- | sound/soc/fsl/imx-sgtl5000.c | 10 | ||||
-rw-r--r-- | sound/soc/fsl/imx-wm8962.c | 11 | ||||
-rw-r--r-- | sound/soc/fsl/wm1133-ev1.c | 11 |
12 files changed, 395 insertions, 192 deletions
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 07f8f141727d..597962ec28fa 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config SND_SOC_FSL_SAI | 1 | config SND_SOC_FSL_SAI |
2 | tristate | 2 | tristate |
3 | select REGMAP_MMIO | ||
3 | select SND_SOC_GENERIC_DMAENGINE_PCM | 4 | select SND_SOC_GENERIC_DMAENGINE_PCM |
4 | 5 | ||
5 | config SND_SOC_FSL_SSI | 6 | config SND_SOC_FSL_SSI |
@@ -7,9 +8,11 @@ config SND_SOC_FSL_SSI | |||
7 | 8 | ||
8 | config SND_SOC_FSL_SPDIF | 9 | config SND_SOC_FSL_SPDIF |
9 | tristate | 10 | tristate |
11 | select REGMAP_MMIO | ||
10 | 12 | ||
11 | config SND_SOC_FSL_ESAI | 13 | config SND_SOC_FSL_ESAI |
12 | tristate | 14 | tristate |
15 | select REGMAP_MMIO | ||
13 | 16 | ||
14 | config SND_SOC_FSL_UTILS | 17 | config SND_SOC_FSL_UTILS |
15 | tristate | 18 | tristate |
@@ -168,12 +171,14 @@ config SND_SOC_EUKREA_TLV320 | |||
168 | depends on MACH_EUKREA_MBIMX27_BASEBOARD \ | 171 | depends on MACH_EUKREA_MBIMX27_BASEBOARD \ |
169 | || MACH_EUKREA_MBIMXSD25_BASEBOARD \ | 172 | || MACH_EUKREA_MBIMXSD25_BASEBOARD \ |
170 | || MACH_EUKREA_MBIMXSD35_BASEBOARD \ | 173 | || MACH_EUKREA_MBIMXSD35_BASEBOARD \ |
171 | || MACH_EUKREA_MBIMXSD51_BASEBOARD | 174 | || MACH_EUKREA_MBIMXSD51_BASEBOARD \ |
175 | || (OF && ARM) | ||
172 | depends on I2C | 176 | depends on I2C |
173 | select SND_SOC_TLV320AIC23 | 177 | select SND_SOC_TLV320AIC23_I2C |
174 | select SND_SOC_IMX_PCM_FIQ | ||
175 | select SND_SOC_IMX_AUDMUX | 178 | select SND_SOC_IMX_AUDMUX |
176 | select SND_SOC_IMX_SSI | 179 | select SND_SOC_IMX_SSI |
180 | select SND_SOC_FSL_SSI | ||
181 | select SND_SOC_IMX_PCM_DMA | ||
177 | help | 182 | help |
178 | Enable I2S based access to the TLV320AIC23B codec attached | 183 | Enable I2S based access to the TLV320AIC23B codec attached |
179 | to the SSI interface | 184 | to the SSI interface |
@@ -204,7 +209,6 @@ config SND_SOC_IMX_SPDIF | |||
204 | tristate "SoC Audio support for i.MX boards with S/PDIF" | 209 | tristate "SoC Audio support for i.MX boards with S/PDIF" |
205 | select SND_SOC_IMX_PCM_DMA | 210 | select SND_SOC_IMX_PCM_DMA |
206 | select SND_SOC_FSL_SPDIF | 211 | select SND_SOC_FSL_SPDIF |
207 | select REGMAP_MMIO | ||
208 | help | 212 | help |
209 | SoC Audio support for i.MX boards with S/PDIF | 213 | SoC Audio support for i.MX boards with S/PDIF |
210 | Say Y if you want to add support for SoC audio on an i.MX board with | 214 | Say Y if you want to add support for SoC audio on an i.MX board with |
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index 5983740be123..eb093d5b85c4 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c | |||
@@ -15,8 +15,11 @@ | |||
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/errno.h> | ||
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
19 | #include <linux/moduleparam.h> | 20 | #include <linux/moduleparam.h> |
21 | #include <linux/of.h> | ||
22 | #include <linux/of_platform.h> | ||
20 | #include <linux/device.h> | 23 | #include <linux/device.h> |
21 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
22 | #include <sound/core.h> | 25 | #include <sound/core.h> |
@@ -26,6 +29,7 @@ | |||
26 | 29 | ||
27 | #include "../codecs/tlv320aic23.h" | 30 | #include "../codecs/tlv320aic23.h" |
28 | #include "imx-ssi.h" | 31 | #include "imx-ssi.h" |
32 | #include "fsl_ssi.h" | ||
29 | #include "imx-audmux.h" | 33 | #include "imx-audmux.h" |
30 | 34 | ||
31 | #define CODEC_CLOCK 12000000 | 35 | #define CODEC_CLOCK 12000000 |
@@ -41,7 +45,8 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream, | |||
41 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | 45 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | |
42 | SND_SOC_DAIFMT_NB_NF | | 46 | SND_SOC_DAIFMT_NB_NF | |
43 | SND_SOC_DAIFMT_CBM_CFM); | 47 | SND_SOC_DAIFMT_CBM_CFM); |
44 | if (ret) { | 48 | /* fsl_ssi lacks the set_fmt ops. */ |
49 | if (ret && ret != -ENOTSUPP) { | ||
45 | dev_err(cpu_dai->dev, | 50 | dev_err(cpu_dai->dev, |
46 | "Failed to set the cpu dai format.\n"); | 51 | "Failed to set the cpu dai format.\n"); |
47 | return ret; | 52 | return ret; |
@@ -63,11 +68,13 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream, | |||
63 | "Failed to set the codec sysclk.\n"); | 68 | "Failed to set the codec sysclk.\n"); |
64 | return ret; | 69 | return ret; |
65 | } | 70 | } |
71 | |||
66 | snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0); | 72 | snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0); |
67 | 73 | ||
68 | ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, | 74 | ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, |
69 | SND_SOC_CLOCK_IN); | 75 | SND_SOC_CLOCK_IN); |
70 | if (ret) { | 76 | /* fsl_ssi lacks the set_sysclk ops */ |
77 | if (ret && ret != -EINVAL) { | ||
71 | dev_err(cpu_dai->dev, | 78 | dev_err(cpu_dai->dev, |
72 | "Can't set the IMX_SSP_SYS_CLK CPU system clock.\n"); | 79 | "Can't set the IMX_SSP_SYS_CLK CPU system clock.\n"); |
73 | return ret; | 80 | return ret; |
@@ -84,14 +91,10 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = { | |||
84 | .name = "tlv320aic23", | 91 | .name = "tlv320aic23", |
85 | .stream_name = "TLV320AIC23", | 92 | .stream_name = "TLV320AIC23", |
86 | .codec_dai_name = "tlv320aic23-hifi", | 93 | .codec_dai_name = "tlv320aic23-hifi", |
87 | .platform_name = "imx-ssi.0", | ||
88 | .codec_name = "tlv320aic23-codec.0-001a", | ||
89 | .cpu_dai_name = "imx-ssi.0", | ||
90 | .ops = &eukrea_tlv320_snd_ops, | 94 | .ops = &eukrea_tlv320_snd_ops, |
91 | }; | 95 | }; |
92 | 96 | ||
93 | static struct snd_soc_card eukrea_tlv320 = { | 97 | static struct snd_soc_card eukrea_tlv320 = { |
94 | .name = "cpuimx-audio", | ||
95 | .owner = THIS_MODULE, | 98 | .owner = THIS_MODULE, |
96 | .dai_link = &eukrea_tlv320_dai, | 99 | .dai_link = &eukrea_tlv320_dai, |
97 | .num_links = 1, | 100 | .num_links = 1, |
@@ -101,8 +104,65 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) | |||
101 | { | 104 | { |
102 | int ret; | 105 | int ret; |
103 | int int_port = 0, ext_port; | 106 | int int_port = 0, ext_port; |
107 | struct device_node *np = pdev->dev.of_node; | ||
108 | struct device_node *ssi_np, *codec_np; | ||
104 | 109 | ||
105 | if (machine_is_eukrea_cpuimx27()) { | 110 | eukrea_tlv320.dev = &pdev->dev; |
111 | if (np) { | ||
112 | ret = snd_soc_of_parse_card_name(&eukrea_tlv320, | ||
113 | "eukrea,model"); | ||
114 | if (ret) { | ||
115 | dev_err(&pdev->dev, | ||
116 | "eukrea,model node missing or invalid.\n"); | ||
117 | goto err; | ||
118 | } | ||
119 | |||
120 | ssi_np = of_parse_phandle(pdev->dev.of_node, | ||
121 | "ssi-controller", 0); | ||
122 | if (!ssi_np) { | ||
123 | dev_err(&pdev->dev, | ||
124 | "ssi-controller missing or invalid.\n"); | ||
125 | ret = -ENODEV; | ||
126 | goto err; | ||
127 | } | ||
128 | |||
129 | codec_np = of_parse_phandle(ssi_np, "codec-handle", 0); | ||
130 | if (codec_np) | ||
131 | eukrea_tlv320_dai.codec_of_node = codec_np; | ||
132 | else | ||
133 | dev_err(&pdev->dev, "codec-handle node missing or invalid.\n"); | ||
134 | |||
135 | ret = of_property_read_u32(np, "fsl,mux-int-port", &int_port); | ||
136 | if (ret) { | ||
137 | dev_err(&pdev->dev, | ||
138 | "fsl,mux-int-port node missing or invalid.\n"); | ||
139 | return ret; | ||
140 | } | ||
141 | ret = of_property_read_u32(np, "fsl,mux-ext-port", &ext_port); | ||
142 | if (ret) { | ||
143 | dev_err(&pdev->dev, | ||
144 | "fsl,mux-ext-port node missing or invalid.\n"); | ||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * The port numbering in the hardware manual starts at 1, while | ||
150 | * the audmux API expects it starts at 0. | ||
151 | */ | ||
152 | int_port--; | ||
153 | ext_port--; | ||
154 | |||
155 | eukrea_tlv320_dai.cpu_of_node = ssi_np; | ||
156 | eukrea_tlv320_dai.platform_of_node = ssi_np; | ||
157 | } else { | ||
158 | eukrea_tlv320_dai.cpu_dai_name = "imx-ssi.0"; | ||
159 | eukrea_tlv320_dai.platform_name = "imx-ssi.0"; | ||
160 | eukrea_tlv320_dai.codec_name = "tlv320aic23-codec.0-001a"; | ||
161 | eukrea_tlv320.name = "cpuimx-audio"; | ||
162 | } | ||
163 | |||
164 | if (machine_is_eukrea_cpuimx27() || | ||
165 | of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux")) { | ||
106 | imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, | 166 | imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, |
107 | IMX_AUDMUX_V1_PCR_SYN | | 167 | IMX_AUDMUX_V1_PCR_SYN | |
108 | IMX_AUDMUX_V1_PCR_TFSDIR | | 168 | IMX_AUDMUX_V1_PCR_TFSDIR | |
@@ -119,8 +179,12 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) | |||
119 | ); | 179 | ); |
120 | } else if (machine_is_eukrea_cpuimx25sd() || | 180 | } else if (machine_is_eukrea_cpuimx25sd() || |
121 | machine_is_eukrea_cpuimx35sd() || | 181 | machine_is_eukrea_cpuimx35sd() || |
122 | machine_is_eukrea_cpuimx51sd()) { | 182 | machine_is_eukrea_cpuimx51sd() || |
123 | ext_port = machine_is_eukrea_cpuimx25sd() ? 4 : 3; | 183 | of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux")) { |
184 | if (!np) | ||
185 | ext_port = machine_is_eukrea_cpuimx25sd() ? | ||
186 | 4 : 3; | ||
187 | |||
124 | imx_audmux_v2_configure_port(int_port, | 188 | imx_audmux_v2_configure_port(int_port, |
125 | IMX_AUDMUX_V2_PTCR_SYN | | 189 | IMX_AUDMUX_V2_PTCR_SYN | |
126 | IMX_AUDMUX_V2_PTCR_TFSDIR | | 190 | IMX_AUDMUX_V2_PTCR_TFSDIR | |
@@ -134,14 +198,27 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) | |||
134 | IMX_AUDMUX_V2_PDCR_RXDSEL(int_port) | 198 | IMX_AUDMUX_V2_PDCR_RXDSEL(int_port) |
135 | ); | 199 | ); |
136 | } else { | 200 | } else { |
137 | /* return happy. We might run on a totally different machine */ | 201 | if (np) { |
138 | return 0; | 202 | /* The eukrea,asoc-tlv320 driver was explicitely |
203 | * requested (through the device tree). | ||
204 | */ | ||
205 | dev_err(&pdev->dev, | ||
206 | "Missing or invalid audmux DT node.\n"); | ||
207 | return -ENODEV; | ||
208 | } else { | ||
209 | /* Return happy. | ||
210 | * We might run on a totally different machine. | ||
211 | */ | ||
212 | return 0; | ||
213 | } | ||
139 | } | 214 | } |
140 | 215 | ||
141 | eukrea_tlv320.dev = &pdev->dev; | ||
142 | ret = snd_soc_register_card(&eukrea_tlv320); | 216 | ret = snd_soc_register_card(&eukrea_tlv320); |
217 | err: | ||
143 | if (ret) | 218 | if (ret) |
144 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); | 219 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); |
220 | if (np) | ||
221 | of_node_put(ssi_np); | ||
145 | 222 | ||
146 | return ret; | 223 | return ret; |
147 | } | 224 | } |
@@ -153,10 +230,17 @@ static int eukrea_tlv320_remove(struct platform_device *pdev) | |||
153 | return 0; | 230 | return 0; |
154 | } | 231 | } |
155 | 232 | ||
233 | static const struct of_device_id imx_tlv320_dt_ids[] = { | ||
234 | { .compatible = "eukrea,asoc-tlv320"}, | ||
235 | { /* sentinel */ } | ||
236 | }; | ||
237 | MODULE_DEVICE_TABLE(of, imx_tlv320_dt_ids); | ||
238 | |||
156 | static struct platform_driver eukrea_tlv320_driver = { | 239 | static struct platform_driver eukrea_tlv320_driver = { |
157 | .driver = { | 240 | .driver = { |
158 | .name = "eukrea_tlv320", | 241 | .name = "eukrea_tlv320", |
159 | .owner = THIS_MODULE, | 242 | .owner = THIS_MODULE, |
243 | .of_match_table = imx_tlv320_dt_ids, | ||
160 | }, | 244 | }, |
161 | .probe = eukrea_tlv320_probe, | 245 | .probe = eukrea_tlv320_probe, |
162 | .remove = eukrea_tlv320_remove, | 246 | .remove = eukrea_tlv320_remove, |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index d0c72ed261e7..0ba37005ab04 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -326,7 +326,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | |||
326 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, | 326 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, |
327 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); | 327 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); |
328 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, | 328 | regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, |
329 | ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(tx_mask)); | 329 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask)); |
330 | 330 | ||
331 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, | 331 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, |
332 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); | 332 | ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); |
@@ -334,7 +334,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | |||
334 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, | 334 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, |
335 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); | 335 | ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); |
336 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, | 336 | regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, |
337 | ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(rx_mask)); | 337 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); |
338 | 338 | ||
339 | esai_priv->slot_width = slot_width; | 339 | esai_priv->slot_width = slot_width; |
340 | 340 | ||
@@ -431,17 +431,26 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
431 | static int fsl_esai_startup(struct snd_pcm_substream *substream, | 431 | static int fsl_esai_startup(struct snd_pcm_substream *substream, |
432 | struct snd_soc_dai *dai) | 432 | struct snd_soc_dai *dai) |
433 | { | 433 | { |
434 | int ret; | ||
434 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); | 435 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); |
435 | 436 | ||
436 | /* | 437 | /* |
437 | * Some platforms might use the same bit to gate all three or two of | 438 | * Some platforms might use the same bit to gate all three or two of |
438 | * clocks, so keep all clocks open/close at the same time for safety | 439 | * clocks, so keep all clocks open/close at the same time for safety |
439 | */ | 440 | */ |
440 | clk_prepare_enable(esai_priv->coreclk); | 441 | ret = clk_prepare_enable(esai_priv->coreclk); |
441 | if (!IS_ERR(esai_priv->extalclk)) | 442 | if (ret) |
442 | clk_prepare_enable(esai_priv->extalclk); | 443 | return ret; |
443 | if (!IS_ERR(esai_priv->fsysclk)) | 444 | if (!IS_ERR(esai_priv->extalclk)) { |
444 | clk_prepare_enable(esai_priv->fsysclk); | 445 | ret = clk_prepare_enable(esai_priv->extalclk); |
446 | if (ret) | ||
447 | goto err_extalck; | ||
448 | } | ||
449 | if (!IS_ERR(esai_priv->fsysclk)) { | ||
450 | ret = clk_prepare_enable(esai_priv->fsysclk); | ||
451 | if (ret) | ||
452 | goto err_fsysclk; | ||
453 | } | ||
445 | 454 | ||
446 | if (!dai->active) { | 455 | if (!dai->active) { |
447 | /* Reset Port C */ | 456 | /* Reset Port C */ |
@@ -463,6 +472,14 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream, | |||
463 | } | 472 | } |
464 | 473 | ||
465 | return 0; | 474 | return 0; |
475 | |||
476 | err_fsysclk: | ||
477 | if (!IS_ERR(esai_priv->extalclk)) | ||
478 | clk_disable_unprepare(esai_priv->extalclk); | ||
479 | err_extalck: | ||
480 | clk_disable_unprepare(esai_priv->coreclk); | ||
481 | |||
482 | return ret; | ||
466 | } | 483 | } |
467 | 484 | ||
468 | static int fsl_esai_hw_params(struct snd_pcm_substream *substream, | 485 | static int fsl_esai_hw_params(struct snd_pcm_substream *substream, |
@@ -661,7 +678,7 @@ static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg) | |||
661 | } | 678 | } |
662 | } | 679 | } |
663 | 680 | ||
664 | static const struct regmap_config fsl_esai_regmap_config = { | 681 | static struct regmap_config fsl_esai_regmap_config = { |
665 | .reg_bits = 32, | 682 | .reg_bits = 32, |
666 | .reg_stride = 4, | 683 | .reg_stride = 4, |
667 | .val_bits = 32, | 684 | .val_bits = 32, |
@@ -687,6 +704,9 @@ static int fsl_esai_probe(struct platform_device *pdev) | |||
687 | esai_priv->pdev = pdev; | 704 | esai_priv->pdev = pdev; |
688 | strcpy(esai_priv->name, np->name); | 705 | strcpy(esai_priv->name, np->name); |
689 | 706 | ||
707 | if (of_property_read_bool(np, "big-endian")) | ||
708 | fsl_esai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; | ||
709 | |||
690 | /* Get the addresses and IRQ */ | 710 | /* Get the addresses and IRQ */ |
691 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 711 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
692 | regs = devm_ioremap_resource(&pdev->dev, res); | 712 | regs = devm_ioremap_resource(&pdev->dev, res); |
diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h index 9c9f957fcae1..75e14033e8d8 100644 --- a/sound/soc/fsl/fsl_esai.h +++ b/sound/soc/fsl/fsl_esai.h | |||
@@ -322,7 +322,7 @@ | |||
322 | #define ESAI_xSMB_xS_SHIFT 0 | 322 | #define ESAI_xSMB_xS_SHIFT 0 |
323 | #define ESAI_xSMB_xS_WIDTH 16 | 323 | #define ESAI_xSMB_xS_WIDTH 16 |
324 | #define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT) | 324 | #define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT) |
325 | #define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMA_xS_MASK) | 325 | #define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMB_xS_MASK) |
326 | 326 | ||
327 | /* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */ | 327 | /* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */ |
328 | #define ESAI_PRRC_PDC_SHIFT 0 | 328 | #define ESAI_PRRC_PDC_SHIFT 0 |
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index cdd3fa830704..c4a423111673 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/dmaengine.h> | 15 | #include <linux/dmaengine.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/of_address.h> | 17 | #include <linux/of_address.h> |
18 | #include <linux/regmap.h> | ||
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
19 | #include <sound/core.h> | 20 | #include <sound/core.h> |
20 | #include <sound/dmaengine_pcm.h> | 21 | #include <sound/dmaengine_pcm.h> |
@@ -22,34 +23,6 @@ | |||
22 | 23 | ||
23 | #include "fsl_sai.h" | 24 | #include "fsl_sai.h" |
24 | 25 | ||
25 | static inline u32 sai_readl(struct fsl_sai *sai, | ||
26 | const void __iomem *addr) | ||
27 | { | ||
28 | u32 val; | ||
29 | |||
30 | val = __raw_readl(addr); | ||
31 | |||
32 | if (likely(sai->big_endian_regs)) | ||
33 | val = be32_to_cpu(val); | ||
34 | else | ||
35 | val = le32_to_cpu(val); | ||
36 | rmb(); | ||
37 | |||
38 | return val; | ||
39 | } | ||
40 | |||
41 | static inline void sai_writel(struct fsl_sai *sai, | ||
42 | u32 val, void __iomem *addr) | ||
43 | { | ||
44 | wmb(); | ||
45 | if (likely(sai->big_endian_regs)) | ||
46 | val = cpu_to_be32(val); | ||
47 | else | ||
48 | val = cpu_to_le32(val); | ||
49 | |||
50 | __raw_writel(val, addr); | ||
51 | } | ||
52 | |||
53 | static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, | 26 | static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, |
54 | int clk_id, unsigned int freq, int fsl_dir) | 27 | int clk_id, unsigned int freq, int fsl_dir) |
55 | { | 28 | { |
@@ -61,7 +34,8 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, | |||
61 | else | 34 | else |
62 | reg_cr2 = FSL_SAI_RCR2; | 35 | reg_cr2 = FSL_SAI_RCR2; |
63 | 36 | ||
64 | val_cr2 = sai_readl(sai, sai->base + reg_cr2); | 37 | regmap_read(sai->regmap, reg_cr2, &val_cr2); |
38 | |||
65 | val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK; | 39 | val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK; |
66 | 40 | ||
67 | switch (clk_id) { | 41 | switch (clk_id) { |
@@ -81,7 +55,7 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, | |||
81 | return -EINVAL; | 55 | return -EINVAL; |
82 | } | 56 | } |
83 | 57 | ||
84 | sai_writel(sai, val_cr2, sai->base + reg_cr2); | 58 | regmap_write(sai->regmap, reg_cr2, val_cr2); |
85 | 59 | ||
86 | return 0; | 60 | return 0; |
87 | } | 61 | } |
@@ -89,32 +63,22 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, | |||
89 | static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | 63 | static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, |
90 | int clk_id, unsigned int freq, int dir) | 64 | int clk_id, unsigned int freq, int dir) |
91 | { | 65 | { |
92 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | ||
93 | int ret; | 66 | int ret; |
94 | 67 | ||
95 | if (dir == SND_SOC_CLOCK_IN) | 68 | if (dir == SND_SOC_CLOCK_IN) |
96 | return 0; | 69 | return 0; |
97 | 70 | ||
98 | ret = clk_prepare_enable(sai->clk); | ||
99 | if (ret) | ||
100 | return ret; | ||
101 | |||
102 | ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, | 71 | ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, |
103 | FSL_FMT_TRANSMITTER); | 72 | FSL_FMT_TRANSMITTER); |
104 | if (ret) { | 73 | if (ret) { |
105 | dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret); | 74 | dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret); |
106 | goto err_clk; | 75 | return ret; |
107 | } | 76 | } |
108 | 77 | ||
109 | ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, | 78 | ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, |
110 | FSL_FMT_RECEIVER); | 79 | FSL_FMT_RECEIVER); |
111 | if (ret) { | 80 | if (ret) |
112 | dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret); | 81 | dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret); |
113 | goto err_clk; | ||
114 | } | ||
115 | |||
116 | err_clk: | ||
117 | clk_disable_unprepare(sai->clk); | ||
118 | 82 | ||
119 | return ret; | 83 | return ret; |
120 | } | 84 | } |
@@ -133,43 +97,84 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, | |||
133 | reg_cr4 = FSL_SAI_RCR4; | 97 | reg_cr4 = FSL_SAI_RCR4; |
134 | } | 98 | } |
135 | 99 | ||
136 | val_cr2 = sai_readl(sai, sai->base + reg_cr2); | 100 | regmap_read(sai->regmap, reg_cr2, &val_cr2); |
137 | val_cr4 = sai_readl(sai, sai->base + reg_cr4); | 101 | regmap_read(sai->regmap, reg_cr4, &val_cr4); |
138 | 102 | ||
139 | if (sai->big_endian_data) | 103 | if (sai->big_endian_data) |
140 | val_cr4 &= ~FSL_SAI_CR4_MF; | 104 | val_cr4 &= ~FSL_SAI_CR4_MF; |
141 | else | 105 | else |
142 | val_cr4 |= FSL_SAI_CR4_MF; | 106 | val_cr4 |= FSL_SAI_CR4_MF; |
143 | 107 | ||
108 | /* DAI mode */ | ||
144 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 109 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
145 | case SND_SOC_DAIFMT_I2S: | 110 | case SND_SOC_DAIFMT_I2S: |
111 | /* | ||
112 | * Frame low, 1clk before data, one word length for frame sync, | ||
113 | * frame sync starts one serial clock cycle earlier, | ||
114 | * that is, together with the last bit of the previous | ||
115 | * data word. | ||
116 | */ | ||
117 | val_cr2 &= ~FSL_SAI_CR2_BCP; | ||
118 | val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP; | ||
119 | break; | ||
120 | case SND_SOC_DAIFMT_LEFT_J: | ||
121 | /* | ||
122 | * Frame high, one word length for frame sync, | ||
123 | * frame sync asserts with the first bit of the frame. | ||
124 | */ | ||
125 | val_cr2 &= ~FSL_SAI_CR2_BCP; | ||
126 | val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); | ||
127 | break; | ||
128 | case SND_SOC_DAIFMT_DSP_A: | ||
129 | /* | ||
130 | * Frame high, 1clk before data, one bit for frame sync, | ||
131 | * frame sync starts one serial clock cycle earlier, | ||
132 | * that is, together with the last bit of the previous | ||
133 | * data word. | ||
134 | */ | ||
135 | val_cr2 &= ~FSL_SAI_CR2_BCP; | ||
136 | val_cr4 &= ~FSL_SAI_CR4_FSP; | ||
146 | val_cr4 |= FSL_SAI_CR4_FSE; | 137 | val_cr4 |= FSL_SAI_CR4_FSE; |
138 | sai->is_dsp_mode = true; | ||
139 | break; | ||
140 | case SND_SOC_DAIFMT_DSP_B: | ||
141 | /* | ||
142 | * Frame high, one bit for frame sync, | ||
143 | * frame sync asserts with the first bit of the frame. | ||
144 | */ | ||
145 | val_cr2 &= ~FSL_SAI_CR2_BCP; | ||
146 | val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); | ||
147 | sai->is_dsp_mode = true; | ||
147 | break; | 148 | break; |
149 | case SND_SOC_DAIFMT_RIGHT_J: | ||
150 | /* To be done */ | ||
148 | default: | 151 | default: |
149 | return -EINVAL; | 152 | return -EINVAL; |
150 | } | 153 | } |
151 | 154 | ||
155 | /* DAI clock inversion */ | ||
152 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 156 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
153 | case SND_SOC_DAIFMT_IB_IF: | 157 | case SND_SOC_DAIFMT_IB_IF: |
154 | val_cr4 |= FSL_SAI_CR4_FSP; | 158 | /* Invert both clocks */ |
155 | val_cr2 &= ~FSL_SAI_CR2_BCP; | 159 | val_cr2 ^= FSL_SAI_CR2_BCP; |
160 | val_cr4 ^= FSL_SAI_CR4_FSP; | ||
156 | break; | 161 | break; |
157 | case SND_SOC_DAIFMT_IB_NF: | 162 | case SND_SOC_DAIFMT_IB_NF: |
158 | val_cr4 &= ~FSL_SAI_CR4_FSP; | 163 | /* Invert bit clock */ |
159 | val_cr2 &= ~FSL_SAI_CR2_BCP; | 164 | val_cr2 ^= FSL_SAI_CR2_BCP; |
160 | break; | 165 | break; |
161 | case SND_SOC_DAIFMT_NB_IF: | 166 | case SND_SOC_DAIFMT_NB_IF: |
162 | val_cr4 |= FSL_SAI_CR4_FSP; | 167 | /* Invert frame clock */ |
163 | val_cr2 |= FSL_SAI_CR2_BCP; | 168 | val_cr4 ^= FSL_SAI_CR4_FSP; |
164 | break; | 169 | break; |
165 | case SND_SOC_DAIFMT_NB_NF: | 170 | case SND_SOC_DAIFMT_NB_NF: |
166 | val_cr4 &= ~FSL_SAI_CR4_FSP; | 171 | /* Nothing to do for both normal cases */ |
167 | val_cr2 |= FSL_SAI_CR2_BCP; | ||
168 | break; | 172 | break; |
169 | default: | 173 | default: |
170 | return -EINVAL; | 174 | return -EINVAL; |
171 | } | 175 | } |
172 | 176 | ||
177 | /* DAI clock master masks */ | ||
173 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 178 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
174 | case SND_SOC_DAIFMT_CBS_CFS: | 179 | case SND_SOC_DAIFMT_CBS_CFS: |
175 | val_cr2 |= FSL_SAI_CR2_BCD_MSTR; | 180 | val_cr2 |= FSL_SAI_CR2_BCD_MSTR; |
@@ -179,39 +184,37 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, | |||
179 | val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; | 184 | val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; |
180 | val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; | 185 | val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; |
181 | break; | 186 | break; |
187 | case SND_SOC_DAIFMT_CBS_CFM: | ||
188 | val_cr2 |= FSL_SAI_CR2_BCD_MSTR; | ||
189 | val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; | ||
190 | break; | ||
191 | case SND_SOC_DAIFMT_CBM_CFS: | ||
192 | val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; | ||
193 | val_cr4 |= FSL_SAI_CR4_FSD_MSTR; | ||
194 | break; | ||
182 | default: | 195 | default: |
183 | return -EINVAL; | 196 | return -EINVAL; |
184 | } | 197 | } |
185 | 198 | ||
186 | sai_writel(sai, val_cr2, sai->base + reg_cr2); | 199 | regmap_write(sai->regmap, reg_cr2, val_cr2); |
187 | sai_writel(sai, val_cr4, sai->base + reg_cr4); | 200 | regmap_write(sai->regmap, reg_cr4, val_cr4); |
188 | 201 | ||
189 | return 0; | 202 | return 0; |
190 | } | 203 | } |
191 | 204 | ||
192 | static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | 205 | static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) |
193 | { | 206 | { |
194 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | ||
195 | int ret; | 207 | int ret; |
196 | 208 | ||
197 | ret = clk_prepare_enable(sai->clk); | ||
198 | if (ret) | ||
199 | return ret; | ||
200 | |||
201 | ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER); | 209 | ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER); |
202 | if (ret) { | 210 | if (ret) { |
203 | dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret); | 211 | dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret); |
204 | goto err_clk; | 212 | return ret; |
205 | } | 213 | } |
206 | 214 | ||
207 | ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER); | 215 | ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER); |
208 | if (ret) { | 216 | if (ret) |
209 | dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret); | 217 | dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret); |
210 | goto err_clk; | ||
211 | } | ||
212 | |||
213 | err_clk: | ||
214 | clk_disable_unprepare(sai->clk); | ||
215 | 218 | ||
216 | return ret; | 219 | return ret; |
217 | } | 220 | } |
@@ -235,16 +238,19 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, | |||
235 | reg_mr = FSL_SAI_RMR; | 238 | reg_mr = FSL_SAI_RMR; |
236 | } | 239 | } |
237 | 240 | ||
238 | val_cr4 = sai_readl(sai, sai->base + reg_cr4); | 241 | regmap_read(sai->regmap, reg_cr4, &val_cr4); |
242 | regmap_read(sai->regmap, reg_cr4, &val_cr5); | ||
243 | |||
239 | val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK; | 244 | val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK; |
240 | val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK; | 245 | val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK; |
241 | 246 | ||
242 | val_cr5 = sai_readl(sai, sai->base + reg_cr5); | ||
243 | val_cr5 &= ~FSL_SAI_CR5_WNW_MASK; | 247 | val_cr5 &= ~FSL_SAI_CR5_WNW_MASK; |
244 | val_cr5 &= ~FSL_SAI_CR5_W0W_MASK; | 248 | val_cr5 &= ~FSL_SAI_CR5_W0W_MASK; |
245 | val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; | 249 | val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; |
246 | 250 | ||
247 | val_cr4 |= FSL_SAI_CR4_SYWD(word_width); | 251 | if (!sai->is_dsp_mode) |
252 | val_cr4 |= FSL_SAI_CR4_SYWD(word_width); | ||
253 | |||
248 | val_cr5 |= FSL_SAI_CR5_WNW(word_width); | 254 | val_cr5 |= FSL_SAI_CR5_WNW(word_width); |
249 | val_cr5 |= FSL_SAI_CR5_W0W(word_width); | 255 | val_cr5 |= FSL_SAI_CR5_W0W(word_width); |
250 | 256 | ||
@@ -257,9 +263,9 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, | |||
257 | val_cr4 |= FSL_SAI_CR4_FRSZ(channels); | 263 | val_cr4 |= FSL_SAI_CR4_FRSZ(channels); |
258 | val_mr = ~0UL - ((1 << channels) - 1); | 264 | val_mr = ~0UL - ((1 << channels) - 1); |
259 | 265 | ||
260 | sai_writel(sai, val_cr4, sai->base + reg_cr4); | 266 | regmap_write(sai->regmap, reg_cr4, val_cr4); |
261 | sai_writel(sai, val_cr5, sai->base + reg_cr5); | 267 | regmap_write(sai->regmap, reg_cr5, val_cr5); |
262 | sai_writel(sai, val_mr, sai->base + reg_mr); | 268 | regmap_write(sai->regmap, reg_mr, val_mr); |
263 | 269 | ||
264 | return 0; | 270 | return 0; |
265 | } | 271 | } |
@@ -268,44 +274,42 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
268 | struct snd_soc_dai *cpu_dai) | 274 | struct snd_soc_dai *cpu_dai) |
269 | { | 275 | { |
270 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 276 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
271 | u32 tcsr, rcsr, val_cr2, val_cr3, reg_cr3; | 277 | u32 tcsr, rcsr; |
272 | |||
273 | val_cr2 = sai_readl(sai, sai->base + FSL_SAI_TCR2); | ||
274 | val_cr2 &= ~FSL_SAI_CR2_SYNC; | ||
275 | sai_writel(sai, val_cr2, sai->base + FSL_SAI_TCR2); | ||
276 | 278 | ||
277 | val_cr2 = sai_readl(sai, sai->base + FSL_SAI_RCR2); | 279 | /* |
278 | val_cr2 |= FSL_SAI_CR2_SYNC; | 280 | * The transmitter bit clock and frame sync are to be |
279 | sai_writel(sai, val_cr2, sai->base + FSL_SAI_RCR2); | 281 | * used by both the transmitter and receiver. |
282 | */ | ||
283 | regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, | ||
284 | ~FSL_SAI_CR2_SYNC); | ||
285 | regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, | ||
286 | FSL_SAI_CR2_SYNC); | ||
280 | 287 | ||
281 | tcsr = sai_readl(sai, sai->base + FSL_SAI_TCSR); | 288 | regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr); |
282 | rcsr = sai_readl(sai, sai->base + FSL_SAI_RCSR); | 289 | regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr); |
283 | 290 | ||
284 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 291 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
285 | tcsr |= FSL_SAI_CSR_FRDE; | 292 | tcsr |= FSL_SAI_CSR_FRDE; |
286 | rcsr &= ~FSL_SAI_CSR_FRDE; | 293 | rcsr &= ~FSL_SAI_CSR_FRDE; |
287 | reg_cr3 = FSL_SAI_TCR3; | ||
288 | } else { | 294 | } else { |
289 | rcsr |= FSL_SAI_CSR_FRDE; | 295 | rcsr |= FSL_SAI_CSR_FRDE; |
290 | tcsr &= ~FSL_SAI_CSR_FRDE; | 296 | tcsr &= ~FSL_SAI_CSR_FRDE; |
291 | reg_cr3 = FSL_SAI_RCR3; | ||
292 | } | 297 | } |
293 | 298 | ||
294 | val_cr3 = sai_readl(sai, sai->base + reg_cr3); | 299 | /* |
295 | 300 | * It is recommended that the transmitter is the last enabled | |
301 | * and the first disabled. | ||
302 | */ | ||
296 | switch (cmd) { | 303 | switch (cmd) { |
297 | case SNDRV_PCM_TRIGGER_START: | 304 | case SNDRV_PCM_TRIGGER_START: |
298 | case SNDRV_PCM_TRIGGER_RESUME: | 305 | case SNDRV_PCM_TRIGGER_RESUME: |
299 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 306 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
300 | tcsr |= FSL_SAI_CSR_TERE; | 307 | tcsr |= FSL_SAI_CSR_TERE; |
301 | rcsr |= FSL_SAI_CSR_TERE; | 308 | rcsr |= FSL_SAI_CSR_TERE; |
302 | val_cr3 |= FSL_SAI_CR3_TRCE; | ||
303 | 309 | ||
304 | sai_writel(sai, val_cr3, sai->base + reg_cr3); | 310 | regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr); |
305 | sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR); | 311 | regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr); |
306 | sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR); | ||
307 | break; | 312 | break; |
308 | |||
309 | case SNDRV_PCM_TRIGGER_STOP: | 313 | case SNDRV_PCM_TRIGGER_STOP: |
310 | case SNDRV_PCM_TRIGGER_SUSPEND: | 314 | case SNDRV_PCM_TRIGGER_SUSPEND: |
311 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 315 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
@@ -314,11 +318,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
314 | rcsr &= ~FSL_SAI_CSR_TERE; | 318 | rcsr &= ~FSL_SAI_CSR_TERE; |
315 | } | 319 | } |
316 | 320 | ||
317 | val_cr3 &= ~FSL_SAI_CR3_TRCE; | 321 | regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr); |
318 | 322 | regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr); | |
319 | sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR); | ||
320 | sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR); | ||
321 | sai_writel(sai, val_cr3, sai->base + reg_cr3); | ||
322 | break; | 323 | break; |
323 | default: | 324 | default: |
324 | return -EINVAL; | 325 | return -EINVAL; |
@@ -331,16 +332,32 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, | |||
331 | struct snd_soc_dai *cpu_dai) | 332 | struct snd_soc_dai *cpu_dai) |
332 | { | 333 | { |
333 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 334 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
335 | u32 reg; | ||
336 | |||
337 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
338 | reg = FSL_SAI_TCR3; | ||
339 | else | ||
340 | reg = FSL_SAI_RCR3; | ||
341 | |||
342 | regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, | ||
343 | FSL_SAI_CR3_TRCE); | ||
334 | 344 | ||
335 | return clk_prepare_enable(sai->clk); | 345 | return 0; |
336 | } | 346 | } |
337 | 347 | ||
338 | static void fsl_sai_shutdown(struct snd_pcm_substream *substream, | 348 | static void fsl_sai_shutdown(struct snd_pcm_substream *substream, |
339 | struct snd_soc_dai *cpu_dai) | 349 | struct snd_soc_dai *cpu_dai) |
340 | { | 350 | { |
341 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 351 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
352 | u32 reg; | ||
353 | |||
354 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
355 | reg = FSL_SAI_TCR3; | ||
356 | else | ||
357 | reg = FSL_SAI_RCR3; | ||
342 | 358 | ||
343 | clk_disable_unprepare(sai->clk); | 359 | regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, |
360 | ~FSL_SAI_CR3_TRCE); | ||
344 | } | 361 | } |
345 | 362 | ||
346 | static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { | 363 | static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { |
@@ -355,18 +372,13 @@ static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { | |||
355 | static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) | 372 | static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) |
356 | { | 373 | { |
357 | struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); | 374 | struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); |
358 | int ret; | ||
359 | 375 | ||
360 | ret = clk_prepare_enable(sai->clk); | 376 | regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0); |
361 | if (ret) | 377 | regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0); |
362 | return ret; | 378 | regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, |
363 | 379 | FSL_SAI_MAXBURST_TX * 2); | |
364 | sai_writel(sai, 0x0, sai->base + FSL_SAI_RCSR); | 380 | regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, |
365 | sai_writel(sai, 0x0, sai->base + FSL_SAI_TCSR); | 381 | FSL_SAI_MAXBURST_RX - 1); |
366 | sai_writel(sai, FSL_SAI_MAXBURST_TX * 2, sai->base + FSL_SAI_TCR1); | ||
367 | sai_writel(sai, FSL_SAI_MAXBURST_RX - 1, sai->base + FSL_SAI_RCR1); | ||
368 | |||
369 | clk_disable_unprepare(sai->clk); | ||
370 | 382 | ||
371 | snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, | 383 | snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, |
372 | &sai->dma_params_rx); | 384 | &sai->dma_params_rx); |
@@ -397,26 +409,109 @@ static const struct snd_soc_component_driver fsl_component = { | |||
397 | .name = "fsl-sai", | 409 | .name = "fsl-sai", |
398 | }; | 410 | }; |
399 | 411 | ||
412 | static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) | ||
413 | { | ||
414 | switch (reg) { | ||
415 | case FSL_SAI_TCSR: | ||
416 | case FSL_SAI_TCR1: | ||
417 | case FSL_SAI_TCR2: | ||
418 | case FSL_SAI_TCR3: | ||
419 | case FSL_SAI_TCR4: | ||
420 | case FSL_SAI_TCR5: | ||
421 | case FSL_SAI_TFR: | ||
422 | case FSL_SAI_TMR: | ||
423 | case FSL_SAI_RCSR: | ||
424 | case FSL_SAI_RCR1: | ||
425 | case FSL_SAI_RCR2: | ||
426 | case FSL_SAI_RCR3: | ||
427 | case FSL_SAI_RCR4: | ||
428 | case FSL_SAI_RCR5: | ||
429 | case FSL_SAI_RDR: | ||
430 | case FSL_SAI_RFR: | ||
431 | case FSL_SAI_RMR: | ||
432 | return true; | ||
433 | default: | ||
434 | return false; | ||
435 | } | ||
436 | } | ||
437 | |||
438 | static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) | ||
439 | { | ||
440 | switch (reg) { | ||
441 | case FSL_SAI_TFR: | ||
442 | case FSL_SAI_RFR: | ||
443 | case FSL_SAI_TDR: | ||
444 | case FSL_SAI_RDR: | ||
445 | return true; | ||
446 | default: | ||
447 | return false; | ||
448 | } | ||
449 | |||
450 | } | ||
451 | |||
452 | static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg) | ||
453 | { | ||
454 | switch (reg) { | ||
455 | case FSL_SAI_TCSR: | ||
456 | case FSL_SAI_TCR1: | ||
457 | case FSL_SAI_TCR2: | ||
458 | case FSL_SAI_TCR3: | ||
459 | case FSL_SAI_TCR4: | ||
460 | case FSL_SAI_TCR5: | ||
461 | case FSL_SAI_TDR: | ||
462 | case FSL_SAI_TMR: | ||
463 | case FSL_SAI_RCSR: | ||
464 | case FSL_SAI_RCR1: | ||
465 | case FSL_SAI_RCR2: | ||
466 | case FSL_SAI_RCR3: | ||
467 | case FSL_SAI_RCR4: | ||
468 | case FSL_SAI_RCR5: | ||
469 | case FSL_SAI_RMR: | ||
470 | return true; | ||
471 | default: | ||
472 | return false; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | static struct regmap_config fsl_sai_regmap_config = { | ||
477 | .reg_bits = 32, | ||
478 | .reg_stride = 4, | ||
479 | .val_bits = 32, | ||
480 | |||
481 | .max_register = FSL_SAI_RMR, | ||
482 | .readable_reg = fsl_sai_readable_reg, | ||
483 | .volatile_reg = fsl_sai_volatile_reg, | ||
484 | .writeable_reg = fsl_sai_writeable_reg, | ||
485 | }; | ||
486 | |||
400 | static int fsl_sai_probe(struct platform_device *pdev) | 487 | static int fsl_sai_probe(struct platform_device *pdev) |
401 | { | 488 | { |
402 | struct device_node *np = pdev->dev.of_node; | 489 | struct device_node *np = pdev->dev.of_node; |
403 | struct fsl_sai *sai; | 490 | struct fsl_sai *sai; |
404 | struct resource *res; | 491 | struct resource *res; |
492 | void __iomem *base; | ||
405 | int ret; | 493 | int ret; |
406 | 494 | ||
407 | sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); | 495 | sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); |
408 | if (!sai) | 496 | if (!sai) |
409 | return -ENOMEM; | 497 | return -ENOMEM; |
410 | 498 | ||
499 | sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs"); | ||
500 | if (sai->big_endian_regs) | ||
501 | fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; | ||
502 | |||
503 | sai->big_endian_data = of_property_read_bool(np, "big-endian-data"); | ||
504 | |||
411 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 505 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
412 | sai->base = devm_ioremap_resource(&pdev->dev, res); | 506 | base = devm_ioremap_resource(&pdev->dev, res); |
413 | if (IS_ERR(sai->base)) | 507 | if (IS_ERR(base)) |
414 | return PTR_ERR(sai->base); | 508 | return PTR_ERR(base); |
415 | 509 | ||
416 | sai->clk = devm_clk_get(&pdev->dev, "sai"); | 510 | sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, |
417 | if (IS_ERR(sai->clk)) { | 511 | "sai", base, &fsl_sai_regmap_config); |
418 | dev_err(&pdev->dev, "Cannot get SAI's clock\n"); | 512 | if (IS_ERR(sai->regmap)) { |
419 | return PTR_ERR(sai->clk); | 513 | dev_err(&pdev->dev, "regmap init failed\n"); |
514 | return PTR_ERR(sai->regmap); | ||
420 | } | 515 | } |
421 | 516 | ||
422 | sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; | 517 | sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; |
@@ -424,9 +519,6 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
424 | sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; | 519 | sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; |
425 | sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; | 520 | sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; |
426 | 521 | ||
427 | sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs"); | ||
428 | sai->big_endian_data = of_property_read_bool(np, "big-endian-data"); | ||
429 | |||
430 | platform_set_drvdata(pdev, sai); | 522 | platform_set_drvdata(pdev, sai); |
431 | 523 | ||
432 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, | 524 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, |
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 41bb62e69361..e432260be598 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h | |||
@@ -15,31 +15,36 @@ | |||
15 | SNDRV_PCM_FMTBIT_S20_3LE |\ | 15 | SNDRV_PCM_FMTBIT_S20_3LE |\ |
16 | SNDRV_PCM_FMTBIT_S24_LE) | 16 | SNDRV_PCM_FMTBIT_S24_LE) |
17 | 17 | ||
18 | /* SAI Register Map Register */ | ||
19 | #define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */ | ||
20 | #define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */ | ||
21 | #define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */ | ||
22 | #define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */ | ||
23 | #define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */ | ||
24 | #define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */ | ||
25 | #define FSL_SAI_TDR 0x20 /* SAI Transmit Data */ | ||
26 | #define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */ | ||
27 | #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ | ||
28 | #define FSL_SAI_RCSR 0x80 /* SAI Receive Control */ | ||
29 | #define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */ | ||
30 | #define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */ | ||
31 | #define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */ | ||
32 | #define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */ | ||
33 | #define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */ | ||
34 | #define FSL_SAI_RDR 0xa0 /* SAI Receive Data */ | ||
35 | #define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ | ||
36 | #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ | ||
37 | |||
18 | /* SAI Transmit/Recieve Control Register */ | 38 | /* SAI Transmit/Recieve Control Register */ |
19 | #define FSL_SAI_TCSR 0x00 | ||
20 | #define FSL_SAI_RCSR 0x80 | ||
21 | #define FSL_SAI_CSR_TERE BIT(31) | 39 | #define FSL_SAI_CSR_TERE BIT(31) |
22 | #define FSL_SAI_CSR_FWF BIT(17) | 40 | #define FSL_SAI_CSR_FWF BIT(17) |
23 | #define FSL_SAI_CSR_FRIE BIT(8) | 41 | #define FSL_SAI_CSR_FRIE BIT(8) |
24 | #define FSL_SAI_CSR_FRDE BIT(0) | 42 | #define FSL_SAI_CSR_FRDE BIT(0) |
25 | 43 | ||
26 | /* SAI Transmit Data/FIFO/MASK Register */ | ||
27 | #define FSL_SAI_TDR 0x20 | ||
28 | #define FSL_SAI_TFR 0x40 | ||
29 | #define FSL_SAI_TMR 0x60 | ||
30 | |||
31 | /* SAI Recieve Data/FIFO/MASK Register */ | ||
32 | #define FSL_SAI_RDR 0xa0 | ||
33 | #define FSL_SAI_RFR 0xc0 | ||
34 | #define FSL_SAI_RMR 0xe0 | ||
35 | |||
36 | /* SAI Transmit and Recieve Configuration 1 Register */ | 44 | /* SAI Transmit and Recieve Configuration 1 Register */ |
37 | #define FSL_SAI_TCR1 0x04 | 45 | #define FSL_SAI_CR1_RFW_MASK 0x1f |
38 | #define FSL_SAI_RCR1 0x84 | ||
39 | 46 | ||
40 | /* SAI Transmit and Recieve Configuration 2 Register */ | 47 | /* SAI Transmit and Recieve Configuration 2 Register */ |
41 | #define FSL_SAI_TCR2 0x08 | ||
42 | #define FSL_SAI_RCR2 0x88 | ||
43 | #define FSL_SAI_CR2_SYNC BIT(30) | 48 | #define FSL_SAI_CR2_SYNC BIT(30) |
44 | #define FSL_SAI_CR2_MSEL_MASK (0xff << 26) | 49 | #define FSL_SAI_CR2_MSEL_MASK (0xff << 26) |
45 | #define FSL_SAI_CR2_MSEL_BUS 0 | 50 | #define FSL_SAI_CR2_MSEL_BUS 0 |
@@ -50,15 +55,11 @@ | |||
50 | #define FSL_SAI_CR2_BCD_MSTR BIT(24) | 55 | #define FSL_SAI_CR2_BCD_MSTR BIT(24) |
51 | 56 | ||
52 | /* SAI Transmit and Recieve Configuration 3 Register */ | 57 | /* SAI Transmit and Recieve Configuration 3 Register */ |
53 | #define FSL_SAI_TCR3 0x0c | ||
54 | #define FSL_SAI_RCR3 0x8c | ||
55 | #define FSL_SAI_CR3_TRCE BIT(16) | 58 | #define FSL_SAI_CR3_TRCE BIT(16) |
56 | #define FSL_SAI_CR3_WDFL(x) (x) | 59 | #define FSL_SAI_CR3_WDFL(x) (x) |
57 | #define FSL_SAI_CR3_WDFL_MASK 0x1f | 60 | #define FSL_SAI_CR3_WDFL_MASK 0x1f |
58 | 61 | ||
59 | /* SAI Transmit and Recieve Configuration 4 Register */ | 62 | /* SAI Transmit and Recieve Configuration 4 Register */ |
60 | #define FSL_SAI_TCR4 0x10 | ||
61 | #define FSL_SAI_RCR4 0x90 | ||
62 | #define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16) | 63 | #define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16) |
63 | #define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16) | 64 | #define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16) |
64 | #define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8) | 65 | #define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8) |
@@ -69,8 +70,6 @@ | |||
69 | #define FSL_SAI_CR4_FSD_MSTR BIT(0) | 70 | #define FSL_SAI_CR4_FSD_MSTR BIT(0) |
70 | 71 | ||
71 | /* SAI Transmit and Recieve Configuration 5 Register */ | 72 | /* SAI Transmit and Recieve Configuration 5 Register */ |
72 | #define FSL_SAI_TCR5 0x14 | ||
73 | #define FSL_SAI_RCR5 0x94 | ||
74 | #define FSL_SAI_CR5_WNW(x) (((x) - 1) << 24) | 73 | #define FSL_SAI_CR5_WNW(x) (((x) - 1) << 24) |
75 | #define FSL_SAI_CR5_WNW_MASK (0x1f << 24) | 74 | #define FSL_SAI_CR5_WNW_MASK (0x1f << 24) |
76 | #define FSL_SAI_CR5_W0W(x) (((x) - 1) << 16) | 75 | #define FSL_SAI_CR5_W0W(x) (((x) - 1) << 16) |
@@ -100,12 +99,11 @@ | |||
100 | #define FSL_SAI_MAXBURST_RX 6 | 99 | #define FSL_SAI_MAXBURST_RX 6 |
101 | 100 | ||
102 | struct fsl_sai { | 101 | struct fsl_sai { |
103 | struct clk *clk; | 102 | struct regmap *regmap; |
104 | |||
105 | void __iomem *base; | ||
106 | 103 | ||
107 | bool big_endian_regs; | 104 | bool big_endian_regs; |
108 | bool big_endian_data; | 105 | bool big_endian_data; |
106 | bool is_dsp_mode; | ||
109 | 107 | ||
110 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 108 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
111 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 109 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 4d075f1abe78..6452ca83d889 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c | |||
@@ -911,8 +911,8 @@ static int fsl_spdif_dai_probe(struct snd_soc_dai *dai) | |||
911 | { | 911 | { |
912 | struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai); | 912 | struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai); |
913 | 913 | ||
914 | dai->playback_dma_data = &spdif_private->dma_params_tx; | 914 | snd_soc_dai_init_dma_data(dai, &spdif_private->dma_params_tx, |
915 | dai->capture_dma_data = &spdif_private->dma_params_rx; | 915 | &spdif_private->dma_params_rx); |
916 | 916 | ||
917 | snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls)); | 917 | snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls)); |
918 | 918 | ||
@@ -985,7 +985,7 @@ static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg) | |||
985 | } | 985 | } |
986 | } | 986 | } |
987 | 987 | ||
988 | static const struct regmap_config fsl_spdif_regmap_config = { | 988 | static struct regmap_config fsl_spdif_regmap_config = { |
989 | .reg_bits = 32, | 989 | .reg_bits = 32, |
990 | .reg_stride = 4, | 990 | .reg_stride = 4, |
991 | .val_bits = 32, | 991 | .val_bits = 32, |
@@ -1105,6 +1105,9 @@ static int fsl_spdif_probe(struct platform_device *pdev) | |||
1105 | memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai)); | 1105 | memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai)); |
1106 | spdif_priv->cpu_dai_drv.name = spdif_priv->name; | 1106 | spdif_priv->cpu_dai_drv.name = spdif_priv->name; |
1107 | 1107 | ||
1108 | if (of_property_read_bool(np, "big-endian")) | ||
1109 | fsl_spdif_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; | ||
1110 | |||
1108 | /* Get the addresses and IRQ */ | 1111 | /* Get the addresses and IRQ */ |
1109 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1112 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1110 | regs = devm_ioremap_resource(&pdev->dev, res); | 1113 | regs = devm_ioremap_resource(&pdev->dev, res); |
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c index 79cee782dbbf..a2fd7321b5a9 100644 --- a/sound/soc/fsl/imx-mc13783.c +++ b/sound/soc/fsl/imx-mc13783.c | |||
@@ -160,7 +160,6 @@ static struct platform_driver imx_mc13783_audio_driver = { | |||
160 | .driver = { | 160 | .driver = { |
161 | .name = "imx_mc13783", | 161 | .name = "imx_mc13783", |
162 | .owner = THIS_MODULE, | 162 | .owner = THIS_MODULE, |
163 | .pm = &snd_soc_pm_ops, | ||
164 | }, | 163 | }, |
165 | .probe = imx_mc13783_probe, | 164 | .probe = imx_mc13783_probe, |
166 | .remove = imx_mc13783_remove | 165 | .remove = imx_mc13783_remove |
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index 6553202dd48c..7abf6a079574 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c | |||
@@ -270,18 +270,17 @@ static int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
270 | ret = imx_pcm_preallocate_dma_buffer(pcm, | 270 | ret = imx_pcm_preallocate_dma_buffer(pcm, |
271 | SNDRV_PCM_STREAM_PLAYBACK); | 271 | SNDRV_PCM_STREAM_PLAYBACK); |
272 | if (ret) | 272 | if (ret) |
273 | goto out; | 273 | return ret; |
274 | } | 274 | } |
275 | 275 | ||
276 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | 276 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { |
277 | ret = imx_pcm_preallocate_dma_buffer(pcm, | 277 | ret = imx_pcm_preallocate_dma_buffer(pcm, |
278 | SNDRV_PCM_STREAM_CAPTURE); | 278 | SNDRV_PCM_STREAM_CAPTURE); |
279 | if (ret) | 279 | if (ret) |
280 | goto out; | 280 | return ret; |
281 | } | 281 | } |
282 | 282 | ||
283 | out: | 283 | return 0; |
284 | return ret; | ||
285 | } | 284 | } |
286 | 285 | ||
287 | static int ssi_irq = 0; | 286 | static int ssi_irq = 0; |
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index f2beae78969f..1cb22dd034eb 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c | |||
@@ -33,8 +33,7 @@ struct imx_sgtl5000_data { | |||
33 | 33 | ||
34 | static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd) | 34 | static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd) |
35 | { | 35 | { |
36 | struct imx_sgtl5000_data *data = container_of(rtd->card, | 36 | struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(rtd->card); |
37 | struct imx_sgtl5000_data, card); | ||
38 | struct device *dev = rtd->card->dev; | 37 | struct device *dev = rtd->card->dev; |
39 | int ret; | 38 | int ret; |
40 | 39 | ||
@@ -159,13 +158,15 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) | |||
159 | data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; | 158 | data->card.dapm_widgets = imx_sgtl5000_dapm_widgets; |
160 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); | 159 | data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets); |
161 | 160 | ||
161 | platform_set_drvdata(pdev, &data->card); | ||
162 | snd_soc_card_set_drvdata(&data->card, data); | ||
163 | |||
162 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); | 164 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); |
163 | if (ret) { | 165 | if (ret) { |
164 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); | 166 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); |
165 | goto fail; | 167 | goto fail; |
166 | } | 168 | } |
167 | 169 | ||
168 | platform_set_drvdata(pdev, data); | ||
169 | of_node_put(ssi_np); | 170 | of_node_put(ssi_np); |
170 | of_node_put(codec_np); | 171 | of_node_put(codec_np); |
171 | 172 | ||
@@ -184,7 +185,8 @@ fail: | |||
184 | 185 | ||
185 | static int imx_sgtl5000_remove(struct platform_device *pdev) | 186 | static int imx_sgtl5000_remove(struct platform_device *pdev) |
186 | { | 187 | { |
187 | struct imx_sgtl5000_data *data = platform_get_drvdata(pdev); | 188 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
189 | struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(card); | ||
188 | 190 | ||
189 | clk_put(data->codec_clk); | 191 | clk_put(data->codec_clk); |
190 | 192 | ||
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c index 3fd76bc391de..3a3d17ce6ba4 100644 --- a/sound/soc/fsl/imx-wm8962.c +++ b/sound/soc/fsl/imx-wm8962.c | |||
@@ -71,7 +71,7 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card, | |||
71 | { | 71 | { |
72 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 72 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; |
73 | struct imx_priv *priv = &card_priv; | 73 | struct imx_priv *priv = &card_priv; |
74 | struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev); | 74 | struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); |
75 | struct device *dev = &priv->pdev->dev; | 75 | struct device *dev = &priv->pdev->dev; |
76 | unsigned int pll_out; | 76 | unsigned int pll_out; |
77 | int ret; | 77 | int ret; |
@@ -137,7 +137,7 @@ static int imx_wm8962_late_probe(struct snd_soc_card *card) | |||
137 | { | 137 | { |
138 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | 138 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; |
139 | struct imx_priv *priv = &card_priv; | 139 | struct imx_priv *priv = &card_priv; |
140 | struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev); | 140 | struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); |
141 | struct device *dev = &priv->pdev->dev; | 141 | struct device *dev = &priv->pdev->dev; |
142 | int ret; | 142 | int ret; |
143 | 143 | ||
@@ -264,13 +264,15 @@ static int imx_wm8962_probe(struct platform_device *pdev) | |||
264 | data->card.late_probe = imx_wm8962_late_probe; | 264 | data->card.late_probe = imx_wm8962_late_probe; |
265 | data->card.set_bias_level = imx_wm8962_set_bias_level; | 265 | data->card.set_bias_level = imx_wm8962_set_bias_level; |
266 | 266 | ||
267 | platform_set_drvdata(pdev, &data->card); | ||
268 | snd_soc_card_set_drvdata(&data->card, data); | ||
269 | |||
267 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); | 270 | ret = devm_snd_soc_register_card(&pdev->dev, &data->card); |
268 | if (ret) { | 271 | if (ret) { |
269 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); | 272 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); |
270 | goto clk_fail; | 273 | goto clk_fail; |
271 | } | 274 | } |
272 | 275 | ||
273 | platform_set_drvdata(pdev, data); | ||
274 | of_node_put(ssi_np); | 276 | of_node_put(ssi_np); |
275 | of_node_put(codec_np); | 277 | of_node_put(codec_np); |
276 | 278 | ||
@@ -289,7 +291,8 @@ fail: | |||
289 | 291 | ||
290 | static int imx_wm8962_remove(struct platform_device *pdev) | 292 | static int imx_wm8962_remove(struct platform_device *pdev) |
291 | { | 293 | { |
292 | struct imx_wm8962_data *data = platform_get_drvdata(pdev); | 294 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
295 | struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); | ||
293 | 296 | ||
294 | if (!IS_ERR(data->codec_clk)) | 297 | if (!IS_ERR(data->codec_clk)) |
295 | clk_disable_unprepare(data->codec_clk); | 298 | clk_disable_unprepare(data->codec_clk); |
diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c index fce63252bdbb..804749a6c61e 100644 --- a/sound/soc/fsl/wm1133-ev1.c +++ b/sound/soc/fsl/wm1133-ev1.c | |||
@@ -214,12 +214,6 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) | |||
214 | struct snd_soc_codec *codec = rtd->codec; | 214 | struct snd_soc_codec *codec = rtd->codec; |
215 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 215 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
216 | 216 | ||
217 | snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets, | ||
218 | ARRAY_SIZE(wm1133_ev1_widgets)); | ||
219 | |||
220 | snd_soc_dapm_add_routes(dapm, wm1133_ev1_map, | ||
221 | ARRAY_SIZE(wm1133_ev1_map)); | ||
222 | |||
223 | /* Headphone jack detection */ | 217 | /* Headphone jack detection */ |
224 | snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack); | 218 | snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack); |
225 | snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), | 219 | snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), |
@@ -257,6 +251,11 @@ static struct snd_soc_card wm1133_ev1 = { | |||
257 | .owner = THIS_MODULE, | 251 | .owner = THIS_MODULE, |
258 | .dai_link = &wm1133_ev1_dai, | 252 | .dai_link = &wm1133_ev1_dai, |
259 | .num_links = 1, | 253 | .num_links = 1, |
254 | |||
255 | .dapm_widgets = wm1133_ev1_widgets, | ||
256 | .num_dapm_widgets = ARRAY_SIZE(wm1133_ev1_widgets), | ||
257 | .dapm_routes = wm1133_ev1_map, | ||
258 | .num_dapm_routes = ARRAY_SIZE(wm1133_ev1_map), | ||
260 | }; | 259 | }; |
261 | 260 | ||
262 | static struct platform_device *wm1133_ev1_snd_device; | 261 | static struct platform_device *wm1133_ev1_snd_device; |