diff options
Diffstat (limited to 'sound/soc/pxa')
-rw-r--r-- | sound/soc/pxa/Kconfig | 9 | ||||
-rw-r--r-- | sound/soc/pxa/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/pxa/pxa-ssp.c | 135 | ||||
-rw-r--r-- | sound/soc/pxa/spitz.c | 43 | ||||
-rw-r--r-- | sound/soc/pxa/z2.c | 246 |
5 files changed, 360 insertions, 75 deletions
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 376e14a9c273..e30c8325f35e 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
@@ -23,6 +23,7 @@ config SND_PXA2XX_SOC_I2S | |||
23 | 23 | ||
24 | config SND_PXA_SOC_SSP | 24 | config SND_PXA_SOC_SSP |
25 | tristate | 25 | tristate |
26 | select PXA_SSP | ||
26 | 27 | ||
27 | config SND_PXA2XX_SOC_CORGI | 28 | config SND_PXA2XX_SOC_CORGI |
28 | tristate "SoC Audio support for Sharp Zaurus SL-C7x0" | 29 | tristate "SoC Audio support for Sharp Zaurus SL-C7x0" |
@@ -42,6 +43,14 @@ config SND_PXA2XX_SOC_SPITZ | |||
42 | Say Y if you want to add support for SoC audio on Sharp | 43 | Say Y if you want to add support for SoC audio on Sharp |
43 | Zaurus SL-Cxx00 models (Spitz, Borzoi and Akita). | 44 | Zaurus SL-Cxx00 models (Spitz, Borzoi and Akita). |
44 | 45 | ||
46 | config SND_PXA2XX_SOC_Z2 | ||
47 | tristate "SoC Audio support for Zipit Z2" | ||
48 | depends on SND_PXA2XX_SOC && MACH_ZIPIT2 | ||
49 | select SND_PXA2XX_SOC_I2S | ||
50 | select SND_SOC_WM8750 | ||
51 | help | ||
52 | Say Y if you want to add support for SoC audio on Zipit Z2. | ||
53 | |||
45 | config SND_PXA2XX_SOC_POODLE | 54 | config SND_PXA2XX_SOC_POODLE |
46 | tristate "SoC Audio support for Poodle" | 55 | tristate "SoC Audio support for Poodle" |
47 | depends on SND_PXA2XX_SOC && MACH_POODLE | 56 | depends on SND_PXA2XX_SOC && MACH_POODLE |
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile index f3e08fd40ca2..caa03d8f4789 100644 --- a/sound/soc/pxa/Makefile +++ b/sound/soc/pxa/Makefile | |||
@@ -22,6 +22,7 @@ snd-soc-palm27x-objs := palm27x.o | |||
22 | snd-soc-zylonite-objs := zylonite.o | 22 | snd-soc-zylonite-objs := zylonite.o |
23 | snd-soc-magician-objs := magician.o | 23 | snd-soc-magician-objs := magician.o |
24 | snd-soc-mioa701-objs := mioa701_wm9713.o | 24 | snd-soc-mioa701-objs := mioa701_wm9713.o |
25 | snd-soc-z2-objs := z2.o | ||
25 | snd-soc-imote2-objs := imote2.o | 26 | snd-soc-imote2-objs := imote2.o |
26 | snd-soc-raumfeld-objs := raumfeld.o | 27 | snd-soc-raumfeld-objs := raumfeld.o |
27 | 28 | ||
@@ -36,6 +37,7 @@ obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o | |||
36 | obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o | 37 | obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o |
37 | obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o | 38 | obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o |
38 | obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o | 39 | obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o |
40 | obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o | ||
39 | obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o | 41 | obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o |
40 | obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o | 42 | obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o |
41 | obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o | 43 | obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o |
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 544fd9566f4d..a1fd23e0e3d0 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -32,9 +32,8 @@ | |||
32 | 32 | ||
33 | #include <mach/hardware.h> | 33 | #include <mach/hardware.h> |
34 | #include <mach/dma.h> | 34 | #include <mach/dma.h> |
35 | #include <mach/regs-ssp.h> | ||
36 | #include <mach/audio.h> | 35 | #include <mach/audio.h> |
37 | #include <mach/ssp.h> | 36 | #include <plat/ssp.h> |
38 | 37 | ||
39 | #include "pxa2xx-pcm.h" | 38 | #include "pxa2xx-pcm.h" |
40 | #include "pxa-ssp.h" | 39 | #include "pxa-ssp.h" |
@@ -57,15 +56,15 @@ struct ssp_priv { | |||
57 | static void dump_registers(struct ssp_device *ssp) | 56 | static void dump_registers(struct ssp_device *ssp) |
58 | { | 57 | { |
59 | dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n", | 58 | dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n", |
60 | ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1), | 59 | pxa_ssp_read_reg(ssp, SSCR0), pxa_ssp_read_reg(ssp, SSCR1), |
61 | ssp_read_reg(ssp, SSTO)); | 60 | pxa_ssp_read_reg(ssp, SSTO)); |
62 | 61 | ||
63 | dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n", | 62 | dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n", |
64 | ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR), | 63 | pxa_ssp_read_reg(ssp, SSPSP), pxa_ssp_read_reg(ssp, SSSR), |
65 | ssp_read_reg(ssp, SSACD)); | 64 | pxa_ssp_read_reg(ssp, SSACD)); |
66 | } | 65 | } |
67 | 66 | ||
68 | static void ssp_enable(struct ssp_device *ssp) | 67 | static void pxa_ssp_enable(struct ssp_device *ssp) |
69 | { | 68 | { |
70 | uint32_t sscr0; | 69 | uint32_t sscr0; |
71 | 70 | ||
@@ -73,7 +72,7 @@ static void ssp_enable(struct ssp_device *ssp) | |||
73 | __raw_writel(sscr0, ssp->mmio_base + SSCR0); | 72 | __raw_writel(sscr0, ssp->mmio_base + SSCR0); |
74 | } | 73 | } |
75 | 74 | ||
76 | static void ssp_disable(struct ssp_device *ssp) | 75 | static void pxa_ssp_disable(struct ssp_device *ssp) |
77 | { | 76 | { |
78 | uint32_t sscr0; | 77 | uint32_t sscr0; |
79 | 78 | ||
@@ -87,7 +86,7 @@ struct pxa2xx_pcm_dma_data { | |||
87 | }; | 86 | }; |
88 | 87 | ||
89 | static struct pxa2xx_pcm_dma_params * | 88 | static struct pxa2xx_pcm_dma_params * |
90 | ssp_get_dma_params(struct ssp_device *ssp, int width4, int out) | 89 | pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out) |
91 | { | 90 | { |
92 | struct pxa2xx_pcm_dma_data *dma; | 91 | struct pxa2xx_pcm_dma_data *dma; |
93 | 92 | ||
@@ -119,7 +118,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, | |||
119 | 118 | ||
120 | if (!cpu_dai->active) { | 119 | if (!cpu_dai->active) { |
121 | clk_enable(ssp->clk); | 120 | clk_enable(ssp->clk); |
122 | ssp_disable(ssp); | 121 | pxa_ssp_disable(ssp); |
123 | } | 122 | } |
124 | 123 | ||
125 | kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); | 124 | kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); |
@@ -137,7 +136,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, | |||
137 | struct ssp_device *ssp = priv->ssp; | 136 | struct ssp_device *ssp = priv->ssp; |
138 | 137 | ||
139 | if (!cpu_dai->active) { | 138 | if (!cpu_dai->active) { |
140 | ssp_disable(ssp); | 139 | pxa_ssp_disable(ssp); |
141 | clk_disable(ssp->clk); | 140 | clk_disable(ssp->clk); |
142 | } | 141 | } |
143 | 142 | ||
@@ -160,7 +159,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) | |||
160 | priv->to = __raw_readl(ssp->mmio_base + SSTO); | 159 | priv->to = __raw_readl(ssp->mmio_base + SSTO); |
161 | priv->psp = __raw_readl(ssp->mmio_base + SSPSP); | 160 | priv->psp = __raw_readl(ssp->mmio_base + SSPSP); |
162 | 161 | ||
163 | ssp_disable(ssp); | 162 | pxa_ssp_disable(ssp); |
164 | clk_disable(ssp->clk); | 163 | clk_disable(ssp->clk); |
165 | return 0; | 164 | return 0; |
166 | } | 165 | } |
@@ -180,7 +179,7 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) | |||
180 | __raw_writel(priv->psp, ssp->mmio_base + SSPSP); | 179 | __raw_writel(priv->psp, ssp->mmio_base + SSPSP); |
181 | 180 | ||
182 | if (cpu_dai->active) | 181 | if (cpu_dai->active) |
183 | ssp_enable(ssp); | 182 | pxa_ssp_enable(ssp); |
184 | else | 183 | else |
185 | clk_disable(ssp->clk); | 184 | clk_disable(ssp->clk); |
186 | 185 | ||
@@ -196,9 +195,9 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) | |||
196 | * ssp_set_clkdiv - set SSP clock divider | 195 | * ssp_set_clkdiv - set SSP clock divider |
197 | * @div: serial clock rate divider | 196 | * @div: serial clock rate divider |
198 | */ | 197 | */ |
199 | static void ssp_set_scr(struct ssp_device *ssp, u32 div) | 198 | static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div) |
200 | { | 199 | { |
201 | u32 sscr0 = ssp_read_reg(ssp, SSCR0); | 200 | u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0); |
202 | 201 | ||
203 | if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) { | 202 | if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) { |
204 | sscr0 &= ~0x0000ff00; | 203 | sscr0 &= ~0x0000ff00; |
@@ -207,15 +206,15 @@ static void ssp_set_scr(struct ssp_device *ssp, u32 div) | |||
207 | sscr0 &= ~0x000fff00; | 206 | sscr0 &= ~0x000fff00; |
208 | sscr0 |= (div - 1) << 8; /* 1..4096 */ | 207 | sscr0 |= (div - 1) << 8; /* 1..4096 */ |
209 | } | 208 | } |
210 | ssp_write_reg(ssp, SSCR0, sscr0); | 209 | pxa_ssp_write_reg(ssp, SSCR0, sscr0); |
211 | } | 210 | } |
212 | 211 | ||
213 | /** | 212 | /** |
214 | * ssp_get_clkdiv - get SSP clock divider | 213 | * pxa_ssp_get_clkdiv - get SSP clock divider |
215 | */ | 214 | */ |
216 | static u32 ssp_get_scr(struct ssp_device *ssp) | 215 | static u32 pxa_ssp_get_scr(struct ssp_device *ssp) |
217 | { | 216 | { |
218 | u32 sscr0 = ssp_read_reg(ssp, SSCR0); | 217 | u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0); |
219 | u32 div; | 218 | u32 div; |
220 | 219 | ||
221 | if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) | 220 | if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) |
@@ -235,7 +234,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
235 | struct ssp_device *ssp = priv->ssp; | 234 | struct ssp_device *ssp = priv->ssp; |
236 | int val; | 235 | int val; |
237 | 236 | ||
238 | u32 sscr0 = ssp_read_reg(ssp, SSCR0) & | 237 | u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & |
239 | ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); | 238 | ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); |
240 | 239 | ||
241 | dev_dbg(&ssp->pdev->dev, | 240 | dev_dbg(&ssp->pdev->dev, |
@@ -263,7 +262,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
263 | break; | 262 | break; |
264 | case PXA_SSP_CLK_AUDIO: | 263 | case PXA_SSP_CLK_AUDIO: |
265 | priv->sysclk = 0; | 264 | priv->sysclk = 0; |
266 | ssp_set_scr(ssp, 1); | 265 | pxa_ssp_set_scr(ssp, 1); |
267 | sscr0 |= SSCR0_ACS; | 266 | sscr0 |= SSCR0_ACS; |
268 | break; | 267 | break; |
269 | default: | 268 | default: |
@@ -274,8 +273,8 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
274 | * on PXA2xx. On PXA3xx it must be enabled when doing so. */ | 273 | * on PXA2xx. On PXA3xx it must be enabled when doing so. */ |
275 | if (!cpu_is_pxa3xx()) | 274 | if (!cpu_is_pxa3xx()) |
276 | clk_disable(ssp->clk); | 275 | clk_disable(ssp->clk); |
277 | val = ssp_read_reg(ssp, SSCR0) | sscr0; | 276 | val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0; |
278 | ssp_write_reg(ssp, SSCR0, val); | 277 | pxa_ssp_write_reg(ssp, SSCR0, val); |
279 | if (!cpu_is_pxa3xx()) | 278 | if (!cpu_is_pxa3xx()) |
280 | clk_enable(ssp->clk); | 279 | clk_enable(ssp->clk); |
281 | 280 | ||
@@ -294,11 +293,11 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, | |||
294 | 293 | ||
295 | switch (div_id) { | 294 | switch (div_id) { |
296 | case PXA_SSP_AUDIO_DIV_ACDS: | 295 | case PXA_SSP_AUDIO_DIV_ACDS: |
297 | val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div); | 296 | val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div); |
298 | ssp_write_reg(ssp, SSACD, val); | 297 | pxa_ssp_write_reg(ssp, SSACD, val); |
299 | break; | 298 | break; |
300 | case PXA_SSP_AUDIO_DIV_SCDB: | 299 | case PXA_SSP_AUDIO_DIV_SCDB: |
301 | val = ssp_read_reg(ssp, SSACD); | 300 | val = pxa_ssp_read_reg(ssp, SSACD); |
302 | val &= ~SSACD_SCDB; | 301 | val &= ~SSACD_SCDB; |
303 | #if defined(CONFIG_PXA3xx) | 302 | #if defined(CONFIG_PXA3xx) |
304 | if (cpu_is_pxa3xx()) | 303 | if (cpu_is_pxa3xx()) |
@@ -321,10 +320,10 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, | |||
321 | default: | 320 | default: |
322 | return -EINVAL; | 321 | return -EINVAL; |
323 | } | 322 | } |
324 | ssp_write_reg(ssp, SSACD, val); | 323 | pxa_ssp_write_reg(ssp, SSACD, val); |
325 | break; | 324 | break; |
326 | case PXA_SSP_DIV_SCR: | 325 | case PXA_SSP_DIV_SCR: |
327 | ssp_set_scr(ssp, div); | 326 | pxa_ssp_set_scr(ssp, div); |
328 | break; | 327 | break; |
329 | default: | 328 | default: |
330 | return -ENODEV; | 329 | return -ENODEV; |
@@ -341,11 +340,11 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, | |||
341 | { | 340 | { |
342 | struct ssp_priv *priv = cpu_dai->private_data; | 341 | struct ssp_priv *priv = cpu_dai->private_data; |
343 | struct ssp_device *ssp = priv->ssp; | 342 | struct ssp_device *ssp = priv->ssp; |
344 | u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70; | 343 | u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70; |
345 | 344 | ||
346 | #if defined(CONFIG_PXA3xx) | 345 | #if defined(CONFIG_PXA3xx) |
347 | if (cpu_is_pxa3xx()) | 346 | if (cpu_is_pxa3xx()) |
348 | ssp_write_reg(ssp, SSACDD, 0); | 347 | pxa_ssp_write_reg(ssp, SSACDD, 0); |
349 | #endif | 348 | #endif |
350 | 349 | ||
351 | switch (freq_out) { | 350 | switch (freq_out) { |
@@ -383,7 +382,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, | |||
383 | val = tmp; | 382 | val = tmp; |
384 | 383 | ||
385 | val = (val << 16) | 64; | 384 | val = (val << 16) | 64; |
386 | ssp_write_reg(ssp, SSACDD, val); | 385 | pxa_ssp_write_reg(ssp, SSACDD, val); |
387 | 386 | ||
388 | ssacd |= (0x6 << 4); | 387 | ssacd |= (0x6 << 4); |
389 | 388 | ||
@@ -397,7 +396,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, | |||
397 | return -EINVAL; | 396 | return -EINVAL; |
398 | } | 397 | } |
399 | 398 | ||
400 | ssp_write_reg(ssp, SSACD, ssacd); | 399 | pxa_ssp_write_reg(ssp, SSACD, ssacd); |
401 | 400 | ||
402 | return 0; | 401 | return 0; |
403 | } | 402 | } |
@@ -412,7 +411,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, | |||
412 | struct ssp_device *ssp = priv->ssp; | 411 | struct ssp_device *ssp = priv->ssp; |
413 | u32 sscr0; | 412 | u32 sscr0; |
414 | 413 | ||
415 | sscr0 = ssp_read_reg(ssp, SSCR0); | 414 | sscr0 = pxa_ssp_read_reg(ssp, SSCR0); |
416 | sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS); | 415 | sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS); |
417 | 416 | ||
418 | /* set slot width */ | 417 | /* set slot width */ |
@@ -429,10 +428,10 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, | |||
429 | sscr0 |= SSCR0_SlotsPerFrm(slots); | 428 | sscr0 |= SSCR0_SlotsPerFrm(slots); |
430 | 429 | ||
431 | /* set active slot mask */ | 430 | /* set active slot mask */ |
432 | ssp_write_reg(ssp, SSTSA, tx_mask); | 431 | pxa_ssp_write_reg(ssp, SSTSA, tx_mask); |
433 | ssp_write_reg(ssp, SSRSA, rx_mask); | 432 | pxa_ssp_write_reg(ssp, SSRSA, rx_mask); |
434 | } | 433 | } |
435 | ssp_write_reg(ssp, SSCR0, sscr0); | 434 | pxa_ssp_write_reg(ssp, SSCR0, sscr0); |
436 | 435 | ||
437 | return 0; | 436 | return 0; |
438 | } | 437 | } |
@@ -447,12 +446,12 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai, | |||
447 | struct ssp_device *ssp = priv->ssp; | 446 | struct ssp_device *ssp = priv->ssp; |
448 | u32 sscr1; | 447 | u32 sscr1; |
449 | 448 | ||
450 | sscr1 = ssp_read_reg(ssp, SSCR1); | 449 | sscr1 = pxa_ssp_read_reg(ssp, SSCR1); |
451 | if (tristate) | 450 | if (tristate) |
452 | sscr1 &= ~SSCR1_TTE; | 451 | sscr1 &= ~SSCR1_TTE; |
453 | else | 452 | else |
454 | sscr1 |= SSCR1_TTE; | 453 | sscr1 |= SSCR1_TTE; |
455 | ssp_write_reg(ssp, SSCR1, sscr1); | 454 | pxa_ssp_write_reg(ssp, SSCR1, sscr1); |
456 | 455 | ||
457 | return 0; | 456 | return 0; |
458 | } | 457 | } |
@@ -476,14 +475,14 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
476 | return 0; | 475 | return 0; |
477 | 476 | ||
478 | /* we can only change the settings if the port is not in use */ | 477 | /* we can only change the settings if the port is not in use */ |
479 | if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { | 478 | if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { |
480 | dev_err(&ssp->pdev->dev, | 479 | dev_err(&ssp->pdev->dev, |
481 | "can't change hardware dai format: stream is in use"); | 480 | "can't change hardware dai format: stream is in use"); |
482 | return -EINVAL; | 481 | return -EINVAL; |
483 | } | 482 | } |
484 | 483 | ||
485 | /* reset port settings */ | 484 | /* reset port settings */ |
486 | sscr0 = ssp_read_reg(ssp, SSCR0) & | 485 | sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & |
487 | (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); | 486 | (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); |
488 | sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7); | 487 | sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7); |
489 | sspsp = 0; | 488 | sspsp = 0; |
@@ -535,9 +534,9 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
535 | return -EINVAL; | 534 | return -EINVAL; |
536 | } | 535 | } |
537 | 536 | ||
538 | ssp_write_reg(ssp, SSCR0, sscr0); | 537 | pxa_ssp_write_reg(ssp, SSCR0, sscr0); |
539 | ssp_write_reg(ssp, SSCR1, sscr1); | 538 | pxa_ssp_write_reg(ssp, SSCR1, sscr1); |
540 | ssp_write_reg(ssp, SSPSP, sspsp); | 539 | pxa_ssp_write_reg(ssp, SSPSP, sspsp); |
541 | 540 | ||
542 | dump_registers(ssp); | 541 | dump_registers(ssp); |
543 | 542 | ||
@@ -566,7 +565,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | |||
566 | u32 sscr0; | 565 | u32 sscr0; |
567 | u32 sspsp; | 566 | u32 sspsp; |
568 | int width = snd_pcm_format_physical_width(params_format(params)); | 567 | int width = snd_pcm_format_physical_width(params_format(params)); |
569 | int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; | 568 | int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf; |
570 | struct pxa2xx_pcm_dma_params *dma_data; | 569 | struct pxa2xx_pcm_dma_params *dma_data; |
571 | 570 | ||
572 | dma_data = snd_soc_dai_get_dma_data(dai, substream); | 571 | dma_data = snd_soc_dai_get_dma_data(dai, substream); |
@@ -578,22 +577,22 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | |||
578 | * to force 16-bit frame width on the wire (for S16_LE), even | 577 | * to force 16-bit frame width on the wire (for S16_LE), even |
579 | * with two channels. Use 16-bit DMA transfers for this case. | 578 | * with two channels. Use 16-bit DMA transfers for this case. |
580 | */ | 579 | */ |
581 | dma_data = ssp_get_dma_params(ssp, | 580 | dma_data = pxa_ssp_get_dma_params(ssp, |
582 | ((chn == 2) && (ttsa != 1)) || (width == 32), | 581 | ((chn == 2) && (ttsa != 1)) || (width == 32), |
583 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK); | 582 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK); |
584 | 583 | ||
585 | snd_soc_dai_set_dma_data(dai, substream, dma_data); | 584 | snd_soc_dai_set_dma_data(dai, substream, dma_data); |
586 | 585 | ||
587 | /* we can only change the settings if the port is not in use */ | 586 | /* we can only change the settings if the port is not in use */ |
588 | if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) | 587 | if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) |
589 | return 0; | 588 | return 0; |
590 | 589 | ||
591 | /* clear selected SSP bits */ | 590 | /* clear selected SSP bits */ |
592 | sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS); | 591 | sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS); |
593 | ssp_write_reg(ssp, SSCR0, sscr0); | 592 | pxa_ssp_write_reg(ssp, SSCR0, sscr0); |
594 | 593 | ||
595 | /* bit size */ | 594 | /* bit size */ |
596 | sscr0 = ssp_read_reg(ssp, SSCR0); | 595 | sscr0 = pxa_ssp_read_reg(ssp, SSCR0); |
597 | switch (params_format(params)) { | 596 | switch (params_format(params)) { |
598 | case SNDRV_PCM_FORMAT_S16_LE: | 597 | case SNDRV_PCM_FORMAT_S16_LE: |
599 | #ifdef CONFIG_PXA3xx | 598 | #ifdef CONFIG_PXA3xx |
@@ -609,13 +608,13 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | |||
609 | sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16)); | 608 | sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16)); |
610 | break; | 609 | break; |
611 | } | 610 | } |
612 | ssp_write_reg(ssp, SSCR0, sscr0); | 611 | pxa_ssp_write_reg(ssp, SSCR0, sscr0); |
613 | 612 | ||
614 | switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 613 | switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
615 | case SND_SOC_DAIFMT_I2S: | 614 | case SND_SOC_DAIFMT_I2S: |
616 | sspsp = ssp_read_reg(ssp, SSPSP); | 615 | sspsp = pxa_ssp_read_reg(ssp, SSPSP); |
617 | 616 | ||
618 | if ((ssp_get_scr(ssp) == 4) && (width == 16)) { | 617 | if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) { |
619 | /* This is a special case where the bitclk is 64fs | 618 | /* This is a special case where the bitclk is 64fs |
620 | * and we're not dealing with 2*32 bits of audio | 619 | * and we're not dealing with 2*32 bits of audio |
621 | * samples. | 620 | * samples. |
@@ -649,7 +648,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | |||
649 | sspsp |= SSPSP_DMYSTRT(1); | 648 | sspsp |= SSPSP_DMYSTRT(1); |
650 | } | 649 | } |
651 | 650 | ||
652 | ssp_write_reg(ssp, SSPSP, sspsp); | 651 | pxa_ssp_write_reg(ssp, SSPSP, sspsp); |
653 | break; | 652 | break; |
654 | default: | 653 | default: |
655 | break; | 654 | break; |
@@ -680,45 +679,45 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, | |||
680 | 679 | ||
681 | switch (cmd) { | 680 | switch (cmd) { |
682 | case SNDRV_PCM_TRIGGER_RESUME: | 681 | case SNDRV_PCM_TRIGGER_RESUME: |
683 | ssp_enable(ssp); | 682 | pxa_ssp_enable(ssp); |
684 | break; | 683 | break; |
685 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 684 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
686 | val = ssp_read_reg(ssp, SSCR1); | 685 | val = pxa_ssp_read_reg(ssp, SSCR1); |
687 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 686 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
688 | val |= SSCR1_TSRE; | 687 | val |= SSCR1_TSRE; |
689 | else | 688 | else |
690 | val |= SSCR1_RSRE; | 689 | val |= SSCR1_RSRE; |
691 | ssp_write_reg(ssp, SSCR1, val); | 690 | pxa_ssp_write_reg(ssp, SSCR1, val); |
692 | val = ssp_read_reg(ssp, SSSR); | 691 | val = pxa_ssp_read_reg(ssp, SSSR); |
693 | ssp_write_reg(ssp, SSSR, val); | 692 | pxa_ssp_write_reg(ssp, SSSR, val); |
694 | break; | 693 | break; |
695 | case SNDRV_PCM_TRIGGER_START: | 694 | case SNDRV_PCM_TRIGGER_START: |
696 | val = ssp_read_reg(ssp, SSCR1); | 695 | val = pxa_ssp_read_reg(ssp, SSCR1); |
697 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 696 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
698 | val |= SSCR1_TSRE; | 697 | val |= SSCR1_TSRE; |
699 | else | 698 | else |
700 | val |= SSCR1_RSRE; | 699 | val |= SSCR1_RSRE; |
701 | ssp_write_reg(ssp, SSCR1, val); | 700 | pxa_ssp_write_reg(ssp, SSCR1, val); |
702 | ssp_enable(ssp); | 701 | pxa_ssp_enable(ssp); |
703 | break; | 702 | break; |
704 | case SNDRV_PCM_TRIGGER_STOP: | 703 | case SNDRV_PCM_TRIGGER_STOP: |
705 | val = ssp_read_reg(ssp, SSCR1); | 704 | val = pxa_ssp_read_reg(ssp, SSCR1); |
706 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 705 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
707 | val &= ~SSCR1_TSRE; | 706 | val &= ~SSCR1_TSRE; |
708 | else | 707 | else |
709 | val &= ~SSCR1_RSRE; | 708 | val &= ~SSCR1_RSRE; |
710 | ssp_write_reg(ssp, SSCR1, val); | 709 | pxa_ssp_write_reg(ssp, SSCR1, val); |
711 | break; | 710 | break; |
712 | case SNDRV_PCM_TRIGGER_SUSPEND: | 711 | case SNDRV_PCM_TRIGGER_SUSPEND: |
713 | ssp_disable(ssp); | 712 | pxa_ssp_disable(ssp); |
714 | break; | 713 | break; |
715 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 714 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
716 | val = ssp_read_reg(ssp, SSCR1); | 715 | val = pxa_ssp_read_reg(ssp, SSCR1); |
717 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 716 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
718 | val &= ~SSCR1_TSRE; | 717 | val &= ~SSCR1_TSRE; |
719 | else | 718 | else |
720 | val &= ~SSCR1_RSRE; | 719 | val &= ~SSCR1_RSRE; |
721 | ssp_write_reg(ssp, SSCR1, val); | 720 | pxa_ssp_write_reg(ssp, SSCR1, val); |
722 | break; | 721 | break; |
723 | 722 | ||
724 | default: | 723 | default: |
@@ -740,7 +739,7 @@ static int pxa_ssp_probe(struct platform_device *pdev, | |||
740 | if (!priv) | 739 | if (!priv) |
741 | return -ENOMEM; | 740 | return -ENOMEM; |
742 | 741 | ||
743 | priv->ssp = ssp_request(dai->id + 1, "SoC audio"); | 742 | priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio"); |
744 | if (priv->ssp == NULL) { | 743 | if (priv->ssp == NULL) { |
745 | ret = -ENODEV; | 744 | ret = -ENODEV; |
746 | goto err_priv; | 745 | goto err_priv; |
@@ -760,7 +759,7 @@ static void pxa_ssp_remove(struct platform_device *pdev, | |||
760 | struct snd_soc_dai *dai) | 759 | struct snd_soc_dai *dai) |
761 | { | 760 | { |
762 | struct ssp_priv *priv = dai->private_data; | 761 | struct ssp_priv *priv = dai->private_data; |
763 | ssp_free(priv->ssp); | 762 | pxa_ssp_free(priv->ssp); |
764 | } | 763 | } |
765 | 764 | ||
766 | #define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ | 765 | #define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ |
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index c4cd2acaacb4..1941a357e8c4 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
@@ -322,19 +322,44 @@ static struct snd_soc_card snd_soc_spitz = { | |||
322 | .num_links = 1, | 322 | .num_links = 1, |
323 | }; | 323 | }; |
324 | 324 | ||
325 | /* spitz audio private data */ | ||
326 | static struct wm8750_setup_data spitz_wm8750_setup = { | ||
327 | .i2c_bus = 0, | ||
328 | .i2c_address = 0x1b, | ||
329 | }; | ||
330 | |||
331 | /* spitz audio subsystem */ | 325 | /* spitz audio subsystem */ |
332 | static struct snd_soc_device spitz_snd_devdata = { | 326 | static struct snd_soc_device spitz_snd_devdata = { |
333 | .card = &snd_soc_spitz, | 327 | .card = &snd_soc_spitz, |
334 | .codec_dev = &soc_codec_dev_wm8750, | 328 | .codec_dev = &soc_codec_dev_wm8750, |
335 | .codec_data = &spitz_wm8750_setup, | ||
336 | }; | 329 | }; |
337 | 330 | ||
331 | /* | ||
332 | * FIXME: This is a temporary bodge to avoid cross-tree merge issues. | ||
333 | * New drivers should register the wm8750 I2C device in the machine | ||
334 | * setup code (under arch/arm for ARM systems). | ||
335 | */ | ||
336 | static int wm8750_i2c_register(void) | ||
337 | { | ||
338 | struct i2c_board_info info; | ||
339 | struct i2c_adapter *adapter; | ||
340 | struct i2c_client *client; | ||
341 | |||
342 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
343 | info.addr = 0x1b; | ||
344 | strlcpy(info.type, "wm8750", I2C_NAME_SIZE); | ||
345 | |||
346 | adapter = i2c_get_adapter(0); | ||
347 | if (!adapter) { | ||
348 | printk(KERN_ERR "can't get i2c adapter 0\n"); | ||
349 | return -ENODEV; | ||
350 | } | ||
351 | |||
352 | client = i2c_new_device(adapter, &info); | ||
353 | i2c_put_adapter(adapter); | ||
354 | if (!client) { | ||
355 | printk(KERN_ERR "can't add i2c device at 0x%x\n", | ||
356 | (unsigned int)info.addr); | ||
357 | return -ENODEV; | ||
358 | } | ||
359 | |||
360 | return 0; | ||
361 | } | ||
362 | |||
338 | static struct platform_device *spitz_snd_device; | 363 | static struct platform_device *spitz_snd_device; |
339 | 364 | ||
340 | static int __init spitz_init(void) | 365 | static int __init spitz_init(void) |
@@ -344,6 +369,10 @@ static int __init spitz_init(void) | |||
344 | if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) | 369 | if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) |
345 | return -ENODEV; | 370 | return -ENODEV; |
346 | 371 | ||
372 | ret = wm8750_i2c_setup(); | ||
373 | if (ret != 0) | ||
374 | return ret; | ||
375 | |||
347 | spitz_snd_device = platform_device_alloc("soc-audio", -1); | 376 | spitz_snd_device = platform_device_alloc("soc-audio", -1); |
348 | if (!spitz_snd_device) | 377 | if (!spitz_snd_device) |
349 | return -ENOMEM; | 378 | return -ENOMEM; |
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c new file mode 100644 index 000000000000..4e4d2fa8ddc5 --- /dev/null +++ b/sound/soc/pxa/z2.c | |||
@@ -0,0 +1,246 @@ | |||
1 | /* | ||
2 | * linux/sound/soc/pxa/z2.c | ||
3 | * | ||
4 | * SoC Audio driver for Aeronix Zipit Z2 | ||
5 | * | ||
6 | * Copyright (C) 2009 Ken McGuire <kenm@desertweyr.com> | ||
7 | * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/moduleparam.h> | ||
16 | #include <linux/timer.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/gpio.h> | ||
20 | |||
21 | #include <sound/core.h> | ||
22 | #include <sound/pcm.h> | ||
23 | #include <sound/soc.h> | ||
24 | #include <sound/soc-dapm.h> | ||
25 | #include <sound/jack.h> | ||
26 | |||
27 | #include <asm/mach-types.h> | ||
28 | #include <mach/hardware.h> | ||
29 | #include <mach/audio.h> | ||
30 | #include <mach/z2.h> | ||
31 | |||
32 | #include "../codecs/wm8750.h" | ||
33 | #include "pxa2xx-pcm.h" | ||
34 | #include "pxa2xx-i2s.h" | ||
35 | |||
36 | static struct snd_soc_card snd_soc_z2; | ||
37 | |||
38 | static int z2_hw_params(struct snd_pcm_substream *substream, | ||
39 | struct snd_pcm_hw_params *params) | ||
40 | { | ||
41 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
42 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; | ||
43 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | ||
44 | unsigned int clk = 0; | ||
45 | int ret = 0; | ||
46 | |||
47 | switch (params_rate(params)) { | ||
48 | case 8000: | ||
49 | case 16000: | ||
50 | case 48000: | ||
51 | case 96000: | ||
52 | clk = 12288000; | ||
53 | break; | ||
54 | case 11025: | ||
55 | case 22050: | ||
56 | case 44100: | ||
57 | clk = 11289600; | ||
58 | break; | ||
59 | } | ||
60 | |||
61 | /* set codec DAI configuration */ | ||
62 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
63 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
64 | if (ret < 0) | ||
65 | return ret; | ||
66 | |||
67 | /* set cpu DAI configuration */ | ||
68 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
69 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
70 | if (ret < 0) | ||
71 | return ret; | ||
72 | |||
73 | /* set the codec system clock for DAC and ADC */ | ||
74 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, | ||
75 | SND_SOC_CLOCK_IN); | ||
76 | if (ret < 0) | ||
77 | return ret; | ||
78 | |||
79 | /* set the I2S system clock as input (unused) */ | ||
80 | ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, | ||
81 | SND_SOC_CLOCK_IN); | ||
82 | if (ret < 0) | ||
83 | return ret; | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static struct snd_soc_jack hs_jack; | ||
89 | |||
90 | /* Headset jack detection DAPM pins */ | ||
91 | static struct snd_soc_jack_pin hs_jack_pins[] = { | ||
92 | { | ||
93 | .pin = "Mic Jack", | ||
94 | .mask = SND_JACK_MICROPHONE, | ||
95 | }, | ||
96 | { | ||
97 | .pin = "Headphone Jack", | ||
98 | .mask = SND_JACK_HEADPHONE, | ||
99 | }, | ||
100 | }; | ||
101 | |||
102 | /* Headset jack detection gpios */ | ||
103 | static struct snd_soc_jack_gpio hs_jack_gpios[] = { | ||
104 | { | ||
105 | .gpio = GPIO37_ZIPITZ2_HEADSET_DETECT, | ||
106 | .name = "hsdet-gpio", | ||
107 | .report = SND_JACK_HEADSET, | ||
108 | .debounce_time = 200, | ||
109 | }, | ||
110 | }; | ||
111 | |||
112 | /* z2 machine dapm widgets */ | ||
113 | static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { | ||
114 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | ||
115 | SND_SOC_DAPM_MIC("Mic Jack", NULL), | ||
116 | SND_SOC_DAPM_SPK("Ext Spk", NULL), | ||
117 | |||
118 | /* headset is a mic and mono headphone */ | ||
119 | SND_SOC_DAPM_HP("Headset Jack", NULL), | ||
120 | }; | ||
121 | |||
122 | /* Z2 machine audio_map */ | ||
123 | static const struct snd_soc_dapm_route audio_map[] = { | ||
124 | |||
125 | /* headphone connected to LOUT1, ROUT1 */ | ||
126 | {"Headphone Jack", NULL, "LOUT1"}, | ||
127 | {"Headphone Jack", NULL, "ROUT1"}, | ||
128 | |||
129 | /* ext speaker connected to LOUT2, ROUT2 */ | ||
130 | {"Ext Spk", NULL , "ROUT2"}, | ||
131 | {"Ext Spk", NULL , "LOUT2"}, | ||
132 | |||
133 | /* mic is connected to R input 2 - with bias */ | ||
134 | {"RINPUT2", NULL, "Mic Bias"}, | ||
135 | {"Mic Bias", NULL, "Mic Jack"}, | ||
136 | }; | ||
137 | |||
138 | /* | ||
139 | * Logic for a wm8750 as connected on a Z2 Device | ||
140 | */ | ||
141 | static int z2_wm8750_init(struct snd_soc_codec *codec) | ||
142 | { | ||
143 | int ret; | ||
144 | |||
145 | /* NC codec pins */ | ||
146 | snd_soc_dapm_disable_pin(codec, "LINPUT3"); | ||
147 | snd_soc_dapm_disable_pin(codec, "RINPUT3"); | ||
148 | snd_soc_dapm_disable_pin(codec, "OUT3"); | ||
149 | snd_soc_dapm_disable_pin(codec, "MONO"); | ||
150 | |||
151 | /* Add z2 specific widgets */ | ||
152 | snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, | ||
153 | ARRAY_SIZE(wm8750_dapm_widgets)); | ||
154 | |||
155 | /* Set up z2 specific audio paths */ | ||
156 | snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | ||
157 | |||
158 | ret = snd_soc_dapm_sync(codec); | ||
159 | if (ret) | ||
160 | goto err; | ||
161 | |||
162 | /* Jack detection API stuff */ | ||
163 | ret = snd_soc_jack_new(&snd_soc_z2, "Headset Jack", SND_JACK_HEADSET, | ||
164 | &hs_jack); | ||
165 | if (ret) | ||
166 | goto err; | ||
167 | |||
168 | ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), | ||
169 | hs_jack_pins); | ||
170 | if (ret) | ||
171 | goto err; | ||
172 | |||
173 | ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), | ||
174 | hs_jack_gpios); | ||
175 | if (ret) | ||
176 | goto err; | ||
177 | |||
178 | return 0; | ||
179 | |||
180 | err: | ||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | static struct snd_soc_ops z2_ops = { | ||
185 | .hw_params = z2_hw_params, | ||
186 | }; | ||
187 | |||
188 | /* z2 digital audio interface glue - connects codec <--> CPU */ | ||
189 | static struct snd_soc_dai_link z2_dai = { | ||
190 | .name = "wm8750", | ||
191 | .stream_name = "WM8750", | ||
192 | .cpu_dai = &pxa_i2s_dai, | ||
193 | .codec_dai = &wm8750_dai, | ||
194 | .init = z2_wm8750_init, | ||
195 | .ops = &z2_ops, | ||
196 | }; | ||
197 | |||
198 | /* z2 audio machine driver */ | ||
199 | static struct snd_soc_card snd_soc_z2 = { | ||
200 | .name = "Z2", | ||
201 | .platform = &pxa2xx_soc_platform, | ||
202 | .dai_link = &z2_dai, | ||
203 | .num_links = 1, | ||
204 | }; | ||
205 | |||
206 | /* z2 audio subsystem */ | ||
207 | static struct snd_soc_device z2_snd_devdata = { | ||
208 | .card = &snd_soc_z2, | ||
209 | .codec_dev = &soc_codec_dev_wm8750, | ||
210 | }; | ||
211 | |||
212 | static struct platform_device *z2_snd_device; | ||
213 | |||
214 | static int __init z2_init(void) | ||
215 | { | ||
216 | int ret; | ||
217 | |||
218 | if (!machine_is_zipit2()) | ||
219 | return -ENODEV; | ||
220 | |||
221 | z2_snd_device = platform_device_alloc("soc-audio", -1); | ||
222 | if (!z2_snd_device) | ||
223 | return -ENOMEM; | ||
224 | |||
225 | platform_set_drvdata(z2_snd_device, &z2_snd_devdata); | ||
226 | z2_snd_devdata.dev = &z2_snd_device->dev; | ||
227 | ret = platform_device_add(z2_snd_device); | ||
228 | |||
229 | if (ret) | ||
230 | platform_device_put(z2_snd_device); | ||
231 | |||
232 | return ret; | ||
233 | } | ||
234 | |||
235 | static void __exit z2_exit(void) | ||
236 | { | ||
237 | platform_device_unregister(z2_snd_device); | ||
238 | } | ||
239 | |||
240 | module_init(z2_init); | ||
241 | module_exit(z2_exit); | ||
242 | |||
243 | MODULE_AUTHOR("Ken McGuire <kenm@desertweyr.com>, " | ||
244 | "Marek Vasut <marek.vasut@gmail.com>"); | ||
245 | MODULE_DESCRIPTION("ALSA SoC ZipitZ2"); | ||
246 | MODULE_LICENSE("GPL"); | ||