aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/Kconfig2
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/at32/at32-pcm.c5
-rw-r--r--sound/soc/at32/playpaq_wm8510.c7
-rw-r--r--sound/soc/at91/at91-ssc.c2
-rw-r--r--sound/soc/at91/eti_b1_wm8731.c1
-rw-r--r--sound/soc/blackfin/Kconfig85
-rw-r--r--sound/soc/blackfin/Makefile20
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c429
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.h29
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c407
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.h36
-rw-r--r--sound/soc/blackfin/bf5xx-ad1980.c113
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c288
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.h29
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c292
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.h14
-rw-r--r--sound/soc/blackfin/bf5xx-sport.c1032
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h192
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c186
-rw-r--r--sound/soc/codecs/Kconfig91
-rw-r--r--sound/soc/codecs/Makefile22
-rw-r--r--sound/soc/codecs/ad1980.c309
-rw-r--r--sound/soc/codecs/ad1980.h23
-rw-r--r--sound/soc/codecs/ak4535.c116
-rw-r--r--sound/soc/codecs/ak4535.h1
-rw-r--r--sound/soc/codecs/cs4270.c103
-rw-r--r--sound/soc/codecs/ssm2602.c776
-rw-r--r--sound/soc/codecs/ssm2602.h130
-rw-r--r--sound/soc/codecs/tlv320aic26.c520
-rw-r--r--sound/soc/codecs/tlv320aic26.h96
-rw-r--r--sound/soc/codecs/tlv320aic3x.c108
-rw-r--r--sound/soc/codecs/tlv320aic3x.h3
-rw-r--r--sound/soc/codecs/uda1380.c115
-rw-r--r--sound/soc/codecs/uda1380.h1
-rw-r--r--sound/soc/codecs/wm8510.c112
-rw-r--r--sound/soc/codecs/wm8510.h1
-rw-r--r--sound/soc/codecs/wm8580.c1055
-rw-r--r--sound/soc/codecs/wm8580.h42
-rw-r--r--sound/soc/codecs/wm8731.c178
-rw-r--r--sound/soc/codecs/wm8731.h2
-rw-r--r--sound/soc/codecs/wm8750.c177
-rw-r--r--sound/soc/codecs/wm8750.h2
-rw-r--r--sound/soc/codecs/wm8753.c110
-rw-r--r--sound/soc/codecs/wm8753.h1
-rw-r--r--sound/soc/codecs/wm8900.c1542
-rw-r--r--sound/soc/codecs/wm8900.h64
-rw-r--r--sound/soc/codecs/wm8903.c1813
-rw-r--r--sound/soc/codecs/wm8903.h1463
-rw-r--r--sound/soc/codecs/wm8971.c942
-rw-r--r--sound/soc/codecs/wm8971.h64
-rw-r--r--sound/soc/codecs/wm8990.c109
-rw-r--r--sound/soc/codecs/wm8990.h1
-rw-r--r--sound/soc/codecs/wm9713.c34
-rw-r--r--sound/soc/davinci/davinci-evm.c3
-rw-r--r--sound/soc/davinci/davinci-i2s.c4
-rw-r--r--sound/soc/davinci/davinci-i2s.h2
-rw-r--r--sound/soc/davinci/davinci-pcm.c2
-rw-r--r--sound/soc/davinci/davinci-pcm.h2
-rw-r--r--sound/soc/fsl/Kconfig10
-rw-r--r--sound/soc/fsl/Makefile5
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c884
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c26
-rw-r--r--sound/soc/fsl/soc-of-simple.c171
-rw-r--r--sound/soc/omap/n810.c1
-rw-r--r--sound/soc/pxa/Kconfig3
-rw-r--r--sound/soc/pxa/corgi.c35
-rw-r--r--sound/soc/pxa/poodle.c1
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c282
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c63
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c265
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.h15
-rw-r--r--sound/soc/pxa/spitz.c47
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c120
-rw-r--r--sound/soc/soc-core.c138
-rw-r--r--sound/soc/soc-dapm.c127
76 files changed, 14164 insertions, 1339 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index f743530add8..4dfda6674be 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -5,6 +5,7 @@
5menuconfig SND_SOC 5menuconfig SND_SOC
6 tristate "ALSA for SoC audio support" 6 tristate "ALSA for SoC audio support"
7 select SND_PCM 7 select SND_PCM
8 select AC97_BUS if SND_SOC_AC97_BUS
8 ---help--- 9 ---help---
9 10
10 If you want ASoC support, you should say Y here and also to the 11 If you want ASoC support, you should say Y here and also to the
@@ -31,6 +32,7 @@ source "sound/soc/sh/Kconfig"
31source "sound/soc/fsl/Kconfig" 32source "sound/soc/fsl/Kconfig"
32source "sound/soc/davinci/Kconfig" 33source "sound/soc/davinci/Kconfig"
33source "sound/soc/omap/Kconfig" 34source "sound/soc/omap/Kconfig"
35source "sound/soc/blackfin/Kconfig"
34 36
35# Supported codecs 37# Supported codecs
36source "sound/soc/codecs/Kconfig" 38source "sound/soc/codecs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 933a66d3080..d849349f2c6 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -2,4 +2,4 @@ snd-soc-core-objs := soc-core.o soc-dapm.o
2 2
3obj-$(CONFIG_SND_SOC) += snd-soc-core.o 3obj-$(CONFIG_SND_SOC) += snd-soc-core.o
4obj-$(CONFIG_SND_SOC) += codecs/ at32/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/ 4obj-$(CONFIG_SND_SOC) += codecs/ at32/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/
5obj-$(CONFIG_SND_SOC) += omap/ au1x/ 5obj-$(CONFIG_SND_SOC) += omap/ au1x/ blackfin/
diff --git a/sound/soc/at32/at32-pcm.c b/sound/soc/at32/at32-pcm.c
index 435f1daf177..c83584f989a 100644
--- a/sound/soc/at32/at32-pcm.c
+++ b/sound/soc/at32/at32-pcm.c
@@ -434,7 +434,8 @@ static int at32_pcm_suspend(struct platform_device *pdev,
434 params = prtd->params; 434 params = prtd->params;
435 435
436 /* Disable the PDC and save the PDC registers */ 436 /* Disable the PDC and save the PDC registers */
437 ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable); 437 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
438 params->mask->pdc_disable);
438 439
439 prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr); 440 prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
440 prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr); 441 prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
@@ -464,7 +465,7 @@ static int at32_pcm_resume(struct platform_device *pdev,
464 ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save); 465 ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
465 ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save); 466 ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
466 467
467 ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable); 468 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, params->mask->pdc_enable);
468 return 0; 469 return 0;
469} 470}
470#else /* CONFIG_PM */ 471#else /* CONFIG_PM */
diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c
index 3f326219f1e..98a2d5826a8 100644
--- a/sound/soc/at32/playpaq_wm8510.c
+++ b/sound/soc/at32/playpaq_wm8510.c
@@ -377,6 +377,7 @@ static struct snd_soc_machine snd_soc_machine_playpaq = {
377 377
378 378
379static struct wm8510_setup_data playpaq_wm8510_setup = { 379static struct wm8510_setup_data playpaq_wm8510_setup = {
380 .i2c_bus = 0,
380 .i2c_address = 0x1a, 381 .i2c_address = 0x1a,
381}; 382};
382 383
@@ -405,7 +406,6 @@ static int __init playpaq_asoc_init(void)
405 ssc = ssc_request(0); 406 ssc = ssc_request(0);
406 if (IS_ERR(ssc)) { 407 if (IS_ERR(ssc)) {
407 ret = PTR_ERR(ssc); 408 ret = PTR_ERR(ssc);
408 ssc = NULL;
409 goto err_ssc; 409 goto err_ssc;
410 } 410 }
411 ssc_p->ssc = ssc; 411 ssc_p->ssc = ssc;
@@ -476,10 +476,7 @@ err_pll0:
476 _gclk0 = NULL; 476 _gclk0 = NULL;
477 } 477 }
478err_gclk0: 478err_gclk0:
479 if (ssc != NULL) { 479 ssc_free(ssc);
480 ssc_free(ssc);
481 ssc = NULL;
482 }
483err_ssc: 480err_ssc:
484 return ret; 481 return ret;
485} 482}
diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c
index 5d44515e62e..a5b1a79ebff 100644
--- a/sound/soc/at91/at91-ssc.c
+++ b/sound/soc/at91/at91-ssc.c
@@ -408,7 +408,7 @@ static int at91_ssc_hw_params(struct snd_pcm_substream *substream,
408 dma_params->pdc_xfer_size = 4; 408 dma_params->pdc_xfer_size = 4;
409 break; 409 break;
410 default: 410 default:
411 printk(KERN_WARNING "at91-ssc: unsupported PCM format"); 411 printk(KERN_WARNING "at91-ssc: unsupported PCM format\n");
412 return -EINVAL; 412 return -EINVAL;
413 } 413 }
414 414
diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c
index b81d6b2cfa1..684781e4088 100644
--- a/sound/soc/at91/eti_b1_wm8731.c
+++ b/sound/soc/at91/eti_b1_wm8731.c
@@ -243,6 +243,7 @@ static struct snd_soc_machine snd_soc_machine_eti_b1 = {
243}; 243};
244 244
245static struct wm8731_setup_data eti_b1_wm8731_setup = { 245static struct wm8731_setup_data eti_b1_wm8731_setup = {
246 .i2c_bus = 0,
246 .i2c_address = 0x1a, 247 .i2c_address = 0x1a,
247}; 248};
248 249
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
new file mode 100644
index 00000000000..f98331d099e
--- /dev/null
+++ b/sound/soc/blackfin/Kconfig
@@ -0,0 +1,85 @@
1config SND_BF5XX_I2S
2 tristate "SoC I2S Audio for the ADI BF5xx chip"
3 depends on BLACKFIN && SND_SOC
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the Blackfin SPORT (synchronous serial ports) interface in I2S
7 mode (supports single stereo In/Out).
8 You will also need to select the audio interfaces to support below.
9
10config SND_BF5XX_SOC_SSM2602
11 tristate "SoC SSM2602 Audio support for BF52x ezkit"
12 depends on SND_BF5XX_I2S
13 select SND_BF5XX_SOC_I2S
14 select SND_SOC_SSM2602
15 select I2C
16 select I2C_BLACKFIN_TWI
17 help
18 Say Y if you want to add support for SoC audio on BF527-EZKIT.
19
20config SND_BF5XX_AC97
21 tristate "SoC AC97 Audio for the ADI BF5xx chip"
22 depends on BLACKFIN && SND_SOC
23 help
24 Say Y or M if you want to add support for codecs attached to
25 the Blackfin SPORT (synchronous serial ports) interface in slot 16
26 mode (pseudo AC97 interface).
27 You will also need to select the audio interfaces to support below.
28
29 Note:
30 AC97 codecs which do not implment the slot-16 mode will not function
31 properly with this driver. This driver is known to work with the
32 Analog Devices line of AC97 codecs.
33
34config SND_MMAP_SUPPORT
35 bool "Enable MMAP Support"
36 depends on SND_BF5XX_AC97
37 default y
38 help
39 Say y if you want AC97 driver to support mmap mode.
40 We introduce an intermediate buffer to simulate mmap.
41
42config SND_BF5XX_SOC_SPORT
43 tristate
44
45config SND_BF5XX_SOC_I2S
46 tristate
47 select SND_BF5XX_SOC_SPORT
48
49config SND_BF5XX_SOC_AC97
50 tristate
51 select AC97_BUS
52 select SND_SOC_AC97_BUS
53 select SND_BF5XX_SOC_SPORT
54
55config SND_BF5XX_SOC_AD1980
56 tristate "SoC AD1980/1 Audio support for BF5xx"
57 depends on SND_BF5XX_AC97
58 select SND_BF5XX_SOC_AC97
59 select SND_SOC_AD1980
60 help
61 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
62
63config SND_BF5XX_SPORT_NUM
64 int "Set a SPORT for Sound chip"
65 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97)
66 range 0 3 if BF54x
67 range 0 1 if (BF53x || BF561)
68 default 0
69 help
70 Set the correct SPORT for sound chip.
71
72config SND_BF5XX_HAVE_COLD_RESET
73 bool "BOARD has COLD Reset GPIO"
74 depends on SND_BF5XX_AC97
75 default y if BFIN548_EZKIT
76 default n if !BFIN548_EZKIT
77
78config SND_BF5XX_RESET_GPIO_NUM
79 int "Set a GPIO for cold reset"
80 depends on SND_BF5XX_HAVE_COLD_RESET
81 range 0 159
82 default 19 if BFIN548_EZKIT
83 default 5 if BFIN537_STAMP
84 help
85 Set the correct GPIO for RESET the sound chip.
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
new file mode 100644
index 00000000000..9ea8bd9e0ba
--- /dev/null
+++ b/sound/soc/blackfin/Makefile
@@ -0,0 +1,20 @@
1# Blackfin Platform Support
2snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o
3snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o
4snd-soc-bf5xx-sport-objs := bf5xx-sport.o
5snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o
6snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o
7
8obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o
9obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o
10obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o
11obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o
12obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o
13
14# Blackfin Machine Support
15snd-ad1980-objs := bf5xx-ad1980.o
16snd-ssm2602-objs := bf5xx-ssm2602.o
17
18
19obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
20obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
new file mode 100644
index 00000000000..51f4907c483
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -0,0 +1,429 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-ac97-pcm.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: DMA Driver for AC97 sound chip
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/platform_device.h>
32#include <linux/slab.h>
33#include <linux/dma-mapping.h>
34
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39
40#include <asm/dma.h>
41
42#include "bf5xx-ac97-pcm.h"
43#include "bf5xx-ac97.h"
44#include "bf5xx-sport.h"
45
46#if defined(CONFIG_SND_MMAP_SUPPORT)
47static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
48 snd_pcm_uframes_t count)
49{
50 struct snd_pcm_runtime *runtime = substream->runtime;
51 struct sport_device *sport = runtime->private_data;
52 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
53 bf5xx_pcm_to_ac97(
54 (struct ac97_frame *)sport->tx_dma_buf + sport->tx_pos,
55 (__u32 *)runtime->dma_area + sport->tx_pos, count);
56 sport->tx_pos += runtime->period_size;
57 if (sport->tx_pos >= runtime->buffer_size)
58 sport->tx_pos %= runtime->buffer_size;
59 } else {
60 bf5xx_ac97_to_pcm(
61 (struct ac97_frame *)sport->rx_dma_buf + sport->rx_pos,
62 (__u32 *)runtime->dma_area + sport->rx_pos, count);
63 sport->rx_pos += runtime->period_size;
64 if (sport->rx_pos >= runtime->buffer_size)
65 sport->rx_pos %= runtime->buffer_size;
66 }
67}
68#endif
69
70static void bf5xx_dma_irq(void *data)
71{
72 struct snd_pcm_substream *pcm = data;
73#if defined(CONFIG_SND_MMAP_SUPPORT)
74 struct snd_pcm_runtime *runtime = pcm->runtime;
75 bf5xx_mmap_copy(pcm, runtime->period_size);
76#endif
77 snd_pcm_period_elapsed(pcm);
78}
79
80/* The memory size for pure pcm data is 128*1024 = 0x20000 bytes.
81 * The total rx/tx buffer is for ac97 frame to hold all pcm data
82 * is 0x20000 * sizeof(struct ac97_frame) / 4.
83 */
84#ifdef CONFIG_SND_MMAP_SUPPORT
85static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
86 .info = SNDRV_PCM_INFO_INTERLEAVED |
87 SNDRV_PCM_INFO_MMAP |
88 SNDRV_PCM_INFO_MMAP_VALID |
89 SNDRV_PCM_INFO_BLOCK_TRANSFER,
90#else
91static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
92 .info = SNDRV_PCM_INFO_INTERLEAVED |
93 SNDRV_PCM_INFO_BLOCK_TRANSFER,
94#endif
95 .formats = SNDRV_PCM_FMTBIT_S16_LE,
96 .period_bytes_min = 32,
97 .period_bytes_max = 0x10000,
98 .periods_min = 1,
99 .periods_max = PAGE_SIZE/32,
100 .buffer_bytes_max = 0x20000, /* 128 kbytes */
101 .fifo_size = 16,
102};
103
104static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
105 struct snd_pcm_hw_params *params)
106{
107 size_t size = bf5xx_pcm_hardware.buffer_bytes_max
108 * sizeof(struct ac97_frame) / 4;
109
110 snd_pcm_lib_malloc_pages(substream, size);
111
112 return 0;
113}
114
115static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
116{
117 snd_pcm_lib_free_pages(substream);
118 return 0;
119}
120
121static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
122{
123 struct snd_pcm_runtime *runtime = substream->runtime;
124 struct sport_device *sport = runtime->private_data;
125
126 /* An intermediate buffer is introduced for implementing mmap for
127 * SPORT working in TMD mode(include AC97).
128 */
129#if defined(CONFIG_SND_MMAP_SUPPORT)
130 size_t size = bf5xx_pcm_hardware.buffer_bytes_max
131 * sizeof(struct ac97_frame) / 4;
132 /*clean up intermediate buffer*/
133 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
134 memset(sport->tx_dma_buf, 0, size);
135 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
136 sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods,
137 runtime->period_size * sizeof(struct ac97_frame));
138 } else {
139 memset(sport->rx_dma_buf, 0, size);
140 sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
141 sport_config_rx_dma(sport, sport->rx_dma_buf, runtime->periods,
142 runtime->period_size * sizeof(struct ac97_frame));
143 }
144#else
145 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
146 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
147 sport_config_tx_dma(sport, runtime->dma_area, runtime->periods,
148 runtime->period_size * sizeof(struct ac97_frame));
149 } else {
150 sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
151 sport_config_rx_dma(sport, runtime->dma_area, runtime->periods,
152 runtime->period_size * sizeof(struct ac97_frame));
153 }
154#endif
155 return 0;
156}
157
158static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
159{
160 struct snd_pcm_runtime *runtime = substream->runtime;
161 struct sport_device *sport = runtime->private_data;
162 int ret = 0;
163
164 pr_debug("%s enter\n", __func__);
165 switch (cmd) {
166 case SNDRV_PCM_TRIGGER_START:
167 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
168 sport_tx_start(sport);
169 else
170 sport_rx_start(sport);
171 break;
172 case SNDRV_PCM_TRIGGER_STOP:
173 case SNDRV_PCM_TRIGGER_SUSPEND:
174 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
175 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
176#if defined(CONFIG_SND_MMAP_SUPPORT)
177 sport->tx_pos = 0;
178#endif
179 sport_tx_stop(sport);
180 } else {
181#if defined(CONFIG_SND_MMAP_SUPPORT)
182 sport->rx_pos = 0;
183#endif
184 sport_rx_stop(sport);
185 }
186 break;
187 default:
188 ret = -EINVAL;
189 }
190 return ret;
191}
192
193static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
194{
195 struct snd_pcm_runtime *runtime = substream->runtime;
196 struct sport_device *sport = runtime->private_data;
197 unsigned int curr;
198
199#if defined(CONFIG_SND_MMAP_SUPPORT)
200 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
201 curr = sport->tx_pos;
202 else
203 curr = sport->rx_pos;
204#else
205
206 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
207 curr = sport_curr_offset_tx(sport) / sizeof(struct ac97_frame);
208 else
209 curr = sport_curr_offset_rx(sport) / sizeof(struct ac97_frame);
210
211#endif
212 return curr;
213}
214
215static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
216{
217 struct snd_pcm_runtime *runtime = substream->runtime;
218 int ret;
219
220 pr_debug("%s enter\n", __func__);
221 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
222
223 ret = snd_pcm_hw_constraint_integer(runtime,
224 SNDRV_PCM_HW_PARAM_PERIODS);
225 if (ret < 0)
226 goto out;
227
228 if (sport_handle != NULL)
229 runtime->private_data = sport_handle;
230 else {
231 pr_err("sport_handle is NULL\n");
232 return -1;
233 }
234 return 0;
235
236 out:
237 return ret;
238}
239
240#ifdef CONFIG_SND_MMAP_SUPPORT
241static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
242 struct vm_area_struct *vma)
243{
244 struct snd_pcm_runtime *runtime = substream->runtime;
245 size_t size = vma->vm_end - vma->vm_start;
246 vma->vm_start = (unsigned long)runtime->dma_area;
247 vma->vm_end = vma->vm_start + size;
248 vma->vm_flags |= VM_SHARED;
249 return 0 ;
250}
251#else
252static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
253 snd_pcm_uframes_t pos,
254 void __user *buf, snd_pcm_uframes_t count)
255{
256 struct snd_pcm_runtime *runtime = substream->runtime;
257
258 pr_debug("%s copy pos:0x%lx count:0x%lx\n",
259 substream->stream ? "Capture" : "Playback", pos, count);
260
261 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
262 bf5xx_pcm_to_ac97(
263 (struct ac97_frame *)runtime->dma_area + pos,
264 buf, count);
265 else
266 bf5xx_ac97_to_pcm(
267 (struct ac97_frame *)runtime->dma_area + pos,
268 buf, count);
269 return 0;
270}
271#endif
272
273struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
274 .open = bf5xx_pcm_open,
275 .ioctl = snd_pcm_lib_ioctl,
276 .hw_params = bf5xx_pcm_hw_params,
277 .hw_free = bf5xx_pcm_hw_free,
278 .prepare = bf5xx_pcm_prepare,
279 .trigger = bf5xx_pcm_trigger,
280 .pointer = bf5xx_pcm_pointer,
281#ifdef CONFIG_SND_MMAP_SUPPORT
282 .mmap = bf5xx_pcm_mmap,
283#else
284 .copy = bf5xx_pcm_copy,
285#endif
286};
287
288static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
289{
290 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
291 struct snd_dma_buffer *buf = &substream->dma_buffer;
292 size_t size = bf5xx_pcm_hardware.buffer_bytes_max
293 * sizeof(struct ac97_frame) / 4;
294
295 buf->dev.type = SNDRV_DMA_TYPE_DEV;
296 buf->dev.dev = pcm->card->dev;
297 buf->private_data = NULL;
298 buf->area = dma_alloc_coherent(pcm->card->dev, size,
299 &buf->addr, GFP_KERNEL);
300 if (!buf->area) {
301 pr_err("Failed to allocate dma memory\n");
302 pr_err("Please increase uncached DMA memory region\n");
303 return -ENOMEM;
304 }
305 buf->bytes = size;
306
307 pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
308 buf->area, buf->bytes);
309
310 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
311 sport_handle->tx_buf = buf->area;
312 else
313 sport_handle->rx_buf = buf->area;
314
315/*
316 * Need to allocate local buffer when enable
317 * MMAP for SPORT working in TMD mode (include AC97).
318 */
319#if defined(CONFIG_SND_MMAP_SUPPORT)
320 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
321 if (!sport_handle->tx_dma_buf) {
322 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
323 size, &sport_handle->tx_dma_phy, GFP_KERNEL);
324 if (!sport_handle->tx_dma_buf) {
325 pr_err("Failed to allocate memory for tx dma \
326 buf - Please increase uncached DMA \
327 memory region\n");
328 return -ENOMEM;
329 } else
330 memset(sport_handle->tx_dma_buf, 0, size);
331 } else
332 memset(sport_handle->tx_dma_buf, 0, size);
333 } else {
334 if (!sport_handle->rx_dma_buf) {
335 sport_handle->rx_dma_buf = dma_alloc_coherent(NULL, \
336 size, &sport_handle->rx_dma_phy, GFP_KERNEL);
337 if (!sport_handle->rx_dma_buf) {
338 pr_err("Failed to allocate memory for rx dma \
339 buf - Please increase uncached DMA \
340 memory region\n");
341 return -ENOMEM;
342 } else
343 memset(sport_handle->rx_dma_buf, 0, size);
344 } else
345 memset(sport_handle->rx_dma_buf, 0, size);
346 }
347#endif
348 return 0;
349}
350
351static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
352{
353 struct snd_pcm_substream *substream;
354 struct snd_dma_buffer *buf;
355 int stream;
356#if defined(CONFIG_SND_MMAP_SUPPORT)
357 size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
358 sizeof(struct ac97_frame) / 4;
359#endif
360 for (stream = 0; stream < 2; stream++) {
361 substream = pcm->streams[stream].substream;
362 if (!substream)
363 continue;
364
365 buf = &substream->dma_buffer;
366 if (!buf->area)
367 continue;
368 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
369 buf->area = NULL;
370#if defined(CONFIG_SND_MMAP_SUPPORT)
371 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
372 if (sport_handle->tx_dma_buf)
373 dma_free_coherent(NULL, size, \
374 sport_handle->tx_dma_buf, 0);
375 sport_handle->tx_dma_buf = NULL;
376 } else {
377
378 if (sport_handle->rx_dma_buf)
379 dma_free_coherent(NULL, size, \
380 sport_handle->rx_dma_buf, 0);
381 sport_handle->rx_dma_buf = NULL;
382 }
383#endif
384 }
385 if (sport_handle)
386 sport_done(sport_handle);
387}
388
389static u64 bf5xx_pcm_dmamask = DMA_32BIT_MASK;
390
391int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
392 struct snd_pcm *pcm)
393{
394 int ret = 0;
395
396 pr_debug("%s enter\n", __func__);
397 if (!card->dev->dma_mask)
398 card->dev->dma_mask = &bf5xx_pcm_dmamask;
399 if (!card->dev->coherent_dma_mask)
400 card->dev->coherent_dma_mask = DMA_32BIT_MASK;
401
402 if (dai->playback.channels_min) {
403 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
404 SNDRV_PCM_STREAM_PLAYBACK);
405 if (ret)
406 goto out;
407 }
408
409 if (dai->capture.channels_min) {
410 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
411 SNDRV_PCM_STREAM_CAPTURE);
412 if (ret)
413 goto out;
414 }
415 out:
416 return ret;
417}
418
419struct snd_soc_platform bf5xx_ac97_soc_platform = {
420 .name = "bf5xx-audio",
421 .pcm_ops = &bf5xx_pcm_ac97_ops,
422 .pcm_new = bf5xx_pcm_ac97_new,
423 .pcm_free = bf5xx_pcm_free_dma_buffers,
424};
425EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform);
426
427MODULE_AUTHOR("Cliff Cai");
428MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
429MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.h b/sound/soc/blackfin/bf5xx-ac97-pcm.h
new file mode 100644
index 00000000000..350125a0ae2
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.h
@@ -0,0 +1,29 @@
1/*
2 * linux/sound/arm/bf5xx-ac97-pcm.h -- ALSA PCM interface for the Blackfin
3 *
4 * Copyright 2007 Analog Device Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _BF5XX_AC97_PCM_H
12#define _BF5XX_AC97_PCM_H
13
14struct bf5xx_pcm_dma_params {
15 char *name; /* stream identifier */
16};
17
18struct bf5xx_gpio {
19 u32 sys;
20 u32 rx;
21 u32 tx;
22 u32 clk;
23 u32 frm;
24};
25
26/* platform data */
27extern struct snd_soc_platform bf5xx_ac97_soc_platform;
28
29#endif
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
new file mode 100644
index 00000000000..c782e311fd5
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -0,0 +1,407 @@
1/*
2 * bf5xx-ac97.c -- AC97 support for the ADI blackfin chip.
3 *
4 * Author: Roy Huang
5 * Created: 11th. June 2007
6 * Copyright: Analog Device Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/interrupt.h>
17#include <linux/wait.h>
18#include <linux/delay.h>
19
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/ac97_codec.h>
23#include <sound/initval.h>
24#include <sound/soc.h>
25
26#include <asm/irq.h>
27#include <asm/portmux.h>
28#include <linux/mutex.h>
29#include <linux/gpio.h>
30
31#include "bf5xx-sport.h"
32#include "bf5xx-ac97.h"
33
34#if defined(CONFIG_BF54x)
35#define PIN_REQ_SPORT_0 {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, \
36 P_SPORT0_RFS, P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0}
37
38#define PIN_REQ_SPORT_1 {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, \
39 P_SPORT1_RFS, P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0}
40
41#define PIN_REQ_SPORT_2 {P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, \
42 P_SPORT2_RFS, P_SPORT2_DRPRI, P_SPORT2_RSCLK, 0}
43
44#define PIN_REQ_SPORT_3 {P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, \
45 P_SPORT3_RFS, P_SPORT3_DRPRI, P_SPORT3_RSCLK, 0}
46#else
47#define PIN_REQ_SPORT_0 {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \
48 P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0}
49
50#define PIN_REQ_SPORT_1 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \
51 P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0}
52#endif
53
54static int *cmd_count;
55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
56
57#if defined(CONFIG_BF54x)
58static struct sport_param sport_params[4] = {
59 {
60 .dma_rx_chan = CH_SPORT0_RX,
61 .dma_tx_chan = CH_SPORT0_TX,
62 .err_irq = IRQ_SPORT0_ERR,
63 .regs = (struct sport_register *)SPORT0_TCR1,
64 },
65 {
66 .dma_rx_chan = CH_SPORT1_RX,
67 .dma_tx_chan = CH_SPORT1_TX,
68 .err_irq = IRQ_SPORT1_ERR,
69 .regs = (struct sport_register *)SPORT1_TCR1,
70 },
71 {
72 .dma_rx_chan = CH_SPORT2_RX,
73 .dma_tx_chan = CH_SPORT2_TX,
74 .err_irq = IRQ_SPORT2_ERR,
75 .regs = (struct sport_register *)SPORT2_TCR1,
76 },
77 {
78 .dma_rx_chan = CH_SPORT3_RX,
79 .dma_tx_chan = CH_SPORT3_TX,
80 .err_irq = IRQ_SPORT3_ERR,
81 .regs = (struct sport_register *)SPORT3_TCR1,
82 }
83};
84#else
85static struct sport_param sport_params[2] = {
86 {
87 .dma_rx_chan = CH_SPORT0_RX,
88 .dma_tx_chan = CH_SPORT0_TX,
89 .err_irq = IRQ_SPORT0_ERROR,
90 .regs = (struct sport_register *)SPORT0_TCR1,
91 },
92 {
93 .dma_rx_chan = CH_SPORT1_RX,
94 .dma_tx_chan = CH_SPORT1_TX,
95 .err_irq = IRQ_SPORT1_ERROR,
96 .regs = (struct sport_register *)SPORT1_TCR1,
97 }
98};
99#endif
100
101void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \
102 size_t count)
103{
104 while (count--) {
105 dst->ac97_tag = TAG_VALID | TAG_PCM;
106 (dst++)->ac97_pcm = *src++;
107 }
108}
109EXPORT_SYMBOL(bf5xx_pcm_to_ac97);
110
111void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \
112 size_t count)
113{
114 while (count--)
115 *(dst++) = (src++)->ac97_pcm;
116}
117EXPORT_SYMBOL(bf5xx_ac97_to_pcm);
118
119static unsigned int sport_tx_curr_frag(struct sport_device *sport)
120{
121 return sport->tx_curr_frag = sport_curr_offset_tx(sport) / \
122 sport->tx_fragsize;
123}
124
125static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
126{
127 struct sport_device *sport = sport_handle;
128 int nextfrag = sport_tx_curr_frag(sport);
129 struct ac97_frame *nextwrite;
130
131 sport_incfrag(sport, &nextfrag, 1);
132 sport_incfrag(sport, &nextfrag, 1);
133
134 nextwrite = (struct ac97_frame *)(sport->tx_buf + \
135 nextfrag * sport->tx_fragsize);
136 pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n",
137 sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]);
138 nextwrite[cmd_count[nextfrag]].ac97_tag |= TAG_CMD;
139 nextwrite[cmd_count[nextfrag]].ac97_addr = addr;
140 nextwrite[cmd_count[nextfrag]].ac97_data = data;
141 ++cmd_count[nextfrag];
142 pr_debug("ac97_sport: Inserting %02x/%04x into fragment %d\n",
143 addr >> 8, data, nextfrag);
144}
145
146static unsigned short bf5xx_ac97_read(struct snd_ac97 *ac97,
147 unsigned short reg)
148{
149 struct ac97_frame out_frame[2], in_frame[2];
150
151 pr_debug("%s enter 0x%x\n", __func__, reg);
152
153 /* When dma descriptor is enabled, the register should not be read */
154 if (sport_handle->tx_run || sport_handle->rx_run) {
155 pr_err("Could you send a mail to cliff.cai@analog.com "
156 "to report this?\n");
157 return -EFAULT;
158 }
159
160 memset(&out_frame, 0, 2 * sizeof(struct ac97_frame));
161 memset(&in_frame, 0, 2 * sizeof(struct ac97_frame));
162 out_frame[0].ac97_tag = TAG_VALID | TAG_CMD;
163 out_frame[0].ac97_addr = ((reg << 8) | 0x8000);
164 sport_send_and_recv(sport_handle, (unsigned char *)&out_frame,
165 (unsigned char *)&in_frame,
166 2 * sizeof(struct ac97_frame));
167 return in_frame[1].ac97_data;
168}
169
170void bf5xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
171 unsigned short val)
172{
173 pr_debug("%s enter 0x%x:0x%04x\n", __func__, reg, val);
174
175 if (sport_handle->tx_run) {
176 enqueue_cmd(ac97, (reg << 8), val); /* write */
177 enqueue_cmd(ac97, (reg << 8) | 0x8000, 0); /* read back */
178 } else {
179 struct ac97_frame frame;
180 memset(&frame, 0, sizeof(struct ac97_frame));
181 frame.ac97_tag = TAG_VALID | TAG_CMD;
182 frame.ac97_addr = (reg << 8);
183 frame.ac97_data = val;
184 sport_send_and_recv(sport_handle, (unsigned char *)&frame, \
185 NULL, sizeof(struct ac97_frame));
186 }
187}
188
189static void bf5xx_ac97_warm_reset(struct snd_ac97 *ac97)
190{
191#if defined(CONFIG_BF54x) || defined(CONFIG_BF561) || \
192 (defined(BF537_FAMILY) && (CONFIG_SND_BF5XX_SPORT_NUM == 1))
193
194#define CONCAT(a, b, c) a ## b ## c
195#define BFIN_SPORT_RFS(x) CONCAT(P_SPORT, x, _RFS)
196
197 u16 per = BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM);
198 u16 gpio = P_IDENT(BFIN_SPORT_RFS(CONFIG_SND_BF5XX_SPORT_NUM));
199
200 pr_debug("%s enter\n", __func__);
201
202 peripheral_free(per);
203 gpio_request(gpio, "bf5xx-ac97");
204 gpio_direction_output(gpio, 1);
205 udelay(2);
206 gpio_set_value(gpio, 0);
207 udelay(1);
208 gpio_free(gpio);
209 peripheral_request(per, "soc-audio");
210#else
211 pr_info("%s: Not implemented\n", __func__);
212#endif
213}
214
215static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
216{
217#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
218 pr_debug("%s enter\n", __func__);
219
220 /* It is specified for bf548-ezkit */
221 gpio_set_value(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 0);
222 /* Keep reset pin low for 1 ms */
223 mdelay(1);
224 gpio_set_value(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
225 /* Wait for bit clock recover */
226 mdelay(1);
227#else
228 pr_info("%s: Not implemented\n", __func__);
229#endif
230}
231
232struct snd_ac97_bus_ops soc_ac97_ops = {
233 .read = bf5xx_ac97_read,
234 .write = bf5xx_ac97_write,
235 .warm_reset = bf5xx_ac97_warm_reset,
236 .reset = bf5xx_ac97_cold_reset,
237};
238EXPORT_SYMBOL_GPL(soc_ac97_ops);
239
240#ifdef CONFIG_PM
241static int bf5xx_ac97_suspend(struct platform_device *pdev,
242 struct snd_soc_dai *dai)
243{
244 struct sport_device *sport =
245 (struct sport_device *)dai->private_data;
246
247 pr_debug("%s : sport %d\n", __func__, dai->id);
248 if (!dai->active)
249 return 0;
250 if (dai->capture.active)
251 sport_rx_stop(sport);
252 if (dai->playback.active)
253 sport_tx_stop(sport);
254 return 0;
255}
256
257static int bf5xx_ac97_resume(struct platform_device *pdev,
258 struct snd_soc_dai *dai)
259{
260 int ret;
261 struct sport_device *sport =
262 (struct sport_device *)dai->private_data;
263
264 pr_debug("%s : sport %d\n", __func__, dai->id);
265 if (!dai->active)
266 return 0;
267
268 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
269 if (ret) {
270 pr_err("SPORT is busy!\n");
271 return -EBUSY;
272 }
273
274 ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
275 if (ret) {
276 pr_err("SPORT is busy!\n");
277 return -EBUSY;
278 }
279
280 ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
281 if (ret) {
282 pr_err("SPORT is busy!\n");
283 return -EBUSY;
284 }
285
286 if (dai->capture.active)
287 sport_rx_start(sport);
288 if (dai->playback.active)
289 sport_tx_start(sport);
290 return 0;
291}
292
293#else
294#define bf5xx_ac97_suspend NULL
295#define bf5xx_ac97_resume NULL
296#endif
297
298static int bf5xx_ac97_probe(struct platform_device *pdev,
299 struct snd_soc_dai *dai)
300{
301 int ret;
302#if defined(CONFIG_BF54x)
303 u16 sport_req[][7] = {PIN_REQ_SPORT_0, PIN_REQ_SPORT_1,
304 PIN_REQ_SPORT_2, PIN_REQ_SPORT_3};
305#else
306 u16 sport_req[][7] = {PIN_REQ_SPORT_0, PIN_REQ_SPORT_1};
307#endif
308 cmd_count = (int *)get_zeroed_page(GFP_KERNEL);
309 if (cmd_count == NULL)
310 return -ENOMEM;
311
312 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
313 pr_err("Requesting Peripherals failed\n");
314 return -EFAULT;
315 }
316
317#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
318 /* Request PB3 as reset pin */
319 if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) {
320 pr_err("Failed to request GPIO_%d for reset\n",
321 CONFIG_SND_BF5XX_RESET_GPIO_NUM);
322 peripheral_free_list(&sport_req[sport_num][0]);
323 return -1;
324 }
325 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
326#endif
327 sport_handle = sport_init(&sport_params[sport_num], 2, \
328 sizeof(struct ac97_frame), NULL);
329 if (!sport_handle) {
330 peripheral_free_list(&sport_req[sport_num][0]);
331#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
332 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
333#endif
334 return -ENODEV;
335 }
336 /*SPORT works in TDM mode to simulate AC97 transfers*/
337 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
338 if (ret) {
339 pr_err("SPORT is busy!\n");
340 kfree(sport_handle);
341 peripheral_free_list(&sport_req[sport_num][0]);
342#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
343 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
344#endif
345 return -EBUSY;
346 }
347
348 ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
349 if (ret) {
350 pr_err("SPORT is busy!\n");
351 kfree(sport_handle);
352 peripheral_free_list(&sport_req[sport_num][0]);
353#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
354 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
355#endif
356 return -EBUSY;
357 }
358
359 ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
360 if (ret) {
361 pr_err("SPORT is busy!\n");
362 kfree(sport_handle);
363 peripheral_free_list(&sport_req[sport_num][0]);
364#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
365 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
366#endif
367 return -EBUSY;
368 }
369 return 0;
370}
371
372static void bf5xx_ac97_remove(struct platform_device *pdev,
373 struct snd_soc_dai *dai)
374{
375 free_page((unsigned long)cmd_count);
376 cmd_count = NULL;
377#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
378 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
379#endif
380}
381
382struct snd_soc_dai bfin_ac97_dai = {
383 .name = "bf5xx-ac97",
384 .id = 0,
385 .type = SND_SOC_DAI_AC97,
386 .probe = bf5xx_ac97_probe,
387 .remove = bf5xx_ac97_remove,
388 .suspend = bf5xx_ac97_suspend,
389 .resume = bf5xx_ac97_resume,
390 .playback = {
391 .stream_name = "AC97 Playback",
392 .channels_min = 2,
393 .channels_max = 2,
394 .rates = SNDRV_PCM_RATE_48000,
395 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
396 .capture = {
397 .stream_name = "AC97 Capture",
398 .channels_min = 2,
399 .channels_max = 2,
400 .rates = SNDRV_PCM_RATE_48000,
401 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
402};
403EXPORT_SYMBOL_GPL(bfin_ac97_dai);
404
405MODULE_AUTHOR("Roy Huang");
406MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
407MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.h b/sound/soc/blackfin/bf5xx-ac97.h
new file mode 100644
index 00000000000..3f77cc558dc
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ac97.h
@@ -0,0 +1,36 @@
1/*
2 * linux/sound/arm/bf5xx-ac97.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _BF5XX_AC97_H
10#define _BF5XX_AC97_H
11
12extern struct snd_ac97_bus_ops bf5xx_ac97_ops;
13extern struct snd_ac97 *ac97;
14/* Frame format in memory, only support stereo currently */
15struct ac97_frame {
16 u16 ac97_tag; /* slot 0 */
17 u16 ac97_addr; /* slot 1 */
18 u16 ac97_data; /* slot 2 */
19 u32 ac97_pcm; /* slot 3 and 4: left and right pcm data */
20} __attribute__ ((packed));
21
22#define TAG_VALID 0x8000
23#define TAG_CMD 0x6000
24#define TAG_PCM_LEFT 0x1000
25#define TAG_PCM_RIGHT 0x0800
26#define TAG_PCM (TAG_PCM_LEFT | TAG_PCM_RIGHT)
27
28extern struct snd_soc_dai bfin_ac97_dai;
29
30void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \
31 size_t count);
32
33void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \
34 size_t count);
35
36#endif
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
new file mode 100644
index 00000000000..124425d2232
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -0,0 +1,113 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-ad1980.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: Board driver for AD1980/1 audio codec
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/device.h>
32#include <asm/dma.h>
33
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/soc.h>
37
38#include <linux/gpio.h>
39#include <asm/portmux.h>
40
41#include "../codecs/ad1980.h"
42#include "bf5xx-sport.h"
43#include "bf5xx-ac97-pcm.h"
44#include "bf5xx-ac97.h"
45
46static struct snd_soc_machine bf5xx_board;
47
48static int bf5xx_board_startup(struct snd_pcm_substream *substream)
49{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
52
53 pr_debug("%s enter\n", __func__);
54 cpu_dai->private_data = sport_handle;
55 return 0;
56}
57
58static struct snd_soc_ops bf5xx_board_ops = {
59 .startup = bf5xx_board_startup,
60};
61
62static struct snd_soc_dai_link bf5xx_board_dai = {
63 .name = "AC97",
64 .stream_name = "AC97 HiFi",
65 .cpu_dai = &bfin_ac97_dai,
66 .codec_dai = &ad1980_dai,
67 .ops = &bf5xx_board_ops,
68};
69
70static struct snd_soc_machine bf5xx_board = {
71 .name = "bf5xx-board",
72 .dai_link = &bf5xx_board_dai,
73 .num_links = 1,
74};
75
76static struct snd_soc_device bf5xx_board_snd_devdata = {
77 .machine = &bf5xx_board,
78 .platform = &bf5xx_ac97_soc_platform,
79 .codec_dev = &soc_codec_dev_ad1980,
80};
81
82static struct platform_device *bf5xx_board_snd_device;
83
84static int __init bf5xx_board_init(void)
85{
86 int ret;
87
88 bf5xx_board_snd_device = platform_device_alloc("soc-audio", -1);
89 if (!bf5xx_board_snd_device)
90 return -ENOMEM;
91
92 platform_set_drvdata(bf5xx_board_snd_device, &bf5xx_board_snd_devdata);
93 bf5xx_board_snd_devdata.dev = &bf5xx_board_snd_device->dev;
94 ret = platform_device_add(bf5xx_board_snd_device);
95
96 if (ret)
97 platform_device_put(bf5xx_board_snd_device);
98
99 return ret;
100}
101
102static void __exit bf5xx_board_exit(void)
103{
104 platform_device_unregister(bf5xx_board_snd_device);
105}
106
107module_init(bf5xx_board_init);
108module_exit(bf5xx_board_exit);
109
110/* Module information */
111MODULE_AUTHOR("Cliff Cai");
112MODULE_DESCRIPTION("ALSA SoC AD1980/1 BF5xx board");
113MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
new file mode 100644
index 00000000000..61fccf92519
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -0,0 +1,288 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-i2s-pcm.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: DMA driver for i2s codec
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/platform_device.h>
32#include <linux/slab.h>
33#include <linux/dma-mapping.h>
34
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39
40#include <asm/dma.h>
41
42#include "bf5xx-i2s-pcm.h"
43#include "bf5xx-i2s.h"
44#include "bf5xx-sport.h"
45
46static void bf5xx_dma_irq(void *data)
47{
48 struct snd_pcm_substream *pcm = data;
49 snd_pcm_period_elapsed(pcm);
50}
51
52static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
53 .info = SNDRV_PCM_INFO_INTERLEAVED |
54 SNDRV_PCM_INFO_MMAP |
55 SNDRV_PCM_INFO_MMAP_VALID |
56 SNDRV_PCM_INFO_BLOCK_TRANSFER,
57 .formats = SNDRV_PCM_FMTBIT_S16_LE |
58 SNDRV_PCM_FMTBIT_S24_LE |
59 SNDRV_PCM_FMTBIT_S32_LE,
60 .period_bytes_min = 32,
61 .period_bytes_max = 0x10000,
62 .periods_min = 1,
63 .periods_max = PAGE_SIZE/32,
64 .buffer_bytes_max = 0x20000, /* 128 kbytes */
65 .fifo_size = 16,
66};
67
68static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
69 struct snd_pcm_hw_params *params)
70{
71 size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
72 snd_pcm_lib_malloc_pages(substream, size);
73
74 return 0;
75}
76
77static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
78{
79 snd_pcm_lib_free_pages(substream);
80
81 return 0;
82}
83
84static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
85{
86 struct snd_pcm_runtime *runtime = substream->runtime;
87 struct sport_device *sport = runtime->private_data;
88 int period_bytes = frames_to_bytes(runtime, runtime->period_size);
89
90 pr_debug("%s enter\n", __func__);
91 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
92 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
93 sport_config_tx_dma(sport, runtime->dma_area,
94 runtime->periods, period_bytes);
95 } else {
96 sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
97 sport_config_rx_dma(sport, runtime->dma_area,
98 runtime->periods, period_bytes);
99 }
100
101 return 0;
102}
103
104static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
105{
106 struct snd_pcm_runtime *runtime = substream->runtime;
107 struct sport_device *sport = runtime->private_data;
108 int ret = 0;
109
110 pr_debug("%s enter\n", __func__);
111 switch (cmd) {
112 case SNDRV_PCM_TRIGGER_START:
113 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
114 sport_tx_start(sport);
115 else
116 sport_rx_start(sport);
117 break;
118 case SNDRV_PCM_TRIGGER_STOP:
119 case SNDRV_PCM_TRIGGER_SUSPEND:
120 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
121 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
122 sport_tx_stop(sport);
123 else
124 sport_rx_stop(sport);
125 break;
126 default:
127 ret = -EINVAL;
128 }
129
130 return ret;
131}
132
133static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
134{
135 struct snd_pcm_runtime *runtime = substream->runtime;
136 struct sport_device *sport = runtime->private_data;
137 unsigned int diff;
138 snd_pcm_uframes_t frames;
139 pr_debug("%s enter\n", __func__);
140 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
141 diff = sport_curr_offset_tx(sport);
142 frames = bytes_to_frames(substream->runtime, diff);
143 } else {
144 diff = sport_curr_offset_rx(sport);
145 frames = bytes_to_frames(substream->runtime, diff);
146 }
147 return frames;
148}
149
150static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
151{
152 struct snd_pcm_runtime *runtime = substream->runtime;
153 int ret;
154
155 pr_debug("%s enter\n", __func__);
156 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
157
158 ret = snd_pcm_hw_constraint_integer(runtime, \
159 SNDRV_PCM_HW_PARAM_PERIODS);
160 if (ret < 0)
161 goto out;
162
163 if (sport_handle != NULL)
164 runtime->private_data = sport_handle;
165 else {
166 pr_err("sport_handle is NULL\n");
167 return -1;
168 }
169 return 0;
170
171 out:
172 return ret;
173}
174
175static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
176 struct vm_area_struct *vma)
177{
178 struct snd_pcm_runtime *runtime = substream->runtime;
179 size_t size = vma->vm_end - vma->vm_start;
180 vma->vm_start = (unsigned long)runtime->dma_area;
181 vma->vm_end = vma->vm_start + size;
182 vma->vm_flags |= VM_SHARED;
183
184 return 0 ;
185}
186
187struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
188 .open = bf5xx_pcm_open,
189 .ioctl = snd_pcm_lib_ioctl,
190 .hw_params = bf5xx_pcm_hw_params,
191 .hw_free = bf5xx_pcm_hw_free,
192 .prepare = bf5xx_pcm_prepare,
193 .trigger = bf5xx_pcm_trigger,
194 .pointer = bf5xx_pcm_pointer,
195 .mmap = bf5xx_pcm_mmap,
196};
197
198static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
199{
200 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
201 struct snd_dma_buffer *buf = &substream->dma_buffer;
202 size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
203
204 buf->dev.type = SNDRV_DMA_TYPE_DEV;
205 buf->dev.dev = pcm->card->dev;
206 buf->private_data = NULL;
207 buf->area = dma_alloc_coherent(pcm->card->dev, size,
208 &buf->addr, GFP_KERNEL);
209 if (!buf->area) {
210 pr_err("Failed to allocate dma memory \
211 Please increase uncached DMA memory region\n");
212 return -ENOMEM;
213 }
214 buf->bytes = size;
215
216 pr_debug("%s, area:%p, size:0x%08lx\n", __func__,
217 buf->area, buf->bytes);
218
219 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
220 sport_handle->tx_buf = buf->area;
221 else
222 sport_handle->rx_buf = buf->area;
223
224 return 0;
225}
226
227static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
228{
229 struct snd_pcm_substream *substream;
230 struct snd_dma_buffer *buf;
231 int stream;
232
233 for (stream = 0; stream < 2; stream++) {
234 substream = pcm->streams[stream].substream;
235 if (!substream)
236 continue;
237
238 buf = &substream->dma_buffer;
239 if (!buf->area)
240 continue;
241 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
242 buf->area = NULL;
243 }
244 if (sport_handle)
245 sport_done(sport_handle);
246}
247
248static u64 bf5xx_pcm_dmamask = DMA_32BIT_MASK;
249
250int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
251 struct snd_pcm *pcm)
252{
253 int ret = 0;
254
255 pr_debug("%s enter\n", __func__);
256 if (!card->dev->dma_mask)
257 card->dev->dma_mask = &bf5xx_pcm_dmamask;
258 if (!card->dev->coherent_dma_mask)
259 card->dev->coherent_dma_mask = DMA_32BIT_MASK;
260
261 if (dai->playback.channels_min) {
262 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
263 SNDRV_PCM_STREAM_PLAYBACK);
264 if (ret)
265 goto out;
266 }
267
268 if (dai->capture.channels_min) {
269 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
270 SNDRV_PCM_STREAM_CAPTURE);
271 if (ret)
272 goto out;
273 }
274 out:
275 return ret;
276}
277
278struct snd_soc_platform bf5xx_i2s_soc_platform = {
279 .name = "bf5xx-audio",
280 .pcm_ops = &bf5xx_pcm_i2s_ops,
281 .pcm_new = bf5xx_pcm_i2s_new,
282 .pcm_free = bf5xx_pcm_free_dma_buffers,
283};
284EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform);
285
286MODULE_AUTHOR("Cliff Cai");
287MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
288MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.h b/sound/soc/blackfin/bf5xx-i2s-pcm.h
new file mode 100644
index 00000000000..4d4609a97c5
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.h
@@ -0,0 +1,29 @@
1/*
2 * linux/sound/arm/bf5xx-i2s-pcm.h -- ALSA PCM interface for the Blackfin
3 *
4 * Copyright 2007 Analog Device Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _BF5XX_I2S_PCM_H
12#define _BF5XX_I2S_PCM_H
13
14struct bf5xx_pcm_dma_params {
15 char *name; /* stream identifier */
16};
17
18struct bf5xx_gpio {
19 u32 sys;
20 u32 rx;
21 u32 tx;
22 u32 clk;
23 u32 frm;
24};
25
26/* platform data */
27extern struct snd_soc_platform bf5xx_i2s_soc_platform;
28
29#endif
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
new file mode 100644
index 00000000000..43a4092eeb8
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -0,0 +1,292 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-i2s.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: Blackfin I2S CPU DAI driver
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/device.h>
32#include <linux/delay.h>
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/initval.h>
37#include <sound/soc.h>
38
39#include <asm/irq.h>
40#include <asm/portmux.h>
41#include <linux/mutex.h>
42#include <linux/gpio.h>
43
44#include "bf5xx-sport.h"
45#include "bf5xx-i2s.h"
46
47struct bf5xx_i2s_port {
48 u16 tcr1;
49 u16 rcr1;
50 u16 tcr2;
51 u16 rcr2;
52 int counter;
53};
54
55static struct bf5xx_i2s_port bf5xx_i2s;
56static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
57
58static struct sport_param sport_params[2] = {
59 {
60 .dma_rx_chan = CH_SPORT0_RX,
61 .dma_tx_chan = CH_SPORT0_TX,
62 .err_irq = IRQ_SPORT0_ERROR,
63 .regs = (struct sport_register *)SPORT0_TCR1,
64 },
65 {
66 .dma_rx_chan = CH_SPORT1_RX,
67 .dma_tx_chan = CH_SPORT1_TX,
68 .err_irq = IRQ_SPORT1_ERROR,
69 .regs = (struct sport_register *)SPORT1_TCR1,
70 }
71};
72
73static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
74 unsigned int fmt)
75{
76 int ret = 0;
77
78 /* interface format:support I2S,slave mode */
79 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
80 case SND_SOC_DAIFMT_I2S:
81 break;
82 case SND_SOC_DAIFMT_LEFT_J:
83 ret = -EINVAL;
84 break;
85 default:
86 ret = -EINVAL;
87 break;
88 }
89
90 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
91 case SND_SOC_DAIFMT_CBS_CFS:
92 ret = -EINVAL;
93 break;
94 case SND_SOC_DAIFMT_CBM_CFS:
95 ret = -EINVAL;
96 break;
97 case SND_SOC_DAIFMT_CBM_CFM:
98 break;
99 case SND_SOC_DAIFMT_CBS_CFM:
100 ret = -EINVAL;
101 break;
102 default:
103 ret = -EINVAL;
104 break;
105 }
106
107 return ret;
108}
109
110static int bf5xx_i2s_startup(struct snd_pcm_substream *substream)
111{
112 pr_debug("%s enter\n", __func__);
113
114 /*this counter is used for counting how many pcm streams are opened*/
115 bf5xx_i2s.counter++;
116 return 0;
117}
118
119static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
120 struct snd_pcm_hw_params *params)
121{
122 int ret = 0;
123
124 bf5xx_i2s.tcr2 &= ~0x1f;
125 bf5xx_i2s.rcr2 &= ~0x1f;
126 switch (params_format(params)) {
127 case SNDRV_PCM_FORMAT_S16_LE:
128 bf5xx_i2s.tcr2 |= 15;
129 bf5xx_i2s.rcr2 |= 15;
130 break;
131 case SNDRV_PCM_FORMAT_S24_LE:
132 bf5xx_i2s.tcr2 |= 23;
133 bf5xx_i2s.rcr2 |= 23;
134 break;
135 case SNDRV_PCM_FORMAT_S32_LE:
136 bf5xx_i2s.tcr2 |= 31;
137 bf5xx_i2s.rcr2 |= 31;
138 break;
139 }
140
141 if (bf5xx_i2s.counter == 1) {
142 /*
143 * TX and RX are not independent,they are enabled at the
144 * same time, even if only one side is running. So, we
145 * need to configure both of them at the time when the first
146 * stream is opened.
147 *
148 * CPU DAI format:I2S, slave mode.
149 */
150 ret = sport_config_rx(sport_handle, RFSR | RCKFE,
151 RSFSE|bf5xx_i2s.rcr2, 0, 0);
152 if (ret) {
153 pr_err("SPORT is busy!\n");
154 return -EBUSY;
155 }
156
157 ret = sport_config_tx(sport_handle, TFSR | TCKFE,
158 TSFSE|bf5xx_i2s.tcr2, 0, 0);
159 if (ret) {
160 pr_err("SPORT is busy!\n");
161 return -EBUSY;
162 }
163 }
164
165 return 0;
166}
167
168static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream)
169{
170 pr_debug("%s enter\n", __func__);
171 bf5xx_i2s.counter--;
172}
173
174static int bf5xx_i2s_probe(struct platform_device *pdev,
175 struct snd_soc_dai *dai)
176{
177 u16 sport_req[][7] = {
178 { P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
179 P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0},
180 { P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
181 P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0},
182 };
183
184 pr_debug("%s enter\n", __func__);
185 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
186 pr_err("Requesting Peripherals failed\n");
187 return -EFAULT;
188 }
189
190 /* request DMA for SPORT */
191 sport_handle = sport_init(&sport_params[sport_num], 4, \
192 2 * sizeof(u32), NULL);
193 if (!sport_handle) {
194 peripheral_free_list(&sport_req[sport_num][0]);
195 return -ENODEV;
196 }
197
198 return 0;
199}
200
201#ifdef CONFIG_PM
202static int bf5xx_i2s_suspend(struct platform_device *dev,
203 struct snd_soc_dai *dai)
204{
205 struct sport_device *sport =
206 (struct sport_device *)dai->private_data;
207
208 pr_debug("%s : sport %d\n", __func__, dai->id);
209 if (!dai->active)
210 return 0;
211 if (dai->capture.active)
212 sport_rx_stop(sport);
213 if (dai->playback.active)
214 sport_tx_stop(sport);
215 return 0;
216}
217
218static int bf5xx_i2s_resume(struct platform_device *pdev,
219 struct snd_soc_dai *dai)
220{
221 int ret;
222 struct sport_device *sport =
223 (struct sport_device *)dai->private_data;
224
225 pr_debug("%s : sport %d\n", __func__, dai->id);
226 if (!dai->active)
227 return 0;
228
229 ret = sport_config_rx(sport_handle, RFSR | RCKFE, RSFSE|0x1f, 0, 0);
230 if (ret) {
231 pr_err("SPORT is busy!\n");
232 return -EBUSY;
233 }
234
235 ret = sport_config_tx(sport_handle, TFSR | TCKFE, TSFSE|0x1f, 0, 0);
236 if (ret) {
237 pr_err("SPORT is busy!\n");
238 return -EBUSY;
239 }
240
241 if (dai->capture.active)
242 sport_rx_start(sport);
243 if (dai->playback.active)
244 sport_tx_start(sport);
245 return 0;
246}
247
248#else
249#define bf5xx_i2s_suspend NULL
250#define bf5xx_i2s_resume NULL
251#endif
252
253#define BF5XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
254 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
255 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
256 SNDRV_PCM_RATE_96000)
257
258#define BF5XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\
259 SNDRV_PCM_FMTBIT_S32_LE)
260
261struct snd_soc_dai bf5xx_i2s_dai = {
262 .name = "bf5xx-i2s",
263 .id = 0,
264 .type = SND_SOC_DAI_I2S,
265 .probe = bf5xx_i2s_probe,
266 .suspend = bf5xx_i2s_suspend,
267 .resume = bf5xx_i2s_resume,
268 .playback = {
269 .channels_min = 2,
270 .channels_max = 2,
271 .rates = BF5XX_I2S_RATES,
272 .formats = BF5XX_I2S_FORMATS,},
273 .capture = {
274 .channels_min = 2,
275 .channels_max = 2,
276 .rates = BF5XX_I2S_RATES,
277 .formats = BF5XX_I2S_FORMATS,},
278 .ops = {
279 .startup = bf5xx_i2s_startup,
280 .shutdown = bf5xx_i2s_shutdown,
281 .hw_params = bf5xx_i2s_hw_params,},
282 .dai_ops = {
283 .set_fmt = bf5xx_i2s_set_dai_fmt,
284 },
285};
286EXPORT_SYMBOL_GPL(bf5xx_i2s_dai);
287
288/* Module information */
289MODULE_AUTHOR("Cliff Cai");
290MODULE_DESCRIPTION("I2S driver for ADI Blackfin");
291MODULE_LICENSE("GPL");
292
diff --git a/sound/soc/blackfin/bf5xx-i2s.h b/sound/soc/blackfin/bf5xx-i2s.h
new file mode 100644
index 00000000000..7107d1a0b06
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-i2s.h
@@ -0,0 +1,14 @@
1/*
2 * linux/sound/arm/bf5xx-i2s.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _BF5XX_I2S_H
10#define _BF5XX_I2S_H
11
12extern struct snd_soc_dai bf5xx_i2s_dai;
13
14#endif
diff --git a/sound/soc/blackfin/bf5xx-sport.c b/sound/soc/blackfin/bf5xx-sport.c
new file mode 100644
index 00000000000..3b99e484d55
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-sport.c
@@ -0,0 +1,1032 @@
1/*
2 * File: bf5xx_sport.c
3 * Based on:
4 * Author: Roy Huang <roy.huang@analog.com>
5 *
6 * Created: Tue Sep 21 10:52:42 CEST 2004
7 * Description:
8 * Blackfin SPORT Driver
9 *
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/kernel.h>
31#include <linux/slab.h>
32#include <linux/delay.h>
33#include <linux/dma-mapping.h>
34#include <linux/gpio.h>
35#include <linux/bug.h>
36#include <asm/portmux.h>
37#include <asm/dma.h>
38#include <asm/blackfin.h>
39#include <asm/cacheflush.h>
40
41#include "bf5xx-sport.h"
42/* delay between frame sync pulse and first data bit in multichannel mode */
43#define FRAME_DELAY (1<<12)
44
45struct sport_device *sport_handle;
46EXPORT_SYMBOL(sport_handle);
47/* note: multichannel is in units of 8 channels,
48 * tdm_count is # channels NOT / 8 ! */
49int sport_set_multichannel(struct sport_device *sport,
50 int tdm_count, u32 mask, int packed)
51{
52 pr_debug("%s tdm_count=%d mask:0x%08x packed=%d\n", __func__,
53 tdm_count, mask, packed);
54
55 if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
56 return -EBUSY;
57
58 if (tdm_count & 0x7)
59 return -EINVAL;
60
61 if (tdm_count > 32)
62 return -EINVAL; /* Only support less than 32 channels now */
63
64 if (tdm_count) {
65 sport->regs->mcmc1 = ((tdm_count>>3)-1) << 12;
66 sport->regs->mcmc2 = FRAME_DELAY | MCMEN | \
67 (packed ? (MCDTXPE|MCDRXPE) : 0);
68
69 sport->regs->mtcs0 = mask;
70 sport->regs->mrcs0 = mask;
71 sport->regs->mtcs1 = 0;
72 sport->regs->mrcs1 = 0;
73 sport->regs->mtcs2 = 0;
74 sport->regs->mrcs2 = 0;
75 sport->regs->mtcs3 = 0;
76 sport->regs->mrcs3 = 0;
77 } else {
78 sport->regs->mcmc1 = 0;
79 sport->regs->mcmc2 = 0;
80
81 sport->regs->mtcs0 = 0;
82 sport->regs->mrcs0 = 0;
83 }
84
85 sport->regs->mtcs1 = 0; sport->regs->mtcs2 = 0; sport->regs->mtcs3 = 0;
86 sport->regs->mrcs1 = 0; sport->regs->mrcs2 = 0; sport->regs->mrcs3 = 0;
87
88 SSYNC();
89
90 return 0;
91}
92EXPORT_SYMBOL(sport_set_multichannel);
93
94int sport_config_rx(struct sport_device *sport, unsigned int rcr1,
95 unsigned int rcr2, unsigned int clkdiv, unsigned int fsdiv)
96{
97 if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
98 return -EBUSY;
99
100 sport->regs->rcr1 = rcr1;
101 sport->regs->rcr2 = rcr2;
102 sport->regs->rclkdiv = clkdiv;
103 sport->regs->rfsdiv = fsdiv;
104
105 SSYNC();
106
107 return 0;
108}
109EXPORT_SYMBOL(sport_config_rx);
110
111int sport_config_tx(struct sport_device *sport, unsigned int tcr1,
112 unsigned int tcr2, unsigned int clkdiv, unsigned int fsdiv)
113{
114 if ((sport->regs->tcr1 & TSPEN) || (sport->regs->rcr1 & RSPEN))
115 return -EBUSY;
116
117 sport->regs->tcr1 = tcr1;
118 sport->regs->tcr2 = tcr2;
119 sport->regs->tclkdiv = clkdiv;
120 sport->regs->tfsdiv = fsdiv;
121
122 SSYNC();
123
124 return 0;
125}
126EXPORT_SYMBOL(sport_config_tx);
127
128static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
129 size_t fragsize, unsigned int cfg,
130 unsigned int x_count, unsigned int ycount, size_t wdsize)
131{
132
133 int i;
134
135 for (i = 0; i < fragcount; ++i) {
136 desc[i].next_desc_addr = (unsigned long)&(desc[i + 1]);
137 desc[i].start_addr = (unsigned long)buf + i*fragsize;
138 desc[i].cfg = cfg;
139 desc[i].x_count = x_count;
140 desc[i].x_modify = wdsize;
141 desc[i].y_count = ycount;
142 desc[i].y_modify = wdsize;
143 }
144
145 /* make circular */
146 desc[fragcount-1].next_desc_addr = (unsigned long)desc;
147
148 pr_debug("setup desc: desc0=%p, next0=%lx, desc1=%p,"
149 "next1=%lx\nx_count=%x,y_count=%x,addr=0x%lx,cfs=0x%x\n",
150 &(desc[0]), desc[0].next_desc_addr,
151 &(desc[1]), desc[1].next_desc_addr,
152 desc[0].x_count, desc[0].y_count,
153 desc[0].start_addr, desc[0].cfg);
154}
155
156static int sport_start(struct sport_device *sport)
157{
158 enable_dma(sport->dma_rx_chan);
159 enable_dma(sport->dma_tx_chan);
160 sport->regs->rcr1 |= RSPEN;
161 sport->regs->tcr1 |= TSPEN;
162 SSYNC();
163
164 return 0;
165}
166
167static int sport_stop(struct sport_device *sport)
168{
169 sport->regs->tcr1 &= ~TSPEN;
170 sport->regs->rcr1 &= ~RSPEN;
171 SSYNC();
172
173 disable_dma(sport->dma_rx_chan);
174 disable_dma(sport->dma_tx_chan);
175 return 0;
176}
177
178static inline int sport_hook_rx_dummy(struct sport_device *sport)
179{
180 struct dmasg *desc, temp_desc;
181 unsigned long flags;
182
183 BUG_ON(sport->dummy_rx_desc == NULL);
184 BUG_ON(sport->curr_rx_desc == sport->dummy_rx_desc);
185
186 /* Maybe the dummy buffer descriptor ring is damaged */
187 sport->dummy_rx_desc->next_desc_addr = \
188 (unsigned long)(sport->dummy_rx_desc+1);
189
190 local_irq_save(flags);
191 desc = (struct dmasg *)get_dma_next_desc_ptr(sport->dma_rx_chan);
192 /* Copy the descriptor which will be damaged to backup */
193 temp_desc = *desc;
194 desc->x_count = 0xa;
195 desc->y_count = 0;
196 desc->next_desc_addr = (unsigned long)(sport->dummy_rx_desc);
197 local_irq_restore(flags);
198 /* Waiting for dummy buffer descriptor is already hooked*/
199 while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
200 sizeof(struct dmasg)) !=
201 (unsigned long)sport->dummy_rx_desc)
202 ;
203 sport->curr_rx_desc = sport->dummy_rx_desc;
204 /* Restore the damaged descriptor */
205 *desc = temp_desc;
206
207 return 0;
208}
209
210static inline int sport_rx_dma_start(struct sport_device *sport, int dummy)
211{
212 if (dummy) {
213 sport->dummy_rx_desc->next_desc_addr = \
214 (unsigned long) sport->dummy_rx_desc;
215 sport->curr_rx_desc = sport->dummy_rx_desc;
216 } else
217 sport->curr_rx_desc = sport->dma_rx_desc;
218
219 set_dma_next_desc_addr(sport->dma_rx_chan, \
220 (unsigned long)(sport->curr_rx_desc));
221 set_dma_x_count(sport->dma_rx_chan, 0);
222 set_dma_x_modify(sport->dma_rx_chan, 0);
223 set_dma_config(sport->dma_rx_chan, (DMAFLOW_LARGE | NDSIZE_9 | \
224 WDSIZE_32 | WNR));
225 set_dma_curr_addr(sport->dma_rx_chan, sport->curr_rx_desc->start_addr);
226 SSYNC();
227
228 return 0;
229}
230
231static inline int sport_tx_dma_start(struct sport_device *sport, int dummy)
232{
233 if (dummy) {
234 sport->dummy_tx_desc->next_desc_addr = \
235 (unsigned long) sport->dummy_tx_desc;
236 sport->curr_tx_desc = sport->dummy_tx_desc;
237 } else
238 sport->curr_tx_desc = sport->dma_tx_desc;
239
240 set_dma_next_desc_addr(sport->dma_tx_chan, \
241 (unsigned long)(sport->curr_tx_desc));
242 set_dma_x_count(sport->dma_tx_chan, 0);
243 set_dma_x_modify(sport->dma_tx_chan, 0);
244 set_dma_config(sport->dma_tx_chan,
245 (DMAFLOW_LARGE | NDSIZE_9 | WDSIZE_32));
246 set_dma_curr_addr(sport->dma_tx_chan, sport->curr_tx_desc->start_addr);
247 SSYNC();
248
249 return 0;
250}
251
252int sport_rx_start(struct sport_device *sport)
253{
254 unsigned long flags;
255 pr_debug("%s enter\n", __func__);
256 if (sport->rx_run)
257 return -EBUSY;
258 if (sport->tx_run) {
259 /* tx is running, rx is not running */
260 BUG_ON(sport->dma_rx_desc == NULL);
261 BUG_ON(sport->curr_rx_desc != sport->dummy_rx_desc);
262 local_irq_save(flags);
263 while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) -
264 sizeof(struct dmasg)) !=
265 (unsigned long)sport->dummy_rx_desc)
266 ;
267 sport->dummy_rx_desc->next_desc_addr =
268 (unsigned long)(sport->dma_rx_desc);
269 local_irq_restore(flags);
270 sport->curr_rx_desc = sport->dma_rx_desc;
271 } else {
272 sport_tx_dma_start(sport, 1);
273 sport_rx_dma_start(sport, 0);
274 sport_start(sport);
275 }
276
277 sport->rx_run = 1;
278
279 return 0;
280}
281EXPORT_SYMBOL(sport_rx_start);
282
283int sport_rx_stop(struct sport_device *sport)
284{
285 pr_debug("%s enter\n", __func__);
286
287 if (!sport->rx_run)
288 return 0;
289 if (sport->tx_run) {
290 /* TX dma is still running, hook the dummy buffer */
291 sport_hook_rx_dummy(sport);
292 } else {
293 /* Both rx and tx dma will be stopped */
294 sport_stop(sport);
295 sport->curr_rx_desc = NULL;
296 sport->curr_tx_desc = NULL;
297 }
298
299 sport->rx_run = 0;
300
301 return 0;
302}
303EXPORT_SYMBOL(sport_rx_stop);
304
305static inline int sport_hook_tx_dummy(struct sport_device *sport)
306{
307 struct dmasg *desc, temp_desc;
308 unsigned long flags;
309
310 BUG_ON(sport->dummy_tx_desc == NULL);
311 BUG_ON(sport->curr_tx_desc == sport->dummy_tx_desc);
312
313 sport->dummy_tx_desc->next_desc_addr = \
314 (unsigned long)(sport->dummy_tx_desc+1);
315
316 /* Shorten the time on last normal descriptor */
317 local_irq_save(flags);
318 desc = (struct dmasg *)get_dma_next_desc_ptr(sport->dma_tx_chan);
319 /* Store the descriptor which will be damaged */
320 temp_desc = *desc;
321 desc->x_count = 0xa;
322 desc->y_count = 0;
323 desc->next_desc_addr = (unsigned long)(sport->dummy_tx_desc);
324 local_irq_restore(flags);
325 /* Waiting for dummy buffer descriptor is already hooked*/
326 while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \
327 sizeof(struct dmasg)) != \
328 (unsigned long)sport->dummy_tx_desc)
329 ;
330 sport->curr_tx_desc = sport->dummy_tx_desc;
331 /* Restore the damaged descriptor */
332 *desc = temp_desc;
333
334 return 0;
335}
336
337int sport_tx_start(struct sport_device *sport)
338{
339 unsigned flags;
340 pr_debug("%s: tx_run:%d, rx_run:%d\n", __func__,
341 sport->tx_run, sport->rx_run);
342 if (sport->tx_run)
343 return -EBUSY;
344 if (sport->rx_run) {
345 BUG_ON(sport->dma_tx_desc == NULL);
346 BUG_ON(sport->curr_tx_desc != sport->dummy_tx_desc);
347 /* Hook the normal buffer descriptor */
348 local_irq_save(flags);
349 while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) -
350 sizeof(struct dmasg)) !=
351 (unsigned long)sport->dummy_tx_desc)
352 ;
353 sport->dummy_tx_desc->next_desc_addr =
354 (unsigned long)(sport->dma_tx_desc);
355 local_irq_restore(flags);
356 sport->curr_tx_desc = sport->dma_tx_desc;
357 } else {
358
359 sport_tx_dma_start(sport, 0);
360 /* Let rx dma run the dummy buffer */
361 sport_rx_dma_start(sport, 1);
362 sport_start(sport);
363 }
364 sport->tx_run = 1;
365 return 0;
366}
367EXPORT_SYMBOL(sport_tx_start);
368
369int sport_tx_stop(struct sport_device *sport)
370{
371 if (!sport->tx_run)
372 return 0;
373 if (sport->rx_run) {
374 /* RX is still running, hook the dummy buffer */
375 sport_hook_tx_dummy(sport);
376 } else {
377 /* Both rx and tx dma stopped */
378 sport_stop(sport);
379 sport->curr_rx_desc = NULL;
380 sport->curr_tx_desc = NULL;
381 }
382
383 sport->tx_run = 0;
384
385 return 0;
386}
387EXPORT_SYMBOL(sport_tx_stop);
388
389static inline int compute_wdsize(size_t wdsize)
390{
391 switch (wdsize) {
392 case 1:
393 return WDSIZE_8;
394 case 2:
395 return WDSIZE_16;
396 case 4:
397 default:
398 return WDSIZE_32;
399 }
400}
401
402int sport_config_rx_dma(struct sport_device *sport, void *buf,
403 int fragcount, size_t fragsize)
404{
405 unsigned int x_count;
406 unsigned int y_count;
407 unsigned int cfg;
408 dma_addr_t addr;
409
410 pr_debug("%s buf:%p, frag:%d, fragsize:0x%lx\n", __func__, \
411 buf, fragcount, fragsize);
412
413 x_count = fragsize / sport->wdsize;
414 y_count = 0;
415
416 /* for fragments larger than 64k words we use 2d dma,
417 * denote fragecount as two numbers' mutliply and both of them
418 * are less than 64k.*/
419 if (x_count >= 0x10000) {
420 int i, count = x_count;
421
422 for (i = 16; i > 0; i--) {
423 x_count = 1 << i;
424 if ((count & (x_count - 1)) == 0) {
425 y_count = count >> i;
426 if (y_count < 0x10000)
427 break;
428 }
429 }
430 if (i == 0)
431 return -EINVAL;
432 }
433 pr_debug("%s(x_count:0x%x, y_count:0x%x)\n", __func__,
434 x_count, y_count);
435
436 if (sport->dma_rx_desc)
437 dma_free_coherent(NULL, sport->rx_desc_bytes,
438 sport->dma_rx_desc, 0);
439
440 /* Allocate a new descritor ring as current one. */
441 sport->dma_rx_desc = dma_alloc_coherent(NULL, \
442 fragcount * sizeof(struct dmasg), &addr, 0);
443 sport->rx_desc_bytes = fragcount * sizeof(struct dmasg);
444
445 if (!sport->dma_rx_desc) {
446 pr_err("Failed to allocate memory for rx desc\n");
447 return -ENOMEM;
448 }
449
450 sport->rx_buf = buf;
451 sport->rx_fragsize = fragsize;
452 sport->rx_frags = fragcount;
453
454 cfg = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | WNR | \
455 (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
456
457 if (y_count != 0)
458 cfg |= DMA2D;
459
460 setup_desc(sport->dma_rx_desc, buf, fragcount, fragsize,
461 cfg|DMAEN, x_count, y_count, sport->wdsize);
462
463 return 0;
464}
465EXPORT_SYMBOL(sport_config_rx_dma);
466
467int sport_config_tx_dma(struct sport_device *sport, void *buf, \
468 int fragcount, size_t fragsize)
469{
470 unsigned int x_count;
471 unsigned int y_count;
472 unsigned int cfg;
473 dma_addr_t addr;
474
475 pr_debug("%s buf:%p, fragcount:%d, fragsize:0x%lx\n",
476 __func__, buf, fragcount, fragsize);
477
478 x_count = fragsize/sport->wdsize;
479 y_count = 0;
480
481 /* for fragments larger than 64k words we use 2d dma,
482 * denote fragecount as two numbers' mutliply and both of them
483 * are less than 64k.*/
484 if (x_count >= 0x10000) {
485 int i, count = x_count;
486
487 for (i = 16; i > 0; i--) {
488 x_count = 1 << i;
489 if ((count & (x_count - 1)) == 0) {
490 y_count = count >> i;
491 if (y_count < 0x10000)
492 break;
493 }
494 }
495 if (i == 0)
496 return -EINVAL;
497 }
498 pr_debug("%s x_count:0x%x, y_count:0x%x\n", __func__,
499 x_count, y_count);
500
501
502 if (sport->dma_tx_desc) {
503 dma_free_coherent(NULL, sport->tx_desc_bytes, \
504 sport->dma_tx_desc, 0);
505 }
506
507 sport->dma_tx_desc = dma_alloc_coherent(NULL, \
508 fragcount * sizeof(struct dmasg), &addr, 0);
509 sport->tx_desc_bytes = fragcount * sizeof(struct dmasg);
510 if (!sport->dma_tx_desc) {
511 pr_err("Failed to allocate memory for tx desc\n");
512 return -ENOMEM;
513 }
514
515 sport->tx_buf = buf;
516 sport->tx_fragsize = fragsize;
517 sport->tx_frags = fragcount;
518 cfg = 0x7000 | DI_EN | compute_wdsize(sport->wdsize) | \
519 (DESC_ELEMENT_COUNT << 8); /* large descriptor mode */
520
521 if (y_count != 0)
522 cfg |= DMA2D;
523
524 setup_desc(sport->dma_tx_desc, buf, fragcount, fragsize,
525 cfg|DMAEN, x_count, y_count, sport->wdsize);
526
527 return 0;
528}
529EXPORT_SYMBOL(sport_config_tx_dma);
530
531/* setup dummy dma descriptor ring, which don't generate interrupts,
532 * the x_modify is set to 0 */
533static int sport_config_rx_dummy(struct sport_device *sport)
534{
535 struct dmasg *desc;
536 unsigned config;
537
538 pr_debug("%s entered\n", __func__);
539#if L1_DATA_A_LENGTH != 0
540 desc = (struct dmasg *) l1_data_sram_alloc(2 * sizeof(*desc));
541#else
542 {
543 dma_addr_t addr;
544 desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
545 }
546#endif
547 if (desc == NULL) {
548 pr_err("Failed to allocate memory for dummy rx desc\n");
549 return -ENOMEM;
550 }
551 memset(desc, 0, 2 * sizeof(*desc));
552 sport->dummy_rx_desc = desc;
553 desc->start_addr = (unsigned long)sport->dummy_buf;
554 config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize)
555 | WNR | DMAEN;
556 desc->cfg = config;
557 desc->x_count = sport->dummy_count/sport->wdsize;
558 desc->x_modify = sport->wdsize;
559 desc->y_count = 0;
560 desc->y_modify = 0;
561 memcpy(desc+1, desc, sizeof(*desc));
562 desc->next_desc_addr = (unsigned long)(desc+1);
563 desc[1].next_desc_addr = (unsigned long)desc;
564 return 0;
565}
566
567static int sport_config_tx_dummy(struct sport_device *sport)
568{
569 struct dmasg *desc;
570 unsigned int config;
571
572 pr_debug("%s entered\n", __func__);
573
574#if L1_DATA_A_LENGTH != 0
575 desc = (struct dmasg *) l1_data_sram_alloc(2 * sizeof(*desc));
576#else
577 {
578 dma_addr_t addr;
579 desc = dma_alloc_coherent(NULL, 2 * sizeof(*desc), &addr, 0);
580 }
581#endif
582 if (!desc) {
583 pr_err("Failed to allocate memory for dummy tx desc\n");
584 return -ENOMEM;
585 }
586 memset(desc, 0, 2 * sizeof(*desc));
587 sport->dummy_tx_desc = desc;
588 desc->start_addr = (unsigned long)sport->dummy_buf + \
589 sport->dummy_count;
590 config = DMAFLOW_LARGE | NDSIZE_9 |
591 compute_wdsize(sport->wdsize) | DMAEN;
592 desc->cfg = config;
593 desc->x_count = sport->dummy_count/sport->wdsize;
594 desc->x_modify = sport->wdsize;
595 desc->y_count = 0;
596 desc->y_modify = 0;
597 memcpy(desc+1, desc, sizeof(*desc));
598 desc->next_desc_addr = (unsigned long)(desc+1);
599 desc[1].next_desc_addr = (unsigned long)desc;
600 return 0;
601}
602
603unsigned long sport_curr_offset_rx(struct sport_device *sport)
604{
605 unsigned long curr = get_dma_curr_addr(sport->dma_rx_chan);
606
607 return (unsigned char *)curr - sport->rx_buf;
608}
609EXPORT_SYMBOL(sport_curr_offset_rx);
610
611unsigned long sport_curr_offset_tx(struct sport_device *sport)
612{
613 unsigned long curr = get_dma_curr_addr(sport->dma_tx_chan);
614
615 return (unsigned char *)curr - sport->tx_buf;
616}
617EXPORT_SYMBOL(sport_curr_offset_tx);
618
619void sport_incfrag(struct sport_device *sport, int *frag, int tx)
620{
621 ++(*frag);
622 if (tx == 1 && *frag == sport->tx_frags)
623 *frag = 0;
624
625 if (tx == 0 && *frag == sport->rx_frags)
626 *frag = 0;
627}
628EXPORT_SYMBOL(sport_incfrag);
629
630void sport_decfrag(struct sport_device *sport, int *frag, int tx)
631{
632 --(*frag);
633 if (tx == 1 && *frag == 0)
634 *frag = sport->tx_frags;
635
636 if (tx == 0 && *frag == 0)
637 *frag = sport->rx_frags;
638}
639EXPORT_SYMBOL(sport_decfrag);
640
641static int sport_check_status(struct sport_device *sport,
642 unsigned int *sport_stat,
643 unsigned int *rx_stat,
644 unsigned int *tx_stat)
645{
646 int status = 0;
647
648 if (sport_stat) {
649 SSYNC();
650 status = sport->regs->stat;
651 if (status & (TOVF|TUVF|ROVF|RUVF))
652 sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
653 SSYNC();
654 *sport_stat = status;
655 }
656
657 if (rx_stat) {
658 SSYNC();
659 status = get_dma_curr_irqstat(sport->dma_rx_chan);
660 if (status & (DMA_DONE|DMA_ERR))
661 clear_dma_irqstat(sport->dma_rx_chan);
662 SSYNC();
663 *rx_stat = status;
664 }
665
666 if (tx_stat) {
667 SSYNC();
668 status = get_dma_curr_irqstat(sport->dma_tx_chan);
669 if (status & (DMA_DONE|DMA_ERR))
670 clear_dma_irqstat(sport->dma_tx_chan);
671 SSYNC();
672 *tx_stat = status;
673 }
674
675 return 0;
676}
677
678int sport_dump_stat(struct sport_device *sport, char *buf, size_t len)
679{
680 int ret;
681
682 ret = snprintf(buf, len,
683 "sts: 0x%04x\n"
684 "rx dma %d sts: 0x%04x tx dma %d sts: 0x%04x\n",
685 sport->regs->stat,
686 sport->dma_rx_chan,
687 get_dma_curr_irqstat(sport->dma_rx_chan),
688 sport->dma_tx_chan,
689 get_dma_curr_irqstat(sport->dma_tx_chan));
690 buf += ret;
691 len -= ret;
692
693 ret += snprintf(buf, len,
694 "curr_rx_desc:0x%p, curr_tx_desc:0x%p\n"
695 "dma_rx_desc:0x%p, dma_tx_desc:0x%p\n"
696 "dummy_rx_desc:0x%p, dummy_tx_desc:0x%p\n",
697 sport->curr_rx_desc, sport->curr_tx_desc,
698 sport->dma_rx_desc, sport->dma_tx_desc,
699 sport->dummy_rx_desc, sport->dummy_tx_desc);
700
701 return ret;
702}
703
704static irqreturn_t rx_handler(int irq, void *dev_id)
705{
706 unsigned int rx_stat;
707 struct sport_device *sport = dev_id;
708
709 pr_debug("%s enter\n", __func__);
710 sport_check_status(sport, NULL, &rx_stat, NULL);
711 if (!(rx_stat & DMA_DONE))
712 pr_err("rx dma is already stopped\n");
713
714 if (sport->rx_callback) {
715 sport->rx_callback(sport->rx_data);
716 return IRQ_HANDLED;
717 }
718
719 return IRQ_NONE;
720}
721
722static irqreturn_t tx_handler(int irq, void *dev_id)
723{
724 unsigned int tx_stat;
725 struct sport_device *sport = dev_id;
726 pr_debug("%s enter\n", __func__);
727 sport_check_status(sport, NULL, NULL, &tx_stat);
728 if (!(tx_stat & DMA_DONE)) {
729 pr_err("tx dma is already stopped\n");
730 return IRQ_HANDLED;
731 }
732 if (sport->tx_callback) {
733 sport->tx_callback(sport->tx_data);
734 return IRQ_HANDLED;
735 }
736
737 return IRQ_NONE;
738}
739
740static irqreturn_t err_handler(int irq, void *dev_id)
741{
742 unsigned int status = 0;
743 struct sport_device *sport = dev_id;
744
745 pr_debug("%s\n", __func__);
746 if (sport_check_status(sport, &status, NULL, NULL)) {
747 pr_err("error checking status ??");
748 return IRQ_NONE;
749 }
750
751 if (status & (TOVF|TUVF|ROVF|RUVF)) {
752 pr_info("sport status error:%s%s%s%s\n",
753 status & TOVF ? " TOVF" : "",
754 status & TUVF ? " TUVF" : "",
755 status & ROVF ? " ROVF" : "",
756 status & RUVF ? " RUVF" : "");
757 if (status & TOVF || status & TUVF) {
758 disable_dma(sport->dma_tx_chan);
759 if (sport->tx_run)
760 sport_tx_dma_start(sport, 0);
761 else
762 sport_tx_dma_start(sport, 1);
763 enable_dma(sport->dma_tx_chan);
764 } else {
765 disable_dma(sport->dma_rx_chan);
766 if (sport->rx_run)
767 sport_rx_dma_start(sport, 0);
768 else
769 sport_rx_dma_start(sport, 1);
770 enable_dma(sport->dma_rx_chan);
771 }
772 }
773 status = sport->regs->stat;
774 if (status & (TOVF|TUVF|ROVF|RUVF))
775 sport->regs->stat = (status & (TOVF|TUVF|ROVF|RUVF));
776 SSYNC();
777
778 if (sport->err_callback)
779 sport->err_callback(sport->err_data);
780
781 return IRQ_HANDLED;
782}
783
784int sport_set_rx_callback(struct sport_device *sport,
785 void (*rx_callback)(void *), void *rx_data)
786{
787 BUG_ON(rx_callback == NULL);
788 sport->rx_callback = rx_callback;
789 sport->rx_data = rx_data;
790
791 return 0;
792}
793EXPORT_SYMBOL(sport_set_rx_callback);
794
795int sport_set_tx_callback(struct sport_device *sport,
796 void (*tx_callback)(void *), void *tx_data)
797{
798 BUG_ON(tx_callback == NULL);
799 sport->tx_callback = tx_callback;
800 sport->tx_data = tx_data;
801
802 return 0;
803}
804EXPORT_SYMBOL(sport_set_tx_callback);
805
806int sport_set_err_callback(struct sport_device *sport,
807 void (*err_callback)(void *), void *err_data)
808{
809 BUG_ON(err_callback == NULL);
810 sport->err_callback = err_callback;
811 sport->err_data = err_data;
812
813 return 0;
814}
815EXPORT_SYMBOL(sport_set_err_callback);
816
817struct sport_device *sport_init(struct sport_param *param, unsigned wdsize,
818 unsigned dummy_count, void *private_data)
819{
820 int ret;
821 struct sport_device *sport;
822 pr_debug("%s enter\n", __func__);
823 BUG_ON(param == NULL);
824 BUG_ON(wdsize == 0 || dummy_count == 0);
825 sport = kmalloc(sizeof(struct sport_device), GFP_KERNEL);
826 if (!sport) {
827 pr_err("Failed to allocate for sport device\n");
828 return NULL;
829 }
830
831 memset(sport, 0, sizeof(struct sport_device));
832 sport->dma_rx_chan = param->dma_rx_chan;
833 sport->dma_tx_chan = param->dma_tx_chan;
834 sport->err_irq = param->err_irq;
835 sport->regs = param->regs;
836 sport->private_data = private_data;
837
838 if (request_dma(sport->dma_rx_chan, "SPORT RX Data") == -EBUSY) {
839 pr_err("Failed to request RX dma %d\n", \
840 sport->dma_rx_chan);
841 goto __init_err1;
842 }
843 if (set_dma_callback(sport->dma_rx_chan, rx_handler, sport) != 0) {
844 pr_err("Failed to request RX irq %d\n", \
845 sport->dma_rx_chan);
846 goto __init_err2;
847 }
848
849 if (request_dma(sport->dma_tx_chan, "SPORT TX Data") == -EBUSY) {
850 pr_err("Failed to request TX dma %d\n", \
851 sport->dma_tx_chan);
852 goto __init_err2;
853 }
854
855 if (set_dma_callback(sport->dma_tx_chan, tx_handler, sport) != 0) {
856 pr_err("Failed to request TX irq %d\n", \
857 sport->dma_tx_chan);
858 goto __init_err3;
859 }
860
861 if (request_irq(sport->err_irq, err_handler, IRQF_SHARED, "SPORT err",
862 sport) < 0) {
863 pr_err("Failed to request err irq:%d\n", \
864 sport->err_irq);
865 goto __init_err3;
866 }
867
868 pr_err("dma rx:%d tx:%d, err irq:%d, regs:%p\n",
869 sport->dma_rx_chan, sport->dma_tx_chan,
870 sport->err_irq, sport->regs);
871
872 sport->wdsize = wdsize;
873 sport->dummy_count = dummy_count;
874
875#if L1_DATA_A_LENGTH != 0
876 sport->dummy_buf = l1_data_sram_alloc(dummy_count * 2);
877#else
878 sport->dummy_buf = kmalloc(dummy_count * 2, GFP_KERNEL);
879#endif
880 if (sport->dummy_buf == NULL) {
881 pr_err("Failed to allocate dummy buffer\n");
882 goto __error;
883 }
884
885 memset(sport->dummy_buf, 0, dummy_count * 2);
886 ret = sport_config_rx_dummy(sport);
887 if (ret) {
888 pr_err("Failed to config rx dummy ring\n");
889 goto __error;
890 }
891 ret = sport_config_tx_dummy(sport);
892 if (ret) {
893 pr_err("Failed to config tx dummy ring\n");
894 goto __error;
895 }
896
897 return sport;
898__error:
899 free_irq(sport->err_irq, sport);
900__init_err3:
901 free_dma(sport->dma_tx_chan);
902__init_err2:
903 free_dma(sport->dma_rx_chan);
904__init_err1:
905 kfree(sport);
906 return NULL;
907}
908EXPORT_SYMBOL(sport_init);
909
910void sport_done(struct sport_device *sport)
911{
912 if (sport == NULL)
913 return;
914
915 sport_stop(sport);
916 if (sport->dma_rx_desc)
917 dma_free_coherent(NULL, sport->rx_desc_bytes,
918 sport->dma_rx_desc, 0);
919 if (sport->dma_tx_desc)
920 dma_free_coherent(NULL, sport->tx_desc_bytes,
921 sport->dma_tx_desc, 0);
922
923#if L1_DATA_A_LENGTH != 0
924 l1_data_sram_free(sport->dummy_rx_desc);
925 l1_data_sram_free(sport->dummy_tx_desc);
926 l1_data_sram_free(sport->dummy_buf);
927#else
928 dma_free_coherent(NULL, 2*sizeof(struct dmasg),
929 sport->dummy_rx_desc, 0);
930 dma_free_coherent(NULL, 2*sizeof(struct dmasg),
931 sport->dummy_tx_desc, 0);
932 kfree(sport->dummy_buf);
933#endif
934 free_dma(sport->dma_rx_chan);
935 free_dma(sport->dma_tx_chan);
936 free_irq(sport->err_irq, sport);
937
938 kfree(sport);
939 sport = NULL;
940}
941EXPORT_SYMBOL(sport_done);
942/*
943* It is only used to send several bytes when dma is not enabled
944 * sport controller is configured but not enabled.
945 * Multichannel cannot works with pio mode */
946/* Used by ac97 to write and read codec register */
947int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
948 u8 *in_data, int len)
949{
950 unsigned short dma_config;
951 unsigned short status;
952 unsigned long flags;
953 unsigned long wait = 0;
954
955 pr_debug("%s enter, out_data:%p, in_data:%p len:%d\n", \
956 __func__, out_data, in_data, len);
957 pr_debug("tcr1:0x%04x, tcr2:0x%04x, tclkdiv:0x%04x, tfsdiv:0x%04x\n"
958 "mcmc1:0x%04x, mcmc2:0x%04x\n",
959 sport->regs->tcr1, sport->regs->tcr2,
960 sport->regs->tclkdiv, sport->regs->tfsdiv,
961 sport->regs->mcmc1, sport->regs->mcmc2);
962 flush_dcache_range((unsigned)out_data, (unsigned)(out_data + len));
963
964 /* Enable tx dma */
965 dma_config = (RESTART | WDSIZE_16 | DI_EN);
966 set_dma_start_addr(sport->dma_tx_chan, (unsigned long)out_data);
967 set_dma_x_count(sport->dma_tx_chan, len/2);
968 set_dma_x_modify(sport->dma_tx_chan, 2);
969 set_dma_config(sport->dma_tx_chan, dma_config);
970 enable_dma(sport->dma_tx_chan);
971
972 if (in_data != NULL) {
973 invalidate_dcache_range((unsigned)in_data, \
974 (unsigned)(in_data + len));
975 /* Enable rx dma */
976 dma_config = (RESTART | WDSIZE_16 | WNR | DI_EN);
977 set_dma_start_addr(sport->dma_rx_chan, (unsigned long)in_data);
978 set_dma_x_count(sport->dma_rx_chan, len/2);
979 set_dma_x_modify(sport->dma_rx_chan, 2);
980 set_dma_config(sport->dma_rx_chan, dma_config);
981 enable_dma(sport->dma_rx_chan);
982 }
983
984 local_irq_save(flags);
985 sport->regs->tcr1 |= TSPEN;
986 sport->regs->rcr1 |= RSPEN;
987 SSYNC();
988
989 status = get_dma_curr_irqstat(sport->dma_tx_chan);
990 while (status & DMA_RUN) {
991 udelay(1);
992 status = get_dma_curr_irqstat(sport->dma_tx_chan);
993 pr_debug("DMA status:0x%04x\n", status);
994 if (wait++ > 100)
995 goto __over;
996 }
997 status = sport->regs->stat;
998 wait = 0;
999
1000 while (!(status & TXHRE)) {
1001 pr_debug("sport status:0x%04x\n", status);
1002 udelay(1);
1003 status = *(unsigned short *)&sport->regs->stat;
1004 if (wait++ > 1000)
1005 goto __over;
1006 }
1007 /* Wait for the last byte sent out */
1008 udelay(20);
1009 pr_debug("sport status:0x%04x\n", status);
1010
1011__over:
1012 sport->regs->tcr1 &= ~TSPEN;
1013 sport->regs->rcr1 &= ~RSPEN;
1014 SSYNC();
1015 disable_dma(sport->dma_tx_chan);
1016 /* Clear the status */
1017 clear_dma_irqstat(sport->dma_tx_chan);
1018 if (in_data != NULL) {
1019 disable_dma(sport->dma_rx_chan);
1020 clear_dma_irqstat(sport->dma_rx_chan);
1021 }
1022 SSYNC();
1023 local_irq_restore(flags);
1024
1025 return 0;
1026}
1027EXPORT_SYMBOL(sport_send_and_recv);
1028
1029MODULE_AUTHOR("Roy Huang");
1030MODULE_DESCRIPTION("SPORT driver for ADI Blackfin");
1031MODULE_LICENSE("GPL");
1032
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
new file mode 100644
index 00000000000..4c163454bbf
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -0,0 +1,192 @@
1/*
2 * File: bf5xx_ac97_sport.h
3 * Based on:
4 * Author: Roy Huang <roy.huang@analog.com>
5 *
6 * Created:
7 * Description:
8 *
9 * Copyright 2004-2007 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29
30#ifndef __BF5XX_SPORT_H__
31#define __BF5XX_SPORT_H__
32
33#include <linux/types.h>
34#include <linux/wait.h>
35#include <linux/workqueue.h>
36#include <asm/dma.h>
37
38struct sport_register {
39 u16 tcr1; u16 reserved0;
40 u16 tcr2; u16 reserved1;
41 u16 tclkdiv; u16 reserved2;
42 u16 tfsdiv; u16 reserved3;
43 u32 tx;
44 u32 reserved_l0;
45 u32 rx;
46 u32 reserved_l1;
47 u16 rcr1; u16 reserved4;
48 u16 rcr2; u16 reserved5;
49 u16 rclkdiv; u16 reserved6;
50 u16 rfsdiv; u16 reserved7;
51 u16 stat; u16 reserved8;
52 u16 chnl; u16 reserved9;
53 u16 mcmc1; u16 reserved10;
54 u16 mcmc2; u16 reserved11;
55 u32 mtcs0;
56 u32 mtcs1;
57 u32 mtcs2;
58 u32 mtcs3;
59 u32 mrcs0;
60 u32 mrcs1;
61 u32 mrcs2;
62 u32 mrcs3;
63};
64
65#define DESC_ELEMENT_COUNT 9
66
67struct sport_device {
68 int dma_rx_chan;
69 int dma_tx_chan;
70 int err_irq;
71 struct sport_register *regs;
72
73 unsigned char *rx_buf;
74 unsigned char *tx_buf;
75 unsigned int rx_fragsize;
76 unsigned int tx_fragsize;
77 unsigned int rx_frags;
78 unsigned int tx_frags;
79 unsigned int wdsize;
80
81 /* for dummy dma transfer */
82 void *dummy_buf;
83 unsigned int dummy_count;
84
85 /* DMA descriptor ring head of current audio stream*/
86 struct dmasg *dma_rx_desc;
87 struct dmasg *dma_tx_desc;
88 unsigned int rx_desc_bytes;
89 unsigned int tx_desc_bytes;
90
91 unsigned int rx_run:1; /* rx is running */
92 unsigned int tx_run:1; /* tx is running */
93
94 struct dmasg *dummy_rx_desc;
95 struct dmasg *dummy_tx_desc;
96
97 struct dmasg *curr_rx_desc;
98 struct dmasg *curr_tx_desc;
99
100 int rx_curr_frag;
101 int tx_curr_frag;
102
103 unsigned int rcr1;
104 unsigned int rcr2;
105 int rx_tdm_count;
106
107 unsigned int tcr1;
108 unsigned int tcr2;
109 int tx_tdm_count;
110
111 void (*rx_callback)(void *data);
112 void *rx_data;
113 void (*tx_callback)(void *data);
114 void *tx_data;
115 void (*err_callback)(void *data);
116 void *err_data;
117 unsigned char *tx_dma_buf;
118 unsigned char *rx_dma_buf;
119#ifdef CONFIG_SND_MMAP_SUPPORT
120 dma_addr_t tx_dma_phy;
121 dma_addr_t rx_dma_phy;
122 int tx_pos;/*pcm sample count*/
123 int rx_pos;
124 unsigned int tx_buffer_size;
125 unsigned int rx_buffer_size;
126#endif
127 void *private_data;
128};
129
130extern struct sport_device *sport_handle;
131
132struct sport_param {
133 int dma_rx_chan;
134 int dma_tx_chan;
135 int err_irq;
136 struct sport_register *regs;
137};
138
139struct sport_device *sport_init(struct sport_param *param, unsigned wdsize,
140 unsigned dummy_count, void *private_data);
141
142void sport_done(struct sport_device *sport);
143
144/* first use these ...*/
145
146/* note: multichannel is in units of 8 channels, tdm_count is number of channels
147 * NOT / 8 ! all channels are enabled by default */
148int sport_set_multichannel(struct sport_device *sport, int tdm_count,
149 u32 mask, int packed);
150
151int sport_config_rx(struct sport_device *sport,
152 unsigned int rcr1, unsigned int rcr2,
153 unsigned int clkdiv, unsigned int fsdiv);
154
155int sport_config_tx(struct sport_device *sport,
156 unsigned int tcr1, unsigned int tcr2,
157 unsigned int clkdiv, unsigned int fsdiv);
158
159/* ... then these: */
160
161/* buffer size (in bytes) == fragcount * fragsize_bytes */
162
163/* this is not a very general api, it sets the dma to 2d autobuffer mode */
164
165int sport_config_rx_dma(struct sport_device *sport, void *buf,
166 int fragcount, size_t fragsize_bytes);
167
168int sport_config_tx_dma(struct sport_device *sport, void *buf,
169 int fragcount, size_t fragsize_bytes);
170
171int sport_tx_start(struct sport_device *sport);
172int sport_tx_stop(struct sport_device *sport);
173int sport_rx_start(struct sport_device *sport);
174int sport_rx_stop(struct sport_device *sport);
175
176/* for use in interrupt handler */
177unsigned long sport_curr_offset_rx(struct sport_device *sport);
178unsigned long sport_curr_offset_tx(struct sport_device *sport);
179
180void sport_incfrag(struct sport_device *sport, int *frag, int tx);
181void sport_decfrag(struct sport_device *sport, int *frag, int tx);
182
183int sport_set_rx_callback(struct sport_device *sport,
184 void (*rx_callback)(void *), void *rx_data);
185int sport_set_tx_callback(struct sport_device *sport,
186 void (*tx_callback)(void *), void *tx_data);
187int sport_set_err_callback(struct sport_device *sport,
188 void (*err_callback)(void *), void *err_data);
189
190int sport_send_and_recv(struct sport_device *sport, u8 *out_data, \
191 u8 *in_data, int len);
192#endif /* BF53X_SPORT_H */
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
new file mode 100644
index 00000000000..e15f67fd776
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -0,0 +1,186 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-ssm2602.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: board driver for SSM2602 sound chip
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/device.h>
32
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/soc.h>
36#include <sound/soc-dapm.h>
37#include <sound/pcm_params.h>
38
39#include <asm/dma.h>
40#include <asm/portmux.h>
41#include <linux/gpio.h>
42#include "../codecs/ssm2602.h"
43#include "bf5xx-sport.h"
44#include "bf5xx-i2s-pcm.h"
45#include "bf5xx-i2s.h"
46
47static struct snd_soc_machine bf5xx_ssm2602;
48
49static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream)
50{
51 struct snd_soc_pcm_runtime *rtd = substream->private_data;
52 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
53
54 pr_debug("%s enter\n", __func__);
55 cpu_dai->private_data = sport_handle;
56 return 0;
57}
58
59static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
60 struct snd_pcm_hw_params *params)
61{
62 struct snd_soc_pcm_runtime *rtd = substream->private_data;
63 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
64 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
65 unsigned int clk = 0;
66 int ret = 0;
67
68 pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
69 params_format(params));
70 /*
71 * If you are using a crystal source which frequency is not 12MHz
72 * then modify the below case statement with frequency of the crystal.
73 *
74 * If you are using the SPORT to generate clocking then this is
75 * where to do it.
76 */
77
78 switch (params_rate(params)) {
79 case 8000:
80 case 16000:
81 case 48000:
82 case 96000:
83 case 11025:
84 case 22050:
85 case 44100:
86 clk = 12000000;
87 break;
88 }
89
90 /*
91 * CODEC is master for BCLK and LRC in this configuration.
92 */
93
94 /* set codec DAI configuration */
95 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
96 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
97 if (ret < 0)
98 return ret;
99 /* set cpu DAI configuration */
100 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
101 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
102 if (ret < 0)
103 return ret;
104
105 ret = codec_dai->dai_ops.set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
106 SND_SOC_CLOCK_IN);
107 if (ret < 0)
108 return ret;
109
110 return 0;
111}
112
113static struct snd_soc_ops bf5xx_ssm2602_ops = {
114 .startup = bf5xx_ssm2602_startup,
115 .hw_params = bf5xx_ssm2602_hw_params,
116};
117
118static struct snd_soc_dai_link bf5xx_ssm2602_dai = {
119 .name = "ssm2602",
120 .stream_name = "SSM2602",
121 .cpu_dai = &bf5xx_i2s_dai,
122 .codec_dai = &ssm2602_dai,
123 .ops = &bf5xx_ssm2602_ops,
124};
125
126/*
127 * SSM2602 2 wire address is determined by CSB
128 * state during powerup.
129 * low = 0x1a
130 * high = 0x1b
131 */
132
133static struct ssm2602_setup_data bf5xx_ssm2602_setup = {
134 .i2c_bus = 0,
135 .i2c_address = 0x1b,
136};
137
138static struct snd_soc_machine bf5xx_ssm2602 = {
139 .name = "bf5xx_ssm2602",
140 .dai_link = &bf5xx_ssm2602_dai,
141 .num_links = 1,
142};
143
144static struct snd_soc_device bf5xx_ssm2602_snd_devdata = {
145 .machine = &bf5xx_ssm2602,
146 .platform = &bf5xx_i2s_soc_platform,
147 .codec_dev = &soc_codec_dev_ssm2602,
148 .codec_data = &bf5xx_ssm2602_setup,
149};
150
151static struct platform_device *bf52x_ssm2602_snd_device;
152
153static int __init bf5xx_ssm2602_init(void)
154{
155 int ret;
156
157 pr_debug("%s enter\n", __func__);
158 bf52x_ssm2602_snd_device = platform_device_alloc("soc-audio", -1);
159 if (!bf52x_ssm2602_snd_device)
160 return -ENOMEM;
161
162 platform_set_drvdata(bf52x_ssm2602_snd_device,
163 &bf5xx_ssm2602_snd_devdata);
164 bf5xx_ssm2602_snd_devdata.dev = &bf52x_ssm2602_snd_device->dev;
165 ret = platform_device_add(bf52x_ssm2602_snd_device);
166
167 if (ret)
168 platform_device_put(bf52x_ssm2602_snd_device);
169
170 return ret;
171}
172
173static void __exit bf5xx_ssm2602_exit(void)
174{
175 pr_debug("%s enter\n", __func__);
176 platform_device_unregister(bf52x_ssm2602_snd_device);
177}
178
179module_init(bf5xx_ssm2602_init);
180module_exit(bf5xx_ssm2602_exit);
181
182/* Module information */
183MODULE_AUTHOR("Cliff Cai");
184MODULE_DESCRIPTION("ALSA SoC SSM2602 BF527-EZKIT");
185MODULE_LICENSE("GPL");
186
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1db04a28a53..e0b9869df0f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1,16 +1,80 @@
1config SND_SOC_ALL_CODECS
2 tristate "Build all ASoC CODEC drivers"
3 depends on I2C
4 select SPI
5 select SPI_MASTER
6 select SND_SOC_AK4535
7 select SND_SOC_CS4270
8 select SND_SOC_SSM2602
9 select SND_SOC_TLV320AIC26
10 select SND_SOC_TLV320AIC3X
11 select SND_SOC_UDA1380
12 select SND_SOC_WM8510
13 select SND_SOC_WM8580
14 select SND_SOC_WM8731
15 select SND_SOC_WM8750
16 select SND_SOC_WM8753
17 select SND_SOC_WM8900
18 select SND_SOC_WM8903
19 select SND_SOC_WM8971
20 select SND_SOC_WM8990
21 help
22 Normally ASoC codec drivers are only built if a machine driver which
23 uses them is also built since they are only usable with a machine
24 driver. Selecting this option will allow these drivers to be built
25 without an explicit machine driver for test and development purposes.
26
27 If unsure select "N".
28
29
1config SND_SOC_AC97_CODEC 30config SND_SOC_AC97_CODEC
2 tristate 31 tristate
3 select SND_AC97_CODEC 32 select SND_AC97_CODEC
4 33
34config SND_SOC_AD1980
35 tristate
36
5config SND_SOC_AK4535 37config SND_SOC_AK4535
6 tristate 38 tristate
7 39
40# Cirrus Logic CS4270 Codec
41config SND_SOC_CS4270
42 tristate
43
44# Cirrus Logic CS4270 Codec Hardware Mute Support
45# Select if you have external muting circuitry attached to your CS4270.
46config SND_SOC_CS4270_HWMUTE
47 bool
48 depends on SND_SOC_CS4270
49
50# Cirrus Logic CS4270 Codec VD = 3.3V Errata
51# Select if you are affected by the errata where the part will not function
52# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will
53# not select any sample rates that require MCLK to be divided by 1.5.
54config SND_SOC_CS4270_VD33_ERRATA
55 bool
56 depends on SND_SOC_CS4270
57
58config SND_SOC_SSM2602
59 tristate
60
61config SND_SOC_TLV320AIC26
62 tristate "TI TLV320AIC26 Codec support"
63 depends on SND_SOC && SPI
64
65config SND_SOC_TLV320AIC3X
66 tristate
67 depends on I2C
68
8config SND_SOC_UDA1380 69config SND_SOC_UDA1380
9 tristate 70 tristate
10 71
11config SND_SOC_WM8510 72config SND_SOC_WM8510
12 tristate 73 tristate
13 74
75config SND_SOC_WM8580
76 tristate
77
14config SND_SOC_WM8731 78config SND_SOC_WM8731
15 tristate 79 tristate
16 80
@@ -20,33 +84,20 @@ config SND_SOC_WM8750
20config SND_SOC_WM8753 84config SND_SOC_WM8753
21 tristate 85 tristate
22 86
23config SND_SOC_WM8990 87config SND_SOC_WM8900
24 tristate 88 tristate
25 89
26config SND_SOC_WM9712 90config SND_SOC_WM8903
27 tristate 91 tristate
28 92
29config SND_SOC_WM9713 93config SND_SOC_WM8971
30 tristate 94 tristate
31 95
32# Cirrus Logic CS4270 Codec 96config SND_SOC_WM8990
33config SND_SOC_CS4270
34 tristate 97 tristate
35 98
36# Cirrus Logic CS4270 Codec Hardware Mute Support 99config SND_SOC_WM9712
37# Select if you have external muting circuitry attached to your CS4270. 100 tristate
38config SND_SOC_CS4270_HWMUTE
39 bool
40 depends on SND_SOC_CS4270
41
42# Cirrus Logic CS4270 Codec VD = 3.3V Errata
43# Select if you are affected by the errata where the part will not function
44# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will
45# not select any sample rates that require MCLK to be divided by 1.5.
46config SND_SOC_CS4270_VD33_ERRATA
47 bool
48 depends on SND_SOC_CS4270
49 101
50config SND_SOC_TLV320AIC3X 102config SND_SOC_WM9713
51 tristate 103 tristate
52 depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index d7b97abcf72..f977978a340 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,25 +1,39 @@
1snd-soc-ac97-objs := ac97.o 1snd-soc-ac97-objs := ac97.o
2snd-soc-ad1980-objs := ad1980.o
2snd-soc-ak4535-objs := ak4535.o 3snd-soc-ak4535-objs := ak4535.o
4snd-soc-cs4270-objs := cs4270.o
5snd-soc-ssm2602-objs := ssm2602.o
6snd-soc-tlv320aic26-objs := tlv320aic26.o
7snd-soc-tlv320aic3x-objs := tlv320aic3x.o
3snd-soc-uda1380-objs := uda1380.o 8snd-soc-uda1380-objs := uda1380.o
4snd-soc-wm8510-objs := wm8510.o 9snd-soc-wm8510-objs := wm8510.o
10snd-soc-wm8580-objs := wm8580.o
5snd-soc-wm8731-objs := wm8731.o 11snd-soc-wm8731-objs := wm8731.o
6snd-soc-wm8750-objs := wm8750.o 12snd-soc-wm8750-objs := wm8750.o
7snd-soc-wm8753-objs := wm8753.o 13snd-soc-wm8753-objs := wm8753.o
14snd-soc-wm8900-objs := wm8900.o
15snd-soc-wm8903-objs := wm8903.o
16snd-soc-wm8971-objs := wm8971.o
8snd-soc-wm8990-objs := wm8990.o 17snd-soc-wm8990-objs := wm8990.o
9snd-soc-wm9712-objs := wm9712.o 18snd-soc-wm9712-objs := wm9712.o
10snd-soc-wm9713-objs := wm9713.o 19snd-soc-wm9713-objs := wm9713.o
11snd-soc-cs4270-objs := cs4270.o
12snd-soc-tlv320aic3x-objs := tlv320aic3x.o
13 20
14obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 21obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
22obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
15obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 23obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
24obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
25obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
26obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
27obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
16obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 28obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
17obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 29obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
30obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
18obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 31obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
19obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 32obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
20obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 33obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
34obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
35obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
36obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
21obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 37obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
22obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 38obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
23obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o 39obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
24obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
25obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
new file mode 100644
index 00000000000..4e09c1f2c06
--- /dev/null
+++ b/sound/soc/codecs/ad1980.c
@@ -0,0 +1,309 @@
1/*
2 * ad1980.c -- ALSA Soc AD1980 codec support
3 *
4 * Copyright: Analog Device Inc.
5 * Author: Roy Huang <roy.huang@analog.com>
6 * Cliff Cai <cliff.cai@analog.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/version.h>
17#include <linux/kernel.h>
18#include <linux/device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/ac97_codec.h>
22#include <sound/initval.h>
23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25
26#include "ad1980.h"
27
28static unsigned int ac97_read(struct snd_soc_codec *codec,
29 unsigned int reg);
30static int ac97_write(struct snd_soc_codec *codec,
31 unsigned int reg, unsigned int val);
32
33/*
34 * AD1980 register cache
35 */
36static const u16 ad1980_reg[] = {
37 0x0090, 0x8000, 0x8000, 0x8000, /* 0 - 6 */
38 0x0000, 0x0000, 0x8008, 0x8008, /* 8 - e */
39 0x8808, 0x8808, 0x0000, 0x8808, /* 10 - 16 */
40 0x8808, 0x0000, 0x8000, 0x0000, /* 18 - 1e */
41 0x0000, 0x0000, 0x0000, 0x0000, /* 20 - 26 */
42 0x03c7, 0x0000, 0xbb80, 0xbb80, /* 28 - 2e */
43 0xbb80, 0xbb80, 0x0000, 0x8080, /* 30 - 36 */
44 0x8080, 0x2000, 0x0000, 0x0000, /* 38 - 3e */
45 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
46 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
47 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
48 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
49 0x8080, 0x0000, 0x0000, 0x0000, /* 60 - 66 */
50 0x0000, 0x0000, 0x0000, 0x0000, /* reserved */
51 0x0000, 0x0000, 0x1001, 0x0000, /* 70 - 76 */
52 0x0000, 0x0000, 0x4144, 0x5370 /* 78 - 7e */
53};
54
55static const char *ad1980_rec_sel[] = {"Mic", "CD", "NC", "AUX", "Line",
56 "Stereo Mix", "Mono Mix", "Phone"};
57
58static const struct soc_enum ad1980_cap_src =
59 SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 7, ad1980_rec_sel);
60
61static const struct snd_kcontrol_new ad1980_snd_ac97_controls[] = {
62SOC_DOUBLE("Master Playback Volume", AC97_MASTER, 8, 0, 31, 1),
63SOC_SINGLE("Master Playback Switch", AC97_MASTER, 15, 1, 1),
64
65SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1),
66SOC_SINGLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 1, 1),
67
68SOC_DOUBLE("PCM Playback Volume", AC97_PCM, 8, 0, 31, 1),
69SOC_SINGLE("PCM Playback Switch", AC97_PCM, 15, 1, 1),
70
71SOC_DOUBLE("PCM Capture Volume", AC97_REC_GAIN, 8, 0, 31, 0),
72SOC_SINGLE("PCM Capture Switch", AC97_REC_GAIN, 15, 1, 1),
73
74SOC_SINGLE("Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1),
75SOC_SINGLE("Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
76
77SOC_SINGLE("Phone Capture Volume", AC97_PHONE, 0, 31, 1),
78SOC_SINGLE("Phone Capture Switch", AC97_PHONE, 15, 1, 1),
79
80SOC_SINGLE("Mic Volume", AC97_MIC, 0, 31, 1),
81SOC_SINGLE("Mic Switch", AC97_MIC, 15, 1, 1),
82
83SOC_SINGLE("Stereo Mic Switch", AC97_AD_MISC, 6, 1, 0),
84SOC_DOUBLE("Line HP Swap Switch", AC97_AD_MISC, 10, 5, 1, 0),
85
86SOC_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
87SOC_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1),
88
89SOC_ENUM("Capture Source", ad1980_cap_src),
90
91SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0),
92};
93
94/* add non dapm controls */
95static int ad1980_add_controls(struct snd_soc_codec *codec)
96{
97 int err, i;
98
99 for (i = 0; i < ARRAY_SIZE(ad1980_snd_ac97_controls); i++) {
100 err = snd_ctl_add(codec->card, snd_soc_cnew(
101 &ad1980_snd_ac97_controls[i], codec, NULL));
102 if (err < 0)
103 return err;
104 }
105 return 0;
106}
107
108static unsigned int ac97_read(struct snd_soc_codec *codec,
109 unsigned int reg)
110{
111 u16 *cache = codec->reg_cache;
112
113 switch (reg) {
114 case AC97_RESET:
115 case AC97_INT_PAGING:
116 case AC97_POWERDOWN:
117 case AC97_EXTENDED_STATUS:
118 case AC97_VENDOR_ID1:
119 case AC97_VENDOR_ID2:
120 return soc_ac97_ops.read(codec->ac97, reg);
121 default:
122 reg = reg >> 1;
123
124 if (reg >= (ARRAY_SIZE(ad1980_reg)))
125 return -EINVAL;
126
127 return cache[reg];
128 }
129}
130
131static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
132 unsigned int val)
133{
134 u16 *cache = codec->reg_cache;
135
136 soc_ac97_ops.write(codec->ac97, reg, val);
137 reg = reg >> 1;
138 if (reg < (ARRAY_SIZE(ad1980_reg)))
139 cache[reg] = val;
140
141 return 0;
142}
143
144struct snd_soc_dai ad1980_dai = {
145 .name = "AC97",
146 .playback = {
147 .stream_name = "Playback",
148 .channels_min = 2,
149 .channels_max = 2,
150 .rates = SNDRV_PCM_RATE_48000,
151 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
152 .capture = {
153 .stream_name = "Capture",
154 .channels_min = 2,
155 .channels_max = 2,
156 .rates = SNDRV_PCM_RATE_48000,
157 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
158};
159EXPORT_SYMBOL_GPL(ad1980_dai);
160
161static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
162{
163 u16 retry_cnt = 0;
164
165retry:
166 if (try_warm && soc_ac97_ops.warm_reset) {
167 soc_ac97_ops.warm_reset(codec->ac97);
168 if (ac97_read(codec, AC97_RESET) == 0x0090)
169 return 1;
170 }
171
172 soc_ac97_ops.reset(codec->ac97);
173 /* Set bit 16slot in register 74h, then every slot will has only 16
174 * bits. This command is sent out in 20bit mode, in which case the
175 * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/
176 ac97_write(codec, AC97_AD_SERIAL_CFG, 0x9900);
177
178 if (ac97_read(codec, AC97_RESET) != 0x0090)
179 goto err;
180 return 0;
181
182err:
183 while (retry_cnt++ < 10)
184 goto retry;
185
186 printk(KERN_ERR "AD1980 AC97 reset failed\n");
187 return -EIO;
188}
189
190static int ad1980_soc_probe(struct platform_device *pdev)
191{
192 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
193 struct snd_soc_codec *codec;
194 int ret = 0;
195 u16 vendor_id2;
196
197 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
198
199 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
200 if (socdev->codec == NULL)
201 return -ENOMEM;
202 codec = socdev->codec;
203 mutex_init(&codec->mutex);
204
205 codec->reg_cache =
206 kzalloc(sizeof(u16) * ARRAY_SIZE(ad1980_reg), GFP_KERNEL);
207 if (codec->reg_cache == NULL) {
208 ret = -ENOMEM;
209 goto cache_err;
210 }
211 memcpy(codec->reg_cache, ad1980_reg, sizeof(u16) * \
212 ARRAY_SIZE(ad1980_reg));
213 codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(ad1980_reg);
214 codec->reg_cache_step = 2;
215 codec->name = "AD1980";
216 codec->owner = THIS_MODULE;
217 codec->dai = &ad1980_dai;
218 codec->num_dai = 1;
219 codec->write = ac97_write;
220 codec->read = ac97_read;
221 INIT_LIST_HEAD(&codec->dapm_widgets);
222 INIT_LIST_HEAD(&codec->dapm_paths);
223
224 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
225 if (ret < 0) {
226 printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
227 goto codec_err;
228 }
229
230 /* register pcms */
231 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
232 if (ret < 0)
233 goto pcm_err;
234
235
236 ret = ad1980_reset(codec, 0);
237 if (ret < 0) {
238 printk(KERN_ERR "AC97 link error\n");
239 goto reset_err;
240 }
241
242 /* Read out vendor ID to make sure it is ad1980 */
243 if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144)
244 goto reset_err;
245
246 vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2);
247
248 if (vendor_id2 != 0x5370) {
249 if (vendor_id2 != 0x5374)
250 goto reset_err;
251 else
252 printk(KERN_WARNING "ad1980: "
253 "Found AD1981 - only 2/2 IN/OUT Channels "
254 "supported\n");
255 }
256
257 ac97_write(codec, AC97_MASTER, 0x0000); /* unmute line out volume */
258 ac97_write(codec, AC97_PCM, 0x0000); /* unmute PCM out volume */
259 ac97_write(codec, AC97_REC_GAIN, 0x0000);/* unmute record volume */
260
261 ad1980_add_controls(codec);
262 ret = snd_soc_register_card(socdev);
263 if (ret < 0) {
264 printk(KERN_ERR "ad1980: failed to register card\n");
265 goto reset_err;
266 }
267
268 return 0;
269
270reset_err:
271 snd_soc_free_pcms(socdev);
272
273pcm_err:
274 snd_soc_free_ac97_codec(codec);
275
276codec_err:
277 kfree(codec->reg_cache);
278
279cache_err:
280 kfree(socdev->codec);
281 socdev->codec = NULL;
282 return ret;
283}
284
285static int ad1980_soc_remove(struct platform_device *pdev)
286{
287 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
288 struct snd_soc_codec *codec = socdev->codec;
289
290 if (codec == NULL)
291 return 0;
292
293 snd_soc_dapm_free(socdev);
294 snd_soc_free_pcms(socdev);
295 snd_soc_free_ac97_codec(codec);
296 kfree(codec->reg_cache);
297 kfree(codec);
298 return 0;
299}
300
301struct snd_soc_codec_device soc_codec_dev_ad1980 = {
302 .probe = ad1980_soc_probe,
303 .remove = ad1980_soc_remove,
304};
305EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980);
306
307MODULE_DESCRIPTION("ASoC ad1980 driver");
308MODULE_AUTHOR("Roy Huang, Cliff Cai");
309MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad1980.h b/sound/soc/codecs/ad1980.h
new file mode 100644
index 00000000000..db6c8500d66
--- /dev/null
+++ b/sound/soc/codecs/ad1980.h
@@ -0,0 +1,23 @@
1/*
2 * ad1980.h -- ad1980 Soc Audio driver
3 */
4
5#ifndef _AD1980_H
6#define _AD1980_H
7/* Bit definition of Power-Down Control/Status Register */
8#define ADC 0x0001
9#define DAC 0x0002
10#define ANL 0x0004
11#define REF 0x0008
12#define PR0 0x0100
13#define PR1 0x0200
14#define PR2 0x0400
15#define PR3 0x0800
16#define PR4 0x1000
17#define PR5 0x2000
18#define PR6 0x4000
19
20extern struct snd_soc_dai ad1980_dai;
21extern struct snd_soc_codec_device soc_codec_dev_ad1980;
22
23#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 7da9f467b7b..088cf992772 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -535,87 +535,85 @@ static struct snd_soc_device *ak4535_socdev;
535 535
536#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 536#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
537 537
538#define I2C_DRIVERID_AK4535 0xfefe /* liam - need a proper id */ 538static int ak4535_i2c_probe(struct i2c_client *i2c,
539 539 const struct i2c_device_id *id)
540static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
541
542/* Magic definition of all other variables and things */
543I2C_CLIENT_INSMOD;
544
545static struct i2c_driver ak4535_i2c_driver;
546static struct i2c_client client_template;
547
548/* If the i2c layer weren't so broken, we could pass this kind of data
549 around */
550static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
551{ 540{
552 struct snd_soc_device *socdev = ak4535_socdev; 541 struct snd_soc_device *socdev = ak4535_socdev;
553 struct ak4535_setup_data *setup = socdev->codec_data;
554 struct snd_soc_codec *codec = socdev->codec; 542 struct snd_soc_codec *codec = socdev->codec;
555 struct i2c_client *i2c;
556 int ret; 543 int ret;
557 544
558 if (addr != setup->i2c_address)
559 return -ENODEV;
560
561 client_template.adapter = adap;
562 client_template.addr = addr;
563
564 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
565 if (i2c == NULL)
566 return -ENOMEM;
567
568 i2c_set_clientdata(i2c, codec); 545 i2c_set_clientdata(i2c, codec);
569 codec->control_data = i2c; 546 codec->control_data = i2c;
570 547
571 ret = i2c_attach_client(i2c);
572 if (ret < 0) {
573 printk(KERN_ERR "failed to attach codec at addr %x\n", addr);
574 goto err;
575 }
576
577 ret = ak4535_init(socdev); 548 ret = ak4535_init(socdev);
578 if (ret < 0) { 549 if (ret < 0)
579 printk(KERN_ERR "failed to initialise AK4535\n"); 550 printk(KERN_ERR "failed to initialise AK4535\n");
580 goto err;
581 }
582 return ret;
583 551
584err:
585 kfree(i2c);
586 return ret; 552 return ret;
587} 553}
588 554
589static int ak4535_i2c_detach(struct i2c_client *client) 555static int ak4535_i2c_remove(struct i2c_client *client)
590{ 556{
591 struct snd_soc_codec *codec = i2c_get_clientdata(client); 557 struct snd_soc_codec *codec = i2c_get_clientdata(client);
592 i2c_detach_client(client);
593 kfree(codec->reg_cache); 558 kfree(codec->reg_cache);
594 kfree(client);
595 return 0; 559 return 0;
596} 560}
597 561
598static int ak4535_i2c_attach(struct i2c_adapter *adap) 562static const struct i2c_device_id ak4535_i2c_id[] = {
599{ 563 { "ak4535", 0 },
600 return i2c_probe(adap, &addr_data, ak4535_codec_probe); 564 { }
601} 565};
566MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
602 567
603/* corgi i2c codec control layer */
604static struct i2c_driver ak4535_i2c_driver = { 568static struct i2c_driver ak4535_i2c_driver = {
605 .driver = { 569 .driver = {
606 .name = "AK4535 I2C Codec", 570 .name = "AK4535 I2C Codec",
607 .owner = THIS_MODULE, 571 .owner = THIS_MODULE,
608 }, 572 },
609 .id = I2C_DRIVERID_AK4535, 573 .probe = ak4535_i2c_probe,
610 .attach_adapter = ak4535_i2c_attach, 574 .remove = ak4535_i2c_remove,
611 .detach_client = ak4535_i2c_detach, 575 .id_table = ak4535_i2c_id,
612 .command = NULL,
613}; 576};
614 577
615static struct i2c_client client_template = { 578static int ak4535_add_i2c_device(struct platform_device *pdev,
616 .name = "AK4535", 579 const struct ak4535_setup_data *setup)
617 .driver = &ak4535_i2c_driver, 580{
618}; 581 struct i2c_board_info info;
582 struct i2c_adapter *adapter;
583 struct i2c_client *client;
584 int ret;
585
586 ret = i2c_add_driver(&ak4535_i2c_driver);
587 if (ret != 0) {
588 dev_err(&pdev->dev, "can't add i2c driver\n");
589 return ret;
590 }
591
592 memset(&info, 0, sizeof(struct i2c_board_info));
593 info.addr = setup->i2c_address;
594 strlcpy(info.type, "ak4535", I2C_NAME_SIZE);
595
596 adapter = i2c_get_adapter(setup->i2c_bus);
597 if (!adapter) {
598 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
599 setup->i2c_bus);
600 goto err_driver;
601 }
602
603 client = i2c_new_device(adapter, &info);
604 i2c_put_adapter(adapter);
605 if (!client) {
606 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
607 (unsigned int)info.addr);
608 goto err_driver;
609 }
610
611 return 0;
612
613err_driver:
614 i2c_del_driver(&ak4535_i2c_driver);
615 return -ENODEV;
616}
619#endif 617#endif
620 618
621static int ak4535_probe(struct platform_device *pdev) 619static int ak4535_probe(struct platform_device *pdev)
@@ -624,7 +622,7 @@ static int ak4535_probe(struct platform_device *pdev)
624 struct ak4535_setup_data *setup; 622 struct ak4535_setup_data *setup;
625 struct snd_soc_codec *codec; 623 struct snd_soc_codec *codec;
626 struct ak4535_priv *ak4535; 624 struct ak4535_priv *ak4535;
627 int ret = 0; 625 int ret;
628 626
629 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); 627 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
630 628
@@ -646,17 +644,14 @@ static int ak4535_probe(struct platform_device *pdev)
646 INIT_LIST_HEAD(&codec->dapm_paths); 644 INIT_LIST_HEAD(&codec->dapm_paths);
647 645
648 ak4535_socdev = socdev; 646 ak4535_socdev = socdev;
647 ret = -ENODEV;
648
649#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 649#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
650 if (setup->i2c_address) { 650 if (setup->i2c_address) {
651 normal_i2c[0] = setup->i2c_address;
652 codec->hw_write = (hw_write_t)i2c_master_send; 651 codec->hw_write = (hw_write_t)i2c_master_send;
653 codec->hw_read = (hw_read_t)i2c_master_recv; 652 codec->hw_read = (hw_read_t)i2c_master_recv;
654 ret = i2c_add_driver(&ak4535_i2c_driver); 653 ret = ak4535_add_i2c_device(pdev, setup);
655 if (ret != 0)
656 printk(KERN_ERR "can't add i2c driver");
657 } 654 }
658#else
659 /* Add other interfaces here */
660#endif 655#endif
661 656
662 if (ret != 0) { 657 if (ret != 0) {
@@ -678,6 +673,7 @@ static int ak4535_remove(struct platform_device *pdev)
678 snd_soc_free_pcms(socdev); 673 snd_soc_free_pcms(socdev);
679 snd_soc_dapm_free(socdev); 674 snd_soc_dapm_free(socdev);
680#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 675#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
676 i2c_unregister_device(codec->control_data);
681 i2c_del_driver(&ak4535_i2c_driver); 677 i2c_del_driver(&ak4535_i2c_driver);
682#endif 678#endif
683 kfree(codec->private_data); 679 kfree(codec->private_data);
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h
index e9fe30e2c05..c7a58703ea3 100644
--- a/sound/soc/codecs/ak4535.h
+++ b/sound/soc/codecs/ak4535.h
@@ -37,6 +37,7 @@
37#define AK4535_CACHEREGNUM 0x10 37#define AK4535_CACHEREGNUM 0x10
38 38
39struct ak4535_setup_data { 39struct ak4535_setup_data {
40 int i2c_bus;
40 unsigned short i2c_address; 41 unsigned short i2c_address;
41}; 42};
42 43
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 9deb8c74fdf..0bbd94501d7 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -490,34 +490,7 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute)
490 490
491#endif 491#endif
492 492
493static int cs4270_i2c_probe(struct i2c_adapter *adap, int addr, int kind); 493static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *);
494
495/*
496 * Notify the driver that a new I2C bus has been found.
497 *
498 * This function is called for each I2C bus in the system. The function
499 * then asks the I2C subsystem to probe that bus at the addresses on which
500 * our device (the CS4270) could exist. If a device is found at one of
501 * those addresses, then our probe function (cs4270_i2c_probe) is called.
502 */
503static int cs4270_i2c_attach(struct i2c_adapter *adapter)
504{
505 return i2c_probe(adapter, &addr_data, cs4270_i2c_probe);
506}
507
508static int cs4270_i2c_detach(struct i2c_client *client)
509{
510 struct snd_soc_codec *codec = i2c_get_clientdata(client);
511
512 i2c_detach_client(client);
513 codec->control_data = NULL;
514
515 kfree(codec->reg_cache);
516 codec->reg_cache = NULL;
517
518 kfree(client);
519 return 0;
520}
521 494
522/* A list of non-DAPM controls that the CS4270 supports */ 495/* A list of non-DAPM controls that the CS4270 supports */
523static const struct snd_kcontrol_new cs4270_snd_controls[] = { 496static const struct snd_kcontrol_new cs4270_snd_controls[] = {
@@ -525,14 +498,19 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
525 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1) 498 CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1)
526}; 499};
527 500
501static const struct i2c_device_id cs4270_id[] = {
502 {"cs4270", 0},
503 {}
504};
505MODULE_DEVICE_TABLE(i2c, cs4270_id);
506
528static struct i2c_driver cs4270_i2c_driver = { 507static struct i2c_driver cs4270_i2c_driver = {
529 .driver = { 508 .driver = {
530 .name = "CS4270 I2C", 509 .name = "CS4270 I2C",
531 .owner = THIS_MODULE, 510 .owner = THIS_MODULE,
532 }, 511 },
533 .id = I2C_DRIVERID_CS4270, 512 .id_table = cs4270_id,
534 .attach_adapter = cs4270_i2c_attach, 513 .probe = cs4270_i2c_probe,
535 .detach_client = cs4270_i2c_detach,
536}; 514};
537 515
538/* 516/*
@@ -561,11 +539,11 @@ static struct snd_soc_device *cs4270_socdev;
561 * Note: snd_soc_new_pcms() must be called before this function can be called, 539 * Note: snd_soc_new_pcms() must be called before this function can be called,
562 * because of snd_ctl_add(). 540 * because of snd_ctl_add().
563 */ 541 */
564static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind) 542static int cs4270_i2c_probe(struct i2c_client *i2c_client,
543 const struct i2c_device_id *id)
565{ 544{
566 struct snd_soc_device *socdev = cs4270_socdev; 545 struct snd_soc_device *socdev = cs4270_socdev;
567 struct snd_soc_codec *codec = socdev->codec; 546 struct snd_soc_codec *codec = socdev->codec;
568 struct i2c_client *i2c_client = NULL;
569 int i; 547 int i;
570 int ret = 0; 548 int ret = 0;
571 549
@@ -578,12 +556,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
578 556
579 /* Note: codec_dai->codec is NULL here */ 557 /* Note: codec_dai->codec is NULL here */
580 558
581 i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
582 if (!i2c_client) {
583 printk(KERN_ERR "cs4270: could not allocate I2C client\n");
584 return -ENOMEM;
585 }
586
587 codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL); 559 codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL);
588 if (!codec->reg_cache) { 560 if (!codec->reg_cache) {
589 printk(KERN_ERR "cs4270: could not allocate register cache\n"); 561 printk(KERN_ERR "cs4270: could not allocate register cache\n");
@@ -591,13 +563,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
591 goto error; 563 goto error;
592 } 564 }
593 565
594 i2c_set_clientdata(i2c_client, codec);
595 strcpy(i2c_client->name, "CS4270");
596
597 i2c_client->driver = &cs4270_i2c_driver;
598 i2c_client->adapter = adapter;
599 i2c_client->addr = addr;
600
601 /* Verify that we have a CS4270 */ 566 /* Verify that we have a CS4270 */
602 567
603 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); 568 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
@@ -612,18 +577,10 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
612 goto error; 577 goto error;
613 } 578 }
614 579
615 printk(KERN_INFO "cs4270: found device at I2C address %X\n", addr); 580 printk(KERN_INFO "cs4270: found device at I2C address %X\n",
581 i2c_client->addr);
616 printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF); 582 printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF);
617 583
618 /* Tell the I2C layer a new client has arrived */
619
620 ret = i2c_attach_client(i2c_client);
621 if (ret) {
622 printk(KERN_ERR "cs4270: could not attach codec, "
623 "I2C address %x, error code %i\n", addr, ret);
624 goto error;
625 }
626
627 codec->control_data = i2c_client; 584 codec->control_data = i2c_client;
628 codec->read = cs4270_read_reg_cache; 585 codec->read = cs4270_read_reg_cache;
629 codec->write = cs4270_i2c_write; 586 codec->write = cs4270_i2c_write;
@@ -648,20 +605,17 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
648 goto error; 605 goto error;
649 } 606 }
650 607
608 i2c_set_clientdata(i2c_client, codec);
609
651 return 0; 610 return 0;
652 611
653error: 612error:
654 if (codec->control_data) { 613 codec->control_data = NULL;
655 i2c_detach_client(i2c_client);
656 codec->control_data = NULL;
657 }
658 614
659 kfree(codec->reg_cache); 615 kfree(codec->reg_cache);
660 codec->reg_cache = NULL; 616 codec->reg_cache = NULL;
661 codec->reg_cache_size = 0; 617 codec->reg_cache_size = 0;
662 618
663 kfree(i2c_client);
664
665 return ret; 619 return ret;
666} 620}
667 621
@@ -727,7 +681,7 @@ static int cs4270_probe(struct platform_device *pdev)
727 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 681 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
728 if (ret < 0) { 682 if (ret < 0) {
729 printk(KERN_ERR "cs4270: failed to create PCMs\n"); 683 printk(KERN_ERR "cs4270: failed to create PCMs\n");
730 return ret; 684 goto error_free_codec;
731 } 685 }
732 686
733#ifdef USE_I2C 687#ifdef USE_I2C
@@ -736,8 +690,7 @@ static int cs4270_probe(struct platform_device *pdev)
736 ret = i2c_add_driver(&cs4270_i2c_driver); 690 ret = i2c_add_driver(&cs4270_i2c_driver);
737 if (ret) { 691 if (ret) {
738 printk(KERN_ERR "cs4270: failed to attach driver"); 692 printk(KERN_ERR "cs4270: failed to attach driver");
739 snd_soc_free_pcms(socdev); 693 goto error_free_pcms;
740 return ret;
741 } 694 }
742 695
743 /* Did we find a CS4270 on the I2C bus? */ 696 /* Did we find a CS4270 on the I2C bus? */
@@ -759,10 +712,23 @@ static int cs4270_probe(struct platform_device *pdev)
759 ret = snd_soc_register_card(socdev); 712 ret = snd_soc_register_card(socdev);
760 if (ret < 0) { 713 if (ret < 0) {
761 printk(KERN_ERR "cs4270: failed to register card\n"); 714 printk(KERN_ERR "cs4270: failed to register card\n");
762 snd_soc_free_pcms(socdev); 715 goto error_del_driver;
763 return ret;
764 } 716 }
765 717
718 return 0;
719
720error_del_driver:
721#ifdef USE_I2C
722 i2c_del_driver(&cs4270_i2c_driver);
723
724error_free_pcms:
725#endif
726 snd_soc_free_pcms(socdev);
727
728error_free_codec:
729 kfree(socdev->codec);
730 socdev->codec = NULL;
731
766 return ret; 732 return ret;
767} 733}
768 734
@@ -773,8 +739,7 @@ static int cs4270_remove(struct platform_device *pdev)
773 snd_soc_free_pcms(socdev); 739 snd_soc_free_pcms(socdev);
774 740
775#ifdef USE_I2C 741#ifdef USE_I2C
776 if (socdev->codec->control_data) 742 i2c_del_driver(&cs4270_i2c_driver);
777 i2c_del_driver(&cs4270_i2c_driver);
778#endif 743#endif
779 744
780 kfree(socdev->codec); 745 kfree(socdev->codec);
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
new file mode 100644
index 00000000000..940ce1c3522
--- /dev/null
+++ b/sound/soc/codecs/ssm2602.c
@@ -0,0 +1,776 @@
1/*
2 * File: sound/soc/codecs/ssm2602.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 * Description: Driver for ssm2602 sound chip
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/pm.h>
34#include <linux/i2c.h>
35#include <linux/platform_device.h>
36#include <sound/core.h>
37#include <sound/pcm.h>
38#include <sound/pcm_params.h>
39#include <sound/soc.h>
40#include <sound/soc-dapm.h>
41#include <sound/initval.h>
42
43#include "ssm2602.h"
44
45#define AUDIO_NAME "ssm2602"
46#define SSM2602_VERSION "0.1"
47
48struct snd_soc_codec_device soc_codec_dev_ssm2602;
49
50/* codec private data */
51struct ssm2602_priv {
52 unsigned int sysclk;
53 struct snd_pcm_substream *master_substream;
54 struct snd_pcm_substream *slave_substream;
55};
56
57/*
58 * ssm2602 register cache
59 * We can't read the ssm2602 register space when we are
60 * using 2 wire for device control, so we cache them instead.
61 * There is no point in caching the reset register
62 */
63static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
64 0x0017, 0x0017, 0x0079, 0x0079,
65 0x0000, 0x0000, 0x0000, 0x000a,
66 0x0000, 0x0000
67};
68
69/*
70 * read ssm2602 register cache
71 */
72static inline unsigned int ssm2602_read_reg_cache(struct snd_soc_codec *codec,
73 unsigned int reg)
74{
75 u16 *cache = codec->reg_cache;
76 if (reg == SSM2602_RESET)
77 return 0;
78 if (reg >= SSM2602_CACHEREGNUM)
79 return -1;
80 return cache[reg];
81}
82
83/*
84 * write ssm2602 register cache
85 */
86static inline void ssm2602_write_reg_cache(struct snd_soc_codec *codec,
87 u16 reg, unsigned int value)
88{
89 u16 *cache = codec->reg_cache;
90 if (reg >= SSM2602_CACHEREGNUM)
91 return;
92 cache[reg] = value;
93}
94
95/*
96 * write to the ssm2602 register space
97 */
98static int ssm2602_write(struct snd_soc_codec *codec, unsigned int reg,
99 unsigned int value)
100{
101 u8 data[2];
102
103 /* data is
104 * D15..D9 ssm2602 register offset
105 * D8...D0 register data
106 */
107 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
108 data[1] = value & 0x00ff;
109
110 ssm2602_write_reg_cache(codec, reg, value);
111 if (codec->hw_write(codec->control_data, data, 2) == 2)
112 return 0;
113 else
114 return -EIO;
115}
116
117#define ssm2602_reset(c) ssm2602_write(c, SSM2602_RESET, 0)
118
119/*Appending several "None"s just for OSS mixer use*/
120static const char *ssm2602_input_select[] = {
121 "Line", "Mic", "None", "None", "None",
122 "None", "None", "None",
123};
124
125static const char *ssm2602_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
126
127static const struct soc_enum ssm2602_enum[] = {
128 SOC_ENUM_SINGLE(SSM2602_APANA, 2, 2, ssm2602_input_select),
129 SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph),
130};
131
132static const struct snd_kcontrol_new ssm2602_snd_controls[] = {
133
134SOC_DOUBLE_R("Master Playback Volume", SSM2602_LOUT1V, SSM2602_ROUT1V,
135 0, 127, 0),
136SOC_DOUBLE_R("Master Playback ZC Switch", SSM2602_LOUT1V, SSM2602_ROUT1V,
137 7, 1, 0),
138
139SOC_DOUBLE_R("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 31, 0),
140SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1),
141
142SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
143SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
144
145SOC_SINGLE("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1),
146
147SOC_SINGLE("ADC High Pass Filter Switch", SSM2602_APDIGI, 0, 1, 1),
148SOC_SINGLE("Store DC Offset Switch", SSM2602_APDIGI, 4, 1, 0),
149
150SOC_ENUM("Capture Source", ssm2602_enum[0]),
151
152SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]),
153};
154
155/* add non dapm controls */
156static int ssm2602_add_controls(struct snd_soc_codec *codec)
157{
158 int err, i;
159
160 for (i = 0; i < ARRAY_SIZE(ssm2602_snd_controls); i++) {
161 err = snd_ctl_add(codec->card,
162 snd_soc_cnew(&ssm2602_snd_controls[i], codec, NULL));
163 if (err < 0)
164 return err;
165 }
166
167 return 0;
168}
169
170/* Output Mixer */
171static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = {
172SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0),
173SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0),
174SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0),
175};
176
177/* Input mux */
178static const struct snd_kcontrol_new ssm2602_input_mux_controls =
179SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]);
180
181static const struct snd_soc_dapm_widget ssm2602_dapm_widgets[] = {
182SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1,
183 &ssm2602_output_mixer_controls[0],
184 ARRAY_SIZE(ssm2602_output_mixer_controls)),
185SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1),
186SND_SOC_DAPM_OUTPUT("LOUT"),
187SND_SOC_DAPM_OUTPUT("LHPOUT"),
188SND_SOC_DAPM_OUTPUT("ROUT"),
189SND_SOC_DAPM_OUTPUT("RHPOUT"),
190SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1),
191SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls),
192SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0),
193SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1),
194SND_SOC_DAPM_INPUT("MICIN"),
195SND_SOC_DAPM_INPUT("RLINEIN"),
196SND_SOC_DAPM_INPUT("LLINEIN"),
197};
198
199static const struct snd_soc_dapm_route audio_conn[] = {
200 /* output mixer */
201 {"Output Mixer", "Line Bypass Switch", "Line Input"},
202 {"Output Mixer", "HiFi Playback Switch", "DAC"},
203 {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
204
205 /* outputs */
206 {"RHPOUT", NULL, "Output Mixer"},
207 {"ROUT", NULL, "Output Mixer"},
208 {"LHPOUT", NULL, "Output Mixer"},
209 {"LOUT", NULL, "Output Mixer"},
210
211 /* input mux */
212 {"Input Mux", "Line", "Line Input"},
213 {"Input Mux", "Mic", "Mic Bias"},
214 {"ADC", NULL, "Input Mux"},
215
216 /* inputs */
217 {"Line Input", NULL, "LLINEIN"},
218 {"Line Input", NULL, "RLINEIN"},
219 {"Mic Bias", NULL, "MICIN"},
220};
221
222static int ssm2602_add_widgets(struct snd_soc_codec *codec)
223{
224 snd_soc_dapm_new_controls(codec, ssm2602_dapm_widgets,
225 ARRAY_SIZE(ssm2602_dapm_widgets));
226
227 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
228
229 snd_soc_dapm_new_widgets(codec);
230 return 0;
231}
232
233struct _coeff_div {
234 u32 mclk;
235 u32 rate;
236 u16 fs;
237 u8 sr:4;
238 u8 bosr:1;
239 u8 usb:1;
240};
241
242/* codec mclk clock divider coefficients */
243static const struct _coeff_div coeff_div[] = {
244 /* 48k */
245 {12288000, 48000, 256, 0x0, 0x0, 0x0},
246 {18432000, 48000, 384, 0x0, 0x1, 0x0},
247 {12000000, 48000, 250, 0x0, 0x0, 0x1},
248
249 /* 32k */
250 {12288000, 32000, 384, 0x6, 0x0, 0x0},
251 {18432000, 32000, 576, 0x6, 0x1, 0x0},
252 {12000000, 32000, 375, 0x6, 0x0, 0x1},
253
254 /* 8k */
255 {12288000, 8000, 1536, 0x3, 0x0, 0x0},
256 {18432000, 8000, 2304, 0x3, 0x1, 0x0},
257 {11289600, 8000, 1408, 0xb, 0x0, 0x0},
258 {16934400, 8000, 2112, 0xb, 0x1, 0x0},
259 {12000000, 8000, 1500, 0x3, 0x0, 0x1},
260
261 /* 96k */
262 {12288000, 96000, 128, 0x7, 0x0, 0x0},
263 {18432000, 96000, 192, 0x7, 0x1, 0x0},
264 {12000000, 96000, 125, 0x7, 0x0, 0x1},
265
266 /* 44.1k */
267 {11289600, 44100, 256, 0x8, 0x0, 0x0},
268 {16934400, 44100, 384, 0x8, 0x1, 0x0},
269 {12000000, 44100, 272, 0x8, 0x1, 0x1},
270
271 /* 88.2k */
272 {11289600, 88200, 128, 0xf, 0x0, 0x0},
273 {16934400, 88200, 192, 0xf, 0x1, 0x0},
274 {12000000, 88200, 136, 0xf, 0x1, 0x1},
275};
276
277static inline int get_coeff(int mclk, int rate)
278{
279 int i;
280
281 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
282 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
283 return i;
284 }
285 return i;
286}
287
288static int ssm2602_hw_params(struct snd_pcm_substream *substream,
289 struct snd_pcm_hw_params *params)
290{
291 u16 srate;
292 struct snd_soc_pcm_runtime *rtd = substream->private_data;
293 struct snd_soc_device *socdev = rtd->socdev;
294 struct snd_soc_codec *codec = socdev->codec;
295 struct ssm2602_priv *ssm2602 = codec->private_data;
296 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
297 int i = get_coeff(ssm2602->sysclk, params_rate(params));
298
299 /*no match is found*/
300 if (i == ARRAY_SIZE(coeff_div))
301 return -EINVAL;
302
303 srate = (coeff_div[i].sr << 2) |
304 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
305
306 ssm2602_write(codec, SSM2602_ACTIVE, 0);
307 ssm2602_write(codec, SSM2602_SRATE, srate);
308
309 /* bit size */
310 switch (params_format(params)) {
311 case SNDRV_PCM_FORMAT_S16_LE:
312 break;
313 case SNDRV_PCM_FORMAT_S20_3LE:
314 iface |= 0x0004;
315 break;
316 case SNDRV_PCM_FORMAT_S24_LE:
317 iface |= 0x0008;
318 break;
319 case SNDRV_PCM_FORMAT_S32_LE:
320 iface |= 0x000c;
321 break;
322 }
323 ssm2602_write(codec, SSM2602_IFACE, iface);
324 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
325 return 0;
326}
327
328static int ssm2602_startup(struct snd_pcm_substream *substream)
329{
330 struct snd_soc_pcm_runtime *rtd = substream->private_data;
331 struct snd_soc_device *socdev = rtd->socdev;
332 struct snd_soc_codec *codec = socdev->codec;
333 struct ssm2602_priv *ssm2602 = codec->private_data;
334 struct snd_pcm_runtime *master_runtime;
335
336 /* The DAI has shared clocks so if we already have a playback or
337 * capture going then constrain this substream to match it.
338 */
339 if (ssm2602->master_substream) {
340 master_runtime = ssm2602->master_substream->runtime;
341 snd_pcm_hw_constraint_minmax(substream->runtime,
342 SNDRV_PCM_HW_PARAM_RATE,
343 master_runtime->rate,
344 master_runtime->rate);
345
346 snd_pcm_hw_constraint_minmax(substream->runtime,
347 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
348 master_runtime->sample_bits,
349 master_runtime->sample_bits);
350
351 ssm2602->slave_substream = substream;
352 } else
353 ssm2602->master_substream = substream;
354
355 return 0;
356}
357
358static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream)
359{
360 struct snd_soc_pcm_runtime *rtd = substream->private_data;
361 struct snd_soc_device *socdev = rtd->socdev;
362 struct snd_soc_codec *codec = socdev->codec;
363 /* set active */
364 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
365
366 return 0;
367}
368
369static void ssm2602_shutdown(struct snd_pcm_substream *substream)
370{
371 struct snd_soc_pcm_runtime *rtd = substream->private_data;
372 struct snd_soc_device *socdev = rtd->socdev;
373 struct snd_soc_codec *codec = socdev->codec;
374 /* deactivate */
375 if (!codec->active)
376 ssm2602_write(codec, SSM2602_ACTIVE, 0);
377}
378
379static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
380{
381 struct snd_soc_codec *codec = dai->codec;
382 u16 mute_reg = ssm2602_read_reg_cache(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE;
383 if (mute)
384 ssm2602_write(codec, SSM2602_APDIGI,
385 mute_reg | APDIGI_ENABLE_DAC_MUTE);
386 else
387 ssm2602_write(codec, SSM2602_APDIGI, mute_reg);
388 return 0;
389}
390
391static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
392 int clk_id, unsigned int freq, int dir)
393{
394 struct snd_soc_codec *codec = codec_dai->codec;
395 struct ssm2602_priv *ssm2602 = codec->private_data;
396 switch (freq) {
397 case 11289600:
398 case 12000000:
399 case 12288000:
400 case 16934400:
401 case 18432000:
402 ssm2602->sysclk = freq;
403 return 0;
404 }
405 return -EINVAL;
406}
407
408static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
409 unsigned int fmt)
410{
411 struct snd_soc_codec *codec = codec_dai->codec;
412 u16 iface = 0;
413
414 /* set master/slave audio interface */
415 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
416 case SND_SOC_DAIFMT_CBM_CFM:
417 iface |= 0x0040;
418 break;
419 case SND_SOC_DAIFMT_CBS_CFS:
420 break;
421 default:
422 return -EINVAL;
423 }
424
425 /* interface format */
426 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
427 case SND_SOC_DAIFMT_I2S:
428 iface |= 0x0002;
429 break;
430 case SND_SOC_DAIFMT_RIGHT_J:
431 break;
432 case SND_SOC_DAIFMT_LEFT_J:
433 iface |= 0x0001;
434 break;
435 case SND_SOC_DAIFMT_DSP_A:
436 iface |= 0x0003;
437 break;
438 case SND_SOC_DAIFMT_DSP_B:
439 iface |= 0x0013;
440 break;
441 default:
442 return -EINVAL;
443 }
444
445 /* clock inversion */
446 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
447 case SND_SOC_DAIFMT_NB_NF:
448 break;
449 case SND_SOC_DAIFMT_IB_IF:
450 iface |= 0x0090;
451 break;
452 case SND_SOC_DAIFMT_IB_NF:
453 iface |= 0x0080;
454 break;
455 case SND_SOC_DAIFMT_NB_IF:
456 iface |= 0x0010;
457 break;
458 default:
459 return -EINVAL;
460 }
461
462 /* set iface */
463 ssm2602_write(codec, SSM2602_IFACE, iface);
464 return 0;
465}
466
467static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
468 enum snd_soc_bias_level level)
469{
470 u16 reg = ssm2602_read_reg_cache(codec, SSM2602_PWR) & 0xff7f;
471
472 switch (level) {
473 case SND_SOC_BIAS_ON:
474 /* vref/mid, osc on, dac unmute */
475 ssm2602_write(codec, SSM2602_PWR, reg);
476 break;
477 case SND_SOC_BIAS_PREPARE:
478 break;
479 case SND_SOC_BIAS_STANDBY:
480 /* everything off except vref/vmid, */
481 ssm2602_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN);
482 break;
483 case SND_SOC_BIAS_OFF:
484 /* everything off, dac mute, inactive */
485 ssm2602_write(codec, SSM2602_ACTIVE, 0);
486 ssm2602_write(codec, SSM2602_PWR, 0xffff);
487 break;
488
489 }
490 codec->bias_level = level;
491 return 0;
492}
493
494#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
495 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
496 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
497 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
498 SNDRV_PCM_RATE_96000)
499
500struct snd_soc_dai ssm2602_dai = {
501 .name = "SSM2602",
502 .playback = {
503 .stream_name = "Playback",
504 .channels_min = 2,
505 .channels_max = 2,
506 .rates = SSM2602_RATES,
507 .formats = SNDRV_PCM_FMTBIT_S32_LE,},
508 .capture = {
509 .stream_name = "Capture",
510 .channels_min = 2,
511 .channels_max = 2,
512 .rates = SSM2602_RATES,
513 .formats = SNDRV_PCM_FMTBIT_S32_LE,},
514 .ops = {
515 .startup = ssm2602_startup,
516 .prepare = ssm2602_pcm_prepare,
517 .hw_params = ssm2602_hw_params,
518 .shutdown = ssm2602_shutdown,
519 },
520 .dai_ops = {
521 .digital_mute = ssm2602_mute,
522 .set_sysclk = ssm2602_set_dai_sysclk,
523 .set_fmt = ssm2602_set_dai_fmt,
524 }
525};
526EXPORT_SYMBOL_GPL(ssm2602_dai);
527
528static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state)
529{
530 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
531 struct snd_soc_codec *codec = socdev->codec;
532
533 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
534 return 0;
535}
536
537static int ssm2602_resume(struct platform_device *pdev)
538{
539 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
540 struct snd_soc_codec *codec = socdev->codec;
541 int i;
542 u8 data[2];
543 u16 *cache = codec->reg_cache;
544
545 /* Sync reg_cache with the hardware */
546 for (i = 0; i < ARRAY_SIZE(ssm2602_reg); i++) {
547 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
548 data[1] = cache[i] & 0x00ff;
549 codec->hw_write(codec->control_data, data, 2);
550 }
551 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
552 ssm2602_set_bias_level(codec, codec->suspend_bias_level);
553 return 0;
554}
555
556/*
557 * initialise the ssm2602 driver
558 * register the mixer and dsp interfaces with the kernel
559 */
560static int ssm2602_init(struct snd_soc_device *socdev)
561{
562 struct snd_soc_codec *codec = socdev->codec;
563 int reg, ret = 0;
564
565 codec->name = "SSM2602";
566 codec->owner = THIS_MODULE;
567 codec->read = ssm2602_read_reg_cache;
568 codec->write = ssm2602_write;
569 codec->set_bias_level = ssm2602_set_bias_level;
570 codec->dai = &ssm2602_dai;
571 codec->num_dai = 1;
572 codec->reg_cache_size = sizeof(ssm2602_reg);
573 codec->reg_cache = kmemdup(ssm2602_reg, sizeof(ssm2602_reg),
574 GFP_KERNEL);
575 if (codec->reg_cache == NULL)
576 return -ENOMEM;
577
578 ssm2602_reset(codec);
579
580 /* register pcms */
581 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
582 if (ret < 0) {
583 pr_err("ssm2602: failed to create pcms\n");
584 goto pcm_err;
585 }
586 /*power on device*/
587 ssm2602_write(codec, SSM2602_ACTIVE, 0);
588 /* set the update bits */
589 reg = ssm2602_read_reg_cache(codec, SSM2602_LINVOL);
590 ssm2602_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH);
591 reg = ssm2602_read_reg_cache(codec, SSM2602_RINVOL);
592 ssm2602_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH);
593 reg = ssm2602_read_reg_cache(codec, SSM2602_LOUT1V);
594 ssm2602_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH);
595 reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V);
596 ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
597 /*select Line in as default input*/
598 ssm2602_write(codec, SSM2602_APANA,
599 APANA_ENABLE_MIC_BOOST2 | APANA_SELECT_DAC |
600 APANA_ENABLE_MIC_BOOST);
601 ssm2602_write(codec, SSM2602_PWR, 0);
602
603 ssm2602_add_controls(codec);
604 ssm2602_add_widgets(codec);
605 ret = snd_soc_register_card(socdev);
606 if (ret < 0) {
607 pr_err("ssm2602: failed to register card\n");
608 goto card_err;
609 }
610
611 return ret;
612
613card_err:
614 snd_soc_free_pcms(socdev);
615 snd_soc_dapm_free(socdev);
616pcm_err:
617 kfree(codec->reg_cache);
618 return ret;
619}
620
621static struct snd_soc_device *ssm2602_socdev;
622
623#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
624/*
625 * ssm2602 2 wire address is determined by GPIO5
626 * state during powerup.
627 * low = 0x1a
628 * high = 0x1b
629 */
630static int ssm2602_i2c_probe(struct i2c_client *i2c,
631 const struct i2c_device_id *id)
632{
633 struct snd_soc_device *socdev = ssm2602_socdev;
634 struct snd_soc_codec *codec = socdev->codec;
635 int ret;
636
637 i2c_set_clientdata(i2c, codec);
638 codec->control_data = i2c;
639
640 ret = ssm2602_init(socdev);
641 if (ret < 0)
642 pr_err("failed to initialise SSM2602\n");
643
644 return ret;
645}
646
647static int ssm2602_i2c_remove(struct i2c_client *client)
648{
649 struct snd_soc_codec *codec = i2c_get_clientdata(client);
650 kfree(codec->reg_cache);
651 return 0;
652}
653
654static const struct i2c_device_id ssm2602_i2c_id[] = {
655 { "ssm2602", 0 },
656 { }
657};
658MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
659/* corgi i2c codec control layer */
660static struct i2c_driver ssm2602_i2c_driver = {
661 .driver = {
662 .name = "SSM2602 I2C Codec",
663 .owner = THIS_MODULE,
664 },
665 .probe = ssm2602_i2c_probe,
666 .remove = ssm2602_i2c_remove,
667 .id_table = ssm2602_i2c_id,
668};
669
670static int ssm2602_add_i2c_device(struct platform_device *pdev,
671 const struct ssm2602_setup_data *setup)
672{
673 struct i2c_board_info info;
674 struct i2c_adapter *adapter;
675 struct i2c_client *client;
676 int ret;
677
678 ret = i2c_add_driver(&ssm2602_i2c_driver);
679 if (ret != 0) {
680 dev_err(&pdev->dev, "can't add i2c driver\n");
681 return ret;
682 }
683 memset(&info, 0, sizeof(struct i2c_board_info));
684 info.addr = setup->i2c_address;
685 strlcpy(info.type, "ssm2602", I2C_NAME_SIZE);
686 adapter = i2c_get_adapter(setup->i2c_bus);
687 if (!adapter) {
688 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
689 setup->i2c_bus);
690 goto err_driver;
691 }
692 client = i2c_new_device(adapter, &info);
693 i2c_put_adapter(adapter);
694 if (!client) {
695 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
696 (unsigned int)info.addr);
697 goto err_driver;
698 }
699 return 0;
700err_driver:
701 i2c_del_driver(&ssm2602_i2c_driver);
702 return -ENODEV;
703}
704#endif
705
706static int ssm2602_probe(struct platform_device *pdev)
707{
708 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
709 struct ssm2602_setup_data *setup;
710 struct snd_soc_codec *codec;
711 struct ssm2602_priv *ssm2602;
712 int ret = 0;
713
714 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
715
716 setup = socdev->codec_data;
717 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
718 if (codec == NULL)
719 return -ENOMEM;
720
721 ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
722 if (ssm2602 == NULL) {
723 kfree(codec);
724 return -ENOMEM;
725 }
726
727 codec->private_data = ssm2602;
728 socdev->codec = codec;
729 mutex_init(&codec->mutex);
730 INIT_LIST_HEAD(&codec->dapm_widgets);
731 INIT_LIST_HEAD(&codec->dapm_paths);
732
733 ssm2602_socdev = socdev;
734#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
735 if (setup->i2c_address) {
736 codec->hw_write = (hw_write_t)i2c_master_send;
737 ret = ssm2602_add_i2c_device(pdev, setup);
738 }
739#else
740 /* other interfaces */
741#endif
742 return ret;
743}
744
745/* remove everything here */
746static int ssm2602_remove(struct platform_device *pdev)
747{
748 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
749 struct snd_soc_codec *codec = socdev->codec;
750
751 if (codec->control_data)
752 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
753
754 snd_soc_free_pcms(socdev);
755 snd_soc_dapm_free(socdev);
756#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
757 i2c_unregister_device(codec->control_data);
758 i2c_del_driver(&ssm2602_i2c_driver);
759#endif
760 kfree(codec->private_data);
761 kfree(codec);
762
763 return 0;
764}
765
766struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
767 .probe = ssm2602_probe,
768 .remove = ssm2602_remove,
769 .suspend = ssm2602_suspend,
770 .resume = ssm2602_resume,
771};
772EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
773
774MODULE_DESCRIPTION("ASoC ssm2602 driver");
775MODULE_AUTHOR("Cliff Cai");
776MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h
new file mode 100644
index 00000000000..f344e6d76e3
--- /dev/null
+++ b/sound/soc/codecs/ssm2602.h
@@ -0,0 +1,130 @@
1/*
2 * File: sound/soc/codecs/ssm2602.h
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Tue June 06 2008
6 *
7 * Modified:
8 * Copyright 2008 Analog Devices Inc.
9 *
10 * Bugs: Enter bugs at http://blackfin.uclinux.org/
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see the file COPYING, or write
24 * to the Free Software Foundation, Inc.,
25 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 */
27
28#ifndef _SSM2602_H
29#define _SSM2602_H
30
31/* SSM2602 Codec Register definitions */
32
33#define SSM2602_LINVOL 0x00
34#define SSM2602_RINVOL 0x01
35#define SSM2602_LOUT1V 0x02
36#define SSM2602_ROUT1V 0x03
37#define SSM2602_APANA 0x04
38#define SSM2602_APDIGI 0x05
39#define SSM2602_PWR 0x06
40#define SSM2602_IFACE 0x07
41#define SSM2602_SRATE 0x08
42#define SSM2602_ACTIVE 0x09
43#define SSM2602_RESET 0x0f
44
45/*SSM2602 Codec Register Field definitions
46 *(Mask value to extract the corresponding Register field)
47 */
48
49/*Left ADC Volume Control (SSM2602_REG_LEFT_ADC_VOL)*/
50#define LINVOL_LIN_VOL 0x01F /* Left Channel PGA Volume control */
51#define LINVOL_LIN_ENABLE_MUTE 0x080 /* Left Channel Input Mute */
52#define LINVOL_LRIN_BOTH 0x100 /* Left Channel Line Input Volume update */
53
54/*Right ADC Volume Control (SSM2602_REG_RIGHT_ADC_VOL)*/
55#define RINVOL_RIN_VOL 0x01F /* Right Channel PGA Volume control */
56#define RINVOL_RIN_ENABLE_MUTE 0x080 /* Right Channel Input Mute */
57#define RINVOL_RLIN_BOTH 0x100 /* Right Channel Line Input Volume update */
58
59/*Left DAC Volume Control (SSM2602_REG_LEFT_DAC_VOL)*/
60#define LOUT1V_LHP_VOL 0x07F /* Left Channel Headphone volume control */
61#define LOUT1V_ENABLE_LZC 0x080 /* Left Channel Zero cross detect enable */
62#define LOUT1V_LRHP_BOTH 0x100 /* Left Channel Headphone volume update */
63
64/*Right DAC Volume Control (SSM2602_REG_RIGHT_DAC_VOL)*/
65#define ROUT1V_RHP_VOL 0x07F /* Right Channel Headphone volume control */
66#define ROUT1V_ENABLE_RZC 0x080 /* Right Channel Zero cross detect enable */
67#define ROUT1V_RLHP_BOTH 0x100 /* Right Channel Headphone volume update */
68
69/*Analogue Audio Path Control (SSM2602_REG_ANALOGUE_PATH)*/
70#define APANA_ENABLE_MIC_BOOST 0x001 /* Primary Microphone Amplifier gain booster control */
71#define APANA_ENABLE_MIC_MUTE 0x002 /* Microphone Mute Control */
72#define APANA_ADC_IN_SELECT 0x004 /* Microphone/Line IN select to ADC (1=MIC, 0=Line In) */
73#define APANA_ENABLE_BYPASS 0x008 /* Line input bypass to line output */
74#define APANA_SELECT_DAC 0x010 /* Select DAC (1=Select DAC, 0=Don't Select DAC) */
75#define APANA_ENABLE_SIDETONE 0x020 /* Enable/Disable Side Tone */
76#define APANA_SIDETONE_ATTN 0x0C0 /* Side Tone Attenuation */
77#define APANA_ENABLE_MIC_BOOST2 0x100 /* Secondary Microphone Amplifier gain booster control */
78
79/*Digital Audio Path Control (SSM2602_REG_DIGITAL_PATH)*/
80#define APDIGI_ENABLE_ADC_HPF 0x001 /* Enable/Disable ADC Highpass Filter */
81#define APDIGI_DE_EMPHASIS 0x006 /* De-Emphasis Control */
82#define APDIGI_ENABLE_DAC_MUTE 0x008 /* DAC Mute Control */
83#define APDIGI_STORE_OFFSET 0x010 /* Store/Clear DC offset when HPF is disabled */
84
85/*Power Down Control (SSM2602_REG_POWER)
86 *(1=Enable PowerDown, 0=Disable PowerDown)
87 */
88#define PWR_LINE_IN_PDN 0x001 /* Line Input Power Down */
89#define PWR_MIC_PDN 0x002 /* Microphone Input & Bias Power Down */
90#define PWR_ADC_PDN 0x004 /* ADC Power Down */
91#define PWR_DAC_PDN 0x008 /* DAC Power Down */
92#define PWR_OUT_PDN 0x010 /* Outputs Power Down */
93#define PWR_OSC_PDN 0x020 /* Oscillator Power Down */
94#define PWR_CLK_OUT_PDN 0x040 /* CLKOUT Power Down */
95#define PWR_POWER_OFF 0x080 /* POWEROFF Mode */
96
97/*Digital Audio Interface Format (SSM2602_REG_DIGITAL_IFACE)*/
98#define IFACE_IFACE_FORMAT 0x003 /* Digital Audio input format control */
99#define IFACE_AUDIO_DATA_LEN 0x00C /* Audio Data word length control */
100#define IFACE_DAC_LR_POLARITY 0x010 /* Polarity Control for clocks in RJ,LJ and I2S modes */
101#define IFACE_DAC_LR_SWAP 0x020 /* Swap DAC data control */
102#define IFACE_ENABLE_MASTER 0x040 /* Enable/Disable Master Mode */
103#define IFACE_BCLK_INVERT 0x080 /* Bit Clock Inversion control */
104
105/*Sampling Control (SSM2602_REG_SAMPLING_CTRL)*/
106#define SRATE_ENABLE_USB_MODE 0x001 /* Enable/Disable USB Mode */
107#define SRATE_BOS_RATE 0x002 /* Base Over-Sampling rate */
108#define SRATE_SAMPLE_RATE 0x03C /* Clock setting condition (Sampling rate control) */
109#define SRATE_CORECLK_DIV2 0x040 /* Core Clock divider select */
110#define SRATE_CLKOUT_DIV2 0x080 /* Clock Out divider select */
111
112/*Active Control (SSM2602_REG_ACTIVE_CTRL)*/
113#define ACTIVE_ACTIVATE_CODEC 0x001 /* Activate Codec Digital Audio Interface */
114
115/*********************************************************************/
116
117#define SSM2602_CACHEREGNUM 10
118
119#define SSM2602_SYSCLK 0
120#define SSM2602_DAI 0
121
122struct ssm2602_setup_data {
123 int i2c_bus;
124 unsigned short i2c_address;
125};
126
127extern struct snd_soc_dai ssm2602_dai;
128extern struct snd_soc_codec_device soc_codec_dev_ssm2602;
129
130#endif
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
new file mode 100644
index 00000000000..bed8a9e63dd
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -0,0 +1,520 @@
1/*
2 * Texas Instruments TLV320AIC26 low power audio CODEC
3 * ALSA SoC CODEC driver
4 *
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/init.h>
11#include <linux/delay.h>
12#include <linux/pm.h>
13#include <linux/device.h>
14#include <linux/sysfs.h>
15#include <linux/spi/spi.h>
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/pcm_params.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <sound/soc-of-simple.h>
22#include <sound/initval.h>
23
24#include "tlv320aic26.h"
25
26MODULE_DESCRIPTION("ASoC TLV320AIC26 codec driver");
27MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
28MODULE_LICENSE("GPL");
29
30/* AIC26 driver private data */
31struct aic26 {
32 struct spi_device *spi;
33 struct snd_soc_codec codec;
34 u16 reg_cache[AIC26_NUM_REGS]; /* shadow registers */
35 int master;
36 int datfm;
37 int mclk;
38
39 /* Keyclick parameters */
40 int keyclick_amplitude;
41 int keyclick_freq;
42 int keyclick_len;
43};
44
45/* ---------------------------------------------------------------------
46 * Register access routines
47 */
48static unsigned int aic26_reg_read(struct snd_soc_codec *codec,
49 unsigned int reg)
50{
51 struct aic26 *aic26 = codec->private_data;
52 u16 *cache = codec->reg_cache;
53 u16 cmd, value;
54 u8 buffer[2];
55 int rc;
56
57 if (reg >= AIC26_NUM_REGS) {
58 WARN_ON_ONCE(1);
59 return 0;
60 }
61
62 /* Do SPI transfer; first 16bits are command; remaining is
63 * register contents */
64 cmd = AIC26_READ_COMMAND_WORD(reg);
65 buffer[0] = (cmd >> 8) & 0xff;
66 buffer[1] = cmd & 0xff;
67 rc = spi_write_then_read(aic26->spi, buffer, 2, buffer, 2);
68 if (rc) {
69 dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
70 return -EIO;
71 }
72 value = (buffer[0] << 8) | buffer[1];
73
74 /* Update the cache before returning with the value */
75 cache[reg] = value;
76 return value;
77}
78
79static unsigned int aic26_reg_read_cache(struct snd_soc_codec *codec,
80 unsigned int reg)
81{
82 u16 *cache = codec->reg_cache;
83
84 if (reg >= AIC26_NUM_REGS) {
85 WARN_ON_ONCE(1);
86 return 0;
87 }
88
89 return cache[reg];
90}
91
92static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
93 unsigned int value)
94{
95 struct aic26 *aic26 = codec->private_data;
96 u16 *cache = codec->reg_cache;
97 u16 cmd;
98 u8 buffer[4];
99 int rc;
100
101 if (reg >= AIC26_NUM_REGS) {
102 WARN_ON_ONCE(1);
103 return -EINVAL;
104 }
105
106 /* Do SPI transfer; first 16bits are command; remaining is data
107 * to write into register */
108 cmd = AIC26_WRITE_COMMAND_WORD(reg);
109 buffer[0] = (cmd >> 8) & 0xff;
110 buffer[1] = cmd & 0xff;
111 buffer[2] = value >> 8;
112 buffer[3] = value;
113 rc = spi_write(aic26->spi, buffer, 4);
114 if (rc) {
115 dev_err(&aic26->spi->dev, "AIC26 reg read error\n");
116 return -EIO;
117 }
118
119 /* update cache before returning */
120 cache[reg] = value;
121 return 0;
122}
123
124/* ---------------------------------------------------------------------
125 * Digital Audio Interface Operations
126 */
127static int aic26_hw_params(struct snd_pcm_substream *substream,
128 struct snd_pcm_hw_params *params)
129{
130 struct snd_soc_pcm_runtime *rtd = substream->private_data;
131 struct snd_soc_device *socdev = rtd->socdev;
132 struct snd_soc_codec *codec = socdev->codec;
133 struct aic26 *aic26 = codec->private_data;
134 int fsref, divisor, wlen, pval, jval, dval, qval;
135 u16 reg;
136
137 dev_dbg(&aic26->spi->dev, "aic26_hw_params(substream=%p, params=%p)\n",
138 substream, params);
139 dev_dbg(&aic26->spi->dev, "rate=%i format=%i\n", params_rate(params),
140 params_format(params));
141
142 switch (params_rate(params)) {
143 case 8000: fsref = 48000; divisor = AIC26_DIV_6; break;
144 case 11025: fsref = 44100; divisor = AIC26_DIV_4; break;
145 case 12000: fsref = 48000; divisor = AIC26_DIV_4; break;
146 case 16000: fsref = 48000; divisor = AIC26_DIV_3; break;
147 case 22050: fsref = 44100; divisor = AIC26_DIV_2; break;
148 case 24000: fsref = 48000; divisor = AIC26_DIV_2; break;
149 case 32000: fsref = 48000; divisor = AIC26_DIV_1_5; break;
150 case 44100: fsref = 44100; divisor = AIC26_DIV_1; break;
151 case 48000: fsref = 48000; divisor = AIC26_DIV_1; break;
152 default:
153 dev_dbg(&aic26->spi->dev, "bad rate\n"); return -EINVAL;
154 }
155
156 /* select data word length */
157 switch (params_format(params)) {
158 case SNDRV_PCM_FORMAT_S8: wlen = AIC26_WLEN_16; break;
159 case SNDRV_PCM_FORMAT_S16_BE: wlen = AIC26_WLEN_16; break;
160 case SNDRV_PCM_FORMAT_S24_BE: wlen = AIC26_WLEN_24; break;
161 case SNDRV_PCM_FORMAT_S32_BE: wlen = AIC26_WLEN_32; break;
162 default:
163 dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
164 }
165
166 /* Configure PLL */
167 pval = 1;
168 jval = (fsref == 44100) ? 7 : 8;
169 dval = (fsref == 44100) ? 5264 : 1920;
170 qval = 0;
171 reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
172 aic26_reg_write(codec, AIC26_REG_PLL_PROG1, reg);
173 reg = dval << 2;
174 aic26_reg_write(codec, AIC26_REG_PLL_PROG2, reg);
175
176 /* Audio Control 3 (master mode, fsref rate) */
177 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL3);
178 reg &= ~0xf800;
179 if (aic26->master)
180 reg |= 0x0800;
181 if (fsref == 48000)
182 reg |= 0x2000;
183 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
184
185 /* Audio Control 1 (FSref divisor) */
186 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL1);
187 reg &= ~0x0fff;
188 reg |= wlen | aic26->datfm | (divisor << 3) | divisor;
189 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL1, reg);
190
191 return 0;
192}
193
194/**
195 * aic26_mute - Mute control to reduce noise when changing audio format
196 */
197static int aic26_mute(struct snd_soc_dai *dai, int mute)
198{
199 struct snd_soc_codec *codec = dai->codec;
200 struct aic26 *aic26 = codec->private_data;
201 u16 reg = aic26_reg_read_cache(codec, AIC26_REG_DAC_GAIN);
202
203 dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n",
204 dai, mute);
205
206 if (mute)
207 reg |= 0x8080;
208 else
209 reg &= ~0x8080;
210 aic26_reg_write(codec, AIC26_REG_DAC_GAIN, reg);
211
212 return 0;
213}
214
215static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
216 int clk_id, unsigned int freq, int dir)
217{
218 struct snd_soc_codec *codec = codec_dai->codec;
219 struct aic26 *aic26 = codec->private_data;
220
221 dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i,"
222 " freq=%i, dir=%i)\n",
223 codec_dai, clk_id, freq, dir);
224
225 /* MCLK needs to fall between 2MHz and 50 MHz */
226 if ((freq < 2000000) || (freq > 50000000))
227 return -EINVAL;
228
229 aic26->mclk = freq;
230 return 0;
231}
232
233static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
234{
235 struct snd_soc_codec *codec = codec_dai->codec;
236 struct aic26 *aic26 = codec->private_data;
237
238 dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n",
239 codec_dai, fmt);
240
241 /* set master/slave audio interface */
242 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
243 case SND_SOC_DAIFMT_CBM_CFM: aic26->master = 1; break;
244 case SND_SOC_DAIFMT_CBS_CFS: aic26->master = 0; break;
245 default:
246 dev_dbg(&aic26->spi->dev, "bad master\n"); return -EINVAL;
247 }
248
249 /* interface format */
250 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
251 case SND_SOC_DAIFMT_I2S: aic26->datfm = AIC26_DATFM_I2S; break;
252 case SND_SOC_DAIFMT_DSP_A: aic26->datfm = AIC26_DATFM_DSP; break;
253 case SND_SOC_DAIFMT_RIGHT_J: aic26->datfm = AIC26_DATFM_RIGHTJ; break;
254 case SND_SOC_DAIFMT_LEFT_J: aic26->datfm = AIC26_DATFM_LEFTJ; break;
255 default:
256 dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
257 }
258
259 return 0;
260}
261
262/* ---------------------------------------------------------------------
263 * Digital Audio Interface Definition
264 */
265#define AIC26_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
266 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
267 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
268 SNDRV_PCM_RATE_48000)
269#define AIC26_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |\
270 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
271
272struct snd_soc_dai aic26_dai = {
273 .name = "tlv320aic26",
274 .playback = {
275 .stream_name = "Playback",
276 .channels_min = 2,
277 .channels_max = 2,
278 .rates = AIC26_RATES,
279 .formats = AIC26_FORMATS,
280 },
281 .capture = {
282 .stream_name = "Capture",
283 .channels_min = 2,
284 .channels_max = 2,
285 .rates = AIC26_RATES,
286 .formats = AIC26_FORMATS,
287 },
288 .ops = {
289 .hw_params = aic26_hw_params,
290 },
291 .dai_ops = {
292 .digital_mute = aic26_mute,
293 .set_sysclk = aic26_set_sysclk,
294 .set_fmt = aic26_set_fmt,
295 },
296};
297EXPORT_SYMBOL_GPL(aic26_dai);
298
299/* ---------------------------------------------------------------------
300 * ALSA controls
301 */
302static const char *aic26_capture_src_text[] = {"Mic", "Aux"};
303static const struct soc_enum aic26_capture_src_enum =
304 SOC_ENUM_SINGLE(AIC26_REG_AUDIO_CTRL1, 12, 2, aic26_capture_src_text);
305
306static const struct snd_kcontrol_new aic26_snd_controls[] = {
307 /* Output */
308 SOC_DOUBLE("PCM Playback Volume", AIC26_REG_DAC_GAIN, 8, 0, 0x7f, 1),
309 SOC_DOUBLE("PCM Playback Switch", AIC26_REG_DAC_GAIN, 15, 7, 1, 1),
310 SOC_SINGLE("PCM Capture Volume", AIC26_REG_ADC_GAIN, 8, 0x7f, 0),
311 SOC_SINGLE("PCM Capture Mute", AIC26_REG_ADC_GAIN, 15, 1, 1),
312 SOC_SINGLE("Keyclick activate", AIC26_REG_AUDIO_CTRL2, 15, 0x1, 0),
313 SOC_SINGLE("Keyclick amplitude", AIC26_REG_AUDIO_CTRL2, 12, 0x7, 0),
314 SOC_SINGLE("Keyclick frequency", AIC26_REG_AUDIO_CTRL2, 8, 0x7, 0),
315 SOC_SINGLE("Keyclick period", AIC26_REG_AUDIO_CTRL2, 4, 0xf, 0),
316 SOC_ENUM("Capture Source", aic26_capture_src_enum),
317};
318
319/* ---------------------------------------------------------------------
320 * SoC CODEC portion of driver: probe and release routines
321 */
322static int aic26_probe(struct platform_device *pdev)
323{
324 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
325 struct snd_soc_codec *codec;
326 struct snd_kcontrol *kcontrol;
327 struct aic26 *aic26;
328 int i, ret, err;
329
330 dev_info(&pdev->dev, "Probing AIC26 SoC CODEC driver\n");
331 dev_dbg(&pdev->dev, "socdev=%p\n", socdev);
332 dev_dbg(&pdev->dev, "codec_data=%p\n", socdev->codec_data);
333
334 /* Fetch the relevant aic26 private data here (it's already been
335 * stored in the .codec pointer) */
336 aic26 = socdev->codec_data;
337 if (aic26 == NULL) {
338 dev_err(&pdev->dev, "aic26: missing codec pointer\n");
339 return -ENODEV;
340 }
341 codec = &aic26->codec;
342 socdev->codec = codec;
343
344 dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n",
345 &pdev->dev, socdev->dev);
346 /* register pcms */
347 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
348 if (ret < 0) {
349 dev_err(&pdev->dev, "aic26: failed to create pcms\n");
350 return -ENODEV;
351 }
352
353 /* register controls */
354 dev_dbg(&pdev->dev, "Registering controls\n");
355 for (i = 0; i < ARRAY_SIZE(aic26_snd_controls); i++) {
356 kcontrol = snd_soc_cnew(&aic26_snd_controls[i], codec, NULL);
357 err = snd_ctl_add(codec->card, kcontrol);
358 WARN_ON(err < 0);
359 }
360
361 /* CODEC is setup, we can register the card now */
362 dev_dbg(&pdev->dev, "Registering card\n");
363 ret = snd_soc_register_card(socdev);
364 if (ret < 0) {
365 dev_err(&pdev->dev, "aic26: failed to register card\n");
366 goto card_err;
367 }
368 return 0;
369
370 card_err:
371 snd_soc_free_pcms(socdev);
372 return ret;
373}
374
375static int aic26_remove(struct platform_device *pdev)
376{
377 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
378 snd_soc_free_pcms(socdev);
379 return 0;
380}
381
382struct snd_soc_codec_device aic26_soc_codec_dev = {
383 .probe = aic26_probe,
384 .remove = aic26_remove,
385};
386EXPORT_SYMBOL_GPL(aic26_soc_codec_dev);
387
388/* ---------------------------------------------------------------------
389 * SPI device portion of driver: sysfs files for debugging
390 */
391
392static ssize_t aic26_keyclick_show(struct device *dev,
393 struct device_attribute *attr, char *buf)
394{
395 struct aic26 *aic26 = dev_get_drvdata(dev);
396 int val, amp, freq, len;
397
398 val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2);
399 amp = (val >> 12) & 0x7;
400 freq = (125 << ((val >> 8) & 0x7)) >> 1;
401 len = 2 * (1 + ((val >> 4) & 0xf));
402
403 return sprintf(buf, "amp=%x freq=%iHz len=%iclks\n", amp, freq, len);
404}
405
406/* Any write to the keyclick attribute will trigger the keyclick event */
407static ssize_t aic26_keyclick_set(struct device *dev,
408 struct device_attribute *attr,
409 const char *buf, size_t count)
410{
411 struct aic26 *aic26 = dev_get_drvdata(dev);
412 int val;
413
414 val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2);
415 val |= 0x8000;
416 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL2, val);
417
418 return count;
419}
420
421static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
422
423/* ---------------------------------------------------------------------
424 * SPI device portion of driver: probe and release routines and SPI
425 * driver registration.
426 */
427static int aic26_spi_probe(struct spi_device *spi)
428{
429 struct aic26 *aic26;
430 int rc, i, reg;
431
432 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
433
434 /* Allocate driver data */
435 aic26 = kzalloc(sizeof *aic26, GFP_KERNEL);
436 if (!aic26)
437 return -ENOMEM;
438
439 /* Initialize the driver data */
440 aic26->spi = spi;
441 dev_set_drvdata(&spi->dev, aic26);
442
443 /* Setup what we can in the codec structure so that the register
444 * access functions will work as expected. More will be filled
445 * out when it is probed by the SoC CODEC part of this driver */
446 aic26->codec.private_data = aic26;
447 aic26->codec.name = "aic26";
448 aic26->codec.owner = THIS_MODULE;
449 aic26->codec.dai = &aic26_dai;
450 aic26->codec.num_dai = 1;
451 aic26->codec.read = aic26_reg_read;
452 aic26->codec.write = aic26_reg_write;
453 aic26->master = 1;
454 mutex_init(&aic26->codec.mutex);
455 INIT_LIST_HEAD(&aic26->codec.dapm_widgets);
456 INIT_LIST_HEAD(&aic26->codec.dapm_paths);
457 aic26->codec.reg_cache_size = AIC26_NUM_REGS;
458 aic26->codec.reg_cache = aic26->reg_cache;
459
460 /* Reset the codec to power on defaults */
461 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00);
462
463 /* Power up CODEC */
464 aic26_reg_write(&aic26->codec, AIC26_REG_POWER_CTRL, 0);
465
466 /* Audio Control 3 (master mode, fsref rate) */
467 reg = aic26_reg_read(&aic26->codec, AIC26_REG_AUDIO_CTRL3);
468 reg &= ~0xf800;
469 reg |= 0x0800; /* set master mode */
470 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL3, reg);
471
472 /* Fill register cache */
473 for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++)
474 aic26_reg_read(&aic26->codec, i);
475
476 /* Register the sysfs files for debugging */
477 /* Create SysFS files */
478 rc = device_create_file(&spi->dev, &dev_attr_keyclick);
479 if (rc)
480 dev_info(&spi->dev, "error creating sysfs files\n");
481
482#if defined(CONFIG_SND_SOC_OF_SIMPLE)
483 /* Tell the of_soc helper about this codec */
484 of_snd_soc_register_codec(&aic26_soc_codec_dev, aic26, &aic26_dai,
485 spi->dev.archdata.of_node);
486#endif
487
488 dev_dbg(&spi->dev, "SPI device initialized\n");
489 return 0;
490}
491
492static int aic26_spi_remove(struct spi_device *spi)
493{
494 struct aic26 *aic26 = dev_get_drvdata(&spi->dev);
495
496 kfree(aic26);
497
498 return 0;
499}
500
501static struct spi_driver aic26_spi = {
502 .driver = {
503 .name = "tlv320aic26",
504 .owner = THIS_MODULE,
505 },
506 .probe = aic26_spi_probe,
507 .remove = aic26_spi_remove,
508};
509
510static int __init aic26_init(void)
511{
512 return spi_register_driver(&aic26_spi);
513}
514module_init(aic26_init);
515
516static void __exit aic26_exit(void)
517{
518 spi_unregister_driver(&aic26_spi);
519}
520module_exit(aic26_exit);
diff --git a/sound/soc/codecs/tlv320aic26.h b/sound/soc/codecs/tlv320aic26.h
new file mode 100644
index 00000000000..786ba16c945
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic26.h
@@ -0,0 +1,96 @@
1/*
2 * Texas Instruments TLV320AIC26 low power audio CODEC
3 * register definitions
4 *
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
6 */
7
8#ifndef _TLV320AIC16_H_
9#define _TLV320AIC16_H_
10
11/* AIC26 Registers */
12#define AIC26_READ_COMMAND_WORD(addr) ((1 << 15) | (addr << 5))
13#define AIC26_WRITE_COMMAND_WORD(addr) ((0 << 15) | (addr << 5))
14#define AIC26_PAGE_ADDR(page, offset) ((page << 6) | offset)
15#define AIC26_NUM_REGS AIC26_PAGE_ADDR(3, 0)
16
17/* Page 0: Auxillary data registers */
18#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05)
19#define AIC26_REG_BAT2 AIC26_PAGE_ADDR(0, 0x06)
20#define AIC26_REG_AUX AIC26_PAGE_ADDR(0, 0x07)
21#define AIC26_REG_TEMP1 AIC26_PAGE_ADDR(0, 0x09)
22#define AIC26_REG_TEMP2 AIC26_PAGE_ADDR(0, 0x0A)
23
24/* Page 1: Auxillary control registers */
25#define AIC26_REG_AUX_ADC AIC26_PAGE_ADDR(1, 0x00)
26#define AIC26_REG_STATUS AIC26_PAGE_ADDR(1, 0x01)
27#define AIC26_REG_REFERENCE AIC26_PAGE_ADDR(1, 0x03)
28#define AIC26_REG_RESET AIC26_PAGE_ADDR(1, 0x04)
29
30/* Page 2: Audio control registers */
31#define AIC26_REG_AUDIO_CTRL1 AIC26_PAGE_ADDR(2, 0x00)
32#define AIC26_REG_ADC_GAIN AIC26_PAGE_ADDR(2, 0x01)
33#define AIC26_REG_DAC_GAIN AIC26_PAGE_ADDR(2, 0x02)
34#define AIC26_REG_SIDETONE AIC26_PAGE_ADDR(2, 0x03)
35#define AIC26_REG_AUDIO_CTRL2 AIC26_PAGE_ADDR(2, 0x04)
36#define AIC26_REG_POWER_CTRL AIC26_PAGE_ADDR(2, 0x05)
37#define AIC26_REG_AUDIO_CTRL3 AIC26_PAGE_ADDR(2, 0x06)
38
39#define AIC26_REG_FILTER_COEFF_L_N0 AIC26_PAGE_ADDR(2, 0x07)
40#define AIC26_REG_FILTER_COEFF_L_N1 AIC26_PAGE_ADDR(2, 0x08)
41#define AIC26_REG_FILTER_COEFF_L_N2 AIC26_PAGE_ADDR(2, 0x09)
42#define AIC26_REG_FILTER_COEFF_L_N3 AIC26_PAGE_ADDR(2, 0x0A)
43#define AIC26_REG_FILTER_COEFF_L_N4 AIC26_PAGE_ADDR(2, 0x0B)
44#define AIC26_REG_FILTER_COEFF_L_N5 AIC26_PAGE_ADDR(2, 0x0C)
45#define AIC26_REG_FILTER_COEFF_L_D1 AIC26_PAGE_ADDR(2, 0x0D)
46#define AIC26_REG_FILTER_COEFF_L_D2 AIC26_PAGE_ADDR(2, 0x0E)
47#define AIC26_REG_FILTER_COEFF_L_D4 AIC26_PAGE_ADDR(2, 0x0F)
48#define AIC26_REG_FILTER_COEFF_L_D5 AIC26_PAGE_ADDR(2, 0x10)
49#define AIC26_REG_FILTER_COEFF_R_N0 AIC26_PAGE_ADDR(2, 0x11)
50#define AIC26_REG_FILTER_COEFF_R_N1 AIC26_PAGE_ADDR(2, 0x12)
51#define AIC26_REG_FILTER_COEFF_R_N2 AIC26_PAGE_ADDR(2, 0x13)
52#define AIC26_REG_FILTER_COEFF_R_N3 AIC26_PAGE_ADDR(2, 0x14)
53#define AIC26_REG_FILTER_COEFF_R_N4 AIC26_PAGE_ADDR(2, 0x15)
54#define AIC26_REG_FILTER_COEFF_R_N5 AIC26_PAGE_ADDR(2, 0x16)
55#define AIC26_REG_FILTER_COEFF_R_D1 AIC26_PAGE_ADDR(2, 0x17)
56#define AIC26_REG_FILTER_COEFF_R_D2 AIC26_PAGE_ADDR(2, 0x18)
57#define AIC26_REG_FILTER_COEFF_R_D4 AIC26_PAGE_ADDR(2, 0x19)
58#define AIC26_REG_FILTER_COEFF_R_D5 AIC26_PAGE_ADDR(2, 0x1A)
59
60#define AIC26_REG_PLL_PROG1 AIC26_PAGE_ADDR(2, 0x1B)
61#define AIC26_REG_PLL_PROG2 AIC26_PAGE_ADDR(2, 0x1C)
62#define AIC26_REG_AUDIO_CTRL4 AIC26_PAGE_ADDR(2, 0x1D)
63#define AIC26_REG_AUDIO_CTRL5 AIC26_PAGE_ADDR(2, 0x1E)
64
65/* fsref dividers; used in register 'Audio Control 1' */
66enum aic26_divisors {
67 AIC26_DIV_1 = 0,
68 AIC26_DIV_1_5 = 1,
69 AIC26_DIV_2 = 2,
70 AIC26_DIV_3 = 3,
71 AIC26_DIV_4 = 4,
72 AIC26_DIV_5 = 5,
73 AIC26_DIV_5_5 = 6,
74 AIC26_DIV_6 = 7,
75};
76
77/* Digital data format */
78enum aic26_datfm {
79 AIC26_DATFM_I2S = 0 << 8,
80 AIC26_DATFM_DSP = 1 << 8,
81 AIC26_DATFM_RIGHTJ = 2 << 8, /* right justified */
82 AIC26_DATFM_LEFTJ = 3 << 8, /* left justified */
83};
84
85/* Sample word length in bits; used in register 'Audio Control 1' */
86enum aic26_wlen {
87 AIC26_WLEN_16 = 0 << 10,
88 AIC26_WLEN_20 = 1 << 10,
89 AIC26_WLEN_24 = 2 << 10,
90 AIC26_WLEN_32 = 3 << 10,
91};
92
93extern struct snd_soc_dai aic26_dai;
94extern struct snd_soc_codec_device aic26_soc_codec_dev;
95
96#endif /* _TLV320AIC16_H_ */
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 5f9abb19943..566a427c928 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC TLV320AIC3X codec driver 2 * ALSA SoC TLV320AIC3X codec driver
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood 7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood
@@ -1172,71 +1172,39 @@ static struct snd_soc_device *aic3x_socdev;
1172 * AIC3X 2 wire address can be up to 4 devices with device addresses 1172 * AIC3X 2 wire address can be up to 4 devices with device addresses
1173 * 0x18, 0x19, 0x1A, 0x1B 1173 * 0x18, 0x19, 0x1A, 0x1B
1174 */ 1174 */
1175static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1176
1177/* Magic definition of all other variables and things */
1178I2C_CLIENT_INSMOD;
1179
1180static struct i2c_driver aic3x_i2c_driver;
1181static struct i2c_client client_template;
1182 1175
1183/* 1176/*
1184 * If the i2c layer weren't so broken, we could pass this kind of data 1177 * If the i2c layer weren't so broken, we could pass this kind of data
1185 * around 1178 * around
1186 */ 1179 */
1187static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind) 1180static int aic3x_i2c_probe(struct i2c_client *i2c,
1181 const struct i2c_device_id *id)
1188{ 1182{
1189 struct snd_soc_device *socdev = aic3x_socdev; 1183 struct snd_soc_device *socdev = aic3x_socdev;
1190 struct aic3x_setup_data *setup = socdev->codec_data;
1191 struct snd_soc_codec *codec = socdev->codec; 1184 struct snd_soc_codec *codec = socdev->codec;
1192 struct i2c_client *i2c;
1193 int ret; 1185 int ret;
1194 1186
1195 if (addr != setup->i2c_address)
1196 return -ENODEV;
1197
1198 client_template.adapter = adap;
1199 client_template.addr = addr;
1200
1201 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1202 if (i2c == NULL)
1203 return -ENOMEM;
1204
1205 i2c_set_clientdata(i2c, codec); 1187 i2c_set_clientdata(i2c, codec);
1206 codec->control_data = i2c; 1188 codec->control_data = i2c;
1207 1189
1208 ret = i2c_attach_client(i2c);
1209 if (ret < 0) {
1210 printk(KERN_ERR "aic3x: failed to attach codec at addr %x\n",
1211 addr);
1212 goto err;
1213 }
1214
1215 ret = aic3x_init(socdev); 1190 ret = aic3x_init(socdev);
1216 if (ret < 0) { 1191 if (ret < 0)
1217 printk(KERN_ERR "aic3x: failed to initialise AIC3X\n"); 1192 printk(KERN_ERR "aic3x: failed to initialise AIC3X\n");
1218 goto err;
1219 }
1220 return ret;
1221
1222err:
1223 kfree(i2c);
1224 return ret; 1193 return ret;
1225} 1194}
1226 1195
1227static int aic3x_i2c_detach(struct i2c_client *client) 1196static int aic3x_i2c_remove(struct i2c_client *client)
1228{ 1197{
1229 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1198 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1230 i2c_detach_client(client);
1231 kfree(codec->reg_cache); 1199 kfree(codec->reg_cache);
1232 kfree(client);
1233 return 0; 1200 return 0;
1234} 1201}
1235 1202
1236static int aic3x_i2c_attach(struct i2c_adapter *adap) 1203static const struct i2c_device_id aic3x_i2c_id[] = {
1237{ 1204 { "tlv320aic3x", 0 },
1238 return i2c_probe(adap, &addr_data, aic3x_codec_probe); 1205 { }
1239} 1206};
1207MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
1240 1208
1241/* machine i2c codec control layer */ 1209/* machine i2c codec control layer */
1242static struct i2c_driver aic3x_i2c_driver = { 1210static struct i2c_driver aic3x_i2c_driver = {
@@ -1244,13 +1212,9 @@ static struct i2c_driver aic3x_i2c_driver = {
1244 .name = "aic3x I2C Codec", 1212 .name = "aic3x I2C Codec",
1245 .owner = THIS_MODULE, 1213 .owner = THIS_MODULE,
1246 }, 1214 },
1247 .attach_adapter = aic3x_i2c_attach, 1215 .probe = aic3x_i2c_probe,
1248 .detach_client = aic3x_i2c_detach, 1216 .remove = aic3x_i2c_remove,
1249}; 1217 .id_table = aic3x_i2c_id,
1250
1251static struct i2c_client client_template = {
1252 .name = "AIC3X",
1253 .driver = &aic3x_i2c_driver,
1254}; 1218};
1255 1219
1256static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len) 1220static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len)
@@ -1258,6 +1222,46 @@ static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len)
1258 value[0] = i2c_smbus_read_byte_data(client, value[0]); 1222 value[0] = i2c_smbus_read_byte_data(client, value[0]);
1259 return (len == 1); 1223 return (len == 1);
1260} 1224}
1225
1226static int aic3x_add_i2c_device(struct platform_device *pdev,
1227 const struct aic3x_setup_data *setup)
1228{
1229 struct i2c_board_info info;
1230 struct i2c_adapter *adapter;
1231 struct i2c_client *client;
1232 int ret;
1233
1234 ret = i2c_add_driver(&aic3x_i2c_driver);
1235 if (ret != 0) {
1236 dev_err(&pdev->dev, "can't add i2c driver\n");
1237 return ret;
1238 }
1239
1240 memset(&info, 0, sizeof(struct i2c_board_info));
1241 info.addr = setup->i2c_address;
1242 strlcpy(info.type, "tlv320aic3x", I2C_NAME_SIZE);
1243
1244 adapter = i2c_get_adapter(setup->i2c_bus);
1245 if (!adapter) {
1246 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1247 setup->i2c_bus);
1248 goto err_driver;
1249 }
1250
1251 client = i2c_new_device(adapter, &info);
1252 i2c_put_adapter(adapter);
1253 if (!client) {
1254 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1255 (unsigned int)info.addr);
1256 goto err_driver;
1257 }
1258
1259 return 0;
1260
1261err_driver:
1262 i2c_del_driver(&aic3x_i2c_driver);
1263 return -ENODEV;
1264}
1261#endif 1265#endif
1262 1266
1263static int aic3x_probe(struct platform_device *pdev) 1267static int aic3x_probe(struct platform_device *pdev)
@@ -1290,12 +1294,9 @@ static int aic3x_probe(struct platform_device *pdev)
1290 aic3x_socdev = socdev; 1294 aic3x_socdev = socdev;
1291#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1295#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1292 if (setup->i2c_address) { 1296 if (setup->i2c_address) {
1293 normal_i2c[0] = setup->i2c_address;
1294 codec->hw_write = (hw_write_t) i2c_master_send; 1297 codec->hw_write = (hw_write_t) i2c_master_send;
1295 codec->hw_read = (hw_read_t) aic3x_i2c_read; 1298 codec->hw_read = (hw_read_t) aic3x_i2c_read;
1296 ret = i2c_add_driver(&aic3x_i2c_driver); 1299 ret = aic3x_add_i2c_device(pdev, setup);
1297 if (ret != 0)
1298 printk(KERN_ERR "can't add i2c driver");
1299 } 1300 }
1300#else 1301#else
1301 /* Add other interfaces here */ 1302 /* Add other interfaces here */
@@ -1320,6 +1321,7 @@ static int aic3x_remove(struct platform_device *pdev)
1320 snd_soc_free_pcms(socdev); 1321 snd_soc_free_pcms(socdev);
1321 snd_soc_dapm_free(socdev); 1322 snd_soc_dapm_free(socdev);
1322#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1323#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1324 i2c_unregister_device(codec->control_data);
1323 i2c_del_driver(&aic3x_i2c_driver); 1325 i2c_del_driver(&aic3x_i2c_driver);
1324#endif 1326#endif
1325 kfree(codec->private_data); 1327 kfree(codec->private_data);
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index d76c079b86e..00a195aa02e 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC TLV320AIC3X codec driver 2 * ALSA SoC TLV320AIC3X codec driver
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -224,6 +224,7 @@ int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
224int aic3x_headset_detected(struct snd_soc_codec *codec); 224int aic3x_headset_detected(struct snd_soc_codec *codec);
225 225
226struct aic3x_setup_data { 226struct aic3x_setup_data {
227 int i2c_bus;
227 unsigned short i2c_address; 228 unsigned short i2c_address;
228 unsigned int gpio_func[2]; 229 unsigned int gpio_func[2];
229}; 230};
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 807318fbdc8..d206d7f892b 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -701,87 +701,86 @@ static struct snd_soc_device *uda1380_socdev;
701 701
702#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 702#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
703 703
704#define I2C_DRIVERID_UDA1380 0xfefe /* liam - need a proper id */ 704static int uda1380_i2c_probe(struct i2c_client *i2c,
705 705 const struct i2c_device_id *id)
706static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
707
708/* Magic definition of all other variables and things */
709I2C_CLIENT_INSMOD;
710
711static struct i2c_driver uda1380_i2c_driver;
712static struct i2c_client client_template;
713
714/* If the i2c layer weren't so broken, we could pass this kind of data
715 around */
716
717static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind)
718{ 706{
719 struct snd_soc_device *socdev = uda1380_socdev; 707 struct snd_soc_device *socdev = uda1380_socdev;
720 struct uda1380_setup_data *setup = socdev->codec_data; 708 struct uda1380_setup_data *setup = socdev->codec_data;
721 struct snd_soc_codec *codec = socdev->codec; 709 struct snd_soc_codec *codec = socdev->codec;
722 struct i2c_client *i2c;
723 int ret; 710 int ret;
724 711
725 if (addr != setup->i2c_address)
726 return -ENODEV;
727
728 client_template.adapter = adap;
729 client_template.addr = addr;
730
731 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
732 if (i2c == NULL)
733 return -ENOMEM;
734
735 i2c_set_clientdata(i2c, codec); 712 i2c_set_clientdata(i2c, codec);
736 codec->control_data = i2c; 713 codec->control_data = i2c;
737 714
738 ret = i2c_attach_client(i2c);
739 if (ret < 0) {
740 pr_err("uda1380: failed to attach codec at addr %x\n", addr);
741 goto err;
742 }
743
744 ret = uda1380_init(socdev, setup->dac_clk); 715 ret = uda1380_init(socdev, setup->dac_clk);
745 if (ret < 0) { 716 if (ret < 0)
746 pr_err("uda1380: failed to initialise UDA1380\n"); 717 pr_err("uda1380: failed to initialise UDA1380\n");
747 goto err;
748 }
749 return ret;
750 718
751err:
752 kfree(i2c);
753 return ret; 719 return ret;
754} 720}
755 721
756static int uda1380_i2c_detach(struct i2c_client *client) 722static int uda1380_i2c_remove(struct i2c_client *client)
757{ 723{
758 struct snd_soc_codec *codec = i2c_get_clientdata(client); 724 struct snd_soc_codec *codec = i2c_get_clientdata(client);
759 i2c_detach_client(client);
760 kfree(codec->reg_cache); 725 kfree(codec->reg_cache);
761 kfree(client);
762 return 0; 726 return 0;
763} 727}
764 728
765static int uda1380_i2c_attach(struct i2c_adapter *adap) 729static const struct i2c_device_id uda1380_i2c_id[] = {
766{ 730 { "uda1380", 0 },
767 return i2c_probe(adap, &addr_data, uda1380_codec_probe); 731 { }
768} 732};
733MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
769 734
770static struct i2c_driver uda1380_i2c_driver = { 735static struct i2c_driver uda1380_i2c_driver = {
771 .driver = { 736 .driver = {
772 .name = "UDA1380 I2C Codec", 737 .name = "UDA1380 I2C Codec",
773 .owner = THIS_MODULE, 738 .owner = THIS_MODULE,
774 }, 739 },
775 .id = I2C_DRIVERID_UDA1380, 740 .probe = uda1380_i2c_probe,
776 .attach_adapter = uda1380_i2c_attach, 741 .remove = uda1380_i2c_remove,
777 .detach_client = uda1380_i2c_detach, 742 .id_table = uda1380_i2c_id,
778 .command = NULL,
779}; 743};
780 744
781static struct i2c_client client_template = { 745static int uda1380_add_i2c_device(struct platform_device *pdev,
782 .name = "UDA1380", 746 const struct uda1380_setup_data *setup)
783 .driver = &uda1380_i2c_driver, 747{
784}; 748 struct i2c_board_info info;
749 struct i2c_adapter *adapter;
750 struct i2c_client *client;
751 int ret;
752
753 ret = i2c_add_driver(&uda1380_i2c_driver);
754 if (ret != 0) {
755 dev_err(&pdev->dev, "can't add i2c driver\n");
756 return ret;
757 }
758
759 memset(&info, 0, sizeof(struct i2c_board_info));
760 info.addr = setup->i2c_address;
761 strlcpy(info.type, "uda1380", I2C_NAME_SIZE);
762
763 adapter = i2c_get_adapter(setup->i2c_bus);
764 if (!adapter) {
765 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
766 setup->i2c_bus);
767 goto err_driver;
768 }
769
770 client = i2c_new_device(adapter, &info);
771 i2c_put_adapter(adapter);
772 if (!client) {
773 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
774 (unsigned int)info.addr);
775 goto err_driver;
776 }
777
778 return 0;
779
780err_driver:
781 i2c_del_driver(&uda1380_i2c_driver);
782 return -ENODEV;
783}
785#endif 784#endif
786 785
787static int uda1380_probe(struct platform_device *pdev) 786static int uda1380_probe(struct platform_device *pdev)
@@ -789,7 +788,7 @@ static int uda1380_probe(struct platform_device *pdev)
789 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 788 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
790 struct uda1380_setup_data *setup; 789 struct uda1380_setup_data *setup;
791 struct snd_soc_codec *codec; 790 struct snd_soc_codec *codec;
792 int ret = 0; 791 int ret;
793 792
794 pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION); 793 pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION);
795 794
@@ -804,16 +803,13 @@ static int uda1380_probe(struct platform_device *pdev)
804 INIT_LIST_HEAD(&codec->dapm_paths); 803 INIT_LIST_HEAD(&codec->dapm_paths);
805 804
806 uda1380_socdev = socdev; 805 uda1380_socdev = socdev;
806 ret = -ENODEV;
807
807#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 808#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
808 if (setup->i2c_address) { 809 if (setup->i2c_address) {
809 normal_i2c[0] = setup->i2c_address;
810 codec->hw_write = (hw_write_t)i2c_master_send; 810 codec->hw_write = (hw_write_t)i2c_master_send;
811 ret = i2c_add_driver(&uda1380_i2c_driver); 811 ret = uda1380_add_i2c_device(pdev, setup);
812 if (ret != 0)
813 printk(KERN_ERR "can't add i2c driver");
814 } 812 }
815#else
816 /* Add other interfaces here */
817#endif 813#endif
818 814
819 if (ret != 0) 815 if (ret != 0)
@@ -833,6 +829,7 @@ static int uda1380_remove(struct platform_device *pdev)
833 snd_soc_free_pcms(socdev); 829 snd_soc_free_pcms(socdev);
834 snd_soc_dapm_free(socdev); 830 snd_soc_dapm_free(socdev);
835#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 831#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
832 i2c_unregister_device(codec->control_data);
836 i2c_del_driver(&uda1380_i2c_driver); 833 i2c_del_driver(&uda1380_i2c_driver);
837#endif 834#endif
838 kfree(codec); 835 kfree(codec);
diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h
index 50c603e2c9f..c55c17a52a1 100644
--- a/sound/soc/codecs/uda1380.h
+++ b/sound/soc/codecs/uda1380.h
@@ -73,6 +73,7 @@
73#define R23_AGC_EN 0x0001 73#define R23_AGC_EN 0x0001
74 74
75struct uda1380_setup_data { 75struct uda1380_setup_data {
76 int i2c_bus;
76 unsigned short i2c_address; 77 unsigned short i2c_address;
77 int dac_clk; 78 int dac_clk;
78#define UDA1380_DAC_CLK_SYSCLK 0 79#define UDA1380_DAC_CLK_SYSCLK 0
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 3d998e6a997..9a37c8d95ed 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -199,7 +199,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8510_MONOMIX, 0, 1, 0),
199}; 199};
200 200
201static const struct snd_kcontrol_new wm8510_boost_controls[] = { 201static const struct snd_kcontrol_new wm8510_boost_controls[] = {
202SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 0), 202SOC_DAPM_SINGLE("Mic PGA Switch", WM8510_INPPGA, 6, 1, 1),
203SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0), 203SOC_DAPM_SINGLE("Aux Volume", WM8510_ADCBOOST, 0, 7, 0),
204SOC_DAPM_SINGLE("Mic Volume", WM8510_ADCBOOST, 4, 7, 0), 204SOC_DAPM_SINGLE("Mic Volume", WM8510_ADCBOOST, 4, 7, 0),
205}; 205};
@@ -665,88 +665,86 @@ static struct snd_soc_device *wm8510_socdev;
665/* 665/*
666 * WM8510 2 wire address is 0x1a 666 * WM8510 2 wire address is 0x1a
667 */ 667 */
668#define I2C_DRIVERID_WM8510 0xfefe /* liam - need a proper id */
669 668
670static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; 669static int wm8510_i2c_probe(struct i2c_client *i2c,
671 670 const struct i2c_device_id *id)
672/* Magic definition of all other variables and things */
673I2C_CLIENT_INSMOD;
674
675static struct i2c_driver wm8510_i2c_driver;
676static struct i2c_client client_template;
677
678/* If the i2c layer weren't so broken, we could pass this kind of data
679 around */
680
681static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind)
682{ 671{
683 struct snd_soc_device *socdev = wm8510_socdev; 672 struct snd_soc_device *socdev = wm8510_socdev;
684 struct wm8510_setup_data *setup = socdev->codec_data;
685 struct snd_soc_codec *codec = socdev->codec; 673 struct snd_soc_codec *codec = socdev->codec;
686 struct i2c_client *i2c;
687 int ret; 674 int ret;
688 675
689 if (addr != setup->i2c_address)
690 return -ENODEV;
691
692 client_template.adapter = adap;
693 client_template.addr = addr;
694
695 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
696 if (i2c == NULL)
697 return -ENOMEM;
698
699 i2c_set_clientdata(i2c, codec); 676 i2c_set_clientdata(i2c, codec);
700 codec->control_data = i2c; 677 codec->control_data = i2c;
701 678
702 ret = i2c_attach_client(i2c);
703 if (ret < 0) {
704 pr_err("failed to attach codec at addr %x\n", addr);
705 goto err;
706 }
707
708 ret = wm8510_init(socdev); 679 ret = wm8510_init(socdev);
709 if (ret < 0) { 680 if (ret < 0)
710 pr_err("failed to initialise WM8510\n"); 681 pr_err("failed to initialise WM8510\n");
711 goto err;
712 }
713 return ret;
714 682
715err:
716 kfree(i2c);
717 return ret; 683 return ret;
718} 684}
719 685
720static int wm8510_i2c_detach(struct i2c_client *client) 686static int wm8510_i2c_remove(struct i2c_client *client)
721{ 687{
722 struct snd_soc_codec *codec = i2c_get_clientdata(client); 688 struct snd_soc_codec *codec = i2c_get_clientdata(client);
723 i2c_detach_client(client);
724 kfree(codec->reg_cache); 689 kfree(codec->reg_cache);
725 kfree(client);
726 return 0; 690 return 0;
727} 691}
728 692
729static int wm8510_i2c_attach(struct i2c_adapter *adap) 693static const struct i2c_device_id wm8510_i2c_id[] = {
730{ 694 { "wm8510", 0 },
731 return i2c_probe(adap, &addr_data, wm8510_codec_probe); 695 { }
732} 696};
697MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id);
733 698
734/* corgi i2c codec control layer */
735static struct i2c_driver wm8510_i2c_driver = { 699static struct i2c_driver wm8510_i2c_driver = {
736 .driver = { 700 .driver = {
737 .name = "WM8510 I2C Codec", 701 .name = "WM8510 I2C Codec",
738 .owner = THIS_MODULE, 702 .owner = THIS_MODULE,
739 }, 703 },
740 .id = I2C_DRIVERID_WM8510, 704 .probe = wm8510_i2c_probe,
741 .attach_adapter = wm8510_i2c_attach, 705 .remove = wm8510_i2c_remove,
742 .detach_client = wm8510_i2c_detach, 706 .id_table = wm8510_i2c_id,
743 .command = NULL,
744}; 707};
745 708
746static struct i2c_client client_template = { 709static int wm8510_add_i2c_device(struct platform_device *pdev,
747 .name = "WM8510", 710 const struct wm8510_setup_data *setup)
748 .driver = &wm8510_i2c_driver, 711{
749}; 712 struct i2c_board_info info;
713 struct i2c_adapter *adapter;
714 struct i2c_client *client;
715 int ret;
716
717 ret = i2c_add_driver(&wm8510_i2c_driver);
718 if (ret != 0) {
719 dev_err(&pdev->dev, "can't add i2c driver\n");
720 return ret;
721 }
722
723 memset(&info, 0, sizeof(struct i2c_board_info));
724 info.addr = setup->i2c_address;
725 strlcpy(info.type, "wm8510", I2C_NAME_SIZE);
726
727 adapter = i2c_get_adapter(setup->i2c_bus);
728 if (!adapter) {
729 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
730 setup->i2c_bus);
731 goto err_driver;
732 }
733
734 client = i2c_new_device(adapter, &info);
735 i2c_put_adapter(adapter);
736 if (!client) {
737 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
738 (unsigned int)info.addr);
739 goto err_driver;
740 }
741
742 return 0;
743
744err_driver:
745 i2c_del_driver(&wm8510_i2c_driver);
746 return -ENODEV;
747}
750#endif 748#endif
751 749
752static int wm8510_probe(struct platform_device *pdev) 750static int wm8510_probe(struct platform_device *pdev)
@@ -771,11 +769,8 @@ static int wm8510_probe(struct platform_device *pdev)
771 wm8510_socdev = socdev; 769 wm8510_socdev = socdev;
772#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 770#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
773 if (setup->i2c_address) { 771 if (setup->i2c_address) {
774 normal_i2c[0] = setup->i2c_address;
775 codec->hw_write = (hw_write_t)i2c_master_send; 772 codec->hw_write = (hw_write_t)i2c_master_send;
776 ret = i2c_add_driver(&wm8510_i2c_driver); 773 ret = wm8510_add_i2c_device(pdev, setup);
777 if (ret != 0)
778 printk(KERN_ERR "can't add i2c driver");
779 } 774 }
780#else 775#else
781 /* Add other interfaces here */ 776 /* Add other interfaces here */
@@ -798,6 +793,7 @@ static int wm8510_remove(struct platform_device *pdev)
798 snd_soc_free_pcms(socdev); 793 snd_soc_free_pcms(socdev);
799 snd_soc_dapm_free(socdev); 794 snd_soc_dapm_free(socdev);
800#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 795#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
796 i2c_unregister_device(codec->control_data);
801 i2c_del_driver(&wm8510_i2c_driver); 797 i2c_del_driver(&wm8510_i2c_driver);
802#endif 798#endif
803 kfree(codec); 799 kfree(codec);
diff --git a/sound/soc/codecs/wm8510.h b/sound/soc/codecs/wm8510.h
index f5d2e42eb3f..c5368396045 100644
--- a/sound/soc/codecs/wm8510.h
+++ b/sound/soc/codecs/wm8510.h
@@ -94,6 +94,7 @@
94#define WM8510_MCLKDIV_12 (7 << 5) 94#define WM8510_MCLKDIV_12 (7 << 5)
95 95
96struct wm8510_setup_data { 96struct wm8510_setup_data {
97 int i2c_bus;
97 unsigned short i2c_address; 98 unsigned short i2c_address;
98}; 99};
99 100
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
new file mode 100644
index 00000000000..df1ffbe305b
--- /dev/null
+++ b/sound/soc/codecs/wm8580.c
@@ -0,0 +1,1055 @@
1/*
2 * wm8580.c -- WM8580 ALSA Soc Audio driver
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Notes:
12 * The WM8580 is a multichannel codec with S/PDIF support, featuring six
13 * DAC channels and two ADC channels.
14 *
15 * Currently only the primary audio interface is supported - S/PDIF and
16 * the secondary audio interfaces are not.
17 */
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/version.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/pm.h>
26#include <linux/i2c.h>
27#include <linux/platform_device.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/tlv.h>
34#include <sound/initval.h>
35#include <asm/div64.h>
36
37#include "wm8580.h"
38
39#define AUDIO_NAME "wm8580"
40#define WM8580_VERSION "0.1"
41
42struct pll_state {
43 unsigned int in;
44 unsigned int out;
45};
46
47/* codec private data */
48struct wm8580_priv {
49 struct pll_state a;
50 struct pll_state b;
51};
52
53/* WM8580 register space */
54#define WM8580_PLLA1 0x00
55#define WM8580_PLLA2 0x01
56#define WM8580_PLLA3 0x02
57#define WM8580_PLLA4 0x03
58#define WM8580_PLLB1 0x04
59#define WM8580_PLLB2 0x05
60#define WM8580_PLLB3 0x06
61#define WM8580_PLLB4 0x07
62#define WM8580_CLKSEL 0x08
63#define WM8580_PAIF1 0x09
64#define WM8580_PAIF2 0x0A
65#define WM8580_SAIF1 0x0B
66#define WM8580_PAIF3 0x0C
67#define WM8580_PAIF4 0x0D
68#define WM8580_SAIF2 0x0E
69#define WM8580_DAC_CONTROL1 0x0F
70#define WM8580_DAC_CONTROL2 0x10
71#define WM8580_DAC_CONTROL3 0x11
72#define WM8580_DAC_CONTROL4 0x12
73#define WM8580_DAC_CONTROL5 0x13
74#define WM8580_DIGITAL_ATTENUATION_DACL1 0x14
75#define WM8580_DIGITAL_ATTENUATION_DACR1 0x15
76#define WM8580_DIGITAL_ATTENUATION_DACL2 0x16
77#define WM8580_DIGITAL_ATTENUATION_DACR2 0x17
78#define WM8580_DIGITAL_ATTENUATION_DACL3 0x18
79#define WM8580_DIGITAL_ATTENUATION_DACR3 0x19
80#define WM8580_MASTER_DIGITAL_ATTENUATION 0x1C
81#define WM8580_ADC_CONTROL1 0x1D
82#define WM8580_SPDTXCHAN0 0x1E
83#define WM8580_SPDTXCHAN1 0x1F
84#define WM8580_SPDTXCHAN2 0x20
85#define WM8580_SPDTXCHAN3 0x21
86#define WM8580_SPDTXCHAN4 0x22
87#define WM8580_SPDTXCHAN5 0x23
88#define WM8580_SPDMODE 0x24
89#define WM8580_INTMASK 0x25
90#define WM8580_GPO1 0x26
91#define WM8580_GPO2 0x27
92#define WM8580_GPO3 0x28
93#define WM8580_GPO4 0x29
94#define WM8580_GPO5 0x2A
95#define WM8580_INTSTAT 0x2B
96#define WM8580_SPDRXCHAN1 0x2C
97#define WM8580_SPDRXCHAN2 0x2D
98#define WM8580_SPDRXCHAN3 0x2E
99#define WM8580_SPDRXCHAN4 0x2F
100#define WM8580_SPDRXCHAN5 0x30
101#define WM8580_SPDSTAT 0x31
102#define WM8580_PWRDN1 0x32
103#define WM8580_PWRDN2 0x33
104#define WM8580_READBACK 0x34
105#define WM8580_RESET 0x35
106
107/* PLLB4 (register 7h) */
108#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60
109#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20
110#define WM8580_PLLB4_MCLKOUTSRC_PLLB 0x40
111#define WM8580_PLLB4_MCLKOUTSRC_OSC 0x60
112
113#define WM8580_PLLB4_CLKOUTSRC_MASK 0x180
114#define WM8580_PLLB4_CLKOUTSRC_PLLACLK 0x080
115#define WM8580_PLLB4_CLKOUTSRC_PLLBCLK 0x100
116#define WM8580_PLLB4_CLKOUTSRC_OSCCLK 0x180
117
118/* CLKSEL (register 8h) */
119#define WM8580_CLKSEL_DAC_CLKSEL_MASK 0x03
120#define WM8580_CLKSEL_DAC_CLKSEL_PLLA 0x01
121#define WM8580_CLKSEL_DAC_CLKSEL_PLLB 0x02
122
123/* AIF control 1 (registers 9h-bh) */
124#define WM8580_AIF_RATE_MASK 0x7
125#define WM8580_AIF_RATE_128 0x0
126#define WM8580_AIF_RATE_192 0x1
127#define WM8580_AIF_RATE_256 0x2
128#define WM8580_AIF_RATE_384 0x3
129#define WM8580_AIF_RATE_512 0x4
130#define WM8580_AIF_RATE_768 0x5
131#define WM8580_AIF_RATE_1152 0x6
132
133#define WM8580_AIF_BCLKSEL_MASK 0x18
134#define WM8580_AIF_BCLKSEL_64 0x00
135#define WM8580_AIF_BCLKSEL_128 0x08
136#define WM8580_AIF_BCLKSEL_256 0x10
137#define WM8580_AIF_BCLKSEL_SYSCLK 0x18
138
139#define WM8580_AIF_MS 0x20
140
141#define WM8580_AIF_CLKSRC_MASK 0xc0
142#define WM8580_AIF_CLKSRC_PLLA 0x40
143#define WM8580_AIF_CLKSRC_PLLB 0x40
144#define WM8580_AIF_CLKSRC_MCLK 0xc0
145
146/* AIF control 2 (registers ch-eh) */
147#define WM8580_AIF_FMT_MASK 0x03
148#define WM8580_AIF_FMT_RIGHTJ 0x00
149#define WM8580_AIF_FMT_LEFTJ 0x01
150#define WM8580_AIF_FMT_I2S 0x02
151#define WM8580_AIF_FMT_DSP 0x03
152
153#define WM8580_AIF_LENGTH_MASK 0x0c
154#define WM8580_AIF_LENGTH_16 0x00
155#define WM8580_AIF_LENGTH_20 0x04
156#define WM8580_AIF_LENGTH_24 0x08
157#define WM8580_AIF_LENGTH_32 0x0c
158
159#define WM8580_AIF_LRP 0x10
160#define WM8580_AIF_BCP 0x20
161
162/* Powerdown Register 1 (register 32h) */
163#define WM8580_PWRDN1_PWDN 0x001
164#define WM8580_PWRDN1_ALLDACPD 0x040
165
166/* Powerdown Register 2 (register 33h) */
167#define WM8580_PWRDN2_OSSCPD 0x001
168#define WM8580_PWRDN2_PLLAPD 0x002
169#define WM8580_PWRDN2_PLLBPD 0x004
170#define WM8580_PWRDN2_SPDIFPD 0x008
171#define WM8580_PWRDN2_SPDIFTXD 0x010
172#define WM8580_PWRDN2_SPDIFRXD 0x020
173
174#define WM8580_DAC_CONTROL5_MUTEALL 0x10
175
176/*
177 * wm8580 register cache
178 * We can't read the WM8580 register space when we
179 * are using 2 wire for device control, so we cache them instead.
180 */
181static const u16 wm8580_reg[] = {
182 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
183 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
184 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/
185 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
186 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
187 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
188 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R27*/
189 0x01f0, 0x0040, 0x0000, 0x0000, /*R31(0x1F)*/
190 0x0000, 0x0000, 0x0031, 0x000b, /*R35*/
191 0x0039, 0x0000, 0x0010, 0x0032, /*R39*/
192 0x0054, 0x0076, 0x0098, 0x0000, /*R43(0x2B)*/
193 0x0000, 0x0000, 0x0000, 0x0000, /*R47*/
194 0x0000, 0x0000, 0x005e, 0x003e, /*R51(0x33)*/
195 0x0000, 0x0000 /*R53*/
196};
197
198/*
199 * read wm8580 register cache
200 */
201static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec,
202 unsigned int reg)
203{
204 u16 *cache = codec->reg_cache;
205 BUG_ON(reg > ARRAY_SIZE(wm8580_reg));
206 return cache[reg];
207}
208
209/*
210 * write wm8580 register cache
211 */
212static inline void wm8580_write_reg_cache(struct snd_soc_codec *codec,
213 unsigned int reg, unsigned int value)
214{
215 u16 *cache = codec->reg_cache;
216
217 cache[reg] = value;
218}
219
220/*
221 * write to the WM8580 register space
222 */
223static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg,
224 unsigned int value)
225{
226 u8 data[2];
227
228 BUG_ON(reg > ARRAY_SIZE(wm8580_reg));
229
230 /* Registers are 9 bits wide */
231 value &= 0x1ff;
232
233 switch (reg) {
234 case WM8580_RESET:
235 /* Uncached */
236 break;
237 default:
238 if (value == wm8580_read_reg_cache(codec, reg))
239 return 0;
240 }
241
242 /* data is
243 * D15..D9 WM8580 register offset
244 * D8...D0 register data
245 */
246 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
247 data[1] = value & 0x00ff;
248
249 wm8580_write_reg_cache(codec, reg, value);
250 if (codec->hw_write(codec->control_data, data, 2) == 2)
251 return 0;
252 else
253 return -EIO;
254}
255
256static inline unsigned int wm8580_read(struct snd_soc_codec *codec,
257 unsigned int reg)
258{
259 switch (reg) {
260 default:
261 return wm8580_read_reg_cache(codec, reg);
262 }
263}
264
265static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
266
267static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
268 struct snd_ctl_elem_value *ucontrol)
269{
270 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
271 int reg = kcontrol->private_value & 0xff;
272 int reg2 = (kcontrol->private_value >> 24) & 0xff;
273 int ret;
274 u16 val;
275
276 /* Clear the register cache so we write without VU set */
277 wm8580_write_reg_cache(codec, reg, 0);
278 wm8580_write_reg_cache(codec, reg2, 0);
279
280 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
281 if (ret < 0)
282 return ret;
283
284 /* Now write again with the volume update bit set */
285 val = wm8580_read_reg_cache(codec, reg);
286 wm8580_write(codec, reg, val | 0x0100);
287
288 val = wm8580_read_reg_cache(codec, reg2);
289 wm8580_write(codec, reg2, val | 0x0100);
290
291 return 0;
292}
293
294#define SOC_WM8580_OUT_DOUBLE_R_TLV(xname, reg_left, reg_right, shift, max, invert, tlv_array) \
295{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
296 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
297 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
298 .tlv.p = (tlv_array), \
299 .info = snd_soc_info_volsw_2r, \
300 .get = snd_soc_get_volsw_2r, .put = wm8580_out_vu, \
301 .private_value = (reg_left) | ((shift) << 8) | \
302 ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) }
303
304static const struct snd_kcontrol_new wm8580_snd_controls[] = {
305SOC_WM8580_OUT_DOUBLE_R_TLV("DAC1 Playback Volume",
306 WM8580_DIGITAL_ATTENUATION_DACL1,
307 WM8580_DIGITAL_ATTENUATION_DACR1,
308 0, 0xff, 0, dac_tlv),
309SOC_WM8580_OUT_DOUBLE_R_TLV("DAC2 Playback Volume",
310 WM8580_DIGITAL_ATTENUATION_DACL2,
311 WM8580_DIGITAL_ATTENUATION_DACR2,
312 0, 0xff, 0, dac_tlv),
313SOC_WM8580_OUT_DOUBLE_R_TLV("DAC3 Playback Volume",
314 WM8580_DIGITAL_ATTENUATION_DACL3,
315 WM8580_DIGITAL_ATTENUATION_DACR3,
316 0, 0xff, 0, dac_tlv),
317
318SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0),
319SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0),
320SOC_SINGLE("DAC3 Deemphasis Switch", WM8580_DAC_CONTROL3, 2, 1, 0),
321
322SOC_DOUBLE("DAC1 Invert Switch", WM8580_DAC_CONTROL4, 0, 1, 1, 0),
323SOC_DOUBLE("DAC2 Invert Switch", WM8580_DAC_CONTROL4, 2, 3, 1, 0),
324SOC_DOUBLE("DAC3 Invert Switch", WM8580_DAC_CONTROL4, 4, 5, 1, 0),
325
326SOC_SINGLE("DAC ZC Switch", WM8580_DAC_CONTROL5, 5, 1, 0),
327SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 0),
328SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 0),
329SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 0),
330
331SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0),
332SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
333};
334
335/* Add non-DAPM controls */
336static int wm8580_add_controls(struct snd_soc_codec *codec)
337{
338 int err, i;
339
340 for (i = 0; i < ARRAY_SIZE(wm8580_snd_controls); i++) {
341 err = snd_ctl_add(codec->card,
342 snd_soc_cnew(&wm8580_snd_controls[i],
343 codec, NULL));
344 if (err < 0)
345 return err;
346 }
347 return 0;
348}
349static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {
350SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1),
351SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1),
352SND_SOC_DAPM_DAC("DAC3", "Playback", WM8580_PWRDN1, 4, 1),
353
354SND_SOC_DAPM_OUTPUT("VOUT1L"),
355SND_SOC_DAPM_OUTPUT("VOUT1R"),
356SND_SOC_DAPM_OUTPUT("VOUT2L"),
357SND_SOC_DAPM_OUTPUT("VOUT2R"),
358SND_SOC_DAPM_OUTPUT("VOUT3L"),
359SND_SOC_DAPM_OUTPUT("VOUT3R"),
360
361SND_SOC_DAPM_ADC("ADC", "Capture", WM8580_PWRDN1, 1, 1),
362
363SND_SOC_DAPM_INPUT("AINL"),
364SND_SOC_DAPM_INPUT("AINR"),
365};
366
367static const struct snd_soc_dapm_route audio_map[] = {
368 { "VOUT1L", NULL, "DAC1" },
369 { "VOUT1R", NULL, "DAC1" },
370
371 { "VOUT2L", NULL, "DAC2" },
372 { "VOUT2R", NULL, "DAC2" },
373
374 { "VOUT3L", NULL, "DAC3" },
375 { "VOUT3R", NULL, "DAC3" },
376
377 { "ADC", NULL, "AINL" },
378 { "ADC", NULL, "AINR" },
379};
380
381static int wm8580_add_widgets(struct snd_soc_codec *codec)
382{
383 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets,
384 ARRAY_SIZE(wm8580_dapm_widgets));
385
386 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
387
388 snd_soc_dapm_new_widgets(codec);
389 return 0;
390}
391
392/* PLL divisors */
393struct _pll_div {
394 u32 prescale:1;
395 u32 postscale:1;
396 u32 freqmode:2;
397 u32 n:4;
398 u32 k:24;
399};
400
401/* The size in bits of the pll divide */
402#define FIXED_PLL_SIZE (1 << 22)
403
404/* PLL rate to output rate divisions */
405static struct {
406 unsigned int div;
407 unsigned int freqmode;
408 unsigned int postscale;
409} post_table[] = {
410 { 2, 0, 0 },
411 { 4, 0, 1 },
412 { 4, 1, 0 },
413 { 8, 1, 1 },
414 { 8, 2, 0 },
415 { 16, 2, 1 },
416 { 12, 3, 0 },
417 { 24, 3, 1 }
418};
419
420static int pll_factors(struct _pll_div *pll_div, unsigned int target,
421 unsigned int source)
422{
423 u64 Kpart;
424 unsigned int K, Ndiv, Nmod;
425 int i;
426
427 pr_debug("wm8580: PLL %dHz->%dHz\n", source, target);
428
429 /* Scale the output frequency up; the PLL should run in the
430 * region of 90-100MHz.
431 */
432 for (i = 0; i < ARRAY_SIZE(post_table); i++) {
433 if (target * post_table[i].div >= 90000000 &&
434 target * post_table[i].div <= 100000000) {
435 pll_div->freqmode = post_table[i].freqmode;
436 pll_div->postscale = post_table[i].postscale;
437 target *= post_table[i].div;
438 break;
439 }
440 }
441
442 if (i == ARRAY_SIZE(post_table)) {
443 printk(KERN_ERR "wm8580: Unable to scale output frequency "
444 "%u\n", target);
445 return -EINVAL;
446 }
447
448 Ndiv = target / source;
449
450 if (Ndiv < 5) {
451 source /= 2;
452 pll_div->prescale = 1;
453 Ndiv = target / source;
454 } else
455 pll_div->prescale = 0;
456
457 if ((Ndiv < 5) || (Ndiv > 13)) {
458 printk(KERN_ERR
459 "WM8580 N=%d outside supported range\n", Ndiv);
460 return -EINVAL;
461 }
462
463 pll_div->n = Ndiv;
464 Nmod = target % source;
465 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
466
467 do_div(Kpart, source);
468
469 K = Kpart & 0xFFFFFFFF;
470
471 pll_div->k = K;
472
473 pr_debug("PLL %x.%x prescale %d freqmode %d postscale %d\n",
474 pll_div->n, pll_div->k, pll_div->prescale, pll_div->freqmode,
475 pll_div->postscale);
476
477 return 0;
478}
479
480static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
481 int pll_id, unsigned int freq_in, unsigned int freq_out)
482{
483 int offset;
484 struct snd_soc_codec *codec = codec_dai->codec;
485 struct wm8580_priv *wm8580 = codec->private_data;
486 struct pll_state *state;
487 struct _pll_div pll_div;
488 unsigned int reg;
489 unsigned int pwr_mask;
490 int ret;
491
492 /* GCC isn't able to work out the ifs below for initialising/using
493 * pll_div so suppress warnings.
494 */
495 memset(&pll_div, 0, sizeof(pll_div));
496
497 switch (pll_id) {
498 case WM8580_PLLA:
499 state = &wm8580->a;
500 offset = 0;
501 pwr_mask = WM8580_PWRDN2_PLLAPD;
502 break;
503 case WM8580_PLLB:
504 state = &wm8580->b;
505 offset = 4;
506 pwr_mask = WM8580_PWRDN2_PLLBPD;
507 break;
508 default:
509 return -ENODEV;
510 }
511
512 if (freq_in && freq_out) {
513 ret = pll_factors(&pll_div, freq_out, freq_in);
514 if (ret != 0)
515 return ret;
516 }
517
518 state->in = freq_in;
519 state->out = freq_out;
520
521 /* Always disable the PLL - it is not safe to leave it running
522 * while reprogramming it.
523 */
524 reg = wm8580_read(codec, WM8580_PWRDN2);
525 wm8580_write(codec, WM8580_PWRDN2, reg | pwr_mask);
526
527 if (!freq_in || !freq_out)
528 return 0;
529
530 wm8580_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
531 wm8580_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0xff);
532 wm8580_write(codec, WM8580_PLLA3 + offset,
533 (pll_div.k >> 18 & 0xf) | (pll_div.n << 4));
534
535 reg = wm8580_read(codec, WM8580_PLLA4 + offset);
536 reg &= ~0x3f;
537 reg |= pll_div.prescale | pll_div.postscale << 1 |
538 pll_div.freqmode << 4;
539
540 wm8580_write(codec, WM8580_PLLA4 + offset, reg);
541
542 /* All done, turn it on */
543 reg = wm8580_read(codec, WM8580_PWRDN2);
544 wm8580_write(codec, WM8580_PWRDN2, reg & ~pwr_mask);
545
546 return 0;
547}
548
549/*
550 * Set PCM DAI bit size and sample rate.
551 */
552static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
553 struct snd_pcm_hw_params *params)
554{
555 struct snd_soc_pcm_runtime *rtd = substream->private_data;
556 struct snd_soc_dai_link *dai = rtd->dai;
557 struct snd_soc_device *socdev = rtd->socdev;
558 struct snd_soc_codec *codec = socdev->codec;
559 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->codec_dai->id);
560
561 paifb &= ~WM8580_AIF_LENGTH_MASK;
562 /* bit size */
563 switch (params_format(params)) {
564 case SNDRV_PCM_FORMAT_S16_LE:
565 break;
566 case SNDRV_PCM_FORMAT_S20_3LE:
567 paifb |= WM8580_AIF_LENGTH_20;
568 break;
569 case SNDRV_PCM_FORMAT_S24_LE:
570 paifb |= WM8580_AIF_LENGTH_24;
571 break;
572 case SNDRV_PCM_FORMAT_S32_LE:
573 paifb |= WM8580_AIF_LENGTH_24;
574 break;
575 default:
576 return -EINVAL;
577 }
578
579 wm8580_write(codec, WM8580_PAIF3 + dai->codec_dai->id, paifb);
580 return 0;
581}
582
583static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
584 unsigned int fmt)
585{
586 struct snd_soc_codec *codec = codec_dai->codec;
587 unsigned int aifa;
588 unsigned int aifb;
589 int can_invert_lrclk;
590
591 aifa = wm8580_read(codec, WM8580_PAIF1 + codec_dai->id);
592 aifb = wm8580_read(codec, WM8580_PAIF3 + codec_dai->id);
593
594 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
595
596 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
597 case SND_SOC_DAIFMT_CBS_CFS:
598 aifa &= ~WM8580_AIF_MS;
599 break;
600 case SND_SOC_DAIFMT_CBM_CFM:
601 aifa |= WM8580_AIF_MS;
602 break;
603 default:
604 return -EINVAL;
605 }
606
607 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
608 case SND_SOC_DAIFMT_I2S:
609 can_invert_lrclk = 1;
610 aifb |= WM8580_AIF_FMT_I2S;
611 break;
612 case SND_SOC_DAIFMT_RIGHT_J:
613 can_invert_lrclk = 1;
614 aifb |= WM8580_AIF_FMT_RIGHTJ;
615 break;
616 case SND_SOC_DAIFMT_LEFT_J:
617 can_invert_lrclk = 1;
618 aifb |= WM8580_AIF_FMT_LEFTJ;
619 break;
620 case SND_SOC_DAIFMT_DSP_A:
621 can_invert_lrclk = 0;
622 aifb |= WM8580_AIF_FMT_DSP;
623 break;
624 case SND_SOC_DAIFMT_DSP_B:
625 can_invert_lrclk = 0;
626 aifb |= WM8580_AIF_FMT_DSP;
627 aifb |= WM8580_AIF_LRP;
628 break;
629 default:
630 return -EINVAL;
631 }
632
633 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
634 case SND_SOC_DAIFMT_NB_NF:
635 break;
636
637 case SND_SOC_DAIFMT_IB_IF:
638 if (!can_invert_lrclk)
639 return -EINVAL;
640 aifb |= WM8580_AIF_BCP;
641 aifb |= WM8580_AIF_LRP;
642 break;
643
644 case SND_SOC_DAIFMT_IB_NF:
645 aifb |= WM8580_AIF_BCP;
646 break;
647
648 case SND_SOC_DAIFMT_NB_IF:
649 if (!can_invert_lrclk)
650 return -EINVAL;
651 aifb |= WM8580_AIF_LRP;
652 break;
653
654 default:
655 return -EINVAL;
656 }
657
658 wm8580_write(codec, WM8580_PAIF1 + codec_dai->id, aifa);
659 wm8580_write(codec, WM8580_PAIF3 + codec_dai->id, aifb);
660
661 return 0;
662}
663
664static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
665 int div_id, int div)
666{
667 struct snd_soc_codec *codec = codec_dai->codec;
668 unsigned int reg;
669
670 switch (div_id) {
671 case WM8580_MCLK:
672 reg = wm8580_read(codec, WM8580_PLLB4);
673 reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK;
674
675 switch (div) {
676 case WM8580_CLKSRC_MCLK:
677 /* Input */
678 break;
679
680 case WM8580_CLKSRC_PLLA:
681 reg |= WM8580_PLLB4_MCLKOUTSRC_PLLA;
682 break;
683 case WM8580_CLKSRC_PLLB:
684 reg |= WM8580_PLLB4_MCLKOUTSRC_PLLB;
685 break;
686
687 case WM8580_CLKSRC_OSC:
688 reg |= WM8580_PLLB4_MCLKOUTSRC_OSC;
689 break;
690
691 default:
692 return -EINVAL;
693 }
694 wm8580_write(codec, WM8580_PLLB4, reg);
695 break;
696
697 case WM8580_DAC_CLKSEL:
698 reg = wm8580_read(codec, WM8580_CLKSEL);
699 reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK;
700
701 switch (div) {
702 case WM8580_CLKSRC_MCLK:
703 break;
704
705 case WM8580_CLKSRC_PLLA:
706 reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLA;
707 break;
708
709 case WM8580_CLKSRC_PLLB:
710 reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLB;
711 break;
712
713 default:
714 return -EINVAL;
715 }
716 wm8580_write(codec, WM8580_CLKSEL, reg);
717 break;
718
719 case WM8580_CLKOUTSRC:
720 reg = wm8580_read(codec, WM8580_PLLB4);
721 reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
722
723 switch (div) {
724 case WM8580_CLKSRC_NONE:
725 break;
726
727 case WM8580_CLKSRC_PLLA:
728 reg |= WM8580_PLLB4_CLKOUTSRC_PLLACLK;
729 break;
730
731 case WM8580_CLKSRC_PLLB:
732 reg |= WM8580_PLLB4_CLKOUTSRC_PLLBCLK;
733 break;
734
735 case WM8580_CLKSRC_OSC:
736 reg |= WM8580_PLLB4_CLKOUTSRC_OSCCLK;
737 break;
738
739 default:
740 return -EINVAL;
741 }
742 wm8580_write(codec, WM8580_PLLB4, reg);
743 break;
744
745 default:
746 return -EINVAL;
747 }
748
749 return 0;
750}
751
752static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
753{
754 struct snd_soc_codec *codec = codec_dai->codec;
755 unsigned int reg;
756
757 reg = wm8580_read(codec, WM8580_DAC_CONTROL5);
758
759 if (mute)
760 reg |= WM8580_DAC_CONTROL5_MUTEALL;
761 else
762 reg &= ~WM8580_DAC_CONTROL5_MUTEALL;
763
764 wm8580_write(codec, WM8580_DAC_CONTROL5, reg);
765
766 return 0;
767}
768
769static int wm8580_set_bias_level(struct snd_soc_codec *codec,
770 enum snd_soc_bias_level level)
771{
772 u16 reg;
773 switch (level) {
774 case SND_SOC_BIAS_ON:
775 case SND_SOC_BIAS_PREPARE:
776 case SND_SOC_BIAS_STANDBY:
777 break;
778 case SND_SOC_BIAS_OFF:
779 reg = wm8580_read(codec, WM8580_PWRDN1);
780 wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
781 break;
782 }
783 codec->bias_level = level;
784 return 0;
785}
786
787#define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
788 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
789
790struct snd_soc_dai wm8580_dai[] = {
791 {
792 .name = "WM8580 PAIFRX",
793 .id = 0,
794 .playback = {
795 .stream_name = "Playback",
796 .channels_min = 1,
797 .channels_max = 6,
798 .rates = SNDRV_PCM_RATE_8000_192000,
799 .formats = WM8580_FORMATS,
800 },
801 .ops = {
802 .hw_params = wm8580_paif_hw_params,
803 },
804 .dai_ops = {
805 .set_fmt = wm8580_set_paif_dai_fmt,
806 .set_clkdiv = wm8580_set_dai_clkdiv,
807 .set_pll = wm8580_set_dai_pll,
808 .digital_mute = wm8580_digital_mute,
809 },
810 },
811 {
812 .name = "WM8580 PAIFTX",
813 .id = 1,
814 .capture = {
815 .stream_name = "Capture",
816 .channels_min = 2,
817 .channels_max = 2,
818 .rates = SNDRV_PCM_RATE_8000_192000,
819 .formats = WM8580_FORMATS,
820 },
821 .ops = {
822 .hw_params = wm8580_paif_hw_params,
823 },
824 .dai_ops = {
825 .set_fmt = wm8580_set_paif_dai_fmt,
826 .set_clkdiv = wm8580_set_dai_clkdiv,
827 .set_pll = wm8580_set_dai_pll,
828 },
829 },
830};
831EXPORT_SYMBOL_GPL(wm8580_dai);
832
833/*
834 * initialise the WM8580 driver
835 * register the mixer and dsp interfaces with the kernel
836 */
837static int wm8580_init(struct snd_soc_device *socdev)
838{
839 struct snd_soc_codec *codec = socdev->codec;
840 int ret = 0;
841
842 codec->name = "WM8580";
843 codec->owner = THIS_MODULE;
844 codec->read = wm8580_read_reg_cache;
845 codec->write = wm8580_write;
846 codec->set_bias_level = wm8580_set_bias_level;
847 codec->dai = wm8580_dai;
848 codec->num_dai = ARRAY_SIZE(wm8580_dai);
849 codec->reg_cache_size = ARRAY_SIZE(wm8580_reg);
850 codec->reg_cache = kmemdup(wm8580_reg, sizeof(wm8580_reg),
851 GFP_KERNEL);
852
853 if (codec->reg_cache == NULL)
854 return -ENOMEM;
855
856 /* Get the codec into a known state */
857 wm8580_write(codec, WM8580_RESET, 0);
858
859 /* Power up and get individual control of the DACs */
860 wm8580_write(codec, WM8580_PWRDN1, wm8580_read(codec, WM8580_PWRDN1) &
861 ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD));
862
863 /* Make VMID high impedence */
864 wm8580_write(codec, WM8580_ADC_CONTROL1,
865 wm8580_read(codec, WM8580_ADC_CONTROL1) & ~0x100);
866
867 /* register pcms */
868 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1,
869 SNDRV_DEFAULT_STR1);
870 if (ret < 0) {
871 printk(KERN_ERR "wm8580: failed to create pcms\n");
872 goto pcm_err;
873 }
874
875 wm8580_add_controls(codec);
876 wm8580_add_widgets(codec);
877
878 ret = snd_soc_register_card(socdev);
879 if (ret < 0) {
880 printk(KERN_ERR "wm8580: failed to register card\n");
881 goto card_err;
882 }
883 return ret;
884
885card_err:
886 snd_soc_free_pcms(socdev);
887 snd_soc_dapm_free(socdev);
888pcm_err:
889 kfree(codec->reg_cache);
890 return ret;
891}
892
893/* If the i2c layer weren't so broken, we could pass this kind of data
894 around */
895static struct snd_soc_device *wm8580_socdev;
896
897#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
898
899/*
900 * WM8580 2 wire address is determined by GPIO5
901 * state during powerup.
902 * low = 0x1a
903 * high = 0x1b
904 */
905static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
906
907/* Magic definition of all other variables and things */
908I2C_CLIENT_INSMOD;
909
910static struct i2c_driver wm8580_i2c_driver;
911static struct i2c_client client_template;
912
913static int wm8580_codec_probe(struct i2c_adapter *adap, int addr, int kind)
914{
915 struct snd_soc_device *socdev = wm8580_socdev;
916 struct wm8580_setup_data *setup = socdev->codec_data;
917 struct snd_soc_codec *codec = socdev->codec;
918 struct i2c_client *i2c;
919 int ret;
920
921 if (addr != setup->i2c_address)
922 return -ENODEV;
923
924 client_template.adapter = adap;
925 client_template.addr = addr;
926
927 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
928 if (i2c == NULL) {
929 kfree(codec);
930 return -ENOMEM;
931 }
932 i2c_set_clientdata(i2c, codec);
933 codec->control_data = i2c;
934
935 ret = i2c_attach_client(i2c);
936 if (ret < 0) {
937 dev_err(&i2c->dev, "failed to attach codec at addr %x\n", addr);
938 goto err;
939 }
940
941 ret = wm8580_init(socdev);
942 if (ret < 0) {
943 dev_err(&i2c->dev, "failed to initialise WM8580\n");
944 goto err;
945 }
946
947 return ret;
948
949err:
950 kfree(codec);
951 kfree(i2c);
952 return ret;
953}
954
955static int wm8580_i2c_detach(struct i2c_client *client)
956{
957 struct snd_soc_codec *codec = i2c_get_clientdata(client);
958 i2c_detach_client(client);
959 kfree(codec->reg_cache);
960 kfree(client);
961 return 0;
962}
963
964static int wm8580_i2c_attach(struct i2c_adapter *adap)
965{
966 return i2c_probe(adap, &addr_data, wm8580_codec_probe);
967}
968
969/* corgi i2c codec control layer */
970static struct i2c_driver wm8580_i2c_driver = {
971 .driver = {
972 .name = "WM8580 I2C Codec",
973 .owner = THIS_MODULE,
974 },
975 .attach_adapter = wm8580_i2c_attach,
976 .detach_client = wm8580_i2c_detach,
977 .command = NULL,
978};
979
980static struct i2c_client client_template = {
981 .name = "WM8580",
982 .driver = &wm8580_i2c_driver,
983};
984#endif
985
986static int wm8580_probe(struct platform_device *pdev)
987{
988 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
989 struct wm8580_setup_data *setup;
990 struct snd_soc_codec *codec;
991 struct wm8580_priv *wm8580;
992 int ret = 0;
993
994 pr_info("WM8580 Audio Codec %s\n", WM8580_VERSION);
995
996 setup = socdev->codec_data;
997 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
998 if (codec == NULL)
999 return -ENOMEM;
1000
1001 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
1002 if (wm8580 == NULL) {
1003 kfree(codec);
1004 return -ENOMEM;
1005 }
1006
1007 codec->private_data = wm8580;
1008 socdev->codec = codec;
1009 mutex_init(&codec->mutex);
1010 INIT_LIST_HEAD(&codec->dapm_widgets);
1011 INIT_LIST_HEAD(&codec->dapm_paths);
1012 wm8580_socdev = socdev;
1013
1014#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1015 if (setup->i2c_address) {
1016 normal_i2c[0] = setup->i2c_address;
1017 codec->hw_write = (hw_write_t)i2c_master_send;
1018 ret = i2c_add_driver(&wm8580_i2c_driver);
1019 if (ret != 0)
1020 printk(KERN_ERR "can't add i2c driver");
1021 }
1022#else
1023 /* Add other interfaces here */
1024#endif
1025 return ret;
1026}
1027
1028/* power down chip */
1029static int wm8580_remove(struct platform_device *pdev)
1030{
1031 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1032 struct snd_soc_codec *codec = socdev->codec;
1033
1034 if (codec->control_data)
1035 wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
1036 snd_soc_free_pcms(socdev);
1037 snd_soc_dapm_free(socdev);
1038#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1039 i2c_del_driver(&wm8580_i2c_driver);
1040#endif
1041 kfree(codec->private_data);
1042 kfree(codec);
1043
1044 return 0;
1045}
1046
1047struct snd_soc_codec_device soc_codec_dev_wm8580 = {
1048 .probe = wm8580_probe,
1049 .remove = wm8580_remove,
1050};
1051EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
1052
1053MODULE_DESCRIPTION("ASoC WM8580 driver");
1054MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1055MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8580.h b/sound/soc/codecs/wm8580.h
new file mode 100644
index 00000000000..589ddaba21d
--- /dev/null
+++ b/sound/soc/codecs/wm8580.h
@@ -0,0 +1,42 @@
1/*
2 * wm8580.h -- audio driver for WM8580
3 *
4 * Copyright 2008 Samsung Electronics.
5 * Author: Ryu Euiyoul
6 * ryu.real@gmail.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef _WM8580_H
16#define _WM8580_H
17
18#define WM8580_PLLA 1
19#define WM8580_PLLB 2
20
21#define WM8580_MCLK 1
22#define WM8580_DAC_CLKSEL 2
23#define WM8580_CLKOUTSRC 3
24
25#define WM8580_CLKSRC_MCLK 1
26#define WM8580_CLKSRC_PLLA 2
27#define WM8580_CLKSRC_PLLB 3
28#define WM8580_CLKSRC_OSC 4
29#define WM8580_CLKSRC_NONE 5
30
31struct wm8580_setup_data {
32 unsigned short i2c_address;
33};
34
35#define WM8580_DAI_PAIFRX 0
36#define WM8580_DAI_PAIFTX 1
37
38extern struct snd_soc_dai wm8580_dai[];
39extern struct snd_soc_codec_device soc_codec_dev_wm8580;
40
41#endif
42
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 9402fcaf04f..7b64d9a7ff7 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -570,88 +571,144 @@ static struct snd_soc_device *wm8731_socdev;
570 * low = 0x1a 571 * low = 0x1a
571 * high = 0x1b 572 * high = 0x1b
572 */ 573 */
573static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
574 574
575/* Magic definition of all other variables and things */ 575static int wm8731_i2c_probe(struct i2c_client *i2c,
576I2C_CLIENT_INSMOD; 576 const struct i2c_device_id *id)
577
578static struct i2c_driver wm8731_i2c_driver;
579static struct i2c_client client_template;
580
581/* If the i2c layer weren't so broken, we could pass this kind of data
582 around */
583
584static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind)
585{ 577{
586 struct snd_soc_device *socdev = wm8731_socdev; 578 struct snd_soc_device *socdev = wm8731_socdev;
587 struct wm8731_setup_data *setup = socdev->codec_data;
588 struct snd_soc_codec *codec = socdev->codec; 579 struct snd_soc_codec *codec = socdev->codec;
589 struct i2c_client *i2c;
590 int ret; 580 int ret;
591 581
592 if (addr != setup->i2c_address)
593 return -ENODEV;
594
595 client_template.adapter = adap;
596 client_template.addr = addr;
597
598 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
599 if (i2c == NULL)
600 return -ENOMEM;
601
602 i2c_set_clientdata(i2c, codec); 582 i2c_set_clientdata(i2c, codec);
603 codec->control_data = i2c; 583 codec->control_data = i2c;
604 584
605 ret = i2c_attach_client(i2c);
606 if (ret < 0) {
607 pr_err("failed to attach codec at addr %x\n", addr);
608 goto err;
609 }
610
611 ret = wm8731_init(socdev); 585 ret = wm8731_init(socdev);
612 if (ret < 0) { 586 if (ret < 0)
613 pr_err("failed to initialise WM8731\n"); 587 pr_err("failed to initialise WM8731\n");
614 goto err;
615 }
616 return ret;
617 588
618err:
619 kfree(i2c);
620 return ret; 589 return ret;
621} 590}
622 591
623static int wm8731_i2c_detach(struct i2c_client *client) 592static int wm8731_i2c_remove(struct i2c_client *client)
624{ 593{
625 struct snd_soc_codec *codec = i2c_get_clientdata(client); 594 struct snd_soc_codec *codec = i2c_get_clientdata(client);
626 i2c_detach_client(client);
627 kfree(codec->reg_cache); 595 kfree(codec->reg_cache);
628 kfree(client);
629 return 0; 596 return 0;
630} 597}
631 598
632static int wm8731_i2c_attach(struct i2c_adapter *adap) 599static const struct i2c_device_id wm8731_i2c_id[] = {
633{ 600 { "wm8731", 0 },
634 return i2c_probe(adap, &addr_data, wm8731_codec_probe); 601 { }
635} 602};
603MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
636 604
637/* corgi i2c codec control layer */
638static struct i2c_driver wm8731_i2c_driver = { 605static struct i2c_driver wm8731_i2c_driver = {
639 .driver = { 606 .driver = {
640 .name = "WM8731 I2C Codec", 607 .name = "WM8731 I2C Codec",
641 .owner = THIS_MODULE, 608 .owner = THIS_MODULE,
642 }, 609 },
643 .id = I2C_DRIVERID_WM8731, 610 .probe = wm8731_i2c_probe,
644 .attach_adapter = wm8731_i2c_attach, 611 .remove = wm8731_i2c_remove,
645 .detach_client = wm8731_i2c_detach, 612 .id_table = wm8731_i2c_id,
646 .command = NULL,
647}; 613};
648 614
649static struct i2c_client client_template = { 615static int wm8731_add_i2c_device(struct platform_device *pdev,
650 .name = "WM8731", 616 const struct wm8731_setup_data *setup)
651 .driver = &wm8731_i2c_driver, 617{
652}; 618 struct i2c_board_info info;
619 struct i2c_adapter *adapter;
620 struct i2c_client *client;
621 int ret;
622
623 ret = i2c_add_driver(&wm8731_i2c_driver);
624 if (ret != 0) {
625 dev_err(&pdev->dev, "can't add i2c driver\n");
626 return ret;
627 }
628
629 memset(&info, 0, sizeof(struct i2c_board_info));
630 info.addr = setup->i2c_address;
631 strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
632
633 adapter = i2c_get_adapter(setup->i2c_bus);
634 if (!adapter) {
635 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
636 setup->i2c_bus);
637 goto err_driver;
638 }
639
640 client = i2c_new_device(adapter, &info);
641 i2c_put_adapter(adapter);
642 if (!client) {
643 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
644 (unsigned int)info.addr);
645 goto err_driver;
646 }
647
648 return 0;
649
650err_driver:
651 i2c_del_driver(&wm8731_i2c_driver);
652 return -ENODEV;
653}
653#endif 654#endif
654 655
656#if defined(CONFIG_SPI_MASTER)
657static int __devinit wm8731_spi_probe(struct spi_device *spi)
658{
659 struct snd_soc_device *socdev = wm8731_socdev;
660 struct snd_soc_codec *codec = socdev->codec;
661 int ret;
662
663 codec->control_data = spi;
664
665 ret = wm8731_init(socdev);
666 if (ret < 0)
667 dev_err(&spi->dev, "failed to initialise WM8731\n");
668
669 return ret;
670}
671
672static int __devexit wm8731_spi_remove(struct spi_device *spi)
673{
674 return 0;
675}
676
677static struct spi_driver wm8731_spi_driver = {
678 .driver = {
679 .name = "wm8731",
680 .bus = &spi_bus_type,
681 .owner = THIS_MODULE,
682 },
683 .probe = wm8731_spi_probe,
684 .remove = __devexit_p(wm8731_spi_remove),
685};
686
687static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
688{
689 struct spi_transfer t;
690 struct spi_message m;
691 u8 msg[2];
692
693 if (len <= 0)
694 return 0;
695
696 msg[0] = data[0];
697 msg[1] = data[1];
698
699 spi_message_init(&m);
700 memset(&t, 0, (sizeof t));
701
702 t.tx_buf = &msg[0];
703 t.len = len;
704
705 spi_message_add_tail(&t, &m);
706 spi_sync(spi, &m);
707
708 return len;
709}
710#endif /* CONFIG_SPI_MASTER */
711
655static int wm8731_probe(struct platform_device *pdev) 712static int wm8731_probe(struct platform_device *pdev)
656{ 713{
657 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 714 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -680,16 +737,21 @@ static int wm8731_probe(struct platform_device *pdev)
680 INIT_LIST_HEAD(&codec->dapm_paths); 737 INIT_LIST_HEAD(&codec->dapm_paths);
681 738
682 wm8731_socdev = socdev; 739 wm8731_socdev = socdev;
740 ret = -ENODEV;
741
683#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 742#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
684 if (setup->i2c_address) { 743 if (setup->i2c_address) {
685 normal_i2c[0] = setup->i2c_address;
686 codec->hw_write = (hw_write_t)i2c_master_send; 744 codec->hw_write = (hw_write_t)i2c_master_send;
687 ret = i2c_add_driver(&wm8731_i2c_driver); 745 ret = wm8731_add_i2c_device(pdev, setup);
746 }
747#endif
748#if defined(CONFIG_SPI_MASTER)
749 if (setup->spi) {
750 codec->hw_write = (hw_write_t)wm8731_spi_write;
751 ret = spi_register_driver(&wm8731_spi_driver);
688 if (ret != 0) 752 if (ret != 0)
689 printk(KERN_ERR "can't add i2c driver"); 753 printk(KERN_ERR "can't add spi driver");
690 } 754 }
691#else
692 /* Add other interfaces here */
693#endif 755#endif
694 756
695 if (ret != 0) { 757 if (ret != 0) {
@@ -711,8 +773,12 @@ static int wm8731_remove(struct platform_device *pdev)
711 snd_soc_free_pcms(socdev); 773 snd_soc_free_pcms(socdev);
712 snd_soc_dapm_free(socdev); 774 snd_soc_dapm_free(socdev);
713#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 775#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
776 i2c_unregister_device(codec->control_data);
714 i2c_del_driver(&wm8731_i2c_driver); 777 i2c_del_driver(&wm8731_i2c_driver);
715#endif 778#endif
779#if defined(CONFIG_SPI_MASTER)
780 spi_unregister_driver(&wm8731_spi_driver);
781#endif
716 kfree(codec->private_data); 782 kfree(codec->private_data);
717 kfree(codec); 783 kfree(codec);
718 784
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h
index 99f2e3c60e3..95190e9c0c1 100644
--- a/sound/soc/codecs/wm8731.h
+++ b/sound/soc/codecs/wm8731.h
@@ -35,6 +35,8 @@
35#define WM8731_DAI 0 35#define WM8731_DAI 0
36 36
37struct wm8731_setup_data { 37struct wm8731_setup_data {
38 int spi;
39 int i2c_bus;
38 unsigned short i2c_address; 40 unsigned short i2c_address;
39}; 41};
40 42
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index dd1f55404b2..4892e398a59 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
@@ -841,88 +842,147 @@ static struct snd_soc_device *wm8750_socdev;
841#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 842#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
842 843
843/* 844/*
844 * WM8731 2 wire address is determined by GPIO5 845 * WM8750 2 wire address is determined by GPIO5
845 * state during powerup. 846 * state during powerup.
846 * low = 0x1a 847 * low = 0x1a
847 * high = 0x1b 848 * high = 0x1b
848 */ 849 */
849static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
850 850
851/* Magic definition of all other variables and things */ 851static int wm8750_i2c_probe(struct i2c_client *i2c,
852I2C_CLIENT_INSMOD; 852 const struct i2c_device_id *id)
853
854static struct i2c_driver wm8750_i2c_driver;
855static struct i2c_client client_template;
856
857static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind)
858{ 853{
859 struct snd_soc_device *socdev = wm8750_socdev; 854 struct snd_soc_device *socdev = wm8750_socdev;
860 struct wm8750_setup_data *setup = socdev->codec_data;
861 struct snd_soc_codec *codec = socdev->codec; 855 struct snd_soc_codec *codec = socdev->codec;
862 struct i2c_client *i2c;
863 int ret; 856 int ret;
864 857
865 if (addr != setup->i2c_address)
866 return -ENODEV;
867
868 client_template.adapter = adap;
869 client_template.addr = addr;
870
871 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
872 if (i2c == NULL)
873 return -ENOMEM;
874
875 i2c_set_clientdata(i2c, codec); 858 i2c_set_clientdata(i2c, codec);
876 codec->control_data = i2c; 859 codec->control_data = i2c;
877 860
878 ret = i2c_attach_client(i2c);
879 if (ret < 0) {
880 pr_err("failed to attach codec at addr %x\n", addr);
881 goto err;
882 }
883
884 ret = wm8750_init(socdev); 861 ret = wm8750_init(socdev);
885 if (ret < 0) { 862 if (ret < 0)
886 pr_err("failed to initialise WM8750\n"); 863 pr_err("failed to initialise WM8750\n");
887 goto err;
888 }
889 return ret;
890 864
891err:
892 kfree(i2c);
893 return ret; 865 return ret;
894} 866}
895 867
896static int wm8750_i2c_detach(struct i2c_client *client) 868static int wm8750_i2c_remove(struct i2c_client *client)
897{ 869{
898 struct snd_soc_codec *codec = i2c_get_clientdata(client); 870 struct snd_soc_codec *codec = i2c_get_clientdata(client);
899 i2c_detach_client(client);
900 kfree(codec->reg_cache); 871 kfree(codec->reg_cache);
901 kfree(client);
902 return 0; 872 return 0;
903} 873}
904 874
905static int wm8750_i2c_attach(struct i2c_adapter *adap) 875static const struct i2c_device_id wm8750_i2c_id[] = {
906{ 876 { "wm8750", 0 },
907 return i2c_probe(adap, &addr_data, wm8750_codec_probe); 877 { }
908} 878};
879MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
909 880
910/* corgi i2c codec control layer */
911static struct i2c_driver wm8750_i2c_driver = { 881static struct i2c_driver wm8750_i2c_driver = {
912 .driver = { 882 .driver = {
913 .name = "WM8750 I2C Codec", 883 .name = "WM8750 I2C Codec",
914 .owner = THIS_MODULE, 884 .owner = THIS_MODULE,
915 }, 885 },
916 .id = I2C_DRIVERID_WM8750, 886 .probe = wm8750_i2c_probe,
917 .attach_adapter = wm8750_i2c_attach, 887 .remove = wm8750_i2c_remove,
918 .detach_client = wm8750_i2c_detach, 888 .id_table = wm8750_i2c_id,
919 .command = NULL,
920}; 889};
921 890
922static struct i2c_client client_template = { 891static int wm8750_add_i2c_device(struct platform_device *pdev,
923 .name = "WM8750", 892 const struct wm8750_setup_data *setup)
924 .driver = &wm8750_i2c_driver, 893{
894 struct i2c_board_info info;
895 struct i2c_adapter *adapter;
896 struct i2c_client *client;
897 int ret;
898
899 ret = i2c_add_driver(&wm8750_i2c_driver);
900 if (ret != 0) {
901 dev_err(&pdev->dev, "can't add i2c driver\n");
902 return ret;
903 }
904
905 memset(&info, 0, sizeof(struct i2c_board_info));
906 info.addr = setup->i2c_address;
907 strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
908
909 adapter = i2c_get_adapter(setup->i2c_bus);
910 if (!adapter) {
911 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
912 setup->i2c_bus);
913 goto err_driver;
914 }
915
916 client = i2c_new_device(adapter, &info);
917 i2c_put_adapter(adapter);
918 if (!client) {
919 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
920 (unsigned int)info.addr);
921 goto err_driver;
922 }
923
924 return 0;
925
926err_driver:
927 i2c_del_driver(&wm8750_i2c_driver);
928 return -ENODEV;
929}
930#endif
931
932#if defined(CONFIG_SPI_MASTER)
933static int __devinit wm8750_spi_probe(struct spi_device *spi)
934{
935 struct snd_soc_device *socdev = wm8750_socdev;
936 struct snd_soc_codec *codec = socdev->codec;
937 int ret;
938
939 codec->control_data = spi;
940
941 ret = wm8750_init(socdev);
942 if (ret < 0)
943 dev_err(&spi->dev, "failed to initialise WM8750\n");
944
945 return ret;
946}
947
948static int __devexit wm8750_spi_remove(struct spi_device *spi)
949{
950 return 0;
951}
952
953static struct spi_driver wm8750_spi_driver = {
954 .driver = {
955 .name = "wm8750",
956 .bus = &spi_bus_type,
957 .owner = THIS_MODULE,
958 },
959 .probe = wm8750_spi_probe,
960 .remove = __devexit_p(wm8750_spi_remove),
925}; 961};
962
963static int wm8750_spi_write(struct spi_device *spi, const char *data, int len)
964{
965 struct spi_transfer t;
966 struct spi_message m;
967 u8 msg[2];
968
969 if (len <= 0)
970 return 0;
971
972 msg[0] = data[0];
973 msg[1] = data[1];
974
975 spi_message_init(&m);
976 memset(&t, 0, (sizeof t));
977
978 t.tx_buf = &msg[0];
979 t.len = len;
980
981 spi_message_add_tail(&t, &m);
982 spi_sync(spi, &m);
983
984 return len;
985}
926#endif 986#endif
927 987
928static int wm8750_probe(struct platform_device *pdev) 988static int wm8750_probe(struct platform_device *pdev)
@@ -931,7 +991,7 @@ static int wm8750_probe(struct platform_device *pdev)
931 struct wm8750_setup_data *setup = socdev->codec_data; 991 struct wm8750_setup_data *setup = socdev->codec_data;
932 struct snd_soc_codec *codec; 992 struct snd_soc_codec *codec;
933 struct wm8750_priv *wm8750; 993 struct wm8750_priv *wm8750;
934 int ret = 0; 994 int ret;
935 995
936 pr_info("WM8750 Audio Codec %s", WM8750_VERSION); 996 pr_info("WM8750 Audio Codec %s", WM8750_VERSION);
937 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 997 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
@@ -952,16 +1012,21 @@ static int wm8750_probe(struct platform_device *pdev)
952 wm8750_socdev = socdev; 1012 wm8750_socdev = socdev;
953 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work); 1013 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work);
954 1014
1015 ret = -ENODEV;
1016
955#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1017#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
956 if (setup->i2c_address) { 1018 if (setup->i2c_address) {
957 normal_i2c[0] = setup->i2c_address;
958 codec->hw_write = (hw_write_t)i2c_master_send; 1019 codec->hw_write = (hw_write_t)i2c_master_send;
959 ret = i2c_add_driver(&wm8750_i2c_driver); 1020 ret = wm8750_add_i2c_device(pdev, setup);
1021 }
1022#endif
1023#if defined(CONFIG_SPI_MASTER)
1024 if (setup->spi) {
1025 codec->hw_write = (hw_write_t)wm8750_spi_write;
1026 ret = spi_register_driver(&wm8750_spi_driver);
960 if (ret != 0) 1027 if (ret != 0)
961 printk(KERN_ERR "can't add i2c driver"); 1028 printk(KERN_ERR "can't add spi driver");
962 } 1029 }
963#else
964 /* Add other interfaces here */
965#endif 1030#endif
966 1031
967 if (ret != 0) { 1032 if (ret != 0) {
@@ -1002,8 +1067,12 @@ static int wm8750_remove(struct platform_device *pdev)
1002 snd_soc_free_pcms(socdev); 1067 snd_soc_free_pcms(socdev);
1003 snd_soc_dapm_free(socdev); 1068 snd_soc_dapm_free(socdev);
1004#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1069#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1070 i2c_unregister_device(codec->control_data);
1005 i2c_del_driver(&wm8750_i2c_driver); 1071 i2c_del_driver(&wm8750_i2c_driver);
1006#endif 1072#endif
1073#if defined(CONFIG_SPI_MASTER)
1074 spi_unregister_driver(&wm8750_spi_driver);
1075#endif
1007 kfree(codec->private_data); 1076 kfree(codec->private_data);
1008 kfree(codec); 1077 kfree(codec);
1009 1078
diff --git a/sound/soc/codecs/wm8750.h b/sound/soc/codecs/wm8750.h
index 8ef30e628b2..1dc100e19cf 100644
--- a/sound/soc/codecs/wm8750.h
+++ b/sound/soc/codecs/wm8750.h
@@ -58,6 +58,8 @@
58#define WM8750_SYSCLK 0 58#define WM8750_SYSCLK 0
59 59
60struct wm8750_setup_data { 60struct wm8750_setup_data {
61 int spi;
62 int i2c_bus;
61 unsigned short i2c_address; 63 unsigned short i2c_address;
62}; 64};
63 65
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 5761164fe16..8c4df44f334 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -583,7 +583,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
583 583
584 /* out 4 */ 584 /* out 4 */
585 {"Out4 Mux", "VREF", "VREF"}, 585 {"Out4 Mux", "VREF", "VREF"},
586 {"Out4 Mux", "Capture ST", "Capture ST Mixer"}, 586 {"Out4 Mux", "Capture ST", "Playback Mixer"},
587 {"Out4 Mux", "LOUT2", "LOUT2"}, 587 {"Out4 Mux", "LOUT2", "LOUT2"},
588 {"Out 4", NULL, "Out4 Mux"}, 588 {"Out 4", NULL, "Out4 Mux"},
589 {"OUT4", NULL, "Out 4"}, 589 {"OUT4", NULL, "Out 4"},
@@ -607,7 +607,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
607 /* Capture Right Mux */ 607 /* Capture Right Mux */
608 {"Capture Right Mux", "PGA", "Right Capture Volume"}, 608 {"Capture Right Mux", "PGA", "Right Capture Volume"},
609 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"}, 609 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
610 {"Capture Right Mux", "Sidetone", "Capture ST Mixer"}, 610 {"Capture Right Mux", "Sidetone", "Playback Mixer"},
611 611
612 /* Mono Capture mixer-mux */ 612 /* Mono Capture mixer-mux */
613 {"Capture Right Mixer", "Stereo", "Capture Right Mux"}, 613 {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
@@ -1637,84 +1637,86 @@ static struct snd_soc_device *wm8753_socdev;
1637 * low = 0x1a 1637 * low = 0x1a
1638 * high = 0x1b 1638 * high = 0x1b
1639 */ 1639 */
1640static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1641 1640
1642/* Magic definition of all other variables and things */ 1641static int wm8753_i2c_probe(struct i2c_client *i2c,
1643I2C_CLIENT_INSMOD; 1642 const struct i2c_device_id *id)
1644
1645static struct i2c_driver wm8753_i2c_driver;
1646static struct i2c_client client_template;
1647
1648static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1649{ 1643{
1650 struct snd_soc_device *socdev = wm8753_socdev; 1644 struct snd_soc_device *socdev = wm8753_socdev;
1651 struct wm8753_setup_data *setup = socdev->codec_data;
1652 struct snd_soc_codec *codec = socdev->codec; 1645 struct snd_soc_codec *codec = socdev->codec;
1653 struct i2c_client *i2c;
1654 int ret; 1646 int ret;
1655 1647
1656 if (addr != setup->i2c_address)
1657 return -ENODEV;
1658
1659 client_template.adapter = adap;
1660 client_template.addr = addr;
1661
1662 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1663 if (!i2c)
1664 return -ENOMEM;
1665
1666 i2c_set_clientdata(i2c, codec); 1648 i2c_set_clientdata(i2c, codec);
1667 codec->control_data = i2c; 1649 codec->control_data = i2c;
1668 1650
1669 ret = i2c_attach_client(i2c);
1670 if (ret < 0) {
1671 pr_err("failed to attach codec at addr %x\n", addr);
1672 goto err;
1673 }
1674
1675 ret = wm8753_init(socdev); 1651 ret = wm8753_init(socdev);
1676 if (ret < 0) { 1652 if (ret < 0)
1677 pr_err("failed to initialise WM8753\n"); 1653 pr_err("failed to initialise WM8753\n");
1678 goto err;
1679 }
1680
1681 return ret;
1682 1654
1683err:
1684 kfree(i2c);
1685 return ret; 1655 return ret;
1686} 1656}
1687 1657
1688static int wm8753_i2c_detach(struct i2c_client *client) 1658static int wm8753_i2c_remove(struct i2c_client *client)
1689{ 1659{
1690 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1660 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1691 i2c_detach_client(client);
1692 kfree(codec->reg_cache); 1661 kfree(codec->reg_cache);
1693 kfree(client);
1694 return 0; 1662 return 0;
1695} 1663}
1696 1664
1697static int wm8753_i2c_attach(struct i2c_adapter *adap) 1665static const struct i2c_device_id wm8753_i2c_id[] = {
1698{ 1666 { "wm8753", 0 },
1699 return i2c_probe(adap, &addr_data, wm8753_codec_probe); 1667 { }
1700} 1668};
1669MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1701 1670
1702/* corgi i2c codec control layer */
1703static struct i2c_driver wm8753_i2c_driver = { 1671static struct i2c_driver wm8753_i2c_driver = {
1704 .driver = { 1672 .driver = {
1705 .name = "WM8753 I2C Codec", 1673 .name = "WM8753 I2C Codec",
1706 .owner = THIS_MODULE, 1674 .owner = THIS_MODULE,
1707 }, 1675 },
1708 .id = I2C_DRIVERID_WM8753, 1676 .probe = wm8753_i2c_probe,
1709 .attach_adapter = wm8753_i2c_attach, 1677 .remove = wm8753_i2c_remove,
1710 .detach_client = wm8753_i2c_detach, 1678 .id_table = wm8753_i2c_id,
1711 .command = NULL,
1712}; 1679};
1713 1680
1714static struct i2c_client client_template = { 1681static int wm8753_add_i2c_device(struct platform_device *pdev,
1715 .name = "WM8753", 1682 const struct wm8753_setup_data *setup)
1716 .driver = &wm8753_i2c_driver, 1683{
1717}; 1684 struct i2c_board_info info;
1685 struct i2c_adapter *adapter;
1686 struct i2c_client *client;
1687 int ret;
1688
1689 ret = i2c_add_driver(&wm8753_i2c_driver);
1690 if (ret != 0) {
1691 dev_err(&pdev->dev, "can't add i2c driver\n");
1692 return ret;
1693 }
1694
1695 memset(&info, 0, sizeof(struct i2c_board_info));
1696 info.addr = setup->i2c_address;
1697 strlcpy(info.type, "wm8753", I2C_NAME_SIZE);
1698
1699 adapter = i2c_get_adapter(setup->i2c_bus);
1700 if (!adapter) {
1701 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1702 setup->i2c_bus);
1703 goto err_driver;
1704 }
1705
1706 client = i2c_new_device(adapter, &info);
1707 i2c_put_adapter(adapter);
1708 if (!client) {
1709 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1710 (unsigned int)info.addr);
1711 goto err_driver;
1712 }
1713
1714 return 0;
1715
1716err_driver:
1717 i2c_del_driver(&wm8753_i2c_driver);
1718 return -ENODEV;
1719}
1718#endif 1720#endif
1719 1721
1720static int wm8753_probe(struct platform_device *pdev) 1722static int wm8753_probe(struct platform_device *pdev)
@@ -1748,11 +1750,8 @@ static int wm8753_probe(struct platform_device *pdev)
1748 1750
1749#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1751#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1750 if (setup->i2c_address) { 1752 if (setup->i2c_address) {
1751 normal_i2c[0] = setup->i2c_address;
1752 codec->hw_write = (hw_write_t)i2c_master_send; 1753 codec->hw_write = (hw_write_t)i2c_master_send;
1753 ret = i2c_add_driver(&wm8753_i2c_driver); 1754 ret = wm8753_add_i2c_device(pdev, setup);
1754 if (ret != 0)
1755 printk(KERN_ERR "can't add i2c driver");
1756 } 1755 }
1757#else 1756#else
1758 /* Add other interfaces here */ 1757 /* Add other interfaces here */
@@ -1796,6 +1795,7 @@ static int wm8753_remove(struct platform_device *pdev)
1796 snd_soc_free_pcms(socdev); 1795 snd_soc_free_pcms(socdev);
1797 snd_soc_dapm_free(socdev); 1796 snd_soc_dapm_free(socdev);
1798#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1797#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1798 i2c_unregister_device(codec->control_data);
1799 i2c_del_driver(&wm8753_i2c_driver); 1799 i2c_del_driver(&wm8753_i2c_driver);
1800#endif 1800#endif
1801 kfree(codec->private_data); 1801 kfree(codec->private_data);
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
index 44f5f1ff0cc..7defde069f1 100644
--- a/sound/soc/codecs/wm8753.h
+++ b/sound/soc/codecs/wm8753.h
@@ -79,6 +79,7 @@
79#define WM8753_ADCTL2 0x3f 79#define WM8753_ADCTL2 0x3f
80 80
81struct wm8753_setup_data { 81struct wm8753_setup_data {
82 int i2c_bus;
82 unsigned short i2c_address; 83 unsigned short i2c_address;
83}; 84};
84 85
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
new file mode 100644
index 00000000000..0b8c6d38b48
--- /dev/null
+++ b/sound/soc/codecs/wm8900.c
@@ -0,0 +1,1542 @@
1/*
2 * wm8900.c -- WM8900 ALSA Soc Audio driver
3 *
4 * Copyright 2007, 2008 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * TODO:
13 * - Tristating.
14 * - TDM.
15 * - Jack detect.
16 * - FLL source configuration, currently only MCLK is supported.
17 */
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/version.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/pm.h>
26#include <linux/i2c.h>
27#include <linux/platform_device.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/initval.h>
34#include <sound/tlv.h>
35
36#include "wm8900.h"
37
38/* WM8900 register space */
39#define WM8900_REG_RESET 0x0
40#define WM8900_REG_ID 0x0
41#define WM8900_REG_POWER1 0x1
42#define WM8900_REG_POWER2 0x2
43#define WM8900_REG_POWER3 0x3
44#define WM8900_REG_AUDIO1 0x4
45#define WM8900_REG_AUDIO2 0x5
46#define WM8900_REG_CLOCKING1 0x6
47#define WM8900_REG_CLOCKING2 0x7
48#define WM8900_REG_AUDIO3 0x8
49#define WM8900_REG_AUDIO4 0x9
50#define WM8900_REG_DACCTRL 0xa
51#define WM8900_REG_LDAC_DV 0xb
52#define WM8900_REG_RDAC_DV 0xc
53#define WM8900_REG_SIDETONE 0xd
54#define WM8900_REG_ADCCTRL 0xe
55#define WM8900_REG_LADC_DV 0xf
56#define WM8900_REG_RADC_DV 0x10
57#define WM8900_REG_GPIO 0x12
58#define WM8900_REG_INCTL 0x15
59#define WM8900_REG_LINVOL 0x16
60#define WM8900_REG_RINVOL 0x17
61#define WM8900_REG_INBOOSTMIX1 0x18
62#define WM8900_REG_INBOOSTMIX2 0x19
63#define WM8900_REG_ADCPATH 0x1a
64#define WM8900_REG_AUXBOOST 0x1b
65#define WM8900_REG_ADDCTL 0x1e
66#define WM8900_REG_FLLCTL1 0x24
67#define WM8900_REG_FLLCTL2 0x25
68#define WM8900_REG_FLLCTL3 0x26
69#define WM8900_REG_FLLCTL4 0x27
70#define WM8900_REG_FLLCTL5 0x28
71#define WM8900_REG_FLLCTL6 0x29
72#define WM8900_REG_LOUTMIXCTL1 0x2c
73#define WM8900_REG_ROUTMIXCTL1 0x2d
74#define WM8900_REG_BYPASS1 0x2e
75#define WM8900_REG_BYPASS2 0x2f
76#define WM8900_REG_AUXOUT_CTL 0x30
77#define WM8900_REG_LOUT1CTL 0x33
78#define WM8900_REG_ROUT1CTL 0x34
79#define WM8900_REG_LOUT2CTL 0x35
80#define WM8900_REG_ROUT2CTL 0x36
81#define WM8900_REG_HPCTL1 0x3a
82#define WM8900_REG_OUTBIASCTL 0x73
83
84#define WM8900_MAXREG 0x80
85
86#define WM8900_REG_ADDCTL_OUT1_DIS 0x80
87#define WM8900_REG_ADDCTL_OUT2_DIS 0x40
88#define WM8900_REG_ADDCTL_VMID_DIS 0x20
89#define WM8900_REG_ADDCTL_BIAS_SRC 0x10
90#define WM8900_REG_ADDCTL_VMID_SOFTST 0x04
91#define WM8900_REG_ADDCTL_TEMP_SD 0x02
92
93#define WM8900_REG_GPIO_TEMP_ENA 0x2
94
95#define WM8900_REG_POWER1_STARTUP_BIAS_ENA 0x0100
96#define WM8900_REG_POWER1_BIAS_ENA 0x0008
97#define WM8900_REG_POWER1_VMID_BUF_ENA 0x0004
98#define WM8900_REG_POWER1_FLL_ENA 0x0040
99
100#define WM8900_REG_POWER2_SYSCLK_ENA 0x8000
101#define WM8900_REG_POWER2_ADCL_ENA 0x0002
102#define WM8900_REG_POWER2_ADCR_ENA 0x0001
103
104#define WM8900_REG_POWER3_DACL_ENA 0x0002
105#define WM8900_REG_POWER3_DACR_ENA 0x0001
106
107#define WM8900_REG_AUDIO1_AIF_FMT_MASK 0x0018
108#define WM8900_REG_AUDIO1_LRCLK_INV 0x0080
109#define WM8900_REG_AUDIO1_BCLK_INV 0x0100
110
111#define WM8900_REG_CLOCKING1_BCLK_DIR 0x1
112#define WM8900_REG_CLOCKING1_MCLK_SRC 0x100
113#define WM8900_REG_CLOCKING1_BCLK_MASK (~0x01e)
114#define WM8900_REG_CLOCKING1_OPCLK_MASK (~0x7000)
115
116#define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0
117#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c
118
119#define WM8900_REG_DACCTRL_MUTE 0x004
120#define WM8900_REG_DACCTRL_AIF_LRCLKRATE 0x400
121
122#define WM8900_REG_AUDIO3_ADCLRC_DIR 0x0800
123
124#define WM8900_REG_AUDIO4_DACLRC_DIR 0x0800
125
126#define WM8900_REG_FLLCTL1_OSC_ENA 0x100
127
128#define WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF 0x100
129
130#define WM8900_REG_HPCTL1_HP_IPSTAGE_ENA 0x80
131#define WM8900_REG_HPCTL1_HP_OPSTAGE_ENA 0x40
132#define WM8900_REG_HPCTL1_HP_CLAMP_IP 0x20
133#define WM8900_REG_HPCTL1_HP_CLAMP_OP 0x10
134#define WM8900_REG_HPCTL1_HP_SHORT 0x08
135#define WM8900_REG_HPCTL1_HP_SHORT2 0x04
136
137#define WM8900_LRC_MASK 0xfc00
138
139struct snd_soc_codec_device soc_codec_dev_wm8900;
140
141struct wm8900_priv {
142 u32 fll_in; /* FLL input frequency */
143 u32 fll_out; /* FLL output frequency */
144};
145
146/*
147 * wm8900 register cache. We can't read the entire register space and we
148 * have slow control buses so we cache the registers.
149 */
150static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
151 0x8900, 0x0000,
152 0xc000, 0x0000,
153 0x4050, 0x4000,
154 0x0008, 0x0000,
155 0x0040, 0x0040,
156 0x1004, 0x00c0,
157 0x00c0, 0x0000,
158 0x0100, 0x00c0,
159 0x00c0, 0x0000,
160 0xb001, 0x0000,
161 0x0000, 0x0044,
162 0x004c, 0x004c,
163 0x0044, 0x0044,
164 0x0000, 0x0044,
165 0x0000, 0x0000,
166 0x0002, 0x0000,
167 0x0000, 0x0000,
168 0x0000, 0x0000,
169 0x0008, 0x0000,
170 0x0000, 0x0008,
171 0x0097, 0x0100,
172 0x0000, 0x0000,
173 0x0050, 0x0050,
174 0x0055, 0x0055,
175 0x0055, 0x0000,
176 0x0000, 0x0079,
177 0x0079, 0x0079,
178 0x0079, 0x0000,
179 /* Remaining registers all zero */
180};
181
182/*
183 * read wm8900 register cache
184 */
185static inline unsigned int wm8900_read_reg_cache(struct snd_soc_codec *codec,
186 unsigned int reg)
187{
188 u16 *cache = codec->reg_cache;
189
190 BUG_ON(reg >= WM8900_MAXREG);
191
192 if (reg == WM8900_REG_ID)
193 return 0;
194
195 return cache[reg];
196}
197
198/*
199 * write wm8900 register cache
200 */
201static inline void wm8900_write_reg_cache(struct snd_soc_codec *codec,
202 u16 reg, unsigned int value)
203{
204 u16 *cache = codec->reg_cache;
205
206 BUG_ON(reg >= WM8900_MAXREG);
207
208 cache[reg] = value;
209}
210
211/*
212 * write to the WM8900 register space
213 */
214static int wm8900_write(struct snd_soc_codec *codec, unsigned int reg,
215 unsigned int value)
216{
217 u8 data[3];
218
219 if (value == wm8900_read_reg_cache(codec, reg))
220 return 0;
221
222 /* data is
223 * D15..D9 WM8900 register offset
224 * D8...D0 register data
225 */
226 data[0] = reg;
227 data[1] = value >> 8;
228 data[2] = value & 0x00ff;
229
230 wm8900_write_reg_cache(codec, reg, value);
231 if (codec->hw_write(codec->control_data, data, 3) == 3)
232 return 0;
233 else
234 return -EIO;
235}
236
237/*
238 * Read from the wm8900.
239 */
240static unsigned int wm8900_chip_read(struct snd_soc_codec *codec, u8 reg)
241{
242 struct i2c_msg xfer[2];
243 u16 data;
244 int ret;
245 struct i2c_client *client = codec->control_data;
246
247 BUG_ON(reg != WM8900_REG_ID && reg != WM8900_REG_POWER1);
248
249 /* Write register */
250 xfer[0].addr = client->addr;
251 xfer[0].flags = 0;
252 xfer[0].len = 1;
253 xfer[0].buf = &reg;
254
255 /* Read data */
256 xfer[1].addr = client->addr;
257 xfer[1].flags = I2C_M_RD;
258 xfer[1].len = 2;
259 xfer[1].buf = (u8 *)&data;
260
261 ret = i2c_transfer(client->adapter, xfer, 2);
262 if (ret != 2) {
263 printk(KERN_CRIT "i2c_transfer returned %d\n", ret);
264 return 0;
265 }
266
267 return (data >> 8) | ((data & 0xff) << 8);
268}
269
270/*
271 * Read from the WM8900 register space. Most registers can't be read
272 * and are therefore supplied from cache.
273 */
274static unsigned int wm8900_read(struct snd_soc_codec *codec, unsigned int reg)
275{
276 switch (reg) {
277 case WM8900_REG_ID:
278 return wm8900_chip_read(codec, reg);
279 default:
280 return wm8900_read_reg_cache(codec, reg);
281 }
282}
283
284static void wm8900_reset(struct snd_soc_codec *codec)
285{
286 wm8900_write(codec, WM8900_REG_RESET, 0);
287
288 memcpy(codec->reg_cache, wm8900_reg_defaults,
289 sizeof(codec->reg_cache));
290}
291
292static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
293 struct snd_kcontrol *kcontrol, int event)
294{
295 struct snd_soc_codec *codec = w->codec;
296 u16 hpctl1 = wm8900_read(codec, WM8900_REG_HPCTL1);
297
298 switch (event) {
299 case SND_SOC_DAPM_PRE_PMU:
300 /* Clamp headphone outputs */
301 hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP |
302 WM8900_REG_HPCTL1_HP_CLAMP_OP;
303 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
304 break;
305
306 case SND_SOC_DAPM_POST_PMU:
307 /* Enable the input stage */
308 hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_IP;
309 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT |
310 WM8900_REG_HPCTL1_HP_SHORT2 |
311 WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
312 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
313
314 msleep(400);
315
316 /* Enable the output stage */
317 hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP;
318 hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
319 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
320
321 /* Remove the shorts */
322 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2;
323 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
324 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT;
325 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
326 break;
327
328 case SND_SOC_DAPM_PRE_PMD:
329 /* Short the output */
330 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT;
331 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
332
333 /* Disable the output stage */
334 hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
335 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
336
337 /* Clamp the outputs and power down input */
338 hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP |
339 WM8900_REG_HPCTL1_HP_CLAMP_OP;
340 hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
341 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1);
342 break;
343
344 case SND_SOC_DAPM_POST_PMD:
345 /* Disable everything */
346 wm8900_write(codec, WM8900_REG_HPCTL1, 0);
347 break;
348
349 default:
350 BUG();
351 }
352
353 return 0;
354}
355
356static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -5700, 100, 0);
357
358static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 0);
359
360static const DECLARE_TLV_DB_SCALE(in_boost_tlv, -1200, 600, 0);
361
362static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1200, 100, 0);
363
364static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
365
366static const DECLARE_TLV_DB_SCALE(dac_tlv, -7200, 75, 1);
367
368static const DECLARE_TLV_DB_SCALE(adc_svol_tlv, -3600, 300, 0);
369
370static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1);
371
372static const char *mic_bias_level_txt[] = { "0.9*AVDD", "0.65*AVDD" };
373
374static const struct soc_enum mic_bias_level =
375SOC_ENUM_SINGLE(WM8900_REG_INCTL, 8, 2, mic_bias_level_txt);
376
377static const char *dac_mute_rate_txt[] = { "Fast", "Slow" };
378
379static const struct soc_enum dac_mute_rate =
380SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 7, 2, dac_mute_rate_txt);
381
382static const char *dac_deemphasis_txt[] = {
383 "Disabled", "32kHz", "44.1kHz", "48kHz"
384};
385
386static const struct soc_enum dac_deemphasis =
387SOC_ENUM_SINGLE(WM8900_REG_DACCTRL, 4, 4, dac_deemphasis_txt);
388
389static const char *adc_hpf_cut_txt[] = {
390 "Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"
391};
392
393static const struct soc_enum adc_hpf_cut =
394SOC_ENUM_SINGLE(WM8900_REG_ADCCTRL, 5, 4, adc_hpf_cut_txt);
395
396static const char *lr_txt[] = {
397 "Left", "Right"
398};
399
400static const struct soc_enum aifl_src =
401SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 15, 2, lr_txt);
402
403static const struct soc_enum aifr_src =
404SOC_ENUM_SINGLE(WM8900_REG_AUDIO1, 14, 2, lr_txt);
405
406static const struct soc_enum dacl_src =
407SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 15, 2, lr_txt);
408
409static const struct soc_enum dacr_src =
410SOC_ENUM_SINGLE(WM8900_REG_AUDIO2, 14, 2, lr_txt);
411
412static const char *sidetone_txt[] = {
413 "Disabled", "Left ADC", "Right ADC"
414};
415
416static const struct soc_enum dacl_sidetone =
417SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 2, 3, sidetone_txt);
418
419static const struct soc_enum dacr_sidetone =
420SOC_ENUM_SINGLE(WM8900_REG_SIDETONE, 0, 3, sidetone_txt);
421
422static const struct snd_kcontrol_new wm8900_snd_controls[] = {
423SOC_ENUM("Mic Bias Level", mic_bias_level),
424
425SOC_SINGLE_TLV("Left Input PGA Volume", WM8900_REG_LINVOL, 0, 31, 0,
426 in_pga_tlv),
427SOC_SINGLE("Left Input PGA Switch", WM8900_REG_LINVOL, 6, 1, 1),
428SOC_SINGLE("Left Input PGA ZC Switch", WM8900_REG_LINVOL, 7, 1, 0),
429
430SOC_SINGLE_TLV("Right Input PGA Volume", WM8900_REG_RINVOL, 0, 31, 0,
431 in_pga_tlv),
432SOC_SINGLE("Right Input PGA Switch", WM8900_REG_RINVOL, 6, 1, 1),
433SOC_SINGLE("Right Input PGA ZC Switch", WM8900_REG_RINVOL, 7, 1, 0),
434
435SOC_SINGLE("DAC Soft Mute Switch", WM8900_REG_DACCTRL, 6, 1, 1),
436SOC_ENUM("DAC Mute Rate", dac_mute_rate),
437SOC_SINGLE("DAC Mono Switch", WM8900_REG_DACCTRL, 9, 1, 0),
438SOC_ENUM("DAC Deemphasis", dac_deemphasis),
439SOC_SINGLE("DAC Sloping Stopband Filter Switch", WM8900_REG_DACCTRL, 8, 1, 0),
440SOC_SINGLE("DAC Sigma-Delta Modulator Clock Switch", WM8900_REG_DACCTRL,
441 12, 1, 0),
442
443SOC_SINGLE("ADC HPF Switch", WM8900_REG_ADCCTRL, 8, 1, 0),
444SOC_ENUM("ADC HPF Cut-Off", adc_hpf_cut),
445SOC_DOUBLE("ADC Invert Switch", WM8900_REG_ADCCTRL, 1, 0, 1, 0),
446SOC_SINGLE_TLV("Left ADC Sidetone Volume", WM8900_REG_SIDETONE, 9, 12, 0,
447 adc_svol_tlv),
448SOC_SINGLE_TLV("Right ADC Sidetone Volume", WM8900_REG_SIDETONE, 5, 12, 0,
449 adc_svol_tlv),
450SOC_ENUM("Left Digital Audio Source", aifl_src),
451SOC_ENUM("Right Digital Audio Source", aifr_src),
452
453SOC_SINGLE_TLV("DAC Input Boost Volume", WM8900_REG_AUDIO2, 10, 4, 0,
454 dac_boost_tlv),
455SOC_ENUM("Left DAC Source", dacl_src),
456SOC_ENUM("Right DAC Source", dacr_src),
457SOC_ENUM("Left DAC Sidetone", dacl_sidetone),
458SOC_ENUM("Right DAC Sidetone", dacr_sidetone),
459SOC_DOUBLE("DAC Invert Switch", WM8900_REG_DACCTRL, 1, 0, 1, 0),
460
461SOC_DOUBLE_R_TLV("Digital Playback Volume",
462 WM8900_REG_LDAC_DV, WM8900_REG_RDAC_DV,
463 1, 96, 0, dac_tlv),
464SOC_DOUBLE_R_TLV("Digital Capture Volume",
465 WM8900_REG_LADC_DV, WM8900_REG_RADC_DV, 1, 119, 0, adc_tlv),
466
467SOC_SINGLE_TLV("LINPUT3 Bypass Volume", WM8900_REG_LOUTMIXCTL1, 4, 7, 0,
468 out_mix_tlv),
469SOC_SINGLE_TLV("RINPUT3 Bypass Volume", WM8900_REG_ROUTMIXCTL1, 4, 7, 0,
470 out_mix_tlv),
471SOC_SINGLE_TLV("Left AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 4, 7, 0,
472 out_mix_tlv),
473SOC_SINGLE_TLV("Right AUX Bypass Volume", WM8900_REG_AUXOUT_CTL, 0, 7, 0,
474 out_mix_tlv),
475
476SOC_SINGLE_TLV("LeftIn to RightOut Mixer Volume", WM8900_REG_BYPASS1, 0, 7, 0,
477 out_mix_tlv),
478SOC_SINGLE_TLV("LeftIn to LeftOut Mixer Volume", WM8900_REG_BYPASS1, 4, 7, 0,
479 out_mix_tlv),
480SOC_SINGLE_TLV("RightIn to LeftOut Mixer Volume", WM8900_REG_BYPASS2, 0, 7, 0,
481 out_mix_tlv),
482SOC_SINGLE_TLV("RightIn to RightOut Mixer Volume", WM8900_REG_BYPASS2, 4, 7, 0,
483 out_mix_tlv),
484
485SOC_SINGLE_TLV("IN2L Boost Volume", WM8900_REG_INBOOSTMIX1, 0, 3, 0,
486 in_boost_tlv),
487SOC_SINGLE_TLV("IN3L Boost Volume", WM8900_REG_INBOOSTMIX1, 4, 3, 0,
488 in_boost_tlv),
489SOC_SINGLE_TLV("IN2R Boost Volume", WM8900_REG_INBOOSTMIX2, 0, 3, 0,
490 in_boost_tlv),
491SOC_SINGLE_TLV("IN3R Boost Volume", WM8900_REG_INBOOSTMIX2, 4, 3, 0,
492 in_boost_tlv),
493SOC_SINGLE_TLV("Left AUX Boost Volume", WM8900_REG_AUXBOOST, 4, 3, 0,
494 in_boost_tlv),
495SOC_SINGLE_TLV("Right AUX Boost Volume", WM8900_REG_AUXBOOST, 0, 3, 0,
496 in_boost_tlv),
497
498SOC_DOUBLE_R_TLV("LINEOUT1 Volume", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
499 0, 63, 0, out_pga_tlv),
500SOC_DOUBLE_R("LINEOUT1 Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
501 6, 1, 1),
502SOC_DOUBLE_R("LINEOUT1 ZC Switch", WM8900_REG_LOUT1CTL, WM8900_REG_ROUT1CTL,
503 7, 1, 0),
504
505SOC_DOUBLE_R_TLV("LINEOUT2 Volume",
506 WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL,
507 0, 63, 0, out_pga_tlv),
508SOC_DOUBLE_R("LINEOUT2 Switch",
509 WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 6, 1, 1),
510SOC_DOUBLE_R("LINEOUT2 ZC Switch",
511 WM8900_REG_LOUT2CTL, WM8900_REG_ROUT2CTL, 7, 1, 0),
512SOC_SINGLE("LINEOUT2 LP -12dB", WM8900_REG_LOUTMIXCTL1,
513 0, 1, 1),
514
515};
516
517/* add non dapm controls */
518static int wm8900_add_controls(struct snd_soc_codec *codec)
519{
520 int err, i;
521
522 for (i = 0; i < ARRAY_SIZE(wm8900_snd_controls); i++) {
523 err = snd_ctl_add(codec->card,
524 snd_soc_cnew(&wm8900_snd_controls[i],
525 codec, NULL));
526 if (err < 0)
527 return err;
528 }
529
530 return 0;
531}
532
533static const struct snd_kcontrol_new wm8900_dapm_loutput2_control =
534SOC_DAPM_SINGLE("LINEOUT2L Switch", WM8900_REG_POWER3, 6, 1, 0);
535
536static const struct snd_kcontrol_new wm8900_dapm_routput2_control =
537SOC_DAPM_SINGLE("LINEOUT2R Switch", WM8900_REG_POWER3, 5, 1, 0);
538
539static const struct snd_kcontrol_new wm8900_loutmix_controls[] = {
540SOC_DAPM_SINGLE("LINPUT3 Bypass Switch", WM8900_REG_LOUTMIXCTL1, 7, 1, 0),
541SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 7, 1, 0),
542SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 7, 1, 0),
543SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 3, 1, 0),
544SOC_DAPM_SINGLE("DACL Switch", WM8900_REG_LOUTMIXCTL1, 8, 1, 0),
545};
546
547static const struct snd_kcontrol_new wm8900_routmix_controls[] = {
548SOC_DAPM_SINGLE("RINPUT3 Bypass Switch", WM8900_REG_ROUTMIXCTL1, 7, 1, 0),
549SOC_DAPM_SINGLE("AUX Bypass Switch", WM8900_REG_AUXOUT_CTL, 3, 1, 0),
550SOC_DAPM_SINGLE("Left Input Mixer Switch", WM8900_REG_BYPASS1, 3, 1, 0),
551SOC_DAPM_SINGLE("Right Input Mixer Switch", WM8900_REG_BYPASS2, 7, 1, 0),
552SOC_DAPM_SINGLE("DACR Switch", WM8900_REG_ROUTMIXCTL1, 8, 1, 0),
553};
554
555static const struct snd_kcontrol_new wm8900_linmix_controls[] = {
556SOC_DAPM_SINGLE("LINPUT2 Switch", WM8900_REG_INBOOSTMIX1, 2, 1, 1),
557SOC_DAPM_SINGLE("LINPUT3 Switch", WM8900_REG_INBOOSTMIX1, 6, 1, 1),
558SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 6, 1, 1),
559SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 6, 1, 0),
560};
561
562static const struct snd_kcontrol_new wm8900_rinmix_controls[] = {
563SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INBOOSTMIX2, 2, 1, 1),
564SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INBOOSTMIX2, 6, 1, 1),
565SOC_DAPM_SINGLE("AUX Switch", WM8900_REG_AUXBOOST, 2, 1, 1),
566SOC_DAPM_SINGLE("Input PGA Switch", WM8900_REG_ADCPATH, 2, 1, 0),
567};
568
569static const struct snd_kcontrol_new wm8900_linpga_controls[] = {
570SOC_DAPM_SINGLE("LINPUT1 Switch", WM8900_REG_INCTL, 6, 1, 0),
571SOC_DAPM_SINGLE("LINPUT2 Switch", WM8900_REG_INCTL, 5, 1, 0),
572SOC_DAPM_SINGLE("LINPUT3 Switch", WM8900_REG_INCTL, 4, 1, 0),
573};
574
575static const struct snd_kcontrol_new wm8900_rinpga_controls[] = {
576SOC_DAPM_SINGLE("RINPUT1 Switch", WM8900_REG_INCTL, 2, 1, 0),
577SOC_DAPM_SINGLE("RINPUT2 Switch", WM8900_REG_INCTL, 1, 1, 0),
578SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0),
579};
580
581static const char *wm9700_lp_mux[] = { "Disabled", "Enabled" };
582
583static const struct soc_enum wm8900_lineout2_lp_mux =
584SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm9700_lp_mux);
585
586static const struct snd_kcontrol_new wm8900_lineout2_lp =
587SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux);
588
589static const struct snd_soc_dapm_widget wm8900_dapm_widgets[] = {
590
591/* Externally visible pins */
592SND_SOC_DAPM_OUTPUT("LINEOUT1L"),
593SND_SOC_DAPM_OUTPUT("LINEOUT1R"),
594SND_SOC_DAPM_OUTPUT("LINEOUT2L"),
595SND_SOC_DAPM_OUTPUT("LINEOUT2R"),
596SND_SOC_DAPM_OUTPUT("HP_L"),
597SND_SOC_DAPM_OUTPUT("HP_R"),
598
599SND_SOC_DAPM_INPUT("RINPUT1"),
600SND_SOC_DAPM_INPUT("LINPUT1"),
601SND_SOC_DAPM_INPUT("RINPUT2"),
602SND_SOC_DAPM_INPUT("LINPUT2"),
603SND_SOC_DAPM_INPUT("RINPUT3"),
604SND_SOC_DAPM_INPUT("LINPUT3"),
605SND_SOC_DAPM_INPUT("AUX"),
606
607SND_SOC_DAPM_VMID("VMID"),
608
609/* Input */
610SND_SOC_DAPM_MIXER("Left Input PGA", WM8900_REG_POWER2, 3, 0,
611 wm8900_linpga_controls,
612 ARRAY_SIZE(wm8900_linpga_controls)),
613SND_SOC_DAPM_MIXER("Right Input PGA", WM8900_REG_POWER2, 2, 0,
614 wm8900_rinpga_controls,
615 ARRAY_SIZE(wm8900_rinpga_controls)),
616
617SND_SOC_DAPM_MIXER("Left Input Mixer", WM8900_REG_POWER2, 5, 0,
618 wm8900_linmix_controls,
619 ARRAY_SIZE(wm8900_linmix_controls)),
620SND_SOC_DAPM_MIXER("Right Input Mixer", WM8900_REG_POWER2, 4, 0,
621 wm8900_rinmix_controls,
622 ARRAY_SIZE(wm8900_rinmix_controls)),
623
624SND_SOC_DAPM_MICBIAS("Mic Bias", WM8900_REG_POWER1, 4, 0),
625
626SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8900_REG_POWER2, 1, 0),
627SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8900_REG_POWER2, 0, 0),
628
629/* Output */
630SND_SOC_DAPM_DAC("DACL", "Left HiFi Playback", WM8900_REG_POWER3, 1, 0),
631SND_SOC_DAPM_DAC("DACR", "Right HiFi Playback", WM8900_REG_POWER3, 0, 0),
632
633SND_SOC_DAPM_PGA_E("Headphone Amplifier", WM8900_REG_POWER3, 7, 0, NULL, 0,
634 wm8900_hp_event,
635 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
636 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
637
638SND_SOC_DAPM_PGA("LINEOUT1L PGA", WM8900_REG_POWER2, 8, 0, NULL, 0),
639SND_SOC_DAPM_PGA("LINEOUT1R PGA", WM8900_REG_POWER2, 7, 0, NULL, 0),
640
641SND_SOC_DAPM_MUX("LINEOUT2 LP", SND_SOC_NOPM, 0, 0, &wm8900_lineout2_lp),
642SND_SOC_DAPM_PGA("LINEOUT2L PGA", WM8900_REG_POWER3, 6, 0, NULL, 0),
643SND_SOC_DAPM_PGA("LINEOUT2R PGA", WM8900_REG_POWER3, 5, 0, NULL, 0),
644
645SND_SOC_DAPM_MIXER("Left Output Mixer", WM8900_REG_POWER3, 3, 0,
646 wm8900_loutmix_controls,
647 ARRAY_SIZE(wm8900_loutmix_controls)),
648SND_SOC_DAPM_MIXER("Right Output Mixer", WM8900_REG_POWER3, 2, 0,
649 wm8900_routmix_controls,
650 ARRAY_SIZE(wm8900_routmix_controls)),
651};
652
653/* Target, Path, Source */
654static const struct snd_soc_dapm_route audio_map[] = {
655/* Inputs */
656{"Left Input PGA", "LINPUT1 Switch", "LINPUT1"},
657{"Left Input PGA", "LINPUT2 Switch", "LINPUT2"},
658{"Left Input PGA", "LINPUT3 Switch", "LINPUT3"},
659
660{"Right Input PGA", "RINPUT1 Switch", "RINPUT1"},
661{"Right Input PGA", "RINPUT2 Switch", "RINPUT2"},
662{"Right Input PGA", "RINPUT3 Switch", "RINPUT3"},
663
664{"Left Input Mixer", "LINPUT2 Switch", "LINPUT2"},
665{"Left Input Mixer", "LINPUT3 Switch", "LINPUT3"},
666{"Left Input Mixer", "AUX Switch", "AUX"},
667{"Left Input Mixer", "Input PGA Switch", "Left Input PGA"},
668
669{"Right Input Mixer", "RINPUT2 Switch", "RINPUT2"},
670{"Right Input Mixer", "RINPUT3 Switch", "RINPUT3"},
671{"Right Input Mixer", "AUX Switch", "AUX"},
672{"Right Input Mixer", "Input PGA Switch", "Right Input PGA"},
673
674{"ADCL", NULL, "Left Input Mixer"},
675{"ADCR", NULL, "Right Input Mixer"},
676
677/* Outputs */
678{"LINEOUT1L", NULL, "LINEOUT1L PGA"},
679{"LINEOUT1L PGA", NULL, "Left Output Mixer"},
680{"LINEOUT1R", NULL, "LINEOUT1R PGA"},
681{"LINEOUT1R PGA", NULL, "Right Output Mixer"},
682
683{"LINEOUT2L PGA", NULL, "Left Output Mixer"},
684{"LINEOUT2 LP", "Disabled", "LINEOUT2L PGA"},
685{"LINEOUT2 LP", "Enabled", "Left Output Mixer"},
686{"LINEOUT2L", NULL, "LINEOUT2 LP"},
687
688{"LINEOUT2R PGA", NULL, "Right Output Mixer"},
689{"LINEOUT2 LP", "Disabled", "LINEOUT2R PGA"},
690{"LINEOUT2 LP", "Enabled", "Right Output Mixer"},
691{"LINEOUT2R", NULL, "LINEOUT2 LP"},
692
693{"Left Output Mixer", "LINPUT3 Bypass Switch", "LINPUT3"},
694{"Left Output Mixer", "AUX Bypass Switch", "AUX"},
695{"Left Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"},
696{"Left Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"},
697{"Left Output Mixer", "DACL Switch", "DACL"},
698
699{"Right Output Mixer", "RINPUT3 Bypass Switch", "RINPUT3"},
700{"Right Output Mixer", "AUX Bypass Switch", "AUX"},
701{"Right Output Mixer", "Left Input Mixer Switch", "Left Input Mixer"},
702{"Right Output Mixer", "Right Input Mixer Switch", "Right Input Mixer"},
703{"Right Output Mixer", "DACR Switch", "DACR"},
704
705/* Note that the headphone output stage needs to be connected
706 * externally to LINEOUT2 via DC blocking capacitors. Other
707 * configurations are not supported.
708 *
709 * Note also that left and right headphone paths are treated as a
710 * mono path.
711 */
712{"Headphone Amplifier", NULL, "LINEOUT2 LP"},
713{"Headphone Amplifier", NULL, "LINEOUT2 LP"},
714{"HP_L", NULL, "Headphone Amplifier"},
715{"HP_R", NULL, "Headphone Amplifier"},
716};
717
718static int wm8900_add_widgets(struct snd_soc_codec *codec)
719{
720 snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets,
721 ARRAY_SIZE(wm8900_dapm_widgets));
722
723 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
724
725 snd_soc_dapm_new_widgets(codec);
726
727 return 0;
728}
729
730static int wm8900_hw_params(struct snd_pcm_substream *substream,
731 struct snd_pcm_hw_params *params)
732{
733 struct snd_soc_pcm_runtime *rtd = substream->private_data;
734 struct snd_soc_device *socdev = rtd->socdev;
735 struct snd_soc_codec *codec = socdev->codec;
736 u16 reg;
737
738 reg = wm8900_read(codec, WM8900_REG_AUDIO1) & ~0x60;
739
740 switch (params_format(params)) {
741 case SNDRV_PCM_FORMAT_S16_LE:
742 break;
743 case SNDRV_PCM_FORMAT_S20_3LE:
744 reg |= 0x20;
745 break;
746 case SNDRV_PCM_FORMAT_S24_LE:
747 reg |= 0x40;
748 break;
749 case SNDRV_PCM_FORMAT_S32_LE:
750 reg |= 0x60;
751 break;
752 default:
753 return -EINVAL;
754 }
755
756 wm8900_write(codec, WM8900_REG_AUDIO1, reg);
757
758 return 0;
759}
760
761/* FLL divisors */
762struct _fll_div {
763 u16 fll_ratio;
764 u16 fllclk_div;
765 u16 fll_slow_lock_ref;
766 u16 n;
767 u16 k;
768};
769
770/* The size in bits of the FLL divide multiplied by 10
771 * to allow rounding later */
772#define FIXED_FLL_SIZE ((1 << 16) * 10)
773
774static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
775 unsigned int Fout)
776{
777 u64 Kpart;
778 unsigned int K, Ndiv, Nmod, target;
779 unsigned int div;
780
781 BUG_ON(!Fout);
782
783 /* The FLL must run at 90-100MHz which is then scaled down to
784 * the output value by FLLCLK_DIV. */
785 target = Fout;
786 div = 1;
787 while (target < 90000000) {
788 div *= 2;
789 target *= 2;
790 }
791
792 if (target > 100000000)
793 printk(KERN_WARNING "wm8900: FLL rate %d out of range, Fref=%d"
794 " Fout=%d\n", target, Fref, Fout);
795 if (div > 32) {
796 printk(KERN_ERR "wm8900: Invalid FLL division rate %u, "
797 "Fref=%d, Fout=%d, target=%d\n",
798 div, Fref, Fout, target);
799 return -EINVAL;
800 }
801
802 fll_div->fllclk_div = div >> 2;
803
804 if (Fref < 48000)
805 fll_div->fll_slow_lock_ref = 1;
806 else
807 fll_div->fll_slow_lock_ref = 0;
808
809 Ndiv = target / Fref;
810
811 if (Fref < 1000000)
812 fll_div->fll_ratio = 8;
813 else
814 fll_div->fll_ratio = 1;
815
816 fll_div->n = Ndiv / fll_div->fll_ratio;
817 Nmod = (target / fll_div->fll_ratio) % Fref;
818
819 /* Calculate fractional part - scale up so we can round. */
820 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
821
822 do_div(Kpart, Fref);
823
824 K = Kpart & 0xFFFFFFFF;
825
826 if ((K % 10) >= 5)
827 K += 5;
828
829 /* Move down to proper range now rounding is done */
830 fll_div->k = K / 10;
831
832 BUG_ON(target != Fout * (fll_div->fllclk_div << 2));
833 BUG_ON(!K && target != Fref * fll_div->fll_ratio * fll_div->n);
834
835 return 0;
836}
837
838static int wm8900_set_fll(struct snd_soc_codec *codec,
839 int fll_id, unsigned int freq_in, unsigned int freq_out)
840{
841 struct wm8900_priv *wm8900 = codec->private_data;
842 struct _fll_div fll_div;
843 unsigned int reg;
844
845 if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out)
846 return 0;
847
848 /* The digital side should be disabled during any change. */
849 reg = wm8900_read(codec, WM8900_REG_POWER1);
850 wm8900_write(codec, WM8900_REG_POWER1,
851 reg & (~WM8900_REG_POWER1_FLL_ENA));
852
853 /* Disable the FLL? */
854 if (!freq_in || !freq_out) {
855 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
856 wm8900_write(codec, WM8900_REG_CLOCKING1,
857 reg & (~WM8900_REG_CLOCKING1_MCLK_SRC));
858
859 reg = wm8900_read(codec, WM8900_REG_FLLCTL1);
860 wm8900_write(codec, WM8900_REG_FLLCTL1,
861 reg & (~WM8900_REG_FLLCTL1_OSC_ENA));
862
863 wm8900->fll_in = freq_in;
864 wm8900->fll_out = freq_out;
865
866 return 0;
867 }
868
869 if (fll_factors(&fll_div, freq_in, freq_out) != 0)
870 goto reenable;
871
872 wm8900->fll_in = freq_in;
873 wm8900->fll_out = freq_out;
874
875 /* The osclilator *MUST* be enabled before we enable the
876 * digital circuit. */
877 wm8900_write(codec, WM8900_REG_FLLCTL1,
878 fll_div.fll_ratio | WM8900_REG_FLLCTL1_OSC_ENA);
879
880 wm8900_write(codec, WM8900_REG_FLLCTL4, fll_div.n >> 5);
881 wm8900_write(codec, WM8900_REG_FLLCTL5,
882 (fll_div.fllclk_div << 6) | (fll_div.n & 0x1f));
883
884 if (fll_div.k) {
885 wm8900_write(codec, WM8900_REG_FLLCTL2,
886 (fll_div.k >> 8) | 0x100);
887 wm8900_write(codec, WM8900_REG_FLLCTL3, fll_div.k & 0xff);
888 } else
889 wm8900_write(codec, WM8900_REG_FLLCTL2, 0);
890
891 if (fll_div.fll_slow_lock_ref)
892 wm8900_write(codec, WM8900_REG_FLLCTL6,
893 WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF);
894 else
895 wm8900_write(codec, WM8900_REG_FLLCTL6, 0);
896
897 reg = wm8900_read(codec, WM8900_REG_POWER1);
898 wm8900_write(codec, WM8900_REG_POWER1,
899 reg | WM8900_REG_POWER1_FLL_ENA);
900
901reenable:
902 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
903 wm8900_write(codec, WM8900_REG_CLOCKING1,
904 reg | WM8900_REG_CLOCKING1_MCLK_SRC);
905
906 return 0;
907}
908
909static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai,
910 int pll_id, unsigned int freq_in, unsigned int freq_out)
911{
912 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
913}
914
915static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
916 int div_id, int div)
917{
918 struct snd_soc_codec *codec = codec_dai->codec;
919 unsigned int reg;
920
921 switch (div_id) {
922 case WM8900_BCLK_DIV:
923 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
924 wm8900_write(codec, WM8900_REG_CLOCKING1,
925 div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK));
926 break;
927 case WM8900_OPCLK_DIV:
928 reg = wm8900_read(codec, WM8900_REG_CLOCKING1);
929 wm8900_write(codec, WM8900_REG_CLOCKING1,
930 div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK));
931 break;
932 case WM8900_DAC_LRCLK:
933 reg = wm8900_read(codec, WM8900_REG_AUDIO4);
934 wm8900_write(codec, WM8900_REG_AUDIO4,
935 div | (reg & WM8900_LRC_MASK));
936 break;
937 case WM8900_ADC_LRCLK:
938 reg = wm8900_read(codec, WM8900_REG_AUDIO3);
939 wm8900_write(codec, WM8900_REG_AUDIO3,
940 div | (reg & WM8900_LRC_MASK));
941 break;
942 case WM8900_DAC_CLKDIV:
943 reg = wm8900_read(codec, WM8900_REG_CLOCKING2);
944 wm8900_write(codec, WM8900_REG_CLOCKING2,
945 div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV));
946 break;
947 case WM8900_ADC_CLKDIV:
948 reg = wm8900_read(codec, WM8900_REG_CLOCKING2);
949 wm8900_write(codec, WM8900_REG_CLOCKING2,
950 div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV));
951 break;
952 case WM8900_LRCLK_MODE:
953 reg = wm8900_read(codec, WM8900_REG_DACCTRL);
954 wm8900_write(codec, WM8900_REG_DACCTRL,
955 div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE));
956 break;
957 default:
958 return -EINVAL;
959 }
960
961 return 0;
962}
963
964
965static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
966 unsigned int fmt)
967{
968 struct snd_soc_codec *codec = codec_dai->codec;
969 unsigned int clocking1, aif1, aif3, aif4;
970
971 clocking1 = wm8900_read(codec, WM8900_REG_CLOCKING1);
972 aif1 = wm8900_read(codec, WM8900_REG_AUDIO1);
973 aif3 = wm8900_read(codec, WM8900_REG_AUDIO3);
974 aif4 = wm8900_read(codec, WM8900_REG_AUDIO4);
975
976 /* set master/slave audio interface */
977 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
978 case SND_SOC_DAIFMT_CBS_CFS:
979 clocking1 &= ~WM8900_REG_CLOCKING1_BCLK_DIR;
980 aif3 &= ~WM8900_REG_AUDIO3_ADCLRC_DIR;
981 aif4 &= ~WM8900_REG_AUDIO4_DACLRC_DIR;
982 break;
983 case SND_SOC_DAIFMT_CBS_CFM:
984 clocking1 &= ~WM8900_REG_CLOCKING1_BCLK_DIR;
985 aif3 |= WM8900_REG_AUDIO3_ADCLRC_DIR;
986 aif4 |= WM8900_REG_AUDIO4_DACLRC_DIR;
987 break;
988 case SND_SOC_DAIFMT_CBM_CFM:
989 clocking1 |= WM8900_REG_CLOCKING1_BCLK_DIR;
990 aif3 |= WM8900_REG_AUDIO3_ADCLRC_DIR;
991 aif4 |= WM8900_REG_AUDIO4_DACLRC_DIR;
992 break;
993 case SND_SOC_DAIFMT_CBM_CFS:
994 clocking1 |= WM8900_REG_CLOCKING1_BCLK_DIR;
995 aif3 &= ~WM8900_REG_AUDIO3_ADCLRC_DIR;
996 aif4 &= ~WM8900_REG_AUDIO4_DACLRC_DIR;
997 break;
998 default:
999 return -EINVAL;
1000 }
1001
1002 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1003 case SND_SOC_DAIFMT_DSP_A:
1004 aif1 |= WM8900_REG_AUDIO1_AIF_FMT_MASK;
1005 aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
1006 break;
1007 case SND_SOC_DAIFMT_DSP_B:
1008 aif1 |= WM8900_REG_AUDIO1_AIF_FMT_MASK;
1009 aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
1010 break;
1011 case SND_SOC_DAIFMT_I2S:
1012 aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
1013 aif1 |= 0x10;
1014 break;
1015 case SND_SOC_DAIFMT_RIGHT_J:
1016 aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
1017 break;
1018 case SND_SOC_DAIFMT_LEFT_J:
1019 aif1 &= ~WM8900_REG_AUDIO1_AIF_FMT_MASK;
1020 aif1 |= 0x8;
1021 break;
1022 default:
1023 return -EINVAL;
1024 }
1025
1026 /* Clock inversion */
1027 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1028 case SND_SOC_DAIFMT_DSP_A:
1029 case SND_SOC_DAIFMT_DSP_B:
1030 /* frame inversion not valid for DSP modes */
1031 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1032 case SND_SOC_DAIFMT_NB_NF:
1033 aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
1034 break;
1035 case SND_SOC_DAIFMT_IB_NF:
1036 aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
1037 break;
1038 default:
1039 return -EINVAL;
1040 }
1041 break;
1042 case SND_SOC_DAIFMT_I2S:
1043 case SND_SOC_DAIFMT_RIGHT_J:
1044 case SND_SOC_DAIFMT_LEFT_J:
1045 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1046 case SND_SOC_DAIFMT_NB_NF:
1047 aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
1048 aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
1049 break;
1050 case SND_SOC_DAIFMT_IB_IF:
1051 aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
1052 aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
1053 break;
1054 case SND_SOC_DAIFMT_IB_NF:
1055 aif1 |= WM8900_REG_AUDIO1_BCLK_INV;
1056 aif1 &= ~WM8900_REG_AUDIO1_LRCLK_INV;
1057 break;
1058 case SND_SOC_DAIFMT_NB_IF:
1059 aif1 &= ~WM8900_REG_AUDIO1_BCLK_INV;
1060 aif1 |= WM8900_REG_AUDIO1_LRCLK_INV;
1061 break;
1062 default:
1063 return -EINVAL;
1064 }
1065 break;
1066 default:
1067 return -EINVAL;
1068 }
1069
1070 wm8900_write(codec, WM8900_REG_CLOCKING1, clocking1);
1071 wm8900_write(codec, WM8900_REG_AUDIO1, aif1);
1072 wm8900_write(codec, WM8900_REG_AUDIO3, aif3);
1073 wm8900_write(codec, WM8900_REG_AUDIO4, aif4);
1074
1075 return 0;
1076}
1077
1078static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1079{
1080 struct snd_soc_codec *codec = codec_dai->codec;
1081 u16 reg;
1082
1083 reg = wm8900_read(codec, WM8900_REG_DACCTRL);
1084
1085 if (mute)
1086 reg |= WM8900_REG_DACCTRL_MUTE;
1087 else
1088 reg &= ~WM8900_REG_DACCTRL_MUTE;
1089
1090 wm8900_write(codec, WM8900_REG_DACCTRL, reg);
1091
1092 return 0;
1093}
1094
1095#define WM8900_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
1096 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
1097 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
1098
1099#define WM8900_PCM_FORMATS \
1100 (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
1101 SNDRV_PCM_FORMAT_S24_LE)
1102
1103struct snd_soc_dai wm8900_dai = {
1104 .name = "WM8900 HiFi",
1105 .playback = {
1106 .stream_name = "HiFi Playback",
1107 .channels_min = 1,
1108 .channels_max = 2,
1109 .rates = WM8900_RATES,
1110 .formats = WM8900_PCM_FORMATS,
1111 },
1112 .capture = {
1113 .stream_name = "HiFi Capture",
1114 .channels_min = 1,
1115 .channels_max = 2,
1116 .rates = WM8900_RATES,
1117 .formats = WM8900_PCM_FORMATS,
1118 },
1119 .ops = {
1120 .hw_params = wm8900_hw_params,
1121 },
1122 .dai_ops = {
1123 .set_clkdiv = wm8900_set_dai_clkdiv,
1124 .set_pll = wm8900_set_dai_pll,
1125 .set_fmt = wm8900_set_dai_fmt,
1126 .digital_mute = wm8900_digital_mute,
1127 },
1128};
1129EXPORT_SYMBOL_GPL(wm8900_dai);
1130
1131static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1132 enum snd_soc_bias_level level)
1133{
1134 u16 reg;
1135
1136 switch (level) {
1137 case SND_SOC_BIAS_ON:
1138 /* Enable thermal shutdown */
1139 reg = wm8900_read(codec, WM8900_REG_GPIO);
1140 wm8900_write(codec, WM8900_REG_GPIO,
1141 reg | WM8900_REG_GPIO_TEMP_ENA);
1142 reg = wm8900_read(codec, WM8900_REG_ADDCTL);
1143 wm8900_write(codec, WM8900_REG_ADDCTL,
1144 reg | WM8900_REG_ADDCTL_TEMP_SD);
1145 break;
1146
1147 case SND_SOC_BIAS_PREPARE:
1148 break;
1149
1150 case SND_SOC_BIAS_STANDBY:
1151 /* Charge capacitors if initial power up */
1152 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1153 /* STARTUP_BIAS_ENA on */
1154 wm8900_write(codec, WM8900_REG_POWER1,
1155 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1156
1157 /* Startup bias mode */
1158 wm8900_write(codec, WM8900_REG_ADDCTL,
1159 WM8900_REG_ADDCTL_BIAS_SRC |
1160 WM8900_REG_ADDCTL_VMID_SOFTST);
1161
1162 /* VMID 2x50k */
1163 wm8900_write(codec, WM8900_REG_POWER1,
1164 WM8900_REG_POWER1_STARTUP_BIAS_ENA | 0x1);
1165
1166 /* Allow capacitors to charge */
1167 schedule_timeout_interruptible(msecs_to_jiffies(400));
1168
1169 /* Enable bias */
1170 wm8900_write(codec, WM8900_REG_POWER1,
1171 WM8900_REG_POWER1_STARTUP_BIAS_ENA |
1172 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1173
1174 wm8900_write(codec, WM8900_REG_ADDCTL, 0);
1175
1176 wm8900_write(codec, WM8900_REG_POWER1,
1177 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1178 }
1179
1180 reg = wm8900_read(codec, WM8900_REG_POWER1);
1181 wm8900_write(codec, WM8900_REG_POWER1,
1182 (reg & WM8900_REG_POWER1_FLL_ENA) |
1183 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1184 wm8900_write(codec, WM8900_REG_POWER2,
1185 WM8900_REG_POWER2_SYSCLK_ENA);
1186 wm8900_write(codec, WM8900_REG_POWER3, 0);
1187 break;
1188
1189 case SND_SOC_BIAS_OFF:
1190 /* Startup bias enable */
1191 reg = wm8900_read(codec, WM8900_REG_POWER1);
1192 wm8900_write(codec, WM8900_REG_POWER1,
1193 reg & WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1194 wm8900_write(codec, WM8900_REG_ADDCTL,
1195 WM8900_REG_ADDCTL_BIAS_SRC |
1196 WM8900_REG_ADDCTL_VMID_SOFTST);
1197
1198 /* Discharge caps */
1199 wm8900_write(codec, WM8900_REG_POWER1,
1200 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1201 schedule_timeout_interruptible(msecs_to_jiffies(500));
1202
1203 /* Remove clamp */
1204 wm8900_write(codec, WM8900_REG_HPCTL1, 0);
1205
1206 /* Power down */
1207 wm8900_write(codec, WM8900_REG_ADDCTL, 0);
1208 wm8900_write(codec, WM8900_REG_POWER1, 0);
1209 wm8900_write(codec, WM8900_REG_POWER2, 0);
1210 wm8900_write(codec, WM8900_REG_POWER3, 0);
1211
1212 /* Need to let things settle before stopping the clock
1213 * to ensure that restart works, see "Stopping the
1214 * master clock" in the datasheet. */
1215 schedule_timeout_interruptible(msecs_to_jiffies(1));
1216 wm8900_write(codec, WM8900_REG_POWER2,
1217 WM8900_REG_POWER2_SYSCLK_ENA);
1218 break;
1219 }
1220 codec->bias_level = level;
1221 return 0;
1222}
1223
1224static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1225{
1226 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1227 struct snd_soc_codec *codec = socdev->codec;
1228 struct wm8900_priv *wm8900 = codec->private_data;
1229 int fll_out = wm8900->fll_out;
1230 int fll_in = wm8900->fll_in;
1231 int ret;
1232
1233 /* Stop the FLL in an orderly fashion */
1234 ret = wm8900_set_fll(codec, 0, 0, 0);
1235 if (ret != 0) {
1236 dev_err(&pdev->dev, "Failed to stop FLL\n");
1237 return ret;
1238 }
1239
1240 wm8900->fll_out = fll_out;
1241 wm8900->fll_in = fll_in;
1242
1243 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1244
1245 return 0;
1246}
1247
1248static int wm8900_resume(struct platform_device *pdev)
1249{
1250 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1251 struct snd_soc_codec *codec = socdev->codec;
1252 struct wm8900_priv *wm8900 = codec->private_data;
1253 u16 *cache;
1254 int i, ret;
1255
1256 cache = kmemdup(codec->reg_cache, sizeof(wm8900_reg_defaults),
1257 GFP_KERNEL);
1258
1259 wm8900_reset(codec);
1260 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1261
1262 /* Restart the FLL? */
1263 if (wm8900->fll_out) {
1264 int fll_out = wm8900->fll_out;
1265 int fll_in = wm8900->fll_in;
1266
1267 wm8900->fll_in = 0;
1268 wm8900->fll_out = 0;
1269
1270 ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
1271 if (ret != 0) {
1272 dev_err(&pdev->dev, "Failed to restart FLL\n");
1273 return ret;
1274 }
1275 }
1276
1277 if (cache) {
1278 for (i = 0; i < WM8900_MAXREG; i++)
1279 wm8900_write(codec, i, cache[i]);
1280 kfree(cache);
1281 } else
1282 dev_err(&pdev->dev, "Unable to allocate register cache\n");
1283
1284 return 0;
1285}
1286
1287/*
1288 * initialise the WM8900 driver
1289 * register the mixer and dsp interfaces with the kernel
1290 */
1291static int wm8900_init(struct snd_soc_device *socdev)
1292{
1293 struct snd_soc_codec *codec = socdev->codec;
1294 int ret = 0;
1295 unsigned int reg;
1296 struct i2c_client *i2c_client = socdev->codec->control_data;
1297
1298 codec->name = "WM8900";
1299 codec->owner = THIS_MODULE;
1300 codec->read = wm8900_read;
1301 codec->write = wm8900_write;
1302 codec->dai = &wm8900_dai;
1303 codec->num_dai = 1;
1304 codec->reg_cache_size = WM8900_MAXREG;
1305 codec->reg_cache = kmemdup(wm8900_reg_defaults,
1306 sizeof(wm8900_reg_defaults), GFP_KERNEL);
1307
1308 if (codec->reg_cache == NULL)
1309 return -ENOMEM;
1310
1311 reg = wm8900_read(codec, WM8900_REG_ID);
1312 if (reg != 0x8900) {
1313 dev_err(&i2c_client->dev, "Device is not a WM8900 - ID %x\n",
1314 reg);
1315 return -ENODEV;
1316 }
1317
1318 codec->private_data = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1319 if (codec->private_data == NULL) {
1320 ret = -ENOMEM;
1321 goto priv_err;
1322 }
1323
1324 /* Read back from the chip */
1325 reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
1326 reg = (reg >> 12) & 0xf;
1327 dev_info(&i2c_client->dev, "WM8900 revision %d\n", reg);
1328
1329 wm8900_reset(codec);
1330
1331 /* Latch the volume update bits */
1332 wm8900_write(codec, WM8900_REG_LINVOL,
1333 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
1334 wm8900_write(codec, WM8900_REG_RINVOL,
1335 wm8900_read(codec, WM8900_REG_RINVOL) | 0x100);
1336 wm8900_write(codec, WM8900_REG_LOUT1CTL,
1337 wm8900_read(codec, WM8900_REG_LOUT1CTL) | 0x100);
1338 wm8900_write(codec, WM8900_REG_ROUT1CTL,
1339 wm8900_read(codec, WM8900_REG_ROUT1CTL) | 0x100);
1340 wm8900_write(codec, WM8900_REG_LOUT2CTL,
1341 wm8900_read(codec, WM8900_REG_LOUT2CTL) | 0x100);
1342 wm8900_write(codec, WM8900_REG_ROUT2CTL,
1343 wm8900_read(codec, WM8900_REG_ROUT2CTL) | 0x100);
1344 wm8900_write(codec, WM8900_REG_LDAC_DV,
1345 wm8900_read(codec, WM8900_REG_LDAC_DV) | 0x100);
1346 wm8900_write(codec, WM8900_REG_RDAC_DV,
1347 wm8900_read(codec, WM8900_REG_RDAC_DV) | 0x100);
1348 wm8900_write(codec, WM8900_REG_LADC_DV,
1349 wm8900_read(codec, WM8900_REG_LADC_DV) | 0x100);
1350 wm8900_write(codec, WM8900_REG_RADC_DV,
1351 wm8900_read(codec, WM8900_REG_RADC_DV) | 0x100);
1352
1353 /* Set the DAC and mixer output bias */
1354 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1355
1356 /* Register pcms */
1357 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1358 if (ret < 0) {
1359 dev_err(&i2c_client->dev, "Failed to register new PCMs\n");
1360 goto pcm_err;
1361 }
1362
1363 /* Turn the chip on */
1364 codec->bias_level = SND_SOC_BIAS_OFF;
1365 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1366
1367 wm8900_add_controls(codec);
1368 wm8900_add_widgets(codec);
1369
1370 ret = snd_soc_register_card(socdev);
1371 if (ret < 0) {
1372 dev_err(&i2c_client->dev, "Failed to register card\n");
1373 goto card_err;
1374 }
1375 return ret;
1376
1377card_err:
1378 snd_soc_free_pcms(socdev);
1379 snd_soc_dapm_free(socdev);
1380pcm_err:
1381 kfree(codec->reg_cache);
1382priv_err:
1383 kfree(codec->private_data);
1384 return ret;
1385}
1386
1387static struct snd_soc_device *wm8900_socdev;
1388
1389#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1390
1391static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1392
1393/* Magic definition of all other variables and things */
1394I2C_CLIENT_INSMOD;
1395
1396static struct i2c_driver wm8900_i2c_driver;
1397static struct i2c_client client_template;
1398
1399/* If the i2c layer weren't so broken, we could pass this kind of data
1400 around */
1401static int wm8900_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1402{
1403 struct snd_soc_device *socdev = wm8900_socdev;
1404 struct wm8900_setup_data *setup = socdev->codec_data;
1405 struct snd_soc_codec *codec = socdev->codec;
1406 struct i2c_client *i2c;
1407 int ret;
1408
1409 if (addr != setup->i2c_address)
1410 return -ENODEV;
1411
1412 dev_err(&adap->dev, "Probe on %x\n", addr);
1413
1414 client_template.adapter = adap;
1415 client_template.addr = addr;
1416
1417 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1418 if (i2c == NULL) {
1419 kfree(codec);
1420 return -ENOMEM;
1421 }
1422 i2c_set_clientdata(i2c, codec);
1423 codec->control_data = i2c;
1424
1425 ret = i2c_attach_client(i2c);
1426 if (ret < 0) {
1427 dev_err(&adap->dev,
1428 "failed to attach codec at addr %x\n", addr);
1429 goto err;
1430 }
1431
1432 ret = wm8900_init(socdev);
1433 if (ret < 0) {
1434 dev_err(&adap->dev, "failed to initialise WM8900\n");
1435 goto err;
1436 }
1437 return ret;
1438
1439err:
1440 kfree(codec);
1441 kfree(i2c);
1442 return ret;
1443}
1444
1445static int wm8900_i2c_detach(struct i2c_client *client)
1446{
1447 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1448 i2c_detach_client(client);
1449 kfree(codec->reg_cache);
1450 kfree(client);
1451 return 0;
1452}
1453
1454static int wm8900_i2c_attach(struct i2c_adapter *adap)
1455{
1456 return i2c_probe(adap, &addr_data, wm8900_codec_probe);
1457}
1458
1459/* corgi i2c codec control layer */
1460static struct i2c_driver wm8900_i2c_driver = {
1461 .driver = {
1462 .name = "WM8900 I2C codec",
1463 .owner = THIS_MODULE,
1464 },
1465 .attach_adapter = wm8900_i2c_attach,
1466 .detach_client = wm8900_i2c_detach,
1467 .command = NULL,
1468};
1469
1470static struct i2c_client client_template = {
1471 .name = "WM8900",
1472 .driver = &wm8900_i2c_driver,
1473};
1474#endif
1475
1476static int wm8900_probe(struct platform_device *pdev)
1477{
1478 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1479 struct wm8900_setup_data *setup;
1480 struct snd_soc_codec *codec;
1481 int ret = 0;
1482
1483 dev_info(&pdev->dev, "WM8900 Audio Codec\n");
1484
1485 setup = socdev->codec_data;
1486 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1487 if (codec == NULL)
1488 return -ENOMEM;
1489
1490 mutex_init(&codec->mutex);
1491 INIT_LIST_HEAD(&codec->dapm_widgets);
1492 INIT_LIST_HEAD(&codec->dapm_paths);
1493
1494 socdev->codec = codec;
1495
1496 codec->set_bias_level = wm8900_set_bias_level;
1497
1498 wm8900_socdev = socdev;
1499#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1500 if (setup->i2c_address) {
1501 normal_i2c[0] = setup->i2c_address;
1502 codec->hw_write = (hw_write_t)i2c_master_send;
1503 ret = i2c_add_driver(&wm8900_i2c_driver);
1504 if (ret != 0)
1505 printk(KERN_ERR "can't add i2c driver");
1506 }
1507#else
1508#error Non-I2C interfaces not yet supported
1509#endif
1510 return ret;
1511}
1512
1513/* power down chip */
1514static int wm8900_remove(struct platform_device *pdev)
1515{
1516 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1517 struct snd_soc_codec *codec = socdev->codec;
1518
1519 if (codec->control_data)
1520 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1521
1522 snd_soc_free_pcms(socdev);
1523 snd_soc_dapm_free(socdev);
1524#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1525 i2c_del_driver(&wm8900_i2c_driver);
1526#endif
1527 kfree(codec);
1528
1529 return 0;
1530}
1531
1532struct snd_soc_codec_device soc_codec_dev_wm8900 = {
1533 .probe = wm8900_probe,
1534 .remove = wm8900_remove,
1535 .suspend = wm8900_suspend,
1536 .resume = wm8900_resume,
1537};
1538EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
1539
1540MODULE_DESCRIPTION("ASoC WM8900 driver");
1541MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
1542MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8900.h b/sound/soc/codecs/wm8900.h
new file mode 100644
index 00000000000..ba450d99e90
--- /dev/null
+++ b/sound/soc/codecs/wm8900.h
@@ -0,0 +1,64 @@
1/*
2 * wm8900.h -- WM890 Soc Audio driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _WM8900_H
10#define _WM8900_H
11
12#define WM8900_FLL 1
13
14#define WM8900_BCLK_DIV 1
15#define WM8900_ADC_CLKDIV 2
16#define WM8900_DAC_CLKDIV 3
17#define WM8900_ADC_LRCLK 4
18#define WM8900_DAC_LRCLK 5
19#define WM8900_OPCLK_DIV 6
20#define WM8900_LRCLK_MODE 7
21
22#define WM8900_BCLK_DIV_1 0x00
23#define WM8900_BCLK_DIV_1_5 0x02
24#define WM8900_BCLK_DIV_2 0x04
25#define WM8900_BCLK_DIV_3 0x06
26#define WM8900_BCLK_DIV_4 0x08
27#define WM8900_BCLK_DIV_5_5 0x0a
28#define WM8900_BCLK_DIV_6 0x0c
29#define WM8900_BCLK_DIV_8 0x0e
30#define WM8900_BCLK_DIV_11 0x10
31#define WM8900_BCLK_DIV_12 0x12
32#define WM8900_BCLK_DIV_16 0x14
33#define WM8900_BCLK_DIV_22 0x16
34#define WM8900_BCLK_DIV_24 0x18
35#define WM8900_BCLK_DIV_32 0x1a
36#define WM8900_BCLK_DIV_44 0x1c
37#define WM8900_BCLK_DIV_48 0x1e
38
39#define WM8900_ADC_CLKDIV_1 0x00
40#define WM8900_ADC_CLKDIV_1_5 0x20
41#define WM8900_ADC_CLKDIV_2 0x40
42#define WM8900_ADC_CLKDIV_3 0x60
43#define WM8900_ADC_CLKDIV_4 0x80
44#define WM8900_ADC_CLKDIV_5_5 0xa0
45#define WM8900_ADC_CLKDIV_6 0xc0
46
47#define WM8900_DAC_CLKDIV_1 0x00
48#define WM8900_DAC_CLKDIV_1_5 0x04
49#define WM8900_DAC_CLKDIV_2 0x08
50#define WM8900_DAC_CLKDIV_3 0x0c
51#define WM8900_DAC_CLKDIV_4 0x10
52#define WM8900_DAC_CLKDIV_5_5 0x14
53#define WM8900_DAC_CLKDIV_6 0x18
54
55#define WM8900_
56
57struct wm8900_setup_data {
58 unsigned short i2c_address;
59};
60
61extern struct snd_soc_dai wm8900_dai;
62extern struct snd_soc_codec_device soc_codec_dev_wm8900;
63
64#endif
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
new file mode 100644
index 00000000000..a3f54ec4226
--- /dev/null
+++ b/sound/soc/codecs/wm8903.c
@@ -0,0 +1,1813 @@
1/*
2 * wm8903.c -- WM8903 ALSA SoC Audio driver
3 *
4 * Copyright 2008 Wolfson Microelectronics
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * TODO:
13 * - TDM mode configuration.
14 * - Mic detect.
15 * - Digital microphone support.
16 * - Interrupt support (mic detect and sequencer).
17 */
18
19#include <linux/module.h>
20#include <linux/moduleparam.h>
21#include <linux/init.h>
22#include <linux/delay.h>
23#include <linux/pm.h>
24#include <linux/i2c.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/tlv.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/initval.h>
33
34#include "wm8903.h"
35
36struct wm8903_priv {
37 int sysclk;
38
39 /* Reference counts */
40 int charge_pump_users;
41 int class_w_users;
42 int playback_active;
43 int capture_active;
44
45 struct snd_pcm_substream *master_substream;
46 struct snd_pcm_substream *slave_substream;
47};
48
49/* Register defaults at reset */
50static u16 wm8903_reg_defaults[] = {
51 0x8903, /* R0 - SW Reset and ID */
52 0x0000, /* R1 - Revision Number */
53 0x0000, /* R2 */
54 0x0000, /* R3 */
55 0x0018, /* R4 - Bias Control 0 */
56 0x0000, /* R5 - VMID Control 0 */
57 0x0000, /* R6 - Mic Bias Control 0 */
58 0x0000, /* R7 */
59 0x0001, /* R8 - Analogue DAC 0 */
60 0x0000, /* R9 */
61 0x0001, /* R10 - Analogue ADC 0 */
62 0x0000, /* R11 */
63 0x0000, /* R12 - Power Management 0 */
64 0x0000, /* R13 - Power Management 1 */
65 0x0000, /* R14 - Power Management 2 */
66 0x0000, /* R15 - Power Management 3 */
67 0x0000, /* R16 - Power Management 4 */
68 0x0000, /* R17 - Power Management 5 */
69 0x0000, /* R18 - Power Management 6 */
70 0x0000, /* R19 */
71 0x0400, /* R20 - Clock Rates 0 */
72 0x0D07, /* R21 - Clock Rates 1 */
73 0x0000, /* R22 - Clock Rates 2 */
74 0x0000, /* R23 */
75 0x0050, /* R24 - Audio Interface 0 */
76 0x0242, /* R25 - Audio Interface 1 */
77 0x0008, /* R26 - Audio Interface 2 */
78 0x0022, /* R27 - Audio Interface 3 */
79 0x0000, /* R28 */
80 0x0000, /* R29 */
81 0x00C0, /* R30 - DAC Digital Volume Left */
82 0x00C0, /* R31 - DAC Digital Volume Right */
83 0x0000, /* R32 - DAC Digital 0 */
84 0x0000, /* R33 - DAC Digital 1 */
85 0x0000, /* R34 */
86 0x0000, /* R35 */
87 0x00C0, /* R36 - ADC Digital Volume Left */
88 0x00C0, /* R37 - ADC Digital Volume Right */
89 0x0000, /* R38 - ADC Digital 0 */
90 0x0073, /* R39 - Digital Microphone 0 */
91 0x09BF, /* R40 - DRC 0 */
92 0x3241, /* R41 - DRC 1 */
93 0x0020, /* R42 - DRC 2 */
94 0x0000, /* R43 - DRC 3 */
95 0x0085, /* R44 - Analogue Left Input 0 */
96 0x0085, /* R45 - Analogue Right Input 0 */
97 0x0044, /* R46 - Analogue Left Input 1 */
98 0x0044, /* R47 - Analogue Right Input 1 */
99 0x0000, /* R48 */
100 0x0000, /* R49 */
101 0x0008, /* R50 - Analogue Left Mix 0 */
102 0x0004, /* R51 - Analogue Right Mix 0 */
103 0x0000, /* R52 - Analogue Spk Mix Left 0 */
104 0x0000, /* R53 - Analogue Spk Mix Left 1 */
105 0x0000, /* R54 - Analogue Spk Mix Right 0 */
106 0x0000, /* R55 - Analogue Spk Mix Right 1 */
107 0x0000, /* R56 */
108 0x002D, /* R57 - Analogue OUT1 Left */
109 0x002D, /* R58 - Analogue OUT1 Right */
110 0x0039, /* R59 - Analogue OUT2 Left */
111 0x0039, /* R60 - Analogue OUT2 Right */
112 0x0100, /* R61 */
113 0x0139, /* R62 - Analogue OUT3 Left */
114 0x0139, /* R63 - Analogue OUT3 Right */
115 0x0000, /* R64 */
116 0x0000, /* R65 - Analogue SPK Output Control 0 */
117 0x0000, /* R66 */
118 0x0010, /* R67 - DC Servo 0 */
119 0x0100, /* R68 */
120 0x00A4, /* R69 - DC Servo 2 */
121 0x0807, /* R70 */
122 0x0000, /* R71 */
123 0x0000, /* R72 */
124 0x0000, /* R73 */
125 0x0000, /* R74 */
126 0x0000, /* R75 */
127 0x0000, /* R76 */
128 0x0000, /* R77 */
129 0x0000, /* R78 */
130 0x000E, /* R79 */
131 0x0000, /* R80 */
132 0x0000, /* R81 */
133 0x0000, /* R82 */
134 0x0000, /* R83 */
135 0x0000, /* R84 */
136 0x0000, /* R85 */
137 0x0000, /* R86 */
138 0x0006, /* R87 */
139 0x0000, /* R88 */
140 0x0000, /* R89 */
141 0x0000, /* R90 - Analogue HP 0 */
142 0x0060, /* R91 */
143 0x0000, /* R92 */
144 0x0000, /* R93 */
145 0x0000, /* R94 - Analogue Lineout 0 */
146 0x0060, /* R95 */
147 0x0000, /* R96 */
148 0x0000, /* R97 */
149 0x0000, /* R98 - Charge Pump 0 */
150 0x1F25, /* R99 */
151 0x2B19, /* R100 */
152 0x01C0, /* R101 */
153 0x01EF, /* R102 */
154 0x2B00, /* R103 */
155 0x0000, /* R104 - Class W 0 */
156 0x01C0, /* R105 */
157 0x1C10, /* R106 */
158 0x0000, /* R107 */
159 0x0000, /* R108 - Write Sequencer 0 */
160 0x0000, /* R109 - Write Sequencer 1 */
161 0x0000, /* R110 - Write Sequencer 2 */
162 0x0000, /* R111 - Write Sequencer 3 */
163 0x0000, /* R112 - Write Sequencer 4 */
164 0x0000, /* R113 */
165 0x0000, /* R114 - Control Interface */
166 0x0000, /* R115 */
167 0x00A8, /* R116 - GPIO Control 1 */
168 0x00A8, /* R117 - GPIO Control 2 */
169 0x00A8, /* R118 - GPIO Control 3 */
170 0x0220, /* R119 - GPIO Control 4 */
171 0x01A0, /* R120 - GPIO Control 5 */
172 0x0000, /* R121 - Interrupt Status 1 */
173 0xFFFF, /* R122 - Interrupt Status 1 Mask */
174 0x0000, /* R123 - Interrupt Polarity 1 */
175 0x0000, /* R124 */
176 0x0003, /* R125 */
177 0x0000, /* R126 - Interrupt Control */
178 0x0000, /* R127 */
179 0x0005, /* R128 */
180 0x0000, /* R129 - Control Interface Test 1 */
181 0x0000, /* R130 */
182 0x0000, /* R131 */
183 0x0000, /* R132 */
184 0x0000, /* R133 */
185 0x0000, /* R134 */
186 0x03FF, /* R135 */
187 0x0007, /* R136 */
188 0x0040, /* R137 */
189 0x0000, /* R138 */
190 0x0000, /* R139 */
191 0x0000, /* R140 */
192 0x0000, /* R141 */
193 0x0000, /* R142 */
194 0x0000, /* R143 */
195 0x0000, /* R144 */
196 0x0000, /* R145 */
197 0x0000, /* R146 */
198 0x0000, /* R147 */
199 0x4000, /* R148 */
200 0x6810, /* R149 - Charge Pump Test 1 */
201 0x0004, /* R150 */
202 0x0000, /* R151 */
203 0x0000, /* R152 */
204 0x0000, /* R153 */
205 0x0000, /* R154 */
206 0x0000, /* R155 */
207 0x0000, /* R156 */
208 0x0000, /* R157 */
209 0x0000, /* R158 */
210 0x0000, /* R159 */
211 0x0000, /* R160 */
212 0x0000, /* R161 */
213 0x0000, /* R162 */
214 0x0000, /* R163 */
215 0x0028, /* R164 - Clock Rate Test 4 */
216 0x0004, /* R165 */
217 0x0000, /* R166 */
218 0x0060, /* R167 */
219 0x0000, /* R168 */
220 0x0000, /* R169 */
221 0x0000, /* R170 */
222 0x0000, /* R171 */
223 0x0000, /* R172 - Analogue Output Bias 0 */
224};
225
226static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec,
227 unsigned int reg)
228{
229 u16 *cache = codec->reg_cache;
230
231 BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
232
233 return cache[reg];
234}
235
236static unsigned int wm8903_hw_read(struct snd_soc_codec *codec, u8 reg)
237{
238 struct i2c_msg xfer[2];
239 u16 data;
240 int ret;
241 struct i2c_client *client = codec->control_data;
242
243 /* Write register */
244 xfer[0].addr = client->addr;
245 xfer[0].flags = 0;
246 xfer[0].len = 1;
247 xfer[0].buf = &reg;
248
249 /* Read data */
250 xfer[1].addr = client->addr;
251 xfer[1].flags = I2C_M_RD;
252 xfer[1].len = 2;
253 xfer[1].buf = (u8 *)&data;
254
255 ret = i2c_transfer(client->adapter, xfer, 2);
256 if (ret != 2) {
257 pr_err("i2c_transfer returned %d\n", ret);
258 return 0;
259 }
260
261 return (data >> 8) | ((data & 0xff) << 8);
262}
263
264static unsigned int wm8903_read(struct snd_soc_codec *codec,
265 unsigned int reg)
266{
267 switch (reg) {
268 case WM8903_SW_RESET_AND_ID:
269 case WM8903_REVISION_NUMBER:
270 case WM8903_INTERRUPT_STATUS_1:
271 case WM8903_WRITE_SEQUENCER_4:
272 return wm8903_hw_read(codec, reg);
273
274 default:
275 return wm8903_read_reg_cache(codec, reg);
276 }
277}
278
279static void wm8903_write_reg_cache(struct snd_soc_codec *codec,
280 u16 reg, unsigned int value)
281{
282 u16 *cache = codec->reg_cache;
283
284 BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
285
286 switch (reg) {
287 case WM8903_SW_RESET_AND_ID:
288 case WM8903_REVISION_NUMBER:
289 break;
290
291 default:
292 cache[reg] = value;
293 break;
294 }
295}
296
297static int wm8903_write(struct snd_soc_codec *codec, unsigned int reg,
298 unsigned int value)
299{
300 u8 data[3];
301
302 wm8903_write_reg_cache(codec, reg, value);
303
304 /* Data format is 1 byte of address followed by 2 bytes of data */
305 data[0] = reg;
306 data[1] = (value >> 8) & 0xff;
307 data[2] = value & 0xff;
308
309 if (codec->hw_write(codec->control_data, data, 3) == 2)
310 return 0;
311 else
312 return -EIO;
313}
314
315static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
316{
317 u16 reg[5];
318 struct i2c_client *i2c = codec->control_data;
319
320 BUG_ON(start > 48);
321
322 /* Enable the sequencer */
323 reg[0] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_0);
324 reg[0] |= WM8903_WSEQ_ENA;
325 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
326
327 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);
328
329 wm8903_write(codec, WM8903_WRITE_SEQUENCER_3,
330 start | WM8903_WSEQ_START);
331
332 /* Wait for it to complete. If we have the interrupt wired up then
333 * we could block waiting for an interrupt, though polling may still
334 * be desirable for diagnostic purposes.
335 */
336 do {
337 msleep(10);
338
339 reg[4] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_4);
340 } while (reg[4] & WM8903_WSEQ_BUSY);
341
342 dev_dbg(&i2c->dev, "Sequence complete\n");
343
344 /* Disable the sequencer again */
345 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0,
346 reg[0] & ~WM8903_WSEQ_ENA);
347
348 return 0;
349}
350
351static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
352{
353 int i;
354
355 /* There really ought to be something better we can do here :/ */
356 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
357 cache[i] = wm8903_hw_read(codec, i);
358}
359
360static void wm8903_reset(struct snd_soc_codec *codec)
361{
362 wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0);
363}
364
365#define WM8903_OUTPUT_SHORT 0x8
366#define WM8903_OUTPUT_OUT 0x4
367#define WM8903_OUTPUT_INT 0x2
368#define WM8903_OUTPUT_IN 0x1
369
370/*
371 * Event for headphone and line out amplifier power changes. Special
372 * power up/down sequences are required in order to maximise pop/click
373 * performance.
374 */
375static int wm8903_output_event(struct snd_soc_dapm_widget *w,
376 struct snd_kcontrol *kcontrol, int event)
377{
378 struct snd_soc_codec *codec = w->codec;
379 struct wm8903_priv *wm8903 = codec->private_data;
380 struct i2c_client *i2c = codec->control_data;
381 u16 val;
382 u16 reg;
383 int shift;
384 u16 cp_reg = wm8903_read(codec, WM8903_CHARGE_PUMP_0);
385
386 switch (w->reg) {
387 case WM8903_POWER_MANAGEMENT_2:
388 reg = WM8903_ANALOGUE_HP_0;
389 break;
390 case WM8903_POWER_MANAGEMENT_3:
391 reg = WM8903_ANALOGUE_LINEOUT_0;
392 break;
393 default:
394 BUG();
395 }
396
397 switch (w->shift) {
398 case 0:
399 shift = 0;
400 break;
401 case 1:
402 shift = 4;
403 break;
404 default:
405 BUG();
406 }
407
408 if (event & SND_SOC_DAPM_PRE_PMU) {
409 val = wm8903_read(codec, reg);
410
411 /* Short the output */
412 val &= ~(WM8903_OUTPUT_SHORT << shift);
413 wm8903_write(codec, reg, val);
414
415 wm8903->charge_pump_users++;
416
417 dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
418 wm8903->charge_pump_users);
419
420 if (wm8903->charge_pump_users == 1) {
421 dev_dbg(&i2c->dev, "Enabling charge pump\n");
422 wm8903_write(codec, WM8903_CHARGE_PUMP_0,
423 cp_reg | WM8903_CP_ENA);
424 mdelay(4);
425 }
426 }
427
428 if (event & SND_SOC_DAPM_POST_PMU) {
429 val = wm8903_read(codec, reg);
430
431 val |= (WM8903_OUTPUT_IN << shift);
432 wm8903_write(codec, reg, val);
433
434 val |= (WM8903_OUTPUT_INT << shift);
435 wm8903_write(codec, reg, val);
436
437 /* Turn on the output ENA_OUTP */
438 val |= (WM8903_OUTPUT_OUT << shift);
439 wm8903_write(codec, reg, val);
440
441 /* Remove the short */
442 val |= (WM8903_OUTPUT_SHORT << shift);
443 wm8903_write(codec, reg, val);
444 }
445
446 if (event & SND_SOC_DAPM_PRE_PMD) {
447 val = wm8903_read(codec, reg);
448
449 /* Short the output */
450 val &= ~(WM8903_OUTPUT_SHORT << shift);
451 wm8903_write(codec, reg, val);
452
453 /* Then disable the intermediate and output stages */
454 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT |
455 WM8903_OUTPUT_IN) << shift);
456 wm8903_write(codec, reg, val);
457 }
458
459 if (event & SND_SOC_DAPM_POST_PMD) {
460 wm8903->charge_pump_users--;
461
462 dev_dbg(&i2c->dev, "Charge pump use count now %d\n",
463 wm8903->charge_pump_users);
464
465 if (wm8903->charge_pump_users == 0) {
466 dev_dbg(&i2c->dev, "Disabling charge pump\n");
467 wm8903_write(codec, WM8903_CHARGE_PUMP_0,
468 cp_reg & ~WM8903_CP_ENA);
469 }
470 }
471
472 return 0;
473}
474
475/*
476 * When used with DAC outputs only the WM8903 charge pump supports
477 * operation in class W mode, providing very low power consumption
478 * when used with digital sources. Enable and disable this mode
479 * automatically depending on the mixer configuration.
480 *
481 * All the relevant controls are simple switches.
482 */
483static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
484 struct snd_ctl_elem_value *ucontrol)
485{
486 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
487 struct snd_soc_codec *codec = widget->codec;
488 struct wm8903_priv *wm8903 = codec->private_data;
489 struct i2c_client *i2c = codec->control_data;
490 u16 reg;
491 int ret;
492
493 reg = wm8903_read(codec, WM8903_CLASS_W_0);
494
495 /* Turn it off if we're about to enable bypass */
496 if (ucontrol->value.integer.value[0]) {
497 if (wm8903->class_w_users == 0) {
498 dev_dbg(&i2c->dev, "Disabling Class W\n");
499 wm8903_write(codec, WM8903_CLASS_W_0, reg &
500 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
501 }
502 wm8903->class_w_users++;
503 }
504
505 /* Implement the change */
506 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
507
508 /* If we've just disabled the last bypass path turn Class W on */
509 if (!ucontrol->value.integer.value[0]) {
510 if (wm8903->class_w_users == 1) {
511 dev_dbg(&i2c->dev, "Enabling Class W\n");
512 wm8903_write(codec, WM8903_CLASS_W_0, reg |
513 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
514 }
515 wm8903->class_w_users--;
516 }
517
518 dev_dbg(&i2c->dev, "Bypass use count now %d\n",
519 wm8903->class_w_users);
520
521 return ret;
522}
523
524#define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \
525{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
526 .info = snd_soc_info_volsw, \
527 .get = snd_soc_dapm_get_volsw, .put = wm8903_class_w_put, \
528 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
529
530
531/* ALSA can only do steps of .01dB */
532static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
533
534static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
535
536static const DECLARE_TLV_DB_SCALE(drc_tlv_thresh, 0, 75, 0);
537static const DECLARE_TLV_DB_SCALE(drc_tlv_amp, -2250, 75, 0);
538static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0);
539static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0);
540static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0);
541
542static const char *drc_slope_text[] = {
543 "1", "1/2", "1/4", "1/8", "1/16", "0"
544};
545
546static const struct soc_enum drc_slope_r0 =
547 SOC_ENUM_SINGLE(WM8903_DRC_2, 3, 6, drc_slope_text);
548
549static const struct soc_enum drc_slope_r1 =
550 SOC_ENUM_SINGLE(WM8903_DRC_2, 0, 6, drc_slope_text);
551
552static const char *drc_attack_text[] = {
553 "instantaneous",
554 "363us", "762us", "1.45ms", "2.9ms", "5.8ms", "11.6ms", "23.2ms",
555 "46.4ms", "92.8ms", "185.6ms"
556};
557
558static const struct soc_enum drc_attack =
559 SOC_ENUM_SINGLE(WM8903_DRC_1, 12, 11, drc_attack_text);
560
561static const char *drc_decay_text[] = {
562 "186ms", "372ms", "743ms", "1.49s", "2.97s", "5.94s", "11.89s",
563 "23.87s", "47.56s"
564};
565
566static const struct soc_enum drc_decay =
567 SOC_ENUM_SINGLE(WM8903_DRC_1, 8, 9, drc_decay_text);
568
569static const char *drc_ff_delay_text[] = {
570 "5 samples", "9 samples"
571};
572
573static const struct soc_enum drc_ff_delay =
574 SOC_ENUM_SINGLE(WM8903_DRC_0, 5, 2, drc_ff_delay_text);
575
576static const char *drc_qr_decay_text[] = {
577 "0.725ms", "1.45ms", "5.8ms"
578};
579
580static const struct soc_enum drc_qr_decay =
581 SOC_ENUM_SINGLE(WM8903_DRC_1, 4, 3, drc_qr_decay_text);
582
583static const char *drc_smoothing_text[] = {
584 "Low", "Medium", "High"
585};
586
587static const struct soc_enum drc_smoothing =
588 SOC_ENUM_SINGLE(WM8903_DRC_0, 11, 3, drc_smoothing_text);
589
590static const char *soft_mute_text[] = {
591 "Fast (fs/2)", "Slow (fs/32)"
592};
593
594static const struct soc_enum soft_mute =
595 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 10, 2, soft_mute_text);
596
597static const char *mute_mode_text[] = {
598 "Hard", "Soft"
599};
600
601static const struct soc_enum mute_mode =
602 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text);
603
604static const char *dac_deemphasis_text[] = {
605 "Disabled", "32kHz", "44.1kHz", "48kHz"
606};
607
608static const struct soc_enum dac_deemphasis =
609 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text);
610
611static const char *companding_text[] = {
612 "ulaw", "alaw"
613};
614
615static const struct soc_enum dac_companding =
616 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 0, 2, companding_text);
617
618static const struct soc_enum adc_companding =
619 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 2, 2, companding_text);
620
621static const char *input_mode_text[] = {
622 "Single-Ended", "Differential Line", "Differential Mic"
623};
624
625static const struct soc_enum linput_mode_enum =
626 SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text);
627
628static const struct soc_enum rinput_mode_enum =
629 SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text);
630
631static const char *linput_mux_text[] = {
632 "IN1L", "IN2L", "IN3L"
633};
634
635static const struct soc_enum linput_enum =
636 SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 2, 3, linput_mux_text);
637
638static const struct soc_enum linput_inv_enum =
639 SOC_ENUM_SINGLE(WM8903_ANALOGUE_LEFT_INPUT_1, 4, 3, linput_mux_text);
640
641static const char *rinput_mux_text[] = {
642 "IN1R", "IN2R", "IN3R"
643};
644
645static const struct soc_enum rinput_enum =
646 SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 2, 3, rinput_mux_text);
647
648static const struct soc_enum rinput_inv_enum =
649 SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 4, 3, rinput_mux_text);
650
651
652static const struct snd_kcontrol_new wm8903_snd_controls[] = {
653
654/* Input PGAs - No TLV since the scale depends on PGA mode */
655SOC_SINGLE("Left Input PGA Switch", WM8903_ANALOGUE_LEFT_INPUT_0,
656 7, 1, 0),
657SOC_SINGLE("Left Input PGA Volume", WM8903_ANALOGUE_LEFT_INPUT_0,
658 0, 31, 0),
659SOC_SINGLE("Left Input PGA Common Mode Switch", WM8903_ANALOGUE_LEFT_INPUT_1,
660 6, 1, 0),
661
662SOC_SINGLE("Right Input PGA Switch", WM8903_ANALOGUE_RIGHT_INPUT_0,
663 7, 1, 0),
664SOC_SINGLE("Right Input PGA Volume", WM8903_ANALOGUE_RIGHT_INPUT_0,
665 0, 31, 0),
666SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
667 6, 1, 0),
668
669/* ADCs */
670SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
671SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
672SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
673SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8903_DRC_3, 5, 124, 1,
674 drc_tlv_thresh),
675SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp),
676SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min),
677SOC_SINGLE_TLV("DRC Maximum Gain Volume", WM8903_DRC_1, 0, 3, 0, drc_tlv_max),
678SOC_ENUM("DRC Attack Rate", drc_attack),
679SOC_ENUM("DRC Decay Rate", drc_decay),
680SOC_ENUM("DRC FF Delay", drc_ff_delay),
681SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0),
682SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0),
683SOC_SINGLE_TLV("DRC QR Threashold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max),
684SOC_ENUM("DRC QR Decay Rate", drc_qr_decay),
685SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0),
686SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0),
687SOC_ENUM("DRC Smoothing Threashold", drc_smoothing),
688SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup),
689
690SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
691 WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv),
692SOC_ENUM("ADC Companding Mode", adc_companding),
693SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0),
694
695/* DAC */
696SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
697 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
698SOC_ENUM("DAC Soft Mute Rate", soft_mute),
699SOC_ENUM("DAC Mute Mode", mute_mode),
700SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
701SOC_ENUM("DAC De-emphasis", dac_deemphasis),
702SOC_SINGLE("DAC Sloping Stopband Filter Switch",
703 WM8903_DAC_DIGITAL_1, 11, 1, 0),
704SOC_ENUM("DAC Companding Mode", dac_companding),
705SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
706
707/* Headphones */
708SOC_DOUBLE_R("Headphone Switch",
709 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
710 8, 1, 1),
711SOC_DOUBLE_R("Headphone ZC Switch",
712 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
713 6, 1, 0),
714SOC_DOUBLE_R_TLV("Headphone Volume",
715 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT,
716 0, 63, 0, out_tlv),
717
718/* Line out */
719SOC_DOUBLE_R("Line Out Switch",
720 WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
721 8, 1, 1),
722SOC_DOUBLE_R("Line Out ZC Switch",
723 WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
724 6, 1, 0),
725SOC_DOUBLE_R_TLV("Line Out Volume",
726 WM8903_ANALOGUE_OUT2_LEFT, WM8903_ANALOGUE_OUT2_RIGHT,
727 0, 63, 0, out_tlv),
728
729/* Speaker */
730SOC_DOUBLE_R("Speaker Switch",
731 WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT, 8, 1, 1),
732SOC_DOUBLE_R("Speaker ZC Switch",
733 WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT, 6, 1, 0),
734SOC_DOUBLE_R_TLV("Speaker Volume",
735 WM8903_ANALOGUE_OUT3_LEFT, WM8903_ANALOGUE_OUT3_RIGHT,
736 0, 63, 0, out_tlv),
737};
738
739static int wm8903_add_controls(struct snd_soc_codec *codec)
740{
741 int err, i;
742
743 for (i = 0; i < ARRAY_SIZE(wm8903_snd_controls); i++) {
744 err = snd_ctl_add(codec->card,
745 snd_soc_cnew(&wm8903_snd_controls[i],
746 codec, NULL));
747 if (err < 0)
748 return err;
749 }
750
751 return 0;
752}
753
754static const struct snd_kcontrol_new linput_mode_mux =
755 SOC_DAPM_ENUM("Left Input Mode Mux", linput_mode_enum);
756
757static const struct snd_kcontrol_new rinput_mode_mux =
758 SOC_DAPM_ENUM("Right Input Mode Mux", rinput_mode_enum);
759
760static const struct snd_kcontrol_new linput_mux =
761 SOC_DAPM_ENUM("Left Input Mux", linput_enum);
762
763static const struct snd_kcontrol_new linput_inv_mux =
764 SOC_DAPM_ENUM("Left Inverting Input Mux", linput_inv_enum);
765
766static const struct snd_kcontrol_new rinput_mux =
767 SOC_DAPM_ENUM("Right Input Mux", rinput_enum);
768
769static const struct snd_kcontrol_new rinput_inv_mux =
770 SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum);
771
772static const struct snd_kcontrol_new left_output_mixer[] = {
773SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
774SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
775SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0),
776SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0),
777};
778
779static const struct snd_kcontrol_new right_output_mixer[] = {
780SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0),
781SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 2, 1, 0),
782SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0),
783SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0),
784};
785
786static const struct snd_kcontrol_new left_speaker_mixer[] = {
787SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 3, 1, 0),
788SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 2, 1, 0),
789SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 1, 1, 0),
790SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0,
791 1, 1, 0),
792};
793
794static const struct snd_kcontrol_new right_speaker_mixer[] = {
795SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 3, 1, 0),
796SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 2, 1, 0),
797SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
798 1, 1, 0),
799SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
800 1, 1, 0),
801};
802
803static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = {
804SND_SOC_DAPM_INPUT("IN1L"),
805SND_SOC_DAPM_INPUT("IN1R"),
806SND_SOC_DAPM_INPUT("IN2L"),
807SND_SOC_DAPM_INPUT("IN2R"),
808SND_SOC_DAPM_INPUT("IN3L"),
809SND_SOC_DAPM_INPUT("IN3R"),
810
811SND_SOC_DAPM_OUTPUT("HPOUTL"),
812SND_SOC_DAPM_OUTPUT("HPOUTR"),
813SND_SOC_DAPM_OUTPUT("LINEOUTL"),
814SND_SOC_DAPM_OUTPUT("LINEOUTR"),
815SND_SOC_DAPM_OUTPUT("LOP"),
816SND_SOC_DAPM_OUTPUT("LON"),
817SND_SOC_DAPM_OUTPUT("ROP"),
818SND_SOC_DAPM_OUTPUT("RON"),
819
820SND_SOC_DAPM_MICBIAS("Mic Bias", WM8903_MIC_BIAS_CONTROL_0, 0, 0),
821
822SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &linput_mux),
823SND_SOC_DAPM_MUX("Left Input Inverting Mux", SND_SOC_NOPM, 0, 0,
824 &linput_inv_mux),
825SND_SOC_DAPM_MUX("Left Input Mode Mux", SND_SOC_NOPM, 0, 0, &linput_mode_mux),
826
827SND_SOC_DAPM_MUX("Right Input Mux", SND_SOC_NOPM, 0, 0, &rinput_mux),
828SND_SOC_DAPM_MUX("Right Input Inverting Mux", SND_SOC_NOPM, 0, 0,
829 &rinput_inv_mux),
830SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux),
831
832SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0),
833SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
834
835SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0),
836SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0),
837
838SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0),
839SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0),
840
841SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0,
842 left_output_mixer, ARRAY_SIZE(left_output_mixer)),
843SND_SOC_DAPM_MIXER("Right Output Mixer", WM8903_POWER_MANAGEMENT_1, 0, 0,
844 right_output_mixer, ARRAY_SIZE(right_output_mixer)),
845
846SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0,
847 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
848SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0,
849 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
850
851SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
852 1, 0, NULL, 0, wm8903_output_event,
853 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
854 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
855SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2,
856 0, 0, NULL, 0, wm8903_output_event,
857 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
858 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
859
860SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0,
861 NULL, 0, wm8903_output_event,
862 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
863 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
864SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0,
865 NULL, 0, wm8903_output_event,
866 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
867 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
868
869SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0,
870 NULL, 0),
871SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0,
872 NULL, 0),
873
874};
875
876static const struct snd_soc_dapm_route intercon[] = {
877
878 { "Left Input Mux", "IN1L", "IN1L" },
879 { "Left Input Mux", "IN2L", "IN2L" },
880 { "Left Input Mux", "IN3L", "IN3L" },
881
882 { "Left Input Inverting Mux", "IN1L", "IN1L" },
883 { "Left Input Inverting Mux", "IN2L", "IN2L" },
884 { "Left Input Inverting Mux", "IN3L", "IN3L" },
885
886 { "Right Input Mux", "IN1R", "IN1R" },
887 { "Right Input Mux", "IN2R", "IN2R" },
888 { "Right Input Mux", "IN3R", "IN3R" },
889
890 { "Right Input Inverting Mux", "IN1R", "IN1R" },
891 { "Right Input Inverting Mux", "IN2R", "IN2R" },
892 { "Right Input Inverting Mux", "IN3R", "IN3R" },
893
894 { "Left Input Mode Mux", "Single-Ended", "Left Input Inverting Mux" },
895 { "Left Input Mode Mux", "Differential Line",
896 "Left Input Mux" },
897 { "Left Input Mode Mux", "Differential Line",
898 "Left Input Inverting Mux" },
899 { "Left Input Mode Mux", "Differential Mic",
900 "Left Input Mux" },
901 { "Left Input Mode Mux", "Differential Mic",
902 "Left Input Inverting Mux" },
903
904 { "Right Input Mode Mux", "Single-Ended",
905 "Right Input Inverting Mux" },
906 { "Right Input Mode Mux", "Differential Line",
907 "Right Input Mux" },
908 { "Right Input Mode Mux", "Differential Line",
909 "Right Input Inverting Mux" },
910 { "Right Input Mode Mux", "Differential Mic",
911 "Right Input Mux" },
912 { "Right Input Mode Mux", "Differential Mic",
913 "Right Input Inverting Mux" },
914
915 { "Left Input PGA", NULL, "Left Input Mode Mux" },
916 { "Right Input PGA", NULL, "Right Input Mode Mux" },
917
918 { "ADCL", NULL, "Left Input PGA" },
919 { "ADCR", NULL, "Right Input PGA" },
920
921 { "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" },
922 { "Left Output Mixer", "Right Bypass Switch", "Right Input PGA" },
923 { "Left Output Mixer", "DACL Switch", "DACL" },
924 { "Left Output Mixer", "DACR Switch", "DACR" },
925
926 { "Right Output Mixer", "Left Bypass Switch", "Left Input PGA" },
927 { "Right Output Mixer", "Right Bypass Switch", "Right Input PGA" },
928 { "Right Output Mixer", "DACL Switch", "DACL" },
929 { "Right Output Mixer", "DACR Switch", "DACR" },
930
931 { "Left Speaker Mixer", "Left Bypass Switch", "Left Input PGA" },
932 { "Left Speaker Mixer", "Right Bypass Switch", "Right Input PGA" },
933 { "Left Speaker Mixer", "DACL Switch", "DACL" },
934 { "Left Speaker Mixer", "DACR Switch", "DACR" },
935
936 { "Right Speaker Mixer", "Left Bypass Switch", "Left Input PGA" },
937 { "Right Speaker Mixer", "Right Bypass Switch", "Right Input PGA" },
938 { "Right Speaker Mixer", "DACL Switch", "DACL" },
939 { "Right Speaker Mixer", "DACR Switch", "DACR" },
940
941 { "Left Line Output PGA", NULL, "Left Output Mixer" },
942 { "Right Line Output PGA", NULL, "Right Output Mixer" },
943
944 { "Left Headphone Output PGA", NULL, "Left Output Mixer" },
945 { "Right Headphone Output PGA", NULL, "Right Output Mixer" },
946
947 { "Left Speaker PGA", NULL, "Left Speaker Mixer" },
948 { "Right Speaker PGA", NULL, "Right Speaker Mixer" },
949
950 { "HPOUTL", NULL, "Left Headphone Output PGA" },
951 { "HPOUTR", NULL, "Right Headphone Output PGA" },
952
953 { "LINEOUTL", NULL, "Left Line Output PGA" },
954 { "LINEOUTR", NULL, "Right Line Output PGA" },
955
956 { "LOP", NULL, "Left Speaker PGA" },
957 { "LON", NULL, "Left Speaker PGA" },
958
959 { "ROP", NULL, "Right Speaker PGA" },
960 { "RON", NULL, "Right Speaker PGA" },
961};
962
963static int wm8903_add_widgets(struct snd_soc_codec *codec)
964{
965 snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets,
966 ARRAY_SIZE(wm8903_dapm_widgets));
967
968 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
969
970 snd_soc_dapm_new_widgets(codec);
971
972 return 0;
973}
974
975static int wm8903_set_bias_level(struct snd_soc_codec *codec,
976 enum snd_soc_bias_level level)
977{
978 struct i2c_client *i2c = codec->control_data;
979 u16 reg, reg2;
980
981 switch (level) {
982 case SND_SOC_BIAS_ON:
983 case SND_SOC_BIAS_PREPARE:
984 reg = wm8903_read(codec, WM8903_VMID_CONTROL_0);
985 reg &= ~(WM8903_VMID_RES_MASK);
986 reg |= WM8903_VMID_RES_50K;
987 wm8903_write(codec, WM8903_VMID_CONTROL_0, reg);
988 break;
989
990 case SND_SOC_BIAS_STANDBY:
991 if (codec->bias_level == SND_SOC_BIAS_OFF) {
992 wm8903_run_sequence(codec, 0);
993 wm8903_sync_reg_cache(codec, codec->reg_cache);
994
995 /* Enable low impedence charge pump output */
996 reg = wm8903_read(codec,
997 WM8903_CONTROL_INTERFACE_TEST_1);
998 wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
999 reg | WM8903_TEST_KEY);
1000 reg2 = wm8903_read(codec, WM8903_CHARGE_PUMP_TEST_1);
1001 wm8903_write(codec, WM8903_CHARGE_PUMP_TEST_1,
1002 reg2 | WM8903_CP_SW_KELVIN_MODE_MASK);
1003 wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
1004 reg);
1005
1006 /* By default no bypass paths are enabled so
1007 * enable Class W support.
1008 */
1009 dev_dbg(&i2c->dev, "Enabling Class W\n");
1010 wm8903_write(codec, WM8903_CLASS_W_0, reg |
1011 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
1012 }
1013
1014 reg = wm8903_read(codec, WM8903_VMID_CONTROL_0);
1015 reg &= ~(WM8903_VMID_RES_MASK);
1016 reg |= WM8903_VMID_RES_250K;
1017 wm8903_write(codec, WM8903_VMID_CONTROL_0, reg);
1018 break;
1019
1020 case SND_SOC_BIAS_OFF:
1021 wm8903_run_sequence(codec, 32);
1022 break;
1023 }
1024
1025 codec->bias_level = level;
1026
1027 return 0;
1028}
1029
1030static int wm8903_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1031 int clk_id, unsigned int freq, int dir)
1032{
1033 struct snd_soc_codec *codec = codec_dai->codec;
1034 struct wm8903_priv *wm8903 = codec->private_data;
1035
1036 wm8903->sysclk = freq;
1037
1038 return 0;
1039}
1040
1041static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
1042 unsigned int fmt)
1043{
1044 struct snd_soc_codec *codec = codec_dai->codec;
1045 u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1);
1046
1047 aif1 &= ~(WM8903_LRCLK_DIR | WM8903_BCLK_DIR | WM8903_AIF_FMT_MASK |
1048 WM8903_AIF_LRCLK_INV | WM8903_AIF_BCLK_INV);
1049
1050 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1051 case SND_SOC_DAIFMT_CBS_CFS:
1052 break;
1053 case SND_SOC_DAIFMT_CBS_CFM:
1054 aif1 |= WM8903_LRCLK_DIR;
1055 break;
1056 case SND_SOC_DAIFMT_CBM_CFM:
1057 aif1 |= WM8903_LRCLK_DIR | WM8903_BCLK_DIR;
1058 break;
1059 case SND_SOC_DAIFMT_CBM_CFS:
1060 aif1 |= WM8903_BCLK_DIR;
1061 break;
1062 default:
1063 return -EINVAL;
1064 }
1065
1066 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1067 case SND_SOC_DAIFMT_DSP_A:
1068 aif1 |= 0x3;
1069 break;
1070 case SND_SOC_DAIFMT_DSP_B:
1071 aif1 |= 0x3 | WM8903_AIF_LRCLK_INV;
1072 break;
1073 case SND_SOC_DAIFMT_I2S:
1074 aif1 |= 0x2;
1075 break;
1076 case SND_SOC_DAIFMT_RIGHT_J:
1077 aif1 |= 0x1;
1078 break;
1079 case SND_SOC_DAIFMT_LEFT_J:
1080 break;
1081 default:
1082 return -EINVAL;
1083 }
1084
1085 /* Clock inversion */
1086 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1087 case SND_SOC_DAIFMT_DSP_A:
1088 case SND_SOC_DAIFMT_DSP_B:
1089 /* frame inversion not valid for DSP modes */
1090 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1091 case SND_SOC_DAIFMT_NB_NF:
1092 break;
1093 case SND_SOC_DAIFMT_IB_NF:
1094 aif1 |= WM8903_AIF_BCLK_INV;
1095 break;
1096 default:
1097 return -EINVAL;
1098 }
1099 break;
1100 case SND_SOC_DAIFMT_I2S:
1101 case SND_SOC_DAIFMT_RIGHT_J:
1102 case SND_SOC_DAIFMT_LEFT_J:
1103 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1104 case SND_SOC_DAIFMT_NB_NF:
1105 break;
1106 case SND_SOC_DAIFMT_IB_IF:
1107 aif1 |= WM8903_AIF_BCLK_INV | WM8903_AIF_LRCLK_INV;
1108 break;
1109 case SND_SOC_DAIFMT_IB_NF:
1110 aif1 |= WM8903_AIF_BCLK_INV;
1111 break;
1112 case SND_SOC_DAIFMT_NB_IF:
1113 aif1 |= WM8903_AIF_LRCLK_INV;
1114 break;
1115 default:
1116 return -EINVAL;
1117 }
1118 break;
1119 default:
1120 return -EINVAL;
1121 }
1122
1123 wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
1124
1125 return 0;
1126}
1127
1128static int wm8903_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1129{
1130 struct snd_soc_codec *codec = codec_dai->codec;
1131 u16 reg;
1132
1133 reg = wm8903_read(codec, WM8903_DAC_DIGITAL_1);
1134
1135 if (mute)
1136 reg |= WM8903_DAC_MUTE;
1137 else
1138 reg &= ~WM8903_DAC_MUTE;
1139
1140 wm8903_write(codec, WM8903_DAC_DIGITAL_1, reg);
1141
1142 return 0;
1143}
1144
1145/* Lookup table for CLK_SYS/fs ratio. 256fs or more is recommended
1146 * for optimal performance so we list the lower rates first and match
1147 * on the last match we find. */
1148static struct {
1149 int div;
1150 int rate;
1151 int mode;
1152 int mclk_div;
1153} clk_sys_ratios[] = {
1154 { 64, 0x0, 0x0, 1 },
1155 { 68, 0x0, 0x1, 1 },
1156 { 125, 0x0, 0x2, 1 },
1157 { 128, 0x1, 0x0, 1 },
1158 { 136, 0x1, 0x1, 1 },
1159 { 192, 0x2, 0x0, 1 },
1160 { 204, 0x2, 0x1, 1 },
1161
1162 { 64, 0x0, 0x0, 2 },
1163 { 68, 0x0, 0x1, 2 },
1164 { 125, 0x0, 0x2, 2 },
1165 { 128, 0x1, 0x0, 2 },
1166 { 136, 0x1, 0x1, 2 },
1167 { 192, 0x2, 0x0, 2 },
1168 { 204, 0x2, 0x1, 2 },
1169
1170 { 250, 0x2, 0x2, 1 },
1171 { 256, 0x3, 0x0, 1 },
1172 { 272, 0x3, 0x1, 1 },
1173 { 384, 0x4, 0x0, 1 },
1174 { 408, 0x4, 0x1, 1 },
1175 { 375, 0x4, 0x2, 1 },
1176 { 512, 0x5, 0x0, 1 },
1177 { 544, 0x5, 0x1, 1 },
1178 { 500, 0x5, 0x2, 1 },
1179 { 768, 0x6, 0x0, 1 },
1180 { 816, 0x6, 0x1, 1 },
1181 { 750, 0x6, 0x2, 1 },
1182 { 1024, 0x7, 0x0, 1 },
1183 { 1088, 0x7, 0x1, 1 },
1184 { 1000, 0x7, 0x2, 1 },
1185 { 1408, 0x8, 0x0, 1 },
1186 { 1496, 0x8, 0x1, 1 },
1187 { 1536, 0x9, 0x0, 1 },
1188 { 1632, 0x9, 0x1, 1 },
1189 { 1500, 0x9, 0x2, 1 },
1190
1191 { 250, 0x2, 0x2, 2 },
1192 { 256, 0x3, 0x0, 2 },
1193 { 272, 0x3, 0x1, 2 },
1194 { 384, 0x4, 0x0, 2 },
1195 { 408, 0x4, 0x1, 2 },
1196 { 375, 0x4, 0x2, 2 },
1197 { 512, 0x5, 0x0, 2 },
1198 { 544, 0x5, 0x1, 2 },
1199 { 500, 0x5, 0x2, 2 },
1200 { 768, 0x6, 0x0, 2 },
1201 { 816, 0x6, 0x1, 2 },
1202 { 750, 0x6, 0x2, 2 },
1203 { 1024, 0x7, 0x0, 2 },
1204 { 1088, 0x7, 0x1, 2 },
1205 { 1000, 0x7, 0x2, 2 },
1206 { 1408, 0x8, 0x0, 2 },
1207 { 1496, 0x8, 0x1, 2 },
1208 { 1536, 0x9, 0x0, 2 },
1209 { 1632, 0x9, 0x1, 2 },
1210 { 1500, 0x9, 0x2, 2 },
1211};
1212
1213/* CLK_SYS/BCLK ratios - multiplied by 10 due to .5s */
1214static struct {
1215 int ratio;
1216 int div;
1217} bclk_divs[] = {
1218 { 10, 0 },
1219 { 15, 1 },
1220 { 20, 2 },
1221 { 30, 3 },
1222 { 40, 4 },
1223 { 50, 5 },
1224 { 55, 6 },
1225 { 60, 7 },
1226 { 80, 8 },
1227 { 100, 9 },
1228 { 110, 10 },
1229 { 120, 11 },
1230 { 160, 12 },
1231 { 200, 13 },
1232 { 220, 14 },
1233 { 240, 15 },
1234 { 250, 16 },
1235 { 300, 17 },
1236 { 320, 18 },
1237 { 440, 19 },
1238 { 480, 20 },
1239};
1240
1241/* Sample rates for DSP */
1242static struct {
1243 int rate;
1244 int value;
1245} sample_rates[] = {
1246 { 8000, 0 },
1247 { 11025, 1 },
1248 { 12000, 2 },
1249 { 16000, 3 },
1250 { 22050, 4 },
1251 { 24000, 5 },
1252 { 32000, 6 },
1253 { 44100, 7 },
1254 { 48000, 8 },
1255 { 88200, 9 },
1256 { 96000, 10 },
1257 { 0, 0 },
1258};
1259
1260static int wm8903_startup(struct snd_pcm_substream *substream)
1261{
1262 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1263 struct snd_soc_device *socdev = rtd->socdev;
1264 struct snd_soc_codec *codec = socdev->codec;
1265 struct wm8903_priv *wm8903 = codec->private_data;
1266 struct i2c_client *i2c = codec->control_data;
1267 struct snd_pcm_runtime *master_runtime;
1268
1269 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1270 wm8903->playback_active++;
1271 else
1272 wm8903->capture_active++;
1273
1274 /* The DAI has shared clocks so if we already have a playback or
1275 * capture going then constrain this substream to match it.
1276 */
1277 if (wm8903->master_substream) {
1278 master_runtime = wm8903->master_substream->runtime;
1279
1280 dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n",
1281 master_runtime->sample_bits,
1282 master_runtime->rate);
1283
1284 snd_pcm_hw_constraint_minmax(substream->runtime,
1285 SNDRV_PCM_HW_PARAM_RATE,
1286 master_runtime->rate,
1287 master_runtime->rate);
1288
1289 snd_pcm_hw_constraint_minmax(substream->runtime,
1290 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1291 master_runtime->sample_bits,
1292 master_runtime->sample_bits);
1293
1294 wm8903->slave_substream = substream;
1295 } else
1296 wm8903->master_substream = substream;
1297
1298 return 0;
1299}
1300
1301static void wm8903_shutdown(struct snd_pcm_substream *substream)
1302{
1303 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1304 struct snd_soc_device *socdev = rtd->socdev;
1305 struct snd_soc_codec *codec = socdev->codec;
1306 struct wm8903_priv *wm8903 = codec->private_data;
1307
1308 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1309 wm8903->playback_active--;
1310 else
1311 wm8903->capture_active--;
1312
1313 if (wm8903->master_substream == substream)
1314 wm8903->master_substream = wm8903->slave_substream;
1315
1316 wm8903->slave_substream = NULL;
1317}
1318
1319static int wm8903_hw_params(struct snd_pcm_substream *substream,
1320 struct snd_pcm_hw_params *params)
1321{
1322 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1323 struct snd_soc_device *socdev = rtd->socdev;
1324 struct snd_soc_codec *codec = socdev->codec;
1325 struct wm8903_priv *wm8903 = codec->private_data;
1326 struct i2c_client *i2c = codec->control_data;
1327 int fs = params_rate(params);
1328 int bclk;
1329 int bclk_div;
1330 int i;
1331 int dsp_config;
1332 int clk_config;
1333 int best_val;
1334 int cur_val;
1335 int clk_sys;
1336
1337 u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1);
1338 u16 aif2 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_2);
1339 u16 aif3 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_3);
1340 u16 clock0 = wm8903_read(codec, WM8903_CLOCK_RATES_0);
1341 u16 clock1 = wm8903_read(codec, WM8903_CLOCK_RATES_1);
1342
1343 if (substream == wm8903->slave_substream) {
1344 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
1345 return 0;
1346 }
1347
1348 /* Configure sample rate logic for DSP - choose nearest rate */
1349 dsp_config = 0;
1350 best_val = abs(sample_rates[dsp_config].rate - fs);
1351 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
1352 cur_val = abs(sample_rates[i].rate - fs);
1353 if (cur_val <= best_val) {
1354 dsp_config = i;
1355 best_val = cur_val;
1356 }
1357 }
1358
1359 /* Constraints should stop us hitting this but let's make sure */
1360 if (wm8903->capture_active)
1361 switch (sample_rates[dsp_config].rate) {
1362 case 88200:
1363 case 96000:
1364 dev_err(&i2c->dev, "%dHz unsupported by ADC\n",
1365 fs);
1366 return -EINVAL;
1367
1368 default:
1369 break;
1370 }
1371
1372 dev_dbg(&i2c->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
1373 clock1 &= ~WM8903_SAMPLE_RATE_MASK;
1374 clock1 |= sample_rates[dsp_config].value;
1375
1376 aif1 &= ~WM8903_AIF_WL_MASK;
1377 bclk = 2 * fs;
1378 switch (params_format(params)) {
1379 case SNDRV_PCM_FORMAT_S16_LE:
1380 bclk *= 16;
1381 break;
1382 case SNDRV_PCM_FORMAT_S20_3LE:
1383 bclk *= 20;
1384 aif1 |= 0x4;
1385 break;
1386 case SNDRV_PCM_FORMAT_S24_LE:
1387 bclk *= 24;
1388 aif1 |= 0x8;
1389 break;
1390 case SNDRV_PCM_FORMAT_S32_LE:
1391 bclk *= 32;
1392 aif1 |= 0xc;
1393 break;
1394 default:
1395 return -EINVAL;
1396 }
1397
1398 dev_dbg(&i2c->dev, "MCLK = %dHz, target sample rate = %dHz\n",
1399 wm8903->sysclk, fs);
1400
1401 /* We may not have an MCLK which allows us to generate exactly
1402 * the clock we want, particularly with USB derived inputs, so
1403 * approximate.
1404 */
1405 clk_config = 0;
1406 best_val = abs((wm8903->sysclk /
1407 (clk_sys_ratios[0].mclk_div *
1408 clk_sys_ratios[0].div)) - fs);
1409 for (i = 1; i < ARRAY_SIZE(clk_sys_ratios); i++) {
1410 cur_val = abs((wm8903->sysclk /
1411 (clk_sys_ratios[i].mclk_div *
1412 clk_sys_ratios[i].div)) - fs);
1413
1414 if (cur_val <= best_val) {
1415 clk_config = i;
1416 best_val = cur_val;
1417 }
1418 }
1419
1420 if (clk_sys_ratios[clk_config].mclk_div == 2) {
1421 clock0 |= WM8903_MCLKDIV2;
1422 clk_sys = wm8903->sysclk / 2;
1423 } else {
1424 clock0 &= ~WM8903_MCLKDIV2;
1425 clk_sys = wm8903->sysclk;
1426 }
1427
1428 clock1 &= ~(WM8903_CLK_SYS_RATE_MASK |
1429 WM8903_CLK_SYS_MODE_MASK);
1430 clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT;
1431 clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT;
1432
1433 dev_dbg(&i2c->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n",
1434 clk_sys_ratios[clk_config].rate,
1435 clk_sys_ratios[clk_config].mode,
1436 clk_sys_ratios[clk_config].div);
1437
1438 dev_dbg(&i2c->dev, "Actual CLK_SYS = %dHz\n", clk_sys);
1439
1440 /* We may not get quite the right frequency if using
1441 * approximate clocks so look for the closest match that is
1442 * higher than the target (we need to ensure that there enough
1443 * BCLKs to clock out the samples).
1444 */
1445 bclk_div = 0;
1446 best_val = ((clk_sys * 10) / bclk_divs[0].ratio) - bclk;
1447 i = 1;
1448 while (i < ARRAY_SIZE(bclk_divs)) {
1449 cur_val = ((clk_sys * 10) / bclk_divs[i].ratio) - bclk;
1450 if (cur_val < 0) /* BCLK table is sorted */
1451 break;
1452 bclk_div = i;
1453 best_val = cur_val;
1454 i++;
1455 }
1456
1457 aif2 &= ~WM8903_BCLK_DIV_MASK;
1458 aif3 &= ~WM8903_LRCLK_RATE_MASK;
1459
1460 dev_dbg(&i2c->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
1461 bclk_divs[bclk_div].ratio / 10, bclk,
1462 (clk_sys * 10) / bclk_divs[bclk_div].ratio);
1463
1464 aif2 |= bclk_divs[bclk_div].div;
1465 aif3 |= bclk / fs;
1466
1467 wm8903_write(codec, WM8903_CLOCK_RATES_0, clock0);
1468 wm8903_write(codec, WM8903_CLOCK_RATES_1, clock1);
1469 wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
1470 wm8903_write(codec, WM8903_AUDIO_INTERFACE_2, aif2);
1471 wm8903_write(codec, WM8903_AUDIO_INTERFACE_3, aif3);
1472
1473 return 0;
1474}
1475
1476#define WM8903_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
1477 SNDRV_PCM_RATE_11025 | \
1478 SNDRV_PCM_RATE_16000 | \
1479 SNDRV_PCM_RATE_22050 | \
1480 SNDRV_PCM_RATE_32000 | \
1481 SNDRV_PCM_RATE_44100 | \
1482 SNDRV_PCM_RATE_48000 | \
1483 SNDRV_PCM_RATE_88200 | \
1484 SNDRV_PCM_RATE_96000)
1485
1486#define WM8903_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
1487 SNDRV_PCM_RATE_11025 | \
1488 SNDRV_PCM_RATE_16000 | \
1489 SNDRV_PCM_RATE_22050 | \
1490 SNDRV_PCM_RATE_32000 | \
1491 SNDRV_PCM_RATE_44100 | \
1492 SNDRV_PCM_RATE_48000)
1493
1494#define WM8903_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1495 SNDRV_PCM_FMTBIT_S20_3LE |\
1496 SNDRV_PCM_FMTBIT_S24_LE)
1497
1498struct snd_soc_dai wm8903_dai = {
1499 .name = "WM8903",
1500 .playback = {
1501 .stream_name = "Playback",
1502 .channels_min = 2,
1503 .channels_max = 2,
1504 .rates = WM8903_PLAYBACK_RATES,
1505 .formats = WM8903_FORMATS,
1506 },
1507 .capture = {
1508 .stream_name = "Capture",
1509 .channels_min = 2,
1510 .channels_max = 2,
1511 .rates = WM8903_CAPTURE_RATES,
1512 .formats = WM8903_FORMATS,
1513 },
1514 .ops = {
1515 .startup = wm8903_startup,
1516 .shutdown = wm8903_shutdown,
1517 .hw_params = wm8903_hw_params,
1518 },
1519 .dai_ops = {
1520 .digital_mute = wm8903_digital_mute,
1521 .set_fmt = wm8903_set_dai_fmt,
1522 .set_sysclk = wm8903_set_dai_sysclk
1523 }
1524};
1525EXPORT_SYMBOL_GPL(wm8903_dai);
1526
1527static int wm8903_suspend(struct platform_device *pdev, pm_message_t state)
1528{
1529 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1530 struct snd_soc_codec *codec = socdev->codec;
1531
1532 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1533
1534 return 0;
1535}
1536
1537static int wm8903_resume(struct platform_device *pdev)
1538{
1539 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1540 struct snd_soc_codec *codec = socdev->codec;
1541 struct i2c_client *i2c = codec->control_data;
1542 int i;
1543 u16 *reg_cache = codec->reg_cache;
1544 u16 *tmp_cache = kmemdup(codec->reg_cache, sizeof(wm8903_reg_defaults),
1545 GFP_KERNEL);
1546
1547 /* Bring the codec back up to standby first to minimise pop/clicks */
1548 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1549 wm8903_set_bias_level(codec, codec->suspend_bias_level);
1550
1551 /* Sync back everything else */
1552 if (tmp_cache) {
1553 for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
1554 if (tmp_cache[i] != reg_cache[i])
1555 wm8903_write(codec, i, tmp_cache[i]);
1556 } else {
1557 dev_err(&i2c->dev, "Failed to allocate temporary cache\n");
1558 }
1559
1560 return 0;
1561}
1562
1563/*
1564 * initialise the WM8903 driver
1565 * register the mixer and dsp interfaces with the kernel
1566 */
1567static int wm8903_init(struct snd_soc_device *socdev)
1568{
1569 struct snd_soc_codec *codec = socdev->codec;
1570 struct i2c_client *i2c = codec->control_data;
1571 int ret = 0;
1572 u16 val;
1573
1574 val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID);
1575 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
1576 dev_err(&i2c->dev,
1577 "Device with ID register %x is not a WM8903\n", val);
1578 return -ENODEV;
1579 }
1580
1581 codec->name = "WM8903";
1582 codec->owner = THIS_MODULE;
1583 codec->read = wm8903_read;
1584 codec->write = wm8903_write;
1585 codec->bias_level = SND_SOC_BIAS_OFF;
1586 codec->set_bias_level = wm8903_set_bias_level;
1587 codec->dai = &wm8903_dai;
1588 codec->num_dai = 1;
1589 codec->reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults);
1590 codec->reg_cache = kmemdup(wm8903_reg_defaults,
1591 sizeof(wm8903_reg_defaults),
1592 GFP_KERNEL);
1593 if (codec->reg_cache == NULL) {
1594 dev_err(&i2c->dev, "Failed to allocate register cache\n");
1595 return -ENOMEM;
1596 }
1597
1598 val = wm8903_read(codec, WM8903_REVISION_NUMBER);
1599 dev_info(&i2c->dev, "WM8903 revision %d\n",
1600 val & WM8903_CHIP_REV_MASK);
1601
1602 wm8903_reset(codec);
1603
1604 /* register pcms */
1605 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1606 if (ret < 0) {
1607 dev_err(&i2c->dev, "failed to create pcms\n");
1608 goto pcm_err;
1609 }
1610
1611 /* SYSCLK is required for pretty much anything */
1612 wm8903_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA);
1613
1614 /* power on device */
1615 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1616
1617 /* Latch volume update bits */
1618 val = wm8903_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT);
1619 val |= WM8903_ADCVU;
1620 wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val);
1621 wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val);
1622
1623 val = wm8903_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT);
1624 val |= WM8903_DACVU;
1625 wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val);
1626 wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val);
1627
1628 val = wm8903_read(codec, WM8903_ANALOGUE_OUT1_LEFT);
1629 val |= WM8903_HPOUTVU;
1630 wm8903_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val);
1631 wm8903_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val);
1632
1633 val = wm8903_read(codec, WM8903_ANALOGUE_OUT2_LEFT);
1634 val |= WM8903_LINEOUTVU;
1635 wm8903_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val);
1636 wm8903_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val);
1637
1638 val = wm8903_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
1639 val |= WM8903_SPKVU;
1640 wm8903_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val);
1641 wm8903_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
1642
1643 /* Enable DAC soft mute by default */
1644 val = wm8903_read(codec, WM8903_DAC_DIGITAL_1);
1645 val |= WM8903_DAC_MUTEMODE;
1646 wm8903_write(codec, WM8903_DAC_DIGITAL_1, val);
1647
1648 wm8903_add_controls(codec);
1649 wm8903_add_widgets(codec);
1650 ret = snd_soc_register_card(socdev);
1651 if (ret < 0) {
1652 dev_err(&i2c->dev, "wm8903: failed to register card\n");
1653 goto card_err;
1654 }
1655
1656 return ret;
1657
1658card_err:
1659 snd_soc_free_pcms(socdev);
1660 snd_soc_dapm_free(socdev);
1661pcm_err:
1662 kfree(codec->reg_cache);
1663 return ret;
1664}
1665
1666static struct snd_soc_device *wm8903_socdev;
1667
1668static int wm8903_i2c_probe(struct i2c_client *i2c,
1669 const struct i2c_device_id *id)
1670{
1671 struct snd_soc_device *socdev = wm8903_socdev;
1672 struct snd_soc_codec *codec = socdev->codec;
1673 int ret;
1674
1675 i2c_set_clientdata(i2c, codec);
1676 codec->control_data = i2c;
1677
1678 ret = wm8903_init(socdev);
1679 if (ret < 0)
1680 dev_err(&i2c->dev, "Device initialisation failed\n");
1681
1682 return ret;
1683}
1684
1685static int wm8903_i2c_remove(struct i2c_client *client)
1686{
1687 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1688 kfree(codec->reg_cache);
1689 return 0;
1690}
1691
1692/* i2c codec control layer */
1693static const struct i2c_device_id wm8903_i2c_id[] = {
1694 { "wm8903", 0 },
1695 { }
1696};
1697MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id);
1698
1699static struct i2c_driver wm8903_i2c_driver = {
1700 .driver = {
1701 .name = "WM8903",
1702 .owner = THIS_MODULE,
1703 },
1704 .probe = wm8903_i2c_probe,
1705 .remove = wm8903_i2c_remove,
1706 .id_table = wm8903_i2c_id,
1707};
1708
1709static int wm8903_probe(struct platform_device *pdev)
1710{
1711 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1712 struct wm8903_setup_data *setup;
1713 struct snd_soc_codec *codec;
1714 struct wm8903_priv *wm8903;
1715 struct i2c_board_info board_info;
1716 struct i2c_adapter *adapter;
1717 struct i2c_client *i2c_client;
1718 int ret = 0;
1719
1720 setup = socdev->codec_data;
1721
1722 if (!setup->i2c_address) {
1723 dev_err(&pdev->dev, "No codec address provided\n");
1724 return -ENODEV;
1725 }
1726
1727 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1728 if (codec == NULL)
1729 return -ENOMEM;
1730
1731 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
1732 if (wm8903 == NULL) {
1733 ret = -ENOMEM;
1734 goto err_codec;
1735 }
1736
1737 codec->private_data = wm8903;
1738 socdev->codec = codec;
1739 mutex_init(&codec->mutex);
1740 INIT_LIST_HEAD(&codec->dapm_widgets);
1741 INIT_LIST_HEAD(&codec->dapm_paths);
1742
1743 wm8903_socdev = socdev;
1744
1745 codec->hw_write = (hw_write_t)i2c_master_send;
1746 ret = i2c_add_driver(&wm8903_i2c_driver);
1747 if (ret != 0) {
1748 dev_err(&pdev->dev, "can't add i2c driver\n");
1749 goto err_priv;
1750 } else {
1751 memset(&board_info, 0, sizeof(board_info));
1752 strlcpy(board_info.type, "wm8903", I2C_NAME_SIZE);
1753 board_info.addr = setup->i2c_address;
1754
1755 adapter = i2c_get_adapter(setup->i2c_bus);
1756 if (!adapter) {
1757 dev_err(&pdev->dev, "Can't get I2C bus %d\n",
1758 setup->i2c_bus);
1759 ret = -ENODEV;
1760 goto err_adapter;
1761 }
1762
1763 i2c_client = i2c_new_device(adapter, &board_info);
1764 i2c_put_adapter(adapter);
1765 if (i2c_client == NULL) {
1766 dev_err(&pdev->dev,
1767 "I2C driver registration failed\n");
1768 ret = -ENODEV;
1769 goto err_adapter;
1770 }
1771 }
1772
1773 return ret;
1774
1775err_adapter:
1776 i2c_del_driver(&wm8903_i2c_driver);
1777err_priv:
1778 kfree(codec->private_data);
1779err_codec:
1780 kfree(codec);
1781 return ret;
1782}
1783
1784/* power down chip */
1785static int wm8903_remove(struct platform_device *pdev)
1786{
1787 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1788 struct snd_soc_codec *codec = socdev->codec;
1789
1790 if (codec->control_data)
1791 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1792
1793 snd_soc_free_pcms(socdev);
1794 snd_soc_dapm_free(socdev);
1795 i2c_unregister_device(socdev->codec->control_data);
1796 i2c_del_driver(&wm8903_i2c_driver);
1797 kfree(codec->private_data);
1798 kfree(codec);
1799
1800 return 0;
1801}
1802
1803struct snd_soc_codec_device soc_codec_dev_wm8903 = {
1804 .probe = wm8903_probe,
1805 .remove = wm8903_remove,
1806 .suspend = wm8903_suspend,
1807 .resume = wm8903_resume,
1808};
1809EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
1810
1811MODULE_DESCRIPTION("ASoC WM8903 driver");
1812MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>");
1813MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
new file mode 100644
index 00000000000..cec622f2f66
--- /dev/null
+++ b/sound/soc/codecs/wm8903.h
@@ -0,0 +1,1463 @@
1/*
2 * wm8903.h - WM8903 audio codec interface
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _WM8903_H
14#define _WM8903_H
15
16#include <linux/i2c.h>
17
18extern struct snd_soc_dai wm8903_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8903;
20
21struct wm8903_setup_data {
22 int i2c_bus;
23 int i2c_address;
24};
25
26#define WM8903_MCLK_DIV_2 1
27#define WM8903_CLK_SYS 2
28#define WM8903_BCLK 3
29#define WM8903_LRCLK 4
30
31/*
32 * Register values.
33 */
34#define WM8903_SW_RESET_AND_ID 0x00
35#define WM8903_REVISION_NUMBER 0x01
36#define WM8903_BIAS_CONTROL_0 0x04
37#define WM8903_VMID_CONTROL_0 0x05
38#define WM8903_MIC_BIAS_CONTROL_0 0x06
39#define WM8903_ANALOGUE_DAC_0 0x08
40#define WM8903_ANALOGUE_ADC_0 0x0A
41#define WM8903_POWER_MANAGEMENT_0 0x0C
42#define WM8903_POWER_MANAGEMENT_1 0x0D
43#define WM8903_POWER_MANAGEMENT_2 0x0E
44#define WM8903_POWER_MANAGEMENT_3 0x0F
45#define WM8903_POWER_MANAGEMENT_4 0x10
46#define WM8903_POWER_MANAGEMENT_5 0x11
47#define WM8903_POWER_MANAGEMENT_6 0x12
48#define WM8903_CLOCK_RATES_0 0x14
49#define WM8903_CLOCK_RATES_1 0x15
50#define WM8903_CLOCK_RATES_2 0x16
51#define WM8903_AUDIO_INTERFACE_0 0x18
52#define WM8903_AUDIO_INTERFACE_1 0x19
53#define WM8903_AUDIO_INTERFACE_2 0x1A
54#define WM8903_AUDIO_INTERFACE_3 0x1B
55#define WM8903_DAC_DIGITAL_VOLUME_LEFT 0x1E
56#define WM8903_DAC_DIGITAL_VOLUME_RIGHT 0x1F
57#define WM8903_DAC_DIGITAL_0 0x20
58#define WM8903_DAC_DIGITAL_1 0x21
59#define WM8903_ADC_DIGITAL_VOLUME_LEFT 0x24
60#define WM8903_ADC_DIGITAL_VOLUME_RIGHT 0x25
61#define WM8903_ADC_DIGITAL_0 0x26
62#define WM8903_DIGITAL_MICROPHONE_0 0x27
63#define WM8903_DRC_0 0x28
64#define WM8903_DRC_1 0x29
65#define WM8903_DRC_2 0x2A
66#define WM8903_DRC_3 0x2B
67#define WM8903_ANALOGUE_LEFT_INPUT_0 0x2C
68#define WM8903_ANALOGUE_RIGHT_INPUT_0 0x2D
69#define WM8903_ANALOGUE_LEFT_INPUT_1 0x2E
70#define WM8903_ANALOGUE_RIGHT_INPUT_1 0x2F
71#define WM8903_ANALOGUE_LEFT_MIX_0 0x32
72#define WM8903_ANALOGUE_RIGHT_MIX_0 0x33
73#define WM8903_ANALOGUE_SPK_MIX_LEFT_0 0x34
74#define WM8903_ANALOGUE_SPK_MIX_LEFT_1 0x35
75#define WM8903_ANALOGUE_SPK_MIX_RIGHT_0 0x36
76#define WM8903_ANALOGUE_SPK_MIX_RIGHT_1 0x37
77#define WM8903_ANALOGUE_OUT1_LEFT 0x39
78#define WM8903_ANALOGUE_OUT1_RIGHT 0x3A
79#define WM8903_ANALOGUE_OUT2_LEFT 0x3B
80#define WM8903_ANALOGUE_OUT2_RIGHT 0x3C
81#define WM8903_ANALOGUE_OUT3_LEFT 0x3E
82#define WM8903_ANALOGUE_OUT3_RIGHT 0x3F
83#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41
84#define WM8903_DC_SERVO_0 0x43
85#define WM8903_DC_SERVO_2 0x45
86#define WM8903_ANALOGUE_HP_0 0x5A
87#define WM8903_ANALOGUE_LINEOUT_0 0x5E
88#define WM8903_CHARGE_PUMP_0 0x62
89#define WM8903_CLASS_W_0 0x68
90#define WM8903_WRITE_SEQUENCER_0 0x6C
91#define WM8903_WRITE_SEQUENCER_1 0x6D
92#define WM8903_WRITE_SEQUENCER_2 0x6E
93#define WM8903_WRITE_SEQUENCER_3 0x6F
94#define WM8903_WRITE_SEQUENCER_4 0x70
95#define WM8903_CONTROL_INTERFACE 0x72
96#define WM8903_GPIO_CONTROL_1 0x74
97#define WM8903_GPIO_CONTROL_2 0x75
98#define WM8903_GPIO_CONTROL_3 0x76
99#define WM8903_GPIO_CONTROL_4 0x77
100#define WM8903_GPIO_CONTROL_5 0x78
101#define WM8903_INTERRUPT_STATUS_1 0x79
102#define WM8903_INTERRUPT_STATUS_1_MASK 0x7A
103#define WM8903_INTERRUPT_POLARITY_1 0x7B
104#define WM8903_INTERRUPT_CONTROL 0x7E
105#define WM8903_CONTROL_INTERFACE_TEST_1 0x81
106#define WM8903_CHARGE_PUMP_TEST_1 0x95
107#define WM8903_CLOCK_RATE_TEST_4 0xA4
108#define WM8903_ANALOGUE_OUTPUT_BIAS_0 0xAC
109
110#define WM8903_REGISTER_COUNT 75
111#define WM8903_MAX_REGISTER 0xAC
112
113/*
114 * Field Definitions.
115 */
116
117/*
118 * R0 (0x00) - SW Reset and ID
119 */
120#define WM8903_SW_RESET_DEV_ID1_MASK 0xFFFF /* SW_RESET_DEV_ID1 - [15:0] */
121#define WM8903_SW_RESET_DEV_ID1_SHIFT 0 /* SW_RESET_DEV_ID1 - [15:0] */
122#define WM8903_SW_RESET_DEV_ID1_WIDTH 16 /* SW_RESET_DEV_ID1 - [15:0] */
123
124/*
125 * R1 (0x01) - Revision Number
126 */
127#define WM8903_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
128#define WM8903_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
129#define WM8903_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
130
131/*
132 * R4 (0x04) - Bias Control 0
133 */
134#define WM8903_POBCTRL 0x0010 /* POBCTRL */
135#define WM8903_POBCTRL_MASK 0x0010 /* POBCTRL */
136#define WM8903_POBCTRL_SHIFT 4 /* POBCTRL */
137#define WM8903_POBCTRL_WIDTH 1 /* POBCTRL */
138#define WM8903_ISEL_MASK 0x000C /* ISEL - [3:2] */
139#define WM8903_ISEL_SHIFT 2 /* ISEL - [3:2] */
140#define WM8903_ISEL_WIDTH 2 /* ISEL - [3:2] */
141#define WM8903_STARTUP_BIAS_ENA 0x0002 /* STARTUP_BIAS_ENA */
142#define WM8903_STARTUP_BIAS_ENA_MASK 0x0002 /* STARTUP_BIAS_ENA */
143#define WM8903_STARTUP_BIAS_ENA_SHIFT 1 /* STARTUP_BIAS_ENA */
144#define WM8903_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
145#define WM8903_BIAS_ENA 0x0001 /* BIAS_ENA */
146#define WM8903_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
147#define WM8903_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
148#define WM8903_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
149
150/*
151 * R5 (0x05) - VMID Control 0
152 */
153#define WM8903_VMID_TIE_ENA 0x0080 /* VMID_TIE_ENA */
154#define WM8903_VMID_TIE_ENA_MASK 0x0080 /* VMID_TIE_ENA */
155#define WM8903_VMID_TIE_ENA_SHIFT 7 /* VMID_TIE_ENA */
156#define WM8903_VMID_TIE_ENA_WIDTH 1 /* VMID_TIE_ENA */
157#define WM8903_BUFIO_ENA 0x0040 /* BUFIO_ENA */
158#define WM8903_BUFIO_ENA_MASK 0x0040 /* BUFIO_ENA */
159#define WM8903_BUFIO_ENA_SHIFT 6 /* BUFIO_ENA */
160#define WM8903_BUFIO_ENA_WIDTH 1 /* BUFIO_ENA */
161#define WM8903_VMID_IO_ENA 0x0020 /* VMID_IO_ENA */
162#define WM8903_VMID_IO_ENA_MASK 0x0020 /* VMID_IO_ENA */
163#define WM8903_VMID_IO_ENA_SHIFT 5 /* VMID_IO_ENA */
164#define WM8903_VMID_IO_ENA_WIDTH 1 /* VMID_IO_ENA */
165#define WM8903_VMID_SOFT_MASK 0x0018 /* VMID_SOFT - [4:3] */
166#define WM8903_VMID_SOFT_SHIFT 3 /* VMID_SOFT - [4:3] */
167#define WM8903_VMID_SOFT_WIDTH 2 /* VMID_SOFT - [4:3] */
168#define WM8903_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
169#define WM8903_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
170#define WM8903_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
171#define WM8903_VMID_BUF_ENA 0x0001 /* VMID_BUF_ENA */
172#define WM8903_VMID_BUF_ENA_MASK 0x0001 /* VMID_BUF_ENA */
173#define WM8903_VMID_BUF_ENA_SHIFT 0 /* VMID_BUF_ENA */
174#define WM8903_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
175
176#define WM8903_VMID_RES_50K 2
177#define WM8903_VMID_RES_250K 3
178#define WM8903_VMID_RES_5K 4
179
180/*
181 * R6 (0x06) - Mic Bias Control 0
182 */
183#define WM8903_MICDET_HYST_ENA 0x0080 /* MICDET_HYST_ENA */
184#define WM8903_MICDET_HYST_ENA_MASK 0x0080 /* MICDET_HYST_ENA */
185#define WM8903_MICDET_HYST_ENA_SHIFT 7 /* MICDET_HYST_ENA */
186#define WM8903_MICDET_HYST_ENA_WIDTH 1 /* MICDET_HYST_ENA */
187#define WM8903_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
188#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
189#define WM8903_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
190#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
191#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
192#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
193#define WM8903_MICDET_ENA 0x0002 /* MICDET_ENA */
194#define WM8903_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
195#define WM8903_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
196#define WM8903_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
197#define WM8903_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
198#define WM8903_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
199#define WM8903_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
200#define WM8903_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
201
202/*
203 * R8 (0x08) - Analogue DAC 0
204 */
205#define WM8903_DACBIAS_SEL_MASK 0x0018 /* DACBIAS_SEL - [4:3] */
206#define WM8903_DACBIAS_SEL_SHIFT 3 /* DACBIAS_SEL - [4:3] */
207#define WM8903_DACBIAS_SEL_WIDTH 2 /* DACBIAS_SEL - [4:3] */
208#define WM8903_DACVMID_BIAS_SEL_MASK 0x0006 /* DACVMID_BIAS_SEL - [2:1] */
209#define WM8903_DACVMID_BIAS_SEL_SHIFT 1 /* DACVMID_BIAS_SEL - [2:1] */
210#define WM8903_DACVMID_BIAS_SEL_WIDTH 2 /* DACVMID_BIAS_SEL - [2:1] */
211
212/*
213 * R10 (0x0A) - Analogue ADC 0
214 */
215#define WM8903_ADC_OSR128 0x0001 /* ADC_OSR128 */
216#define WM8903_ADC_OSR128_MASK 0x0001 /* ADC_OSR128 */
217#define WM8903_ADC_OSR128_SHIFT 0 /* ADC_OSR128 */
218#define WM8903_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
219
220/*
221 * R12 (0x0C) - Power Management 0
222 */
223#define WM8903_INL_ENA 0x0002 /* INL_ENA */
224#define WM8903_INL_ENA_MASK 0x0002 /* INL_ENA */
225#define WM8903_INL_ENA_SHIFT 1 /* INL_ENA */
226#define WM8903_INL_ENA_WIDTH 1 /* INL_ENA */
227#define WM8903_INR_ENA 0x0001 /* INR_ENA */
228#define WM8903_INR_ENA_MASK 0x0001 /* INR_ENA */
229#define WM8903_INR_ENA_SHIFT 0 /* INR_ENA */
230#define WM8903_INR_ENA_WIDTH 1 /* INR_ENA */
231
232/*
233 * R13 (0x0D) - Power Management 1
234 */
235#define WM8903_MIXOUTL_ENA 0x0002 /* MIXOUTL_ENA */
236#define WM8903_MIXOUTL_ENA_MASK 0x0002 /* MIXOUTL_ENA */
237#define WM8903_MIXOUTL_ENA_SHIFT 1 /* MIXOUTL_ENA */
238#define WM8903_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
239#define WM8903_MIXOUTR_ENA 0x0001 /* MIXOUTR_ENA */
240#define WM8903_MIXOUTR_ENA_MASK 0x0001 /* MIXOUTR_ENA */
241#define WM8903_MIXOUTR_ENA_SHIFT 0 /* MIXOUTR_ENA */
242#define WM8903_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
243
244/*
245 * R14 (0x0E) - Power Management 2
246 */
247#define WM8903_HPL_PGA_ENA 0x0002 /* HPL_PGA_ENA */
248#define WM8903_HPL_PGA_ENA_MASK 0x0002 /* HPL_PGA_ENA */
249#define WM8903_HPL_PGA_ENA_SHIFT 1 /* HPL_PGA_ENA */
250#define WM8903_HPL_PGA_ENA_WIDTH 1 /* HPL_PGA_ENA */
251#define WM8903_HPR_PGA_ENA 0x0001 /* HPR_PGA_ENA */
252#define WM8903_HPR_PGA_ENA_MASK 0x0001 /* HPR_PGA_ENA */
253#define WM8903_HPR_PGA_ENA_SHIFT 0 /* HPR_PGA_ENA */
254#define WM8903_HPR_PGA_ENA_WIDTH 1 /* HPR_PGA_ENA */
255
256/*
257 * R15 (0x0F) - Power Management 3
258 */
259#define WM8903_LINEOUTL_PGA_ENA 0x0002 /* LINEOUTL_PGA_ENA */
260#define WM8903_LINEOUTL_PGA_ENA_MASK 0x0002 /* LINEOUTL_PGA_ENA */
261#define WM8903_LINEOUTL_PGA_ENA_SHIFT 1 /* LINEOUTL_PGA_ENA */
262#define WM8903_LINEOUTL_PGA_ENA_WIDTH 1 /* LINEOUTL_PGA_ENA */
263#define WM8903_LINEOUTR_PGA_ENA 0x0001 /* LINEOUTR_PGA_ENA */
264#define WM8903_LINEOUTR_PGA_ENA_MASK 0x0001 /* LINEOUTR_PGA_ENA */
265#define WM8903_LINEOUTR_PGA_ENA_SHIFT 0 /* LINEOUTR_PGA_ENA */
266#define WM8903_LINEOUTR_PGA_ENA_WIDTH 1 /* LINEOUTR_PGA_ENA */
267
268/*
269 * R16 (0x10) - Power Management 4
270 */
271#define WM8903_MIXSPKL_ENA 0x0002 /* MIXSPKL_ENA */
272#define WM8903_MIXSPKL_ENA_MASK 0x0002 /* MIXSPKL_ENA */
273#define WM8903_MIXSPKL_ENA_SHIFT 1 /* MIXSPKL_ENA */
274#define WM8903_MIXSPKL_ENA_WIDTH 1 /* MIXSPKL_ENA */
275#define WM8903_MIXSPKR_ENA 0x0001 /* MIXSPKR_ENA */
276#define WM8903_MIXSPKR_ENA_MASK 0x0001 /* MIXSPKR_ENA */
277#define WM8903_MIXSPKR_ENA_SHIFT 0 /* MIXSPKR_ENA */
278#define WM8903_MIXSPKR_ENA_WIDTH 1 /* MIXSPKR_ENA */
279
280/*
281 * R17 (0x11) - Power Management 5
282 */
283#define WM8903_SPKL_ENA 0x0002 /* SPKL_ENA */
284#define WM8903_SPKL_ENA_MASK 0x0002 /* SPKL_ENA */
285#define WM8903_SPKL_ENA_SHIFT 1 /* SPKL_ENA */
286#define WM8903_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
287#define WM8903_SPKR_ENA 0x0001 /* SPKR_ENA */
288#define WM8903_SPKR_ENA_MASK 0x0001 /* SPKR_ENA */
289#define WM8903_SPKR_ENA_SHIFT 0 /* SPKR_ENA */
290#define WM8903_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
291
292/*
293 * R18 (0x12) - Power Management 6
294 */
295#define WM8903_DACL_ENA 0x0008 /* DACL_ENA */
296#define WM8903_DACL_ENA_MASK 0x0008 /* DACL_ENA */
297#define WM8903_DACL_ENA_SHIFT 3 /* DACL_ENA */
298#define WM8903_DACL_ENA_WIDTH 1 /* DACL_ENA */
299#define WM8903_DACR_ENA 0x0004 /* DACR_ENA */
300#define WM8903_DACR_ENA_MASK 0x0004 /* DACR_ENA */
301#define WM8903_DACR_ENA_SHIFT 2 /* DACR_ENA */
302#define WM8903_DACR_ENA_WIDTH 1 /* DACR_ENA */
303#define WM8903_ADCL_ENA 0x0002 /* ADCL_ENA */
304#define WM8903_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
305#define WM8903_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
306#define WM8903_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
307#define WM8903_ADCR_ENA 0x0001 /* ADCR_ENA */
308#define WM8903_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
309#define WM8903_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
310#define WM8903_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
311
312/*
313 * R20 (0x14) - Clock Rates 0
314 */
315#define WM8903_MCLKDIV2 0x0001 /* MCLKDIV2 */
316#define WM8903_MCLKDIV2_MASK 0x0001 /* MCLKDIV2 */
317#define WM8903_MCLKDIV2_SHIFT 0 /* MCLKDIV2 */
318#define WM8903_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */
319
320/*
321 * R21 (0x15) - Clock Rates 1
322 */
323#define WM8903_CLK_SYS_RATE_MASK 0x3C00 /* CLK_SYS_RATE - [13:10] */
324#define WM8903_CLK_SYS_RATE_SHIFT 10 /* CLK_SYS_RATE - [13:10] */
325#define WM8903_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [13:10] */
326#define WM8903_CLK_SYS_MODE_MASK 0x0300 /* CLK_SYS_MODE - [9:8] */
327#define WM8903_CLK_SYS_MODE_SHIFT 8 /* CLK_SYS_MODE - [9:8] */
328#define WM8903_CLK_SYS_MODE_WIDTH 2 /* CLK_SYS_MODE - [9:8] */
329#define WM8903_SAMPLE_RATE_MASK 0x000F /* SAMPLE_RATE - [3:0] */
330#define WM8903_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [3:0] */
331#define WM8903_SAMPLE_RATE_WIDTH 4 /* SAMPLE_RATE - [3:0] */
332
333/*
334 * R22 (0x16) - Clock Rates 2
335 */
336#define WM8903_CLK_SYS_ENA 0x0004 /* CLK_SYS_ENA */
337#define WM8903_CLK_SYS_ENA_MASK 0x0004 /* CLK_SYS_ENA */
338#define WM8903_CLK_SYS_ENA_SHIFT 2 /* CLK_SYS_ENA */
339#define WM8903_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
340#define WM8903_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */
341#define WM8903_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */
342#define WM8903_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */
343#define WM8903_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
344#define WM8903_TO_ENA 0x0001 /* TO_ENA */
345#define WM8903_TO_ENA_MASK 0x0001 /* TO_ENA */
346#define WM8903_TO_ENA_SHIFT 0 /* TO_ENA */
347#define WM8903_TO_ENA_WIDTH 1 /* TO_ENA */
348
349/*
350 * R24 (0x18) - Audio Interface 0
351 */
352#define WM8903_DACL_DATINV 0x1000 /* DACL_DATINV */
353#define WM8903_DACL_DATINV_MASK 0x1000 /* DACL_DATINV */
354#define WM8903_DACL_DATINV_SHIFT 12 /* DACL_DATINV */
355#define WM8903_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
356#define WM8903_DACR_DATINV 0x0800 /* DACR_DATINV */
357#define WM8903_DACR_DATINV_MASK 0x0800 /* DACR_DATINV */
358#define WM8903_DACR_DATINV_SHIFT 11 /* DACR_DATINV */
359#define WM8903_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
360#define WM8903_DAC_BOOST_MASK 0x0600 /* DAC_BOOST - [10:9] */
361#define WM8903_DAC_BOOST_SHIFT 9 /* DAC_BOOST - [10:9] */
362#define WM8903_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [10:9] */
363#define WM8903_LOOPBACK 0x0100 /* LOOPBACK */
364#define WM8903_LOOPBACK_MASK 0x0100 /* LOOPBACK */
365#define WM8903_LOOPBACK_SHIFT 8 /* LOOPBACK */
366#define WM8903_LOOPBACK_WIDTH 1 /* LOOPBACK */
367#define WM8903_AIFADCL_SRC 0x0080 /* AIFADCL_SRC */
368#define WM8903_AIFADCL_SRC_MASK 0x0080 /* AIFADCL_SRC */
369#define WM8903_AIFADCL_SRC_SHIFT 7 /* AIFADCL_SRC */
370#define WM8903_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
371#define WM8903_AIFADCR_SRC 0x0040 /* AIFADCR_SRC */
372#define WM8903_AIFADCR_SRC_MASK 0x0040 /* AIFADCR_SRC */
373#define WM8903_AIFADCR_SRC_SHIFT 6 /* AIFADCR_SRC */
374#define WM8903_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
375#define WM8903_AIFDACL_SRC 0x0020 /* AIFDACL_SRC */
376#define WM8903_AIFDACL_SRC_MASK 0x0020 /* AIFDACL_SRC */
377#define WM8903_AIFDACL_SRC_SHIFT 5 /* AIFDACL_SRC */
378#define WM8903_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
379#define WM8903_AIFDACR_SRC 0x0010 /* AIFDACR_SRC */
380#define WM8903_AIFDACR_SRC_MASK 0x0010 /* AIFDACR_SRC */
381#define WM8903_AIFDACR_SRC_SHIFT 4 /* AIFDACR_SRC */
382#define WM8903_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
383#define WM8903_ADC_COMP 0x0008 /* ADC_COMP */
384#define WM8903_ADC_COMP_MASK 0x0008 /* ADC_COMP */
385#define WM8903_ADC_COMP_SHIFT 3 /* ADC_COMP */
386#define WM8903_ADC_COMP_WIDTH 1 /* ADC_COMP */
387#define WM8903_ADC_COMPMODE 0x0004 /* ADC_COMPMODE */
388#define WM8903_ADC_COMPMODE_MASK 0x0004 /* ADC_COMPMODE */
389#define WM8903_ADC_COMPMODE_SHIFT 2 /* ADC_COMPMODE */
390#define WM8903_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
391#define WM8903_DAC_COMP 0x0002 /* DAC_COMP */
392#define WM8903_DAC_COMP_MASK 0x0002 /* DAC_COMP */
393#define WM8903_DAC_COMP_SHIFT 1 /* DAC_COMP */
394#define WM8903_DAC_COMP_WIDTH 1 /* DAC_COMP */
395#define WM8903_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */
396#define WM8903_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */
397#define WM8903_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */
398#define WM8903_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
399
400/*
401 * R25 (0x19) - Audio Interface 1
402 */
403#define WM8903_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
404#define WM8903_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
405#define WM8903_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
406#define WM8903_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
407#define WM8903_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
408#define WM8903_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
409#define WM8903_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
410#define WM8903_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
411#define WM8903_AIFADC_TDM 0x0800 /* AIFADC_TDM */
412#define WM8903_AIFADC_TDM_MASK 0x0800 /* AIFADC_TDM */
413#define WM8903_AIFADC_TDM_SHIFT 11 /* AIFADC_TDM */
414#define WM8903_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
415#define WM8903_AIFADC_TDM_CHAN 0x0400 /* AIFADC_TDM_CHAN */
416#define WM8903_AIFADC_TDM_CHAN_MASK 0x0400 /* AIFADC_TDM_CHAN */
417#define WM8903_AIFADC_TDM_CHAN_SHIFT 10 /* AIFADC_TDM_CHAN */
418#define WM8903_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
419#define WM8903_LRCLK_DIR 0x0200 /* LRCLK_DIR */
420#define WM8903_LRCLK_DIR_MASK 0x0200 /* LRCLK_DIR */
421#define WM8903_LRCLK_DIR_SHIFT 9 /* LRCLK_DIR */
422#define WM8903_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
423#define WM8903_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */
424#define WM8903_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */
425#define WM8903_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */
426#define WM8903_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
427#define WM8903_BCLK_DIR 0x0040 /* BCLK_DIR */
428#define WM8903_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */
429#define WM8903_BCLK_DIR_SHIFT 6 /* BCLK_DIR */
430#define WM8903_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
431#define WM8903_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */
432#define WM8903_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */
433#define WM8903_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */
434#define WM8903_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
435#define WM8903_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */
436#define WM8903_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */
437#define WM8903_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */
438#define WM8903_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */
439#define WM8903_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */
440#define WM8903_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */
441
442/*
443 * R26 (0x1A) - Audio Interface 2
444 */
445#define WM8903_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */
446#define WM8903_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */
447#define WM8903_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */
448
449/*
450 * R27 (0x1B) - Audio Interface 3
451 */
452#define WM8903_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
453#define WM8903_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
454#define WM8903_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
455
456/*
457 * R30 (0x1E) - DAC Digital Volume Left
458 */
459#define WM8903_DACVU 0x0100 /* DACVU */
460#define WM8903_DACVU_MASK 0x0100 /* DACVU */
461#define WM8903_DACVU_SHIFT 8 /* DACVU */
462#define WM8903_DACVU_WIDTH 1 /* DACVU */
463#define WM8903_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
464#define WM8903_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
465#define WM8903_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
466
467/*
468 * R31 (0x1F) - DAC Digital Volume Right
469 */
470#define WM8903_DACVU 0x0100 /* DACVU */
471#define WM8903_DACVU_MASK 0x0100 /* DACVU */
472#define WM8903_DACVU_SHIFT 8 /* DACVU */
473#define WM8903_DACVU_WIDTH 1 /* DACVU */
474#define WM8903_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
475#define WM8903_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
476#define WM8903_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
477
478/*
479 * R32 (0x20) - DAC Digital 0
480 */
481#define WM8903_ADCL_DAC_SVOL_MASK 0x0F00 /* ADCL_DAC_SVOL - [11:8] */
482#define WM8903_ADCL_DAC_SVOL_SHIFT 8 /* ADCL_DAC_SVOL - [11:8] */
483#define WM8903_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [11:8] */
484#define WM8903_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
485#define WM8903_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
486#define WM8903_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
487#define WM8903_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
488#define WM8903_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
489#define WM8903_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
490#define WM8903_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
491#define WM8903_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
492#define WM8903_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
493
494/*
495 * R33 (0x21) - DAC Digital 1
496 */
497#define WM8903_DAC_MONO 0x1000 /* DAC_MONO */
498#define WM8903_DAC_MONO_MASK 0x1000 /* DAC_MONO */
499#define WM8903_DAC_MONO_SHIFT 12 /* DAC_MONO */
500#define WM8903_DAC_MONO_WIDTH 1 /* DAC_MONO */
501#define WM8903_DAC_SB_FILT 0x0800 /* DAC_SB_FILT */
502#define WM8903_DAC_SB_FILT_MASK 0x0800 /* DAC_SB_FILT */
503#define WM8903_DAC_SB_FILT_SHIFT 11 /* DAC_SB_FILT */
504#define WM8903_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
505#define WM8903_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */
506#define WM8903_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */
507#define WM8903_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */
508#define WM8903_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
509#define WM8903_DAC_MUTEMODE 0x0200 /* DAC_MUTEMODE */
510#define WM8903_DAC_MUTEMODE_MASK 0x0200 /* DAC_MUTEMODE */
511#define WM8903_DAC_MUTEMODE_SHIFT 9 /* DAC_MUTEMODE */
512#define WM8903_DAC_MUTEMODE_WIDTH 1 /* DAC_MUTEMODE */
513#define WM8903_DAC_MUTE 0x0008 /* DAC_MUTE */
514#define WM8903_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
515#define WM8903_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
516#define WM8903_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
517#define WM8903_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
518#define WM8903_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
519#define WM8903_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
520
521/*
522 * R36 (0x24) - ADC Digital Volume Left
523 */
524#define WM8903_ADCVU 0x0100 /* ADCVU */
525#define WM8903_ADCVU_MASK 0x0100 /* ADCVU */
526#define WM8903_ADCVU_SHIFT 8 /* ADCVU */
527#define WM8903_ADCVU_WIDTH 1 /* ADCVU */
528#define WM8903_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
529#define WM8903_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
530#define WM8903_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
531
532/*
533 * R37 (0x25) - ADC Digital Volume Right
534 */
535#define WM8903_ADCVU 0x0100 /* ADCVU */
536#define WM8903_ADCVU_MASK 0x0100 /* ADCVU */
537#define WM8903_ADCVU_SHIFT 8 /* ADCVU */
538#define WM8903_ADCVU_WIDTH 1 /* ADCVU */
539#define WM8903_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
540#define WM8903_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
541#define WM8903_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
542
543/*
544 * R38 (0x26) - ADC Digital 0
545 */
546#define WM8903_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
547#define WM8903_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
548#define WM8903_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
549#define WM8903_ADC_HPF_ENA 0x0010 /* ADC_HPF_ENA */
550#define WM8903_ADC_HPF_ENA_MASK 0x0010 /* ADC_HPF_ENA */
551#define WM8903_ADC_HPF_ENA_SHIFT 4 /* ADC_HPF_ENA */
552#define WM8903_ADC_HPF_ENA_WIDTH 1 /* ADC_HPF_ENA */
553#define WM8903_ADCL_DATINV 0x0002 /* ADCL_DATINV */
554#define WM8903_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
555#define WM8903_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
556#define WM8903_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
557#define WM8903_ADCR_DATINV 0x0001 /* ADCR_DATINV */
558#define WM8903_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
559#define WM8903_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
560#define WM8903_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
561
562/*
563 * R39 (0x27) - Digital Microphone 0
564 */
565#define WM8903_DIGMIC_MODE_SEL 0x0100 /* DIGMIC_MODE_SEL */
566#define WM8903_DIGMIC_MODE_SEL_MASK 0x0100 /* DIGMIC_MODE_SEL */
567#define WM8903_DIGMIC_MODE_SEL_SHIFT 8 /* DIGMIC_MODE_SEL */
568#define WM8903_DIGMIC_MODE_SEL_WIDTH 1 /* DIGMIC_MODE_SEL */
569#define WM8903_DIGMIC_CLK_SEL_L_MASK 0x00C0 /* DIGMIC_CLK_SEL_L - [7:6] */
570#define WM8903_DIGMIC_CLK_SEL_L_SHIFT 6 /* DIGMIC_CLK_SEL_L - [7:6] */
571#define WM8903_DIGMIC_CLK_SEL_L_WIDTH 2 /* DIGMIC_CLK_SEL_L - [7:6] */
572#define WM8903_DIGMIC_CLK_SEL_R_MASK 0x0030 /* DIGMIC_CLK_SEL_R - [5:4] */
573#define WM8903_DIGMIC_CLK_SEL_R_SHIFT 4 /* DIGMIC_CLK_SEL_R - [5:4] */
574#define WM8903_DIGMIC_CLK_SEL_R_WIDTH 2 /* DIGMIC_CLK_SEL_R - [5:4] */
575#define WM8903_DIGMIC_CLK_SEL_RT_MASK 0x000C /* DIGMIC_CLK_SEL_RT - [3:2] */
576#define WM8903_DIGMIC_CLK_SEL_RT_SHIFT 2 /* DIGMIC_CLK_SEL_RT - [3:2] */
577#define WM8903_DIGMIC_CLK_SEL_RT_WIDTH 2 /* DIGMIC_CLK_SEL_RT - [3:2] */
578#define WM8903_DIGMIC_CLK_SEL_MASK 0x0003 /* DIGMIC_CLK_SEL - [1:0] */
579#define WM8903_DIGMIC_CLK_SEL_SHIFT 0 /* DIGMIC_CLK_SEL - [1:0] */
580#define WM8903_DIGMIC_CLK_SEL_WIDTH 2 /* DIGMIC_CLK_SEL - [1:0] */
581
582/*
583 * R40 (0x28) - DRC 0
584 */
585#define WM8903_DRC_ENA 0x8000 /* DRC_ENA */
586#define WM8903_DRC_ENA_MASK 0x8000 /* DRC_ENA */
587#define WM8903_DRC_ENA_SHIFT 15 /* DRC_ENA */
588#define WM8903_DRC_ENA_WIDTH 1 /* DRC_ENA */
589#define WM8903_DRC_THRESH_HYST_MASK 0x1800 /* DRC_THRESH_HYST - [12:11] */
590#define WM8903_DRC_THRESH_HYST_SHIFT 11 /* DRC_THRESH_HYST - [12:11] */
591#define WM8903_DRC_THRESH_HYST_WIDTH 2 /* DRC_THRESH_HYST - [12:11] */
592#define WM8903_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */
593#define WM8903_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */
594#define WM8903_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */
595#define WM8903_DRC_FF_DELAY 0x0020 /* DRC_FF_DELAY */
596#define WM8903_DRC_FF_DELAY_MASK 0x0020 /* DRC_FF_DELAY */
597#define WM8903_DRC_FF_DELAY_SHIFT 5 /* DRC_FF_DELAY */
598#define WM8903_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
599#define WM8903_DRC_SMOOTH_ENA 0x0008 /* DRC_SMOOTH_ENA */
600#define WM8903_DRC_SMOOTH_ENA_MASK 0x0008 /* DRC_SMOOTH_ENA */
601#define WM8903_DRC_SMOOTH_ENA_SHIFT 3 /* DRC_SMOOTH_ENA */
602#define WM8903_DRC_SMOOTH_ENA_WIDTH 1 /* DRC_SMOOTH_ENA */
603#define WM8903_DRC_QR_ENA 0x0004 /* DRC_QR_ENA */
604#define WM8903_DRC_QR_ENA_MASK 0x0004 /* DRC_QR_ENA */
605#define WM8903_DRC_QR_ENA_SHIFT 2 /* DRC_QR_ENA */
606#define WM8903_DRC_QR_ENA_WIDTH 1 /* DRC_QR_ENA */
607#define WM8903_DRC_ANTICLIP_ENA 0x0002 /* DRC_ANTICLIP_ENA */
608#define WM8903_DRC_ANTICLIP_ENA_MASK 0x0002 /* DRC_ANTICLIP_ENA */
609#define WM8903_DRC_ANTICLIP_ENA_SHIFT 1 /* DRC_ANTICLIP_ENA */
610#define WM8903_DRC_ANTICLIP_ENA_WIDTH 1 /* DRC_ANTICLIP_ENA */
611#define WM8903_DRC_HYST_ENA 0x0001 /* DRC_HYST_ENA */
612#define WM8903_DRC_HYST_ENA_MASK 0x0001 /* DRC_HYST_ENA */
613#define WM8903_DRC_HYST_ENA_SHIFT 0 /* DRC_HYST_ENA */
614#define WM8903_DRC_HYST_ENA_WIDTH 1 /* DRC_HYST_ENA */
615
616/*
617 * R41 (0x29) - DRC 1
618 */
619#define WM8903_DRC_ATTACK_RATE_MASK 0xF000 /* DRC_ATTACK_RATE - [15:12] */
620#define WM8903_DRC_ATTACK_RATE_SHIFT 12 /* DRC_ATTACK_RATE - [15:12] */
621#define WM8903_DRC_ATTACK_RATE_WIDTH 4 /* DRC_ATTACK_RATE - [15:12] */
622#define WM8903_DRC_DECAY_RATE_MASK 0x0F00 /* DRC_DECAY_RATE - [11:8] */
623#define WM8903_DRC_DECAY_RATE_SHIFT 8 /* DRC_DECAY_RATE - [11:8] */
624#define WM8903_DRC_DECAY_RATE_WIDTH 4 /* DRC_DECAY_RATE - [11:8] */
625#define WM8903_DRC_THRESH_QR_MASK 0x00C0 /* DRC_THRESH_QR - [7:6] */
626#define WM8903_DRC_THRESH_QR_SHIFT 6 /* DRC_THRESH_QR - [7:6] */
627#define WM8903_DRC_THRESH_QR_WIDTH 2 /* DRC_THRESH_QR - [7:6] */
628#define WM8903_DRC_RATE_QR_MASK 0x0030 /* DRC_RATE_QR - [5:4] */
629#define WM8903_DRC_RATE_QR_SHIFT 4 /* DRC_RATE_QR - [5:4] */
630#define WM8903_DRC_RATE_QR_WIDTH 2 /* DRC_RATE_QR - [5:4] */
631#define WM8903_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
632#define WM8903_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
633#define WM8903_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
634#define WM8903_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
635#define WM8903_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
636#define WM8903_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
637
638/*
639 * R42 (0x2A) - DRC 2
640 */
641#define WM8903_DRC_R0_SLOPE_COMP_MASK 0x0038 /* DRC_R0_SLOPE_COMP - [5:3] */
642#define WM8903_DRC_R0_SLOPE_COMP_SHIFT 3 /* DRC_R0_SLOPE_COMP - [5:3] */
643#define WM8903_DRC_R0_SLOPE_COMP_WIDTH 3 /* DRC_R0_SLOPE_COMP - [5:3] */
644#define WM8903_DRC_R1_SLOPE_COMP_MASK 0x0007 /* DRC_R1_SLOPE_COMP - [2:0] */
645#define WM8903_DRC_R1_SLOPE_COMP_SHIFT 0 /* DRC_R1_SLOPE_COMP - [2:0] */
646#define WM8903_DRC_R1_SLOPE_COMP_WIDTH 3 /* DRC_R1_SLOPE_COMP - [2:0] */
647
648/*
649 * R43 (0x2B) - DRC 3
650 */
651#define WM8903_DRC_THRESH_COMP_MASK 0x07E0 /* DRC_THRESH_COMP - [10:5] */
652#define WM8903_DRC_THRESH_COMP_SHIFT 5 /* DRC_THRESH_COMP - [10:5] */
653#define WM8903_DRC_THRESH_COMP_WIDTH 6 /* DRC_THRESH_COMP - [10:5] */
654#define WM8903_DRC_AMP_COMP_MASK 0x001F /* DRC_AMP_COMP - [4:0] */
655#define WM8903_DRC_AMP_COMP_SHIFT 0 /* DRC_AMP_COMP - [4:0] */
656#define WM8903_DRC_AMP_COMP_WIDTH 5 /* DRC_AMP_COMP - [4:0] */
657
658/*
659 * R44 (0x2C) - Analogue Left Input 0
660 */
661#define WM8903_LINMUTE 0x0080 /* LINMUTE */
662#define WM8903_LINMUTE_MASK 0x0080 /* LINMUTE */
663#define WM8903_LINMUTE_SHIFT 7 /* LINMUTE */
664#define WM8903_LINMUTE_WIDTH 1 /* LINMUTE */
665#define WM8903_LIN_VOL_MASK 0x001F /* LIN_VOL - [4:0] */
666#define WM8903_LIN_VOL_SHIFT 0 /* LIN_VOL - [4:0] */
667#define WM8903_LIN_VOL_WIDTH 5 /* LIN_VOL - [4:0] */
668
669/*
670 * R45 (0x2D) - Analogue Right Input 0
671 */
672#define WM8903_RINMUTE 0x0080 /* RINMUTE */
673#define WM8903_RINMUTE_MASK 0x0080 /* RINMUTE */
674#define WM8903_RINMUTE_SHIFT 7 /* RINMUTE */
675#define WM8903_RINMUTE_WIDTH 1 /* RINMUTE */
676#define WM8903_RIN_VOL_MASK 0x001F /* RIN_VOL - [4:0] */
677#define WM8903_RIN_VOL_SHIFT 0 /* RIN_VOL - [4:0] */
678#define WM8903_RIN_VOL_WIDTH 5 /* RIN_VOL - [4:0] */
679
680/*
681 * R46 (0x2E) - Analogue Left Input 1
682 */
683#define WM8903_INL_CM_ENA 0x0040 /* INL_CM_ENA */
684#define WM8903_INL_CM_ENA_MASK 0x0040 /* INL_CM_ENA */
685#define WM8903_INL_CM_ENA_SHIFT 6 /* INL_CM_ENA */
686#define WM8903_INL_CM_ENA_WIDTH 1 /* INL_CM_ENA */
687#define WM8903_L_IP_SEL_N_MASK 0x0030 /* L_IP_SEL_N - [5:4] */
688#define WM8903_L_IP_SEL_N_SHIFT 4 /* L_IP_SEL_N - [5:4] */
689#define WM8903_L_IP_SEL_N_WIDTH 2 /* L_IP_SEL_N - [5:4] */
690#define WM8903_L_IP_SEL_P_MASK 0x000C /* L_IP_SEL_P - [3:2] */
691#define WM8903_L_IP_SEL_P_SHIFT 2 /* L_IP_SEL_P - [3:2] */
692#define WM8903_L_IP_SEL_P_WIDTH 2 /* L_IP_SEL_P - [3:2] */
693#define WM8903_L_MODE_MASK 0x0003 /* L_MODE - [1:0] */
694#define WM8903_L_MODE_SHIFT 0 /* L_MODE - [1:0] */
695#define WM8903_L_MODE_WIDTH 2 /* L_MODE - [1:0] */
696
697/*
698 * R47 (0x2F) - Analogue Right Input 1
699 */
700#define WM8903_INR_CM_ENA 0x0040 /* INR_CM_ENA */
701#define WM8903_INR_CM_ENA_MASK 0x0040 /* INR_CM_ENA */
702#define WM8903_INR_CM_ENA_SHIFT 6 /* INR_CM_ENA */
703#define WM8903_INR_CM_ENA_WIDTH 1 /* INR_CM_ENA */
704#define WM8903_R_IP_SEL_N_MASK 0x0030 /* R_IP_SEL_N - [5:4] */
705#define WM8903_R_IP_SEL_N_SHIFT 4 /* R_IP_SEL_N - [5:4] */
706#define WM8903_R_IP_SEL_N_WIDTH 2 /* R_IP_SEL_N - [5:4] */
707#define WM8903_R_IP_SEL_P_MASK 0x000C /* R_IP_SEL_P - [3:2] */
708#define WM8903_R_IP_SEL_P_SHIFT 2 /* R_IP_SEL_P - [3:2] */
709#define WM8903_R_IP_SEL_P_WIDTH 2 /* R_IP_SEL_P - [3:2] */
710#define WM8903_R_MODE_MASK 0x0003 /* R_MODE - [1:0] */
711#define WM8903_R_MODE_SHIFT 0 /* R_MODE - [1:0] */
712#define WM8903_R_MODE_WIDTH 2 /* R_MODE - [1:0] */
713
714/*
715 * R50 (0x32) - Analogue Left Mix 0
716 */
717#define WM8903_DACL_TO_MIXOUTL 0x0008 /* DACL_TO_MIXOUTL */
718#define WM8903_DACL_TO_MIXOUTL_MASK 0x0008 /* DACL_TO_MIXOUTL */
719#define WM8903_DACL_TO_MIXOUTL_SHIFT 3 /* DACL_TO_MIXOUTL */
720#define WM8903_DACL_TO_MIXOUTL_WIDTH 1 /* DACL_TO_MIXOUTL */
721#define WM8903_DACR_TO_MIXOUTL 0x0004 /* DACR_TO_MIXOUTL */
722#define WM8903_DACR_TO_MIXOUTL_MASK 0x0004 /* DACR_TO_MIXOUTL */
723#define WM8903_DACR_TO_MIXOUTL_SHIFT 2 /* DACR_TO_MIXOUTL */
724#define WM8903_DACR_TO_MIXOUTL_WIDTH 1 /* DACR_TO_MIXOUTL */
725#define WM8903_BYPASSL_TO_MIXOUTL 0x0002 /* BYPASSL_TO_MIXOUTL */
726#define WM8903_BYPASSL_TO_MIXOUTL_MASK 0x0002 /* BYPASSL_TO_MIXOUTL */
727#define WM8903_BYPASSL_TO_MIXOUTL_SHIFT 1 /* BYPASSL_TO_MIXOUTL */
728#define WM8903_BYPASSL_TO_MIXOUTL_WIDTH 1 /* BYPASSL_TO_MIXOUTL */
729#define WM8903_BYPASSR_TO_MIXOUTL 0x0001 /* BYPASSR_TO_MIXOUTL */
730#define WM8903_BYPASSR_TO_MIXOUTL_MASK 0x0001 /* BYPASSR_TO_MIXOUTL */
731#define WM8903_BYPASSR_TO_MIXOUTL_SHIFT 0 /* BYPASSR_TO_MIXOUTL */
732#define WM8903_BYPASSR_TO_MIXOUTL_WIDTH 1 /* BYPASSR_TO_MIXOUTL */
733
734/*
735 * R51 (0x33) - Analogue Right Mix 0
736 */
737#define WM8903_DACL_TO_MIXOUTR 0x0008 /* DACL_TO_MIXOUTR */
738#define WM8903_DACL_TO_MIXOUTR_MASK 0x0008 /* DACL_TO_MIXOUTR */
739#define WM8903_DACL_TO_MIXOUTR_SHIFT 3 /* DACL_TO_MIXOUTR */
740#define WM8903_DACL_TO_MIXOUTR_WIDTH 1 /* DACL_TO_MIXOUTR */
741#define WM8903_DACR_TO_MIXOUTR 0x0004 /* DACR_TO_MIXOUTR */
742#define WM8903_DACR_TO_MIXOUTR_MASK 0x0004 /* DACR_TO_MIXOUTR */
743#define WM8903_DACR_TO_MIXOUTR_SHIFT 2 /* DACR_TO_MIXOUTR */
744#define WM8903_DACR_TO_MIXOUTR_WIDTH 1 /* DACR_TO_MIXOUTR */
745#define WM8903_BYPASSL_TO_MIXOUTR 0x0002 /* BYPASSL_TO_MIXOUTR */
746#define WM8903_BYPASSL_TO_MIXOUTR_MASK 0x0002 /* BYPASSL_TO_MIXOUTR */
747#define WM8903_BYPASSL_TO_MIXOUTR_SHIFT 1 /* BYPASSL_TO_MIXOUTR */
748#define WM8903_BYPASSL_TO_MIXOUTR_WIDTH 1 /* BYPASSL_TO_MIXOUTR */
749#define WM8903_BYPASSR_TO_MIXOUTR 0x0001 /* BYPASSR_TO_MIXOUTR */
750#define WM8903_BYPASSR_TO_MIXOUTR_MASK 0x0001 /* BYPASSR_TO_MIXOUTR */
751#define WM8903_BYPASSR_TO_MIXOUTR_SHIFT 0 /* BYPASSR_TO_MIXOUTR */
752#define WM8903_BYPASSR_TO_MIXOUTR_WIDTH 1 /* BYPASSR_TO_MIXOUTR */
753
754/*
755 * R52 (0x34) - Analogue Spk Mix Left 0
756 */
757#define WM8903_DACL_TO_MIXSPKL 0x0008 /* DACL_TO_MIXSPKL */
758#define WM8903_DACL_TO_MIXSPKL_MASK 0x0008 /* DACL_TO_MIXSPKL */
759#define WM8903_DACL_TO_MIXSPKL_SHIFT 3 /* DACL_TO_MIXSPKL */
760#define WM8903_DACL_TO_MIXSPKL_WIDTH 1 /* DACL_TO_MIXSPKL */
761#define WM8903_DACR_TO_MIXSPKL 0x0004 /* DACR_TO_MIXSPKL */
762#define WM8903_DACR_TO_MIXSPKL_MASK 0x0004 /* DACR_TO_MIXSPKL */
763#define WM8903_DACR_TO_MIXSPKL_SHIFT 2 /* DACR_TO_MIXSPKL */
764#define WM8903_DACR_TO_MIXSPKL_WIDTH 1 /* DACR_TO_MIXSPKL */
765#define WM8903_BYPASSL_TO_MIXSPKL 0x0002 /* BYPASSL_TO_MIXSPKL */
766#define WM8903_BYPASSL_TO_MIXSPKL_MASK 0x0002 /* BYPASSL_TO_MIXSPKL */
767#define WM8903_BYPASSL_TO_MIXSPKL_SHIFT 1 /* BYPASSL_TO_MIXSPKL */
768#define WM8903_BYPASSL_TO_MIXSPKL_WIDTH 1 /* BYPASSL_TO_MIXSPKL */
769#define WM8903_BYPASSR_TO_MIXSPKL 0x0001 /* BYPASSR_TO_MIXSPKL */
770#define WM8903_BYPASSR_TO_MIXSPKL_MASK 0x0001 /* BYPASSR_TO_MIXSPKL */
771#define WM8903_BYPASSR_TO_MIXSPKL_SHIFT 0 /* BYPASSR_TO_MIXSPKL */
772#define WM8903_BYPASSR_TO_MIXSPKL_WIDTH 1 /* BYPASSR_TO_MIXSPKL */
773
774/*
775 * R53 (0x35) - Analogue Spk Mix Left 1
776 */
777#define WM8903_DACL_MIXSPKL_VOL 0x0008 /* DACL_MIXSPKL_VOL */
778#define WM8903_DACL_MIXSPKL_VOL_MASK 0x0008 /* DACL_MIXSPKL_VOL */
779#define WM8903_DACL_MIXSPKL_VOL_SHIFT 3 /* DACL_MIXSPKL_VOL */
780#define WM8903_DACL_MIXSPKL_VOL_WIDTH 1 /* DACL_MIXSPKL_VOL */
781#define WM8903_DACR_MIXSPKL_VOL 0x0004 /* DACR_MIXSPKL_VOL */
782#define WM8903_DACR_MIXSPKL_VOL_MASK 0x0004 /* DACR_MIXSPKL_VOL */
783#define WM8903_DACR_MIXSPKL_VOL_SHIFT 2 /* DACR_MIXSPKL_VOL */
784#define WM8903_DACR_MIXSPKL_VOL_WIDTH 1 /* DACR_MIXSPKL_VOL */
785#define WM8903_BYPASSL_MIXSPKL_VOL 0x0002 /* BYPASSL_MIXSPKL_VOL */
786#define WM8903_BYPASSL_MIXSPKL_VOL_MASK 0x0002 /* BYPASSL_MIXSPKL_VOL */
787#define WM8903_BYPASSL_MIXSPKL_VOL_SHIFT 1 /* BYPASSL_MIXSPKL_VOL */
788#define WM8903_BYPASSL_MIXSPKL_VOL_WIDTH 1 /* BYPASSL_MIXSPKL_VOL */
789#define WM8903_BYPASSR_MIXSPKL_VOL 0x0001 /* BYPASSR_MIXSPKL_VOL */
790#define WM8903_BYPASSR_MIXSPKL_VOL_MASK 0x0001 /* BYPASSR_MIXSPKL_VOL */
791#define WM8903_BYPASSR_MIXSPKL_VOL_SHIFT 0 /* BYPASSR_MIXSPKL_VOL */
792#define WM8903_BYPASSR_MIXSPKL_VOL_WIDTH 1 /* BYPASSR_MIXSPKL_VOL */
793
794/*
795 * R54 (0x36) - Analogue Spk Mix Right 0
796 */
797#define WM8903_DACL_TO_MIXSPKR 0x0008 /* DACL_TO_MIXSPKR */
798#define WM8903_DACL_TO_MIXSPKR_MASK 0x0008 /* DACL_TO_MIXSPKR */
799#define WM8903_DACL_TO_MIXSPKR_SHIFT 3 /* DACL_TO_MIXSPKR */
800#define WM8903_DACL_TO_MIXSPKR_WIDTH 1 /* DACL_TO_MIXSPKR */
801#define WM8903_DACR_TO_MIXSPKR 0x0004 /* DACR_TO_MIXSPKR */
802#define WM8903_DACR_TO_MIXSPKR_MASK 0x0004 /* DACR_TO_MIXSPKR */
803#define WM8903_DACR_TO_MIXSPKR_SHIFT 2 /* DACR_TO_MIXSPKR */
804#define WM8903_DACR_TO_MIXSPKR_WIDTH 1 /* DACR_TO_MIXSPKR */
805#define WM8903_BYPASSL_TO_MIXSPKR 0x0002 /* BYPASSL_TO_MIXSPKR */
806#define WM8903_BYPASSL_TO_MIXSPKR_MASK 0x0002 /* BYPASSL_TO_MIXSPKR */
807#define WM8903_BYPASSL_TO_MIXSPKR_SHIFT 1 /* BYPASSL_TO_MIXSPKR */
808#define WM8903_BYPASSL_TO_MIXSPKR_WIDTH 1 /* BYPASSL_TO_MIXSPKR */
809#define WM8903_BYPASSR_TO_MIXSPKR 0x0001 /* BYPASSR_TO_MIXSPKR */
810#define WM8903_BYPASSR_TO_MIXSPKR_MASK 0x0001 /* BYPASSR_TO_MIXSPKR */
811#define WM8903_BYPASSR_TO_MIXSPKR_SHIFT 0 /* BYPASSR_TO_MIXSPKR */
812#define WM8903_BYPASSR_TO_MIXSPKR_WIDTH 1 /* BYPASSR_TO_MIXSPKR */
813
814/*
815 * R55 (0x37) - Analogue Spk Mix Right 1
816 */
817#define WM8903_DACL_MIXSPKR_VOL 0x0008 /* DACL_MIXSPKR_VOL */
818#define WM8903_DACL_MIXSPKR_VOL_MASK 0x0008 /* DACL_MIXSPKR_VOL */
819#define WM8903_DACL_MIXSPKR_VOL_SHIFT 3 /* DACL_MIXSPKR_VOL */
820#define WM8903_DACL_MIXSPKR_VOL_WIDTH 1 /* DACL_MIXSPKR_VOL */
821#define WM8903_DACR_MIXSPKR_VOL 0x0004 /* DACR_MIXSPKR_VOL */
822#define WM8903_DACR_MIXSPKR_VOL_MASK 0x0004 /* DACR_MIXSPKR_VOL */
823#define WM8903_DACR_MIXSPKR_VOL_SHIFT 2 /* DACR_MIXSPKR_VOL */
824#define WM8903_DACR_MIXSPKR_VOL_WIDTH 1 /* DACR_MIXSPKR_VOL */
825#define WM8903_BYPASSL_MIXSPKR_VOL 0x0002 /* BYPASSL_MIXSPKR_VOL */
826#define WM8903_BYPASSL_MIXSPKR_VOL_MASK 0x0002 /* BYPASSL_MIXSPKR_VOL */
827#define WM8903_BYPASSL_MIXSPKR_VOL_SHIFT 1 /* BYPASSL_MIXSPKR_VOL */
828#define WM8903_BYPASSL_MIXSPKR_VOL_WIDTH 1 /* BYPASSL_MIXSPKR_VOL */
829#define WM8903_BYPASSR_MIXSPKR_VOL 0x0001 /* BYPASSR_MIXSPKR_VOL */
830#define WM8903_BYPASSR_MIXSPKR_VOL_MASK 0x0001 /* BYPASSR_MIXSPKR_VOL */
831#define WM8903_BYPASSR_MIXSPKR_VOL_SHIFT 0 /* BYPASSR_MIXSPKR_VOL */
832#define WM8903_BYPASSR_MIXSPKR_VOL_WIDTH 1 /* BYPASSR_MIXSPKR_VOL */
833
834/*
835 * R57 (0x39) - Analogue OUT1 Left
836 */
837#define WM8903_HPL_MUTE 0x0100 /* HPL_MUTE */
838#define WM8903_HPL_MUTE_MASK 0x0100 /* HPL_MUTE */
839#define WM8903_HPL_MUTE_SHIFT 8 /* HPL_MUTE */
840#define WM8903_HPL_MUTE_WIDTH 1 /* HPL_MUTE */
841#define WM8903_HPOUTVU 0x0080 /* HPOUTVU */
842#define WM8903_HPOUTVU_MASK 0x0080 /* HPOUTVU */
843#define WM8903_HPOUTVU_SHIFT 7 /* HPOUTVU */
844#define WM8903_HPOUTVU_WIDTH 1 /* HPOUTVU */
845#define WM8903_HPOUTLZC 0x0040 /* HPOUTLZC */
846#define WM8903_HPOUTLZC_MASK 0x0040 /* HPOUTLZC */
847#define WM8903_HPOUTLZC_SHIFT 6 /* HPOUTLZC */
848#define WM8903_HPOUTLZC_WIDTH 1 /* HPOUTLZC */
849#define WM8903_HPOUTL_VOL_MASK 0x003F /* HPOUTL_VOL - [5:0] */
850#define WM8903_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [5:0] */
851#define WM8903_HPOUTL_VOL_WIDTH 6 /* HPOUTL_VOL - [5:0] */
852
853/*
854 * R58 (0x3A) - Analogue OUT1 Right
855 */
856#define WM8903_HPR_MUTE 0x0100 /* HPR_MUTE */
857#define WM8903_HPR_MUTE_MASK 0x0100 /* HPR_MUTE */
858#define WM8903_HPR_MUTE_SHIFT 8 /* HPR_MUTE */
859#define WM8903_HPR_MUTE_WIDTH 1 /* HPR_MUTE */
860#define WM8903_HPOUTVU 0x0080 /* HPOUTVU */
861#define WM8903_HPOUTVU_MASK 0x0080 /* HPOUTVU */
862#define WM8903_HPOUTVU_SHIFT 7 /* HPOUTVU */
863#define WM8903_HPOUTVU_WIDTH 1 /* HPOUTVU */
864#define WM8903_HPOUTRZC 0x0040 /* HPOUTRZC */
865#define WM8903_HPOUTRZC_MASK 0x0040 /* HPOUTRZC */
866#define WM8903_HPOUTRZC_SHIFT 6 /* HPOUTRZC */
867#define WM8903_HPOUTRZC_WIDTH 1 /* HPOUTRZC */
868#define WM8903_HPOUTR_VOL_MASK 0x003F /* HPOUTR_VOL - [5:0] */
869#define WM8903_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [5:0] */
870#define WM8903_HPOUTR_VOL_WIDTH 6 /* HPOUTR_VOL - [5:0] */
871
872/*
873 * R59 (0x3B) - Analogue OUT2 Left
874 */
875#define WM8903_LINEOUTL_MUTE 0x0100 /* LINEOUTL_MUTE */
876#define WM8903_LINEOUTL_MUTE_MASK 0x0100 /* LINEOUTL_MUTE */
877#define WM8903_LINEOUTL_MUTE_SHIFT 8 /* LINEOUTL_MUTE */
878#define WM8903_LINEOUTL_MUTE_WIDTH 1 /* LINEOUTL_MUTE */
879#define WM8903_LINEOUTVU 0x0080 /* LINEOUTVU */
880#define WM8903_LINEOUTVU_MASK 0x0080 /* LINEOUTVU */
881#define WM8903_LINEOUTVU_SHIFT 7 /* LINEOUTVU */
882#define WM8903_LINEOUTVU_WIDTH 1 /* LINEOUTVU */
883#define WM8903_LINEOUTLZC 0x0040 /* LINEOUTLZC */
884#define WM8903_LINEOUTLZC_MASK 0x0040 /* LINEOUTLZC */
885#define WM8903_LINEOUTLZC_SHIFT 6 /* LINEOUTLZC */
886#define WM8903_LINEOUTLZC_WIDTH 1 /* LINEOUTLZC */
887#define WM8903_LINEOUTL_VOL_MASK 0x003F /* LINEOUTL_VOL - [5:0] */
888#define WM8903_LINEOUTL_VOL_SHIFT 0 /* LINEOUTL_VOL - [5:0] */
889#define WM8903_LINEOUTL_VOL_WIDTH 6 /* LINEOUTL_VOL - [5:0] */
890
891/*
892 * R60 (0x3C) - Analogue OUT2 Right
893 */
894#define WM8903_LINEOUTR_MUTE 0x0100 /* LINEOUTR_MUTE */
895#define WM8903_LINEOUTR_MUTE_MASK 0x0100 /* LINEOUTR_MUTE */
896#define WM8903_LINEOUTR_MUTE_SHIFT 8 /* LINEOUTR_MUTE */
897#define WM8903_LINEOUTR_MUTE_WIDTH 1 /* LINEOUTR_MUTE */
898#define WM8903_LINEOUTVU 0x0080 /* LINEOUTVU */
899#define WM8903_LINEOUTVU_MASK 0x0080 /* LINEOUTVU */
900#define WM8903_LINEOUTVU_SHIFT 7 /* LINEOUTVU */
901#define WM8903_LINEOUTVU_WIDTH 1 /* LINEOUTVU */
902#define WM8903_LINEOUTRZC 0x0040 /* LINEOUTRZC */
903#define WM8903_LINEOUTRZC_MASK 0x0040 /* LINEOUTRZC */
904#define WM8903_LINEOUTRZC_SHIFT 6 /* LINEOUTRZC */
905#define WM8903_LINEOUTRZC_WIDTH 1 /* LINEOUTRZC */
906#define WM8903_LINEOUTR_VOL_MASK 0x003F /* LINEOUTR_VOL - [5:0] */
907#define WM8903_LINEOUTR_VOL_SHIFT 0 /* LINEOUTR_VOL - [5:0] */
908#define WM8903_LINEOUTR_VOL_WIDTH 6 /* LINEOUTR_VOL - [5:0] */
909
910/*
911 * R62 (0x3E) - Analogue OUT3 Left
912 */
913#define WM8903_SPKL_MUTE 0x0100 /* SPKL_MUTE */
914#define WM8903_SPKL_MUTE_MASK 0x0100 /* SPKL_MUTE */
915#define WM8903_SPKL_MUTE_SHIFT 8 /* SPKL_MUTE */
916#define WM8903_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */
917#define WM8903_SPKVU 0x0080 /* SPKVU */
918#define WM8903_SPKVU_MASK 0x0080 /* SPKVU */
919#define WM8903_SPKVU_SHIFT 7 /* SPKVU */
920#define WM8903_SPKVU_WIDTH 1 /* SPKVU */
921#define WM8903_SPKLZC 0x0040 /* SPKLZC */
922#define WM8903_SPKLZC_MASK 0x0040 /* SPKLZC */
923#define WM8903_SPKLZC_SHIFT 6 /* SPKLZC */
924#define WM8903_SPKLZC_WIDTH 1 /* SPKLZC */
925#define WM8903_SPKL_VOL_MASK 0x003F /* SPKL_VOL - [5:0] */
926#define WM8903_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [5:0] */
927#define WM8903_SPKL_VOL_WIDTH 6 /* SPKL_VOL - [5:0] */
928
929/*
930 * R63 (0x3F) - Analogue OUT3 Right
931 */
932#define WM8903_SPKR_MUTE 0x0100 /* SPKR_MUTE */
933#define WM8903_SPKR_MUTE_MASK 0x0100 /* SPKR_MUTE */
934#define WM8903_SPKR_MUTE_SHIFT 8 /* SPKR_MUTE */
935#define WM8903_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */
936#define WM8903_SPKVU 0x0080 /* SPKVU */
937#define WM8903_SPKVU_MASK 0x0080 /* SPKVU */
938#define WM8903_SPKVU_SHIFT 7 /* SPKVU */
939#define WM8903_SPKVU_WIDTH 1 /* SPKVU */
940#define WM8903_SPKRZC 0x0040 /* SPKRZC */
941#define WM8903_SPKRZC_MASK 0x0040 /* SPKRZC */
942#define WM8903_SPKRZC_SHIFT 6 /* SPKRZC */
943#define WM8903_SPKRZC_WIDTH 1 /* SPKRZC */
944#define WM8903_SPKR_VOL_MASK 0x003F /* SPKR_VOL - [5:0] */
945#define WM8903_SPKR_VOL_SHIFT 0 /* SPKR_VOL - [5:0] */
946#define WM8903_SPKR_VOL_WIDTH 6 /* SPKR_VOL - [5:0] */
947
948/*
949 * R65 (0x41) - Analogue SPK Output Control 0
950 */
951#define WM8903_SPK_DISCHARGE 0x0002 /* SPK_DISCHARGE */
952#define WM8903_SPK_DISCHARGE_MASK 0x0002 /* SPK_DISCHARGE */
953#define WM8903_SPK_DISCHARGE_SHIFT 1 /* SPK_DISCHARGE */
954#define WM8903_SPK_DISCHARGE_WIDTH 1 /* SPK_DISCHARGE */
955#define WM8903_VROI 0x0001 /* VROI */
956#define WM8903_VROI_MASK 0x0001 /* VROI */
957#define WM8903_VROI_SHIFT 0 /* VROI */
958#define WM8903_VROI_WIDTH 1 /* VROI */
959
960/*
961 * R67 (0x43) - DC Servo 0
962 */
963#define WM8903_DCS_MASTER_ENA 0x0010 /* DCS_MASTER_ENA */
964#define WM8903_DCS_MASTER_ENA_MASK 0x0010 /* DCS_MASTER_ENA */
965#define WM8903_DCS_MASTER_ENA_SHIFT 4 /* DCS_MASTER_ENA */
966#define WM8903_DCS_MASTER_ENA_WIDTH 1 /* DCS_MASTER_ENA */
967#define WM8903_DCS_ENA_MASK 0x000F /* DCS_ENA - [3:0] */
968#define WM8903_DCS_ENA_SHIFT 0 /* DCS_ENA - [3:0] */
969#define WM8903_DCS_ENA_WIDTH 4 /* DCS_ENA - [3:0] */
970
971/*
972 * R69 (0x45) - DC Servo 2
973 */
974#define WM8903_DCS_MODE_MASK 0x0003 /* DCS_MODE - [1:0] */
975#define WM8903_DCS_MODE_SHIFT 0 /* DCS_MODE - [1:0] */
976#define WM8903_DCS_MODE_WIDTH 2 /* DCS_MODE - [1:0] */
977
978/*
979 * R90 (0x5A) - Analogue HP 0
980 */
981#define WM8903_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
982#define WM8903_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
983#define WM8903_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
984#define WM8903_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
985#define WM8903_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
986#define WM8903_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
987#define WM8903_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
988#define WM8903_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
989#define WM8903_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
990#define WM8903_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
991#define WM8903_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
992#define WM8903_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
993#define WM8903_HPL_ENA 0x0010 /* HPL_ENA */
994#define WM8903_HPL_ENA_MASK 0x0010 /* HPL_ENA */
995#define WM8903_HPL_ENA_SHIFT 4 /* HPL_ENA */
996#define WM8903_HPL_ENA_WIDTH 1 /* HPL_ENA */
997#define WM8903_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
998#define WM8903_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
999#define WM8903_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
1000#define WM8903_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
1001#define WM8903_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
1002#define WM8903_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
1003#define WM8903_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
1004#define WM8903_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
1005#define WM8903_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
1006#define WM8903_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
1007#define WM8903_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
1008#define WM8903_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
1009#define WM8903_HPR_ENA 0x0001 /* HPR_ENA */
1010#define WM8903_HPR_ENA_MASK 0x0001 /* HPR_ENA */
1011#define WM8903_HPR_ENA_SHIFT 0 /* HPR_ENA */
1012#define WM8903_HPR_ENA_WIDTH 1 /* HPR_ENA */
1013
1014/*
1015 * R94 (0x5E) - Analogue Lineout 0
1016 */
1017#define WM8903_LINEOUTL_RMV_SHORT 0x0080 /* LINEOUTL_RMV_SHORT */
1018#define WM8903_LINEOUTL_RMV_SHORT_MASK 0x0080 /* LINEOUTL_RMV_SHORT */
1019#define WM8903_LINEOUTL_RMV_SHORT_SHIFT 7 /* LINEOUTL_RMV_SHORT */
1020#define WM8903_LINEOUTL_RMV_SHORT_WIDTH 1 /* LINEOUTL_RMV_SHORT */
1021#define WM8903_LINEOUTL_ENA_OUTP 0x0040 /* LINEOUTL_ENA_OUTP */
1022#define WM8903_LINEOUTL_ENA_OUTP_MASK 0x0040 /* LINEOUTL_ENA_OUTP */
1023#define WM8903_LINEOUTL_ENA_OUTP_SHIFT 6 /* LINEOUTL_ENA_OUTP */
1024#define WM8903_LINEOUTL_ENA_OUTP_WIDTH 1 /* LINEOUTL_ENA_OUTP */
1025#define WM8903_LINEOUTL_ENA_DLY 0x0020 /* LINEOUTL_ENA_DLY */
1026#define WM8903_LINEOUTL_ENA_DLY_MASK 0x0020 /* LINEOUTL_ENA_DLY */
1027#define WM8903_LINEOUTL_ENA_DLY_SHIFT 5 /* LINEOUTL_ENA_DLY */
1028#define WM8903_LINEOUTL_ENA_DLY_WIDTH 1 /* LINEOUTL_ENA_DLY */
1029#define WM8903_LINEOUTL_ENA 0x0010 /* LINEOUTL_ENA */
1030#define WM8903_LINEOUTL_ENA_MASK 0x0010 /* LINEOUTL_ENA */
1031#define WM8903_LINEOUTL_ENA_SHIFT 4 /* LINEOUTL_ENA */
1032#define WM8903_LINEOUTL_ENA_WIDTH 1 /* LINEOUTL_ENA */
1033#define WM8903_LINEOUTR_RMV_SHORT 0x0008 /* LINEOUTR_RMV_SHORT */
1034#define WM8903_LINEOUTR_RMV_SHORT_MASK 0x0008 /* LINEOUTR_RMV_SHORT */
1035#define WM8903_LINEOUTR_RMV_SHORT_SHIFT 3 /* LINEOUTR_RMV_SHORT */
1036#define WM8903_LINEOUTR_RMV_SHORT_WIDTH 1 /* LINEOUTR_RMV_SHORT */
1037#define WM8903_LINEOUTR_ENA_OUTP 0x0004 /* LINEOUTR_ENA_OUTP */
1038#define WM8903_LINEOUTR_ENA_OUTP_MASK 0x0004 /* LINEOUTR_ENA_OUTP */
1039#define WM8903_LINEOUTR_ENA_OUTP_SHIFT 2 /* LINEOUTR_ENA_OUTP */
1040#define WM8903_LINEOUTR_ENA_OUTP_WIDTH 1 /* LINEOUTR_ENA_OUTP */
1041#define WM8903_LINEOUTR_ENA_DLY 0x0002 /* LINEOUTR_ENA_DLY */
1042#define WM8903_LINEOUTR_ENA_DLY_MASK 0x0002 /* LINEOUTR_ENA_DLY */
1043#define WM8903_LINEOUTR_ENA_DLY_SHIFT 1 /* LINEOUTR_ENA_DLY */
1044#define WM8903_LINEOUTR_ENA_DLY_WIDTH 1 /* LINEOUTR_ENA_DLY */
1045#define WM8903_LINEOUTR_ENA 0x0001 /* LINEOUTR_ENA */
1046#define WM8903_LINEOUTR_ENA_MASK 0x0001 /* LINEOUTR_ENA */
1047#define WM8903_LINEOUTR_ENA_SHIFT 0 /* LINEOUTR_ENA */
1048#define WM8903_LINEOUTR_ENA_WIDTH 1 /* LINEOUTR_ENA */
1049
1050/*
1051 * R98 (0x62) - Charge Pump 0
1052 */
1053#define WM8903_CP_ENA 0x0001 /* CP_ENA */
1054#define WM8903_CP_ENA_MASK 0x0001 /* CP_ENA */
1055#define WM8903_CP_ENA_SHIFT 0 /* CP_ENA */
1056#define WM8903_CP_ENA_WIDTH 1 /* CP_ENA */
1057
1058/*
1059 * R104 (0x68) - Class W 0
1060 */
1061#define WM8903_CP_DYN_FREQ 0x0002 /* CP_DYN_FREQ */
1062#define WM8903_CP_DYN_FREQ_MASK 0x0002 /* CP_DYN_FREQ */
1063#define WM8903_CP_DYN_FREQ_SHIFT 1 /* CP_DYN_FREQ */
1064#define WM8903_CP_DYN_FREQ_WIDTH 1 /* CP_DYN_FREQ */
1065#define WM8903_CP_DYN_V 0x0001 /* CP_DYN_V */
1066#define WM8903_CP_DYN_V_MASK 0x0001 /* CP_DYN_V */
1067#define WM8903_CP_DYN_V_SHIFT 0 /* CP_DYN_V */
1068#define WM8903_CP_DYN_V_WIDTH 1 /* CP_DYN_V */
1069
1070/*
1071 * R108 (0x6C) - Write Sequencer 0
1072 */
1073#define WM8903_WSEQ_ENA 0x0100 /* WSEQ_ENA */
1074#define WM8903_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
1075#define WM8903_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
1076#define WM8903_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1077#define WM8903_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
1078#define WM8903_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
1079#define WM8903_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
1080
1081/*
1082 * R109 (0x6D) - Write Sequencer 1
1083 */
1084#define WM8903_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
1085#define WM8903_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
1086#define WM8903_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
1087#define WM8903_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
1088#define WM8903_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
1089#define WM8903_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
1090#define WM8903_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
1091#define WM8903_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
1092#define WM8903_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
1093
1094/*
1095 * R110 (0x6E) - Write Sequencer 2
1096 */
1097#define WM8903_WSEQ_EOS 0x4000 /* WSEQ_EOS */
1098#define WM8903_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
1099#define WM8903_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
1100#define WM8903_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
1101#define WM8903_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
1102#define WM8903_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
1103#define WM8903_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
1104#define WM8903_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
1105#define WM8903_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
1106#define WM8903_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
1107
1108/*
1109 * R111 (0x6F) - Write Sequencer 3
1110 */
1111#define WM8903_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1112#define WM8903_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1113#define WM8903_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1114#define WM8903_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1115#define WM8903_WSEQ_START 0x0100 /* WSEQ_START */
1116#define WM8903_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1117#define WM8903_WSEQ_START_SHIFT 8 /* WSEQ_START */
1118#define WM8903_WSEQ_START_WIDTH 1 /* WSEQ_START */
1119#define WM8903_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
1120#define WM8903_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
1121#define WM8903_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
1122
1123/*
1124 * R112 (0x70) - Write Sequencer 4
1125 */
1126#define WM8903_WSEQ_CURRENT_INDEX_MASK 0x03F0 /* WSEQ_CURRENT_INDEX - [9:4] */
1127#define WM8903_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [9:4] */
1128#define WM8903_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [9:4] */
1129#define WM8903_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
1130#define WM8903_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
1131#define WM8903_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
1132#define WM8903_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1133
1134/*
1135 * R114 (0x72) - Control Interface
1136 */
1137#define WM8903_MASK_WRITE_ENA 0x0001 /* MASK_WRITE_ENA */
1138#define WM8903_MASK_WRITE_ENA_MASK 0x0001 /* MASK_WRITE_ENA */
1139#define WM8903_MASK_WRITE_ENA_SHIFT 0 /* MASK_WRITE_ENA */
1140#define WM8903_MASK_WRITE_ENA_WIDTH 1 /* MASK_WRITE_ENA */
1141
1142/*
1143 * R116 (0x74) - GPIO Control 1
1144 */
1145#define WM8903_GP1_FN_MASK 0x1F00 /* GP1_FN - [12:8] */
1146#define WM8903_GP1_FN_SHIFT 8 /* GP1_FN - [12:8] */
1147#define WM8903_GP1_FN_WIDTH 5 /* GP1_FN - [12:8] */
1148#define WM8903_GP1_DIR 0x0080 /* GP1_DIR */
1149#define WM8903_GP1_DIR_MASK 0x0080 /* GP1_DIR */
1150#define WM8903_GP1_DIR_SHIFT 7 /* GP1_DIR */
1151#define WM8903_GP1_DIR_WIDTH 1 /* GP1_DIR */
1152#define WM8903_GP1_OP_CFG 0x0040 /* GP1_OP_CFG */
1153#define WM8903_GP1_OP_CFG_MASK 0x0040 /* GP1_OP_CFG */
1154#define WM8903_GP1_OP_CFG_SHIFT 6 /* GP1_OP_CFG */
1155#define WM8903_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
1156#define WM8903_GP1_IP_CFG 0x0020 /* GP1_IP_CFG */
1157#define WM8903_GP1_IP_CFG_MASK 0x0020 /* GP1_IP_CFG */
1158#define WM8903_GP1_IP_CFG_SHIFT 5 /* GP1_IP_CFG */
1159#define WM8903_GP1_IP_CFG_WIDTH 1 /* GP1_IP_CFG */
1160#define WM8903_GP1_LVL 0x0010 /* GP1_LVL */
1161#define WM8903_GP1_LVL_MASK 0x0010 /* GP1_LVL */
1162#define WM8903_GP1_LVL_SHIFT 4 /* GP1_LVL */
1163#define WM8903_GP1_LVL_WIDTH 1 /* GP1_LVL */
1164#define WM8903_GP1_PD 0x0008 /* GP1_PD */
1165#define WM8903_GP1_PD_MASK 0x0008 /* GP1_PD */
1166#define WM8903_GP1_PD_SHIFT 3 /* GP1_PD */
1167#define WM8903_GP1_PD_WIDTH 1 /* GP1_PD */
1168#define WM8903_GP1_PU 0x0004 /* GP1_PU */
1169#define WM8903_GP1_PU_MASK 0x0004 /* GP1_PU */
1170#define WM8903_GP1_PU_SHIFT 2 /* GP1_PU */
1171#define WM8903_GP1_PU_WIDTH 1 /* GP1_PU */
1172#define WM8903_GP1_INTMODE 0x0002 /* GP1_INTMODE */
1173#define WM8903_GP1_INTMODE_MASK 0x0002 /* GP1_INTMODE */
1174#define WM8903_GP1_INTMODE_SHIFT 1 /* GP1_INTMODE */
1175#define WM8903_GP1_INTMODE_WIDTH 1 /* GP1_INTMODE */
1176#define WM8903_GP1_DB 0x0001 /* GP1_DB */
1177#define WM8903_GP1_DB_MASK 0x0001 /* GP1_DB */
1178#define WM8903_GP1_DB_SHIFT 0 /* GP1_DB */
1179#define WM8903_GP1_DB_WIDTH 1 /* GP1_DB */
1180
1181/*
1182 * R117 (0x75) - GPIO Control 2
1183 */
1184#define WM8903_GP2_FN_MASK 0x1F00 /* GP2_FN - [12:8] */
1185#define WM8903_GP2_FN_SHIFT 8 /* GP2_FN - [12:8] */
1186#define WM8903_GP2_FN_WIDTH 5 /* GP2_FN - [12:8] */
1187#define WM8903_GP2_DIR 0x0080 /* GP2_DIR */
1188#define WM8903_GP2_DIR_MASK 0x0080 /* GP2_DIR */
1189#define WM8903_GP2_DIR_SHIFT 7 /* GP2_DIR */
1190#define WM8903_GP2_DIR_WIDTH 1 /* GP2_DIR */
1191#define WM8903_GP2_OP_CFG 0x0040 /* GP2_OP_CFG */
1192#define WM8903_GP2_OP_CFG_MASK 0x0040 /* GP2_OP_CFG */
1193#define WM8903_GP2_OP_CFG_SHIFT 6 /* GP2_OP_CFG */
1194#define WM8903_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
1195#define WM8903_GP2_IP_CFG 0x0020 /* GP2_IP_CFG */
1196#define WM8903_GP2_IP_CFG_MASK 0x0020 /* GP2_IP_CFG */
1197#define WM8903_GP2_IP_CFG_SHIFT 5 /* GP2_IP_CFG */
1198#define WM8903_GP2_IP_CFG_WIDTH 1 /* GP2_IP_CFG */
1199#define WM8903_GP2_LVL 0x0010 /* GP2_LVL */
1200#define WM8903_GP2_LVL_MASK 0x0010 /* GP2_LVL */
1201#define WM8903_GP2_LVL_SHIFT 4 /* GP2_LVL */
1202#define WM8903_GP2_LVL_WIDTH 1 /* GP2_LVL */
1203#define WM8903_GP2_PD 0x0008 /* GP2_PD */
1204#define WM8903_GP2_PD_MASK 0x0008 /* GP2_PD */
1205#define WM8903_GP2_PD_SHIFT 3 /* GP2_PD */
1206#define WM8903_GP2_PD_WIDTH 1 /* GP2_PD */
1207#define WM8903_GP2_PU 0x0004 /* GP2_PU */
1208#define WM8903_GP2_PU_MASK 0x0004 /* GP2_PU */
1209#define WM8903_GP2_PU_SHIFT 2 /* GP2_PU */
1210#define WM8903_GP2_PU_WIDTH 1 /* GP2_PU */
1211#define WM8903_GP2_INTMODE 0x0002 /* GP2_INTMODE */
1212#define WM8903_GP2_INTMODE_MASK 0x0002 /* GP2_INTMODE */
1213#define WM8903_GP2_INTMODE_SHIFT 1 /* GP2_INTMODE */
1214#define WM8903_GP2_INTMODE_WIDTH 1 /* GP2_INTMODE */
1215#define WM8903_GP2_DB 0x0001 /* GP2_DB */
1216#define WM8903_GP2_DB_MASK 0x0001 /* GP2_DB */
1217#define WM8903_GP2_DB_SHIFT 0 /* GP2_DB */
1218#define WM8903_GP2_DB_WIDTH 1 /* GP2_DB */
1219
1220/*
1221 * R118 (0x76) - GPIO Control 3
1222 */
1223#define WM8903_GP3_FN_MASK 0x1F00 /* GP3_FN - [12:8] */
1224#define WM8903_GP3_FN_SHIFT 8 /* GP3_FN - [12:8] */
1225#define WM8903_GP3_FN_WIDTH 5 /* GP3_FN - [12:8] */
1226#define WM8903_GP3_DIR 0x0080 /* GP3_DIR */
1227#define WM8903_GP3_DIR_MASK 0x0080 /* GP3_DIR */
1228#define WM8903_GP3_DIR_SHIFT 7 /* GP3_DIR */
1229#define WM8903_GP3_DIR_WIDTH 1 /* GP3_DIR */
1230#define WM8903_GP3_OP_CFG 0x0040 /* GP3_OP_CFG */
1231#define WM8903_GP3_OP_CFG_MASK 0x0040 /* GP3_OP_CFG */
1232#define WM8903_GP3_OP_CFG_SHIFT 6 /* GP3_OP_CFG */
1233#define WM8903_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
1234#define WM8903_GP3_IP_CFG 0x0020 /* GP3_IP_CFG */
1235#define WM8903_GP3_IP_CFG_MASK 0x0020 /* GP3_IP_CFG */
1236#define WM8903_GP3_IP_CFG_SHIFT 5 /* GP3_IP_CFG */
1237#define WM8903_GP3_IP_CFG_WIDTH 1 /* GP3_IP_CFG */
1238#define WM8903_GP3_LVL 0x0010 /* GP3_LVL */
1239#define WM8903_GP3_LVL_MASK 0x0010 /* GP3_LVL */
1240#define WM8903_GP3_LVL_SHIFT 4 /* GP3_LVL */
1241#define WM8903_GP3_LVL_WIDTH 1 /* GP3_LVL */
1242#define WM8903_GP3_PD 0x0008 /* GP3_PD */
1243#define WM8903_GP3_PD_MASK 0x0008 /* GP3_PD */
1244#define WM8903_GP3_PD_SHIFT 3 /* GP3_PD */
1245#define WM8903_GP3_PD_WIDTH 1 /* GP3_PD */
1246#define WM8903_GP3_PU 0x0004 /* GP3_PU */
1247#define WM8903_GP3_PU_MASK 0x0004 /* GP3_PU */
1248#define WM8903_GP3_PU_SHIFT 2 /* GP3_PU */
1249#define WM8903_GP3_PU_WIDTH 1 /* GP3_PU */
1250#define WM8903_GP3_INTMODE 0x0002 /* GP3_INTMODE */
1251#define WM8903_GP3_INTMODE_MASK 0x0002 /* GP3_INTMODE */
1252#define WM8903_GP3_INTMODE_SHIFT 1 /* GP3_INTMODE */
1253#define WM8903_GP3_INTMODE_WIDTH 1 /* GP3_INTMODE */
1254#define WM8903_GP3_DB 0x0001 /* GP3_DB */
1255#define WM8903_GP3_DB_MASK 0x0001 /* GP3_DB */
1256#define WM8903_GP3_DB_SHIFT 0 /* GP3_DB */
1257#define WM8903_GP3_DB_WIDTH 1 /* GP3_DB */
1258
1259/*
1260 * R119 (0x77) - GPIO Control 4
1261 */
1262#define WM8903_GP4_FN_MASK 0x1F00 /* GP4_FN - [12:8] */
1263#define WM8903_GP4_FN_SHIFT 8 /* GP4_FN - [12:8] */
1264#define WM8903_GP4_FN_WIDTH 5 /* GP4_FN - [12:8] */
1265#define WM8903_GP4_DIR 0x0080 /* GP4_DIR */
1266#define WM8903_GP4_DIR_MASK 0x0080 /* GP4_DIR */
1267#define WM8903_GP4_DIR_SHIFT 7 /* GP4_DIR */
1268#define WM8903_GP4_DIR_WIDTH 1 /* GP4_DIR */
1269#define WM8903_GP4_OP_CFG 0x0040 /* GP4_OP_CFG */
1270#define WM8903_GP4_OP_CFG_MASK 0x0040 /* GP4_OP_CFG */
1271#define WM8903_GP4_OP_CFG_SHIFT 6 /* GP4_OP_CFG */
1272#define WM8903_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
1273#define WM8903_GP4_IP_CFG 0x0020 /* GP4_IP_CFG */
1274#define WM8903_GP4_IP_CFG_MASK 0x0020 /* GP4_IP_CFG */
1275#define WM8903_GP4_IP_CFG_SHIFT 5 /* GP4_IP_CFG */
1276#define WM8903_GP4_IP_CFG_WIDTH 1 /* GP4_IP_CFG */
1277#define WM8903_GP4_LVL 0x0010 /* GP4_LVL */
1278#define WM8903_GP4_LVL_MASK 0x0010 /* GP4_LVL */
1279#define WM8903_GP4_LVL_SHIFT 4 /* GP4_LVL */
1280#define WM8903_GP4_LVL_WIDTH 1 /* GP4_LVL */
1281#define WM8903_GP4_PD 0x0008 /* GP4_PD */
1282#define WM8903_GP4_PD_MASK 0x0008 /* GP4_PD */
1283#define WM8903_GP4_PD_SHIFT 3 /* GP4_PD */
1284#define WM8903_GP4_PD_WIDTH 1 /* GP4_PD */
1285#define WM8903_GP4_PU 0x0004 /* GP4_PU */
1286#define WM8903_GP4_PU_MASK 0x0004 /* GP4_PU */
1287#define WM8903_GP4_PU_SHIFT 2 /* GP4_PU */
1288#define WM8903_GP4_PU_WIDTH 1 /* GP4_PU */
1289#define WM8903_GP4_INTMODE 0x0002 /* GP4_INTMODE */
1290#define WM8903_GP4_INTMODE_MASK 0x0002 /* GP4_INTMODE */
1291#define WM8903_GP4_INTMODE_SHIFT 1 /* GP4_INTMODE */
1292#define WM8903_GP4_INTMODE_WIDTH 1 /* GP4_INTMODE */
1293#define WM8903_GP4_DB 0x0001 /* GP4_DB */
1294#define WM8903_GP4_DB_MASK 0x0001 /* GP4_DB */
1295#define WM8903_GP4_DB_SHIFT 0 /* GP4_DB */
1296#define WM8903_GP4_DB_WIDTH 1 /* GP4_DB */
1297
1298/*
1299 * R120 (0x78) - GPIO Control 5
1300 */
1301#define WM8903_GP5_FN_MASK 0x1F00 /* GP5_FN - [12:8] */
1302#define WM8903_GP5_FN_SHIFT 8 /* GP5_FN - [12:8] */
1303#define WM8903_GP5_FN_WIDTH 5 /* GP5_FN - [12:8] */
1304#define WM8903_GP5_DIR 0x0080 /* GP5_DIR */
1305#define WM8903_GP5_DIR_MASK 0x0080 /* GP5_DIR */
1306#define WM8903_GP5_DIR_SHIFT 7 /* GP5_DIR */
1307#define WM8903_GP5_DIR_WIDTH 1 /* GP5_DIR */
1308#define WM8903_GP5_OP_CFG 0x0040 /* GP5_OP_CFG */
1309#define WM8903_GP5_OP_CFG_MASK 0x0040 /* GP5_OP_CFG */
1310#define WM8903_GP5_OP_CFG_SHIFT 6 /* GP5_OP_CFG */
1311#define WM8903_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
1312#define WM8903_GP5_IP_CFG 0x0020 /* GP5_IP_CFG */
1313#define WM8903_GP5_IP_CFG_MASK 0x0020 /* GP5_IP_CFG */
1314#define WM8903_GP5_IP_CFG_SHIFT 5 /* GP5_IP_CFG */
1315#define WM8903_GP5_IP_CFG_WIDTH 1 /* GP5_IP_CFG */
1316#define WM8903_GP5_LVL 0x0010 /* GP5_LVL */
1317#define WM8903_GP5_LVL_MASK 0x0010 /* GP5_LVL */
1318#define WM8903_GP5_LVL_SHIFT 4 /* GP5_LVL */
1319#define WM8903_GP5_LVL_WIDTH 1 /* GP5_LVL */
1320#define WM8903_GP5_PD 0x0008 /* GP5_PD */
1321#define WM8903_GP5_PD_MASK 0x0008 /* GP5_PD */
1322#define WM8903_GP5_PD_SHIFT 3 /* GP5_PD */
1323#define WM8903_GP5_PD_WIDTH 1 /* GP5_PD */
1324#define WM8903_GP5_PU 0x0004 /* GP5_PU */
1325#define WM8903_GP5_PU_MASK 0x0004 /* GP5_PU */
1326#define WM8903_GP5_PU_SHIFT 2 /* GP5_PU */
1327#define WM8903_GP5_PU_WIDTH 1 /* GP5_PU */
1328#define WM8903_GP5_INTMODE 0x0002 /* GP5_INTMODE */
1329#define WM8903_GP5_INTMODE_MASK 0x0002 /* GP5_INTMODE */
1330#define WM8903_GP5_INTMODE_SHIFT 1 /* GP5_INTMODE */
1331#define WM8903_GP5_INTMODE_WIDTH 1 /* GP5_INTMODE */
1332#define WM8903_GP5_DB 0x0001 /* GP5_DB */
1333#define WM8903_GP5_DB_MASK 0x0001 /* GP5_DB */
1334#define WM8903_GP5_DB_SHIFT 0 /* GP5_DB */
1335#define WM8903_GP5_DB_WIDTH 1 /* GP5_DB */
1336
1337/*
1338 * R121 (0x79) - Interrupt Status 1
1339 */
1340#define WM8903_MICSHRT_EINT 0x8000 /* MICSHRT_EINT */
1341#define WM8903_MICSHRT_EINT_MASK 0x8000 /* MICSHRT_EINT */
1342#define WM8903_MICSHRT_EINT_SHIFT 15 /* MICSHRT_EINT */
1343#define WM8903_MICSHRT_EINT_WIDTH 1 /* MICSHRT_EINT */
1344#define WM8903_MICDET_EINT 0x4000 /* MICDET_EINT */
1345#define WM8903_MICDET_EINT_MASK 0x4000 /* MICDET_EINT */
1346#define WM8903_MICDET_EINT_SHIFT 14 /* MICDET_EINT */
1347#define WM8903_MICDET_EINT_WIDTH 1 /* MICDET_EINT */
1348#define WM8903_WSEQ_BUSY_EINT 0x2000 /* WSEQ_BUSY_EINT */
1349#define WM8903_WSEQ_BUSY_EINT_MASK 0x2000 /* WSEQ_BUSY_EINT */
1350#define WM8903_WSEQ_BUSY_EINT_SHIFT 13 /* WSEQ_BUSY_EINT */
1351#define WM8903_WSEQ_BUSY_EINT_WIDTH 1 /* WSEQ_BUSY_EINT */
1352#define WM8903_GP5_EINT 0x0010 /* GP5_EINT */
1353#define WM8903_GP5_EINT_MASK 0x0010 /* GP5_EINT */
1354#define WM8903_GP5_EINT_SHIFT 4 /* GP5_EINT */
1355#define WM8903_GP5_EINT_WIDTH 1 /* GP5_EINT */
1356#define WM8903_GP4_EINT 0x0008 /* GP4_EINT */
1357#define WM8903_GP4_EINT_MASK 0x0008 /* GP4_EINT */
1358#define WM8903_GP4_EINT_SHIFT 3 /* GP4_EINT */
1359#define WM8903_GP4_EINT_WIDTH 1 /* GP4_EINT */
1360#define WM8903_GP3_EINT 0x0004 /* GP3_EINT */
1361#define WM8903_GP3_EINT_MASK 0x0004 /* GP3_EINT */
1362#define WM8903_GP3_EINT_SHIFT 2 /* GP3_EINT */
1363#define WM8903_GP3_EINT_WIDTH 1 /* GP3_EINT */
1364#define WM8903_GP2_EINT 0x0002 /* GP2_EINT */
1365#define WM8903_GP2_EINT_MASK 0x0002 /* GP2_EINT */
1366#define WM8903_GP2_EINT_SHIFT 1 /* GP2_EINT */
1367#define WM8903_GP2_EINT_WIDTH 1 /* GP2_EINT */
1368#define WM8903_GP1_EINT 0x0001 /* GP1_EINT */
1369#define WM8903_GP1_EINT_MASK 0x0001 /* GP1_EINT */
1370#define WM8903_GP1_EINT_SHIFT 0 /* GP1_EINT */
1371#define WM8903_GP1_EINT_WIDTH 1 /* GP1_EINT */
1372
1373/*
1374 * R122 (0x7A) - Interrupt Status 1 Mask
1375 */
1376#define WM8903_IM_MICSHRT_EINT 0x8000 /* IM_MICSHRT_EINT */
1377#define WM8903_IM_MICSHRT_EINT_MASK 0x8000 /* IM_MICSHRT_EINT */
1378#define WM8903_IM_MICSHRT_EINT_SHIFT 15 /* IM_MICSHRT_EINT */
1379#define WM8903_IM_MICSHRT_EINT_WIDTH 1 /* IM_MICSHRT_EINT */
1380#define WM8903_IM_MICDET_EINT 0x4000 /* IM_MICDET_EINT */
1381#define WM8903_IM_MICDET_EINT_MASK 0x4000 /* IM_MICDET_EINT */
1382#define WM8903_IM_MICDET_EINT_SHIFT 14 /* IM_MICDET_EINT */
1383#define WM8903_IM_MICDET_EINT_WIDTH 1 /* IM_MICDET_EINT */
1384#define WM8903_IM_WSEQ_BUSY_EINT 0x2000 /* IM_WSEQ_BUSY_EINT */
1385#define WM8903_IM_WSEQ_BUSY_EINT_MASK 0x2000 /* IM_WSEQ_BUSY_EINT */
1386#define WM8903_IM_WSEQ_BUSY_EINT_SHIFT 13 /* IM_WSEQ_BUSY_EINT */
1387#define WM8903_IM_WSEQ_BUSY_EINT_WIDTH 1 /* IM_WSEQ_BUSY_EINT */
1388#define WM8903_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
1389#define WM8903_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
1390#define WM8903_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
1391#define WM8903_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
1392#define WM8903_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
1393#define WM8903_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
1394#define WM8903_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
1395#define WM8903_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
1396#define WM8903_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
1397#define WM8903_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
1398#define WM8903_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
1399#define WM8903_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
1400#define WM8903_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
1401#define WM8903_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
1402#define WM8903_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
1403#define WM8903_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
1404#define WM8903_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
1405#define WM8903_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
1406#define WM8903_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
1407#define WM8903_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
1408
1409/*
1410 * R123 (0x7B) - Interrupt Polarity 1
1411 */
1412#define WM8903_MICSHRT_INV 0x8000 /* MICSHRT_INV */
1413#define WM8903_MICSHRT_INV_MASK 0x8000 /* MICSHRT_INV */
1414#define WM8903_MICSHRT_INV_SHIFT 15 /* MICSHRT_INV */
1415#define WM8903_MICSHRT_INV_WIDTH 1 /* MICSHRT_INV */
1416#define WM8903_MICDET_INV 0x4000 /* MICDET_INV */
1417#define WM8903_MICDET_INV_MASK 0x4000 /* MICDET_INV */
1418#define WM8903_MICDET_INV_SHIFT 14 /* MICDET_INV */
1419#define WM8903_MICDET_INV_WIDTH 1 /* MICDET_INV */
1420
1421/*
1422 * R126 (0x7E) - Interrupt Control
1423 */
1424#define WM8903_IRQ_POL 0x0001 /* IRQ_POL */
1425#define WM8903_IRQ_POL_MASK 0x0001 /* IRQ_POL */
1426#define WM8903_IRQ_POL_SHIFT 0 /* IRQ_POL */
1427#define WM8903_IRQ_POL_WIDTH 1 /* IRQ_POL */
1428
1429/*
1430 * R129 (0x81) - Control Interface Test 1
1431 */
1432#define WM8903_USER_KEY 0x0002 /* USER_KEY */
1433#define WM8903_USER_KEY_MASK 0x0002 /* USER_KEY */
1434#define WM8903_USER_KEY_SHIFT 1 /* USER_KEY */
1435#define WM8903_USER_KEY_WIDTH 1 /* USER_KEY */
1436#define WM8903_TEST_KEY 0x0001 /* TEST_KEY */
1437#define WM8903_TEST_KEY_MASK 0x0001 /* TEST_KEY */
1438#define WM8903_TEST_KEY_SHIFT 0 /* TEST_KEY */
1439#define WM8903_TEST_KEY_WIDTH 1 /* TEST_KEY */
1440
1441/*
1442 * R149 (0x95) - Charge Pump Test 1
1443 */
1444#define WM8903_CP_SW_KELVIN_MODE_MASK 0x0006 /* CP_SW_KELVIN_MODE - [2:1] */
1445#define WM8903_CP_SW_KELVIN_MODE_SHIFT 1 /* CP_SW_KELVIN_MODE - [2:1] */
1446#define WM8903_CP_SW_KELVIN_MODE_WIDTH 2 /* CP_SW_KELVIN_MODE - [2:1] */
1447
1448/*
1449 * R164 (0xA4) - Clock Rate Test 4
1450 */
1451#define WM8903_ADC_DIG_MIC 0x0200 /* ADC_DIG_MIC */
1452#define WM8903_ADC_DIG_MIC_MASK 0x0200 /* ADC_DIG_MIC */
1453#define WM8903_ADC_DIG_MIC_SHIFT 9 /* ADC_DIG_MIC */
1454#define WM8903_ADC_DIG_MIC_WIDTH 1 /* ADC_DIG_MIC */
1455
1456/*
1457 * R172 (0xAC) - Analogue Output Bias 0
1458 */
1459#define WM8903_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */
1460#define WM8903_PGA_BIAS_SHIFT 4 /* PGA_BIAS - [6:4] */
1461#define WM8903_PGA_BIAS_WIDTH 3 /* PGA_BIAS - [6:4] */
1462
1463#endif
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
new file mode 100644
index 00000000000..974a4cd0f3f
--- /dev/null
+++ b/sound/soc/codecs/wm8971.c
@@ -0,0 +1,942 @@
1/*
2 * wm8971.c -- WM8971 ALSA SoC Audio driver
3 *
4 * Copyright 2005 Lab126, Inc.
5 *
6 * Author: Kenneth Kiraly <kiraly@lab126.com>
7 *
8 * Based on wm8753.c by Liam Girdwood
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/pm.h>
21#include <linux/i2c.h>
22#include <linux/platform_device.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29
30#include "wm8971.h"
31
32#define AUDIO_NAME "wm8971"
33#define WM8971_VERSION "0.9"
34
35#define WM8971_REG_COUNT 43
36
37static struct workqueue_struct *wm8971_workq = NULL;
38
39/* codec private data */
40struct wm8971_priv {
41 unsigned int sysclk;
42};
43
44/*
45 * wm8971 register cache
46 * We can't read the WM8971 register space when we
47 * are using 2 wire for device control, so we cache them instead.
48 */
49static const u16 wm8971_reg[] = {
50 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */
51 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */
52 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */
53 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */
54 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */
55 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */
56 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */
57 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */
58 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */
59 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */
60 0x0079, 0x0079, 0x0079, /* 40 */
61};
62
63static inline unsigned int wm8971_read_reg_cache(struct snd_soc_codec *codec,
64 unsigned int reg)
65{
66 u16 *cache = codec->reg_cache;
67 if (reg < WM8971_REG_COUNT)
68 return cache[reg];
69
70 return -1;
71}
72
73static inline void wm8971_write_reg_cache(struct snd_soc_codec *codec,
74 unsigned int reg, unsigned int value)
75{
76 u16 *cache = codec->reg_cache;
77 if (reg < WM8971_REG_COUNT)
78 cache[reg] = value;
79}
80
81static int wm8971_write(struct snd_soc_codec *codec, unsigned int reg,
82 unsigned int value)
83{
84 u8 data[2];
85
86 /* data is
87 * D15..D9 WM8753 register offset
88 * D8...D0 register data
89 */
90 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
91 data[1] = value & 0x00ff;
92
93 wm8971_write_reg_cache (codec, reg, value);
94 if (codec->hw_write(codec->control_data, data, 2) == 2)
95 return 0;
96 else
97 return -EIO;
98}
99
100#define wm8971_reset(c) wm8971_write(c, WM8971_RESET, 0)
101
102/* WM8971 Controls */
103static const char *wm8971_bass[] = { "Linear Control", "Adaptive Boost" };
104static const char *wm8971_bass_filter[] = { "130Hz @ 48kHz",
105 "200Hz @ 48kHz" };
106static const char *wm8971_treble[] = { "8kHz", "4kHz" };
107static const char *wm8971_alc_func[] = { "Off", "Right", "Left", "Stereo" };
108static const char *wm8971_ng_type[] = { "Constant PGA Gain",
109 "Mute ADC Output" };
110static const char *wm8971_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
111static const char *wm8971_mono_mux[] = {"Stereo", "Mono (Left)",
112 "Mono (Right)", "Digital Mono"};
113static const char *wm8971_dac_phase[] = { "Non Inverted", "Inverted" };
114static const char *wm8971_lline_mux[] = {"Line", "NC", "NC", "PGA",
115 "Differential"};
116static const char *wm8971_rline_mux[] = {"Line", "Mic", "NC", "PGA",
117 "Differential"};
118static const char *wm8971_lpga_sel[] = {"Line", "NC", "NC", "Differential"};
119static const char *wm8971_rpga_sel[] = {"Line", "Mic", "NC", "Differential"};
120static const char *wm8971_adcpol[] = {"Normal", "L Invert", "R Invert",
121 "L + R Invert"};
122
123static const struct soc_enum wm8971_enum[] = {
124 SOC_ENUM_SINGLE(WM8971_BASS, 7, 2, wm8971_bass), /* 0 */
125 SOC_ENUM_SINGLE(WM8971_BASS, 6, 2, wm8971_bass_filter),
126 SOC_ENUM_SINGLE(WM8971_TREBLE, 6, 2, wm8971_treble),
127 SOC_ENUM_SINGLE(WM8971_ALC1, 7, 4, wm8971_alc_func),
128 SOC_ENUM_SINGLE(WM8971_NGATE, 1, 2, wm8971_ng_type), /* 4 */
129 SOC_ENUM_SINGLE(WM8971_ADCDAC, 1, 4, wm8971_deemp),
130 SOC_ENUM_SINGLE(WM8971_ADCTL1, 4, 4, wm8971_mono_mux),
131 SOC_ENUM_SINGLE(WM8971_ADCTL1, 1, 2, wm8971_dac_phase),
132 SOC_ENUM_SINGLE(WM8971_LOUTM1, 0, 5, wm8971_lline_mux), /* 8 */
133 SOC_ENUM_SINGLE(WM8971_ROUTM1, 0, 5, wm8971_rline_mux),
134 SOC_ENUM_SINGLE(WM8971_LADCIN, 6, 4, wm8971_lpga_sel),
135 SOC_ENUM_SINGLE(WM8971_RADCIN, 6, 4, wm8971_rpga_sel),
136 SOC_ENUM_SINGLE(WM8971_ADCDAC, 5, 4, wm8971_adcpol), /* 12 */
137 SOC_ENUM_SINGLE(WM8971_ADCIN, 6, 4, wm8971_mono_mux),
138};
139
140static const struct snd_kcontrol_new wm8971_snd_controls[] = {
141 SOC_DOUBLE_R("Capture Volume", WM8971_LINVOL, WM8971_RINVOL, 0, 63, 0),
142 SOC_DOUBLE_R("Capture ZC Switch", WM8971_LINVOL, WM8971_RINVOL,
143 6, 1, 0),
144 SOC_DOUBLE_R("Capture Switch", WM8971_LINVOL, WM8971_RINVOL, 7, 1, 1),
145
146 SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8971_LOUT1V,
147 WM8971_ROUT1V, 7, 1, 0),
148 SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8971_LOUT2V,
149 WM8971_ROUT2V, 7, 1, 0),
150 SOC_SINGLE("Mono Playback ZC Switch", WM8971_MOUTV, 7, 1, 0),
151
152 SOC_DOUBLE_R("PCM Volume", WM8971_LDAC, WM8971_RDAC, 0, 255, 0),
153
154 SOC_DOUBLE_R("Bypass Left Playback Volume", WM8971_LOUTM1,
155 WM8971_LOUTM2, 4, 7, 1),
156 SOC_DOUBLE_R("Bypass Right Playback Volume", WM8971_ROUTM1,
157 WM8971_ROUTM2, 4, 7, 1),
158 SOC_DOUBLE_R("Bypass Mono Playback Volume", WM8971_MOUTM1,
159 WM8971_MOUTM2, 4, 7, 1),
160
161 SOC_DOUBLE_R("Headphone Playback Volume", WM8971_LOUT1V,
162 WM8971_ROUT1V, 0, 127, 0),
163 SOC_DOUBLE_R("Speaker Playback Volume", WM8971_LOUT2V,
164 WM8971_ROUT2V, 0, 127, 0),
165
166 SOC_ENUM("Bass Boost", wm8971_enum[0]),
167 SOC_ENUM("Bass Filter", wm8971_enum[1]),
168 SOC_SINGLE("Bass Volume", WM8971_BASS, 0, 7, 1),
169
170 SOC_SINGLE("Treble Volume", WM8971_TREBLE, 0, 7, 0),
171 SOC_ENUM("Treble Cut-off", wm8971_enum[2]),
172
173 SOC_SINGLE("Capture Filter Switch", WM8971_ADCDAC, 0, 1, 1),
174
175 SOC_SINGLE("ALC Target Volume", WM8971_ALC1, 0, 7, 0),
176 SOC_SINGLE("ALC Max Volume", WM8971_ALC1, 4, 7, 0),
177
178 SOC_SINGLE("ALC Capture Target Volume", WM8971_ALC1, 0, 7, 0),
179 SOC_SINGLE("ALC Capture Max Volume", WM8971_ALC1, 4, 7, 0),
180 SOC_ENUM("ALC Capture Function", wm8971_enum[3]),
181 SOC_SINGLE("ALC Capture ZC Switch", WM8971_ALC2, 7, 1, 0),
182 SOC_SINGLE("ALC Capture Hold Time", WM8971_ALC2, 0, 15, 0),
183 SOC_SINGLE("ALC Capture Decay Time", WM8971_ALC3, 4, 15, 0),
184 SOC_SINGLE("ALC Capture Attack Time", WM8971_ALC3, 0, 15, 0),
185 SOC_SINGLE("ALC Capture NG Threshold", WM8971_NGATE, 3, 31, 0),
186 SOC_ENUM("ALC Capture NG Type", wm8971_enum[4]),
187 SOC_SINGLE("ALC Capture NG Switch", WM8971_NGATE, 0, 1, 0),
188
189 SOC_SINGLE("Capture 6dB Attenuate", WM8971_ADCDAC, 8, 1, 0),
190 SOC_SINGLE("Playback 6dB Attenuate", WM8971_ADCDAC, 7, 1, 0),
191
192 SOC_ENUM("Playback De-emphasis", wm8971_enum[5]),
193 SOC_ENUM("Playback Function", wm8971_enum[6]),
194 SOC_ENUM("Playback Phase", wm8971_enum[7]),
195
196 SOC_DOUBLE_R("Mic Boost", WM8971_LADCIN, WM8971_RADCIN, 4, 3, 0),
197};
198
199/* add non-DAPM controls */
200static int wm8971_add_controls(struct snd_soc_codec *codec)
201{
202 int err, i;
203
204 for (i = 0; i < ARRAY_SIZE(wm8971_snd_controls); i++) {
205 err = snd_ctl_add(codec->card,
206 snd_soc_cnew(&wm8971_snd_controls[i],
207 codec, NULL));
208 if (err < 0)
209 return err;
210 }
211 return 0;
212}
213
214/*
215 * DAPM Controls
216 */
217
218/* Left Mixer */
219static const struct snd_kcontrol_new wm8971_left_mixer_controls[] = {
220SOC_DAPM_SINGLE("Playback Switch", WM8971_LOUTM1, 8, 1, 0),
221SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_LOUTM1, 7, 1, 0),
222SOC_DAPM_SINGLE("Right Playback Switch", WM8971_LOUTM2, 8, 1, 0),
223SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_LOUTM2, 7, 1, 0),
224};
225
226/* Right Mixer */
227static const struct snd_kcontrol_new wm8971_right_mixer_controls[] = {
228SOC_DAPM_SINGLE("Left Playback Switch", WM8971_ROUTM1, 8, 1, 0),
229SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_ROUTM1, 7, 1, 0),
230SOC_DAPM_SINGLE("Playback Switch", WM8971_ROUTM2, 8, 1, 0),
231SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_ROUTM2, 7, 1, 0),
232};
233
234/* Mono Mixer */
235static const struct snd_kcontrol_new wm8971_mono_mixer_controls[] = {
236SOC_DAPM_SINGLE("Left Playback Switch", WM8971_MOUTM1, 8, 1, 0),
237SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_MOUTM1, 7, 1, 0),
238SOC_DAPM_SINGLE("Right Playback Switch", WM8971_MOUTM2, 8, 1, 0),
239SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_MOUTM2, 7, 1, 0),
240};
241
242/* Left Line Mux */
243static const struct snd_kcontrol_new wm8971_left_line_controls =
244SOC_DAPM_ENUM("Route", wm8971_enum[8]);
245
246/* Right Line Mux */
247static const struct snd_kcontrol_new wm8971_right_line_controls =
248SOC_DAPM_ENUM("Route", wm8971_enum[9]);
249
250/* Left PGA Mux */
251static const struct snd_kcontrol_new wm8971_left_pga_controls =
252SOC_DAPM_ENUM("Route", wm8971_enum[10]);
253
254/* Right PGA Mux */
255static const struct snd_kcontrol_new wm8971_right_pga_controls =
256SOC_DAPM_ENUM("Route", wm8971_enum[11]);
257
258/* Mono ADC Mux */
259static const struct snd_kcontrol_new wm8971_monomux_controls =
260SOC_DAPM_ENUM("Route", wm8971_enum[13]);
261
262static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = {
263 SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
264 &wm8971_left_mixer_controls[0],
265 ARRAY_SIZE(wm8971_left_mixer_controls)),
266 SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
267 &wm8971_right_mixer_controls[0],
268 ARRAY_SIZE(wm8971_right_mixer_controls)),
269 SND_SOC_DAPM_MIXER("Mono Mixer", WM8971_PWR2, 2, 0,
270 &wm8971_mono_mixer_controls[0],
271 ARRAY_SIZE(wm8971_mono_mixer_controls)),
272
273 SND_SOC_DAPM_PGA("Right Out 2", WM8971_PWR2, 3, 0, NULL, 0),
274 SND_SOC_DAPM_PGA("Left Out 2", WM8971_PWR2, 4, 0, NULL, 0),
275 SND_SOC_DAPM_PGA("Right Out 1", WM8971_PWR2, 5, 0, NULL, 0),
276 SND_SOC_DAPM_PGA("Left Out 1", WM8971_PWR2, 6, 0, NULL, 0),
277 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8971_PWR2, 7, 0),
278 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8971_PWR2, 8, 0),
279 SND_SOC_DAPM_PGA("Mono Out 1", WM8971_PWR2, 2, 0, NULL, 0),
280
281 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8971_PWR1, 1, 0),
282 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8971_PWR1, 2, 0),
283 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8971_PWR1, 3, 0),
284
285 SND_SOC_DAPM_MUX("Left PGA Mux", WM8971_PWR1, 5, 0,
286 &wm8971_left_pga_controls),
287 SND_SOC_DAPM_MUX("Right PGA Mux", WM8971_PWR1, 4, 0,
288 &wm8971_right_pga_controls),
289 SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
290 &wm8971_left_line_controls),
291 SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
292 &wm8971_right_line_controls),
293
294 SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
295 &wm8971_monomux_controls),
296 SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
297 &wm8971_monomux_controls),
298
299 SND_SOC_DAPM_OUTPUT("LOUT1"),
300 SND_SOC_DAPM_OUTPUT("ROUT1"),
301 SND_SOC_DAPM_OUTPUT("LOUT2"),
302 SND_SOC_DAPM_OUTPUT("ROUT2"),
303 SND_SOC_DAPM_OUTPUT("MONO"),
304
305 SND_SOC_DAPM_INPUT("LINPUT1"),
306 SND_SOC_DAPM_INPUT("RINPUT1"),
307 SND_SOC_DAPM_INPUT("MIC"),
308};
309
310static const struct snd_soc_dapm_route audio_map[] = {
311 /* left mixer */
312 {"Left Mixer", "Playback Switch", "Left DAC"},
313 {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
314 {"Left Mixer", "Right Playback Switch", "Right DAC"},
315 {"Left Mixer", "Right Bypass Switch", "Right Line Mux"},
316
317 /* right mixer */
318 {"Right Mixer", "Left Playback Switch", "Left DAC"},
319 {"Right Mixer", "Left Bypass Switch", "Left Line Mux"},
320 {"Right Mixer", "Playback Switch", "Right DAC"},
321 {"Right Mixer", "Right Bypass Switch", "Right Line Mux"},
322
323 /* left out 1 */
324 {"Left Out 1", NULL, "Left Mixer"},
325 {"LOUT1", NULL, "Left Out 1"},
326
327 /* left out 2 */
328 {"Left Out 2", NULL, "Left Mixer"},
329 {"LOUT2", NULL, "Left Out 2"},
330
331 /* right out 1 */
332 {"Right Out 1", NULL, "Right Mixer"},
333 {"ROUT1", NULL, "Right Out 1"},
334
335 /* right out 2 */
336 {"Right Out 2", NULL, "Right Mixer"},
337 {"ROUT2", NULL, "Right Out 2"},
338
339 /* mono mixer */
340 {"Mono Mixer", "Left Playback Switch", "Left DAC"},
341 {"Mono Mixer", "Left Bypass Switch", "Left Line Mux"},
342 {"Mono Mixer", "Right Playback Switch", "Right DAC"},
343 {"Mono Mixer", "Right Bypass Switch", "Right Line Mux"},
344
345 /* mono out */
346 {"Mono Out", NULL, "Mono Mixer"},
347 {"MONO1", NULL, "Mono Out"},
348
349 /* Left Line Mux */
350 {"Left Line Mux", "Line", "LINPUT1"},
351 {"Left Line Mux", "PGA", "Left PGA Mux"},
352 {"Left Line Mux", "Differential", "Differential Mux"},
353
354 /* Right Line Mux */
355 {"Right Line Mux", "Line", "RINPUT1"},
356 {"Right Line Mux", "Mic", "MIC"},
357 {"Right Line Mux", "PGA", "Right PGA Mux"},
358 {"Right Line Mux", "Differential", "Differential Mux"},
359
360 /* Left PGA Mux */
361 {"Left PGA Mux", "Line", "LINPUT1"},
362 {"Left PGA Mux", "Differential", "Differential Mux"},
363
364 /* Right PGA Mux */
365 {"Right PGA Mux", "Line", "RINPUT1"},
366 {"Right PGA Mux", "Differential", "Differential Mux"},
367
368 /* Differential Mux */
369 {"Differential Mux", "Line", "LINPUT1"},
370 {"Differential Mux", "Line", "RINPUT1"},
371
372 /* Left ADC Mux */
373 {"Left ADC Mux", "Stereo", "Left PGA Mux"},
374 {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},
375 {"Left ADC Mux", "Digital Mono", "Left PGA Mux"},
376
377 /* Right ADC Mux */
378 {"Right ADC Mux", "Stereo", "Right PGA Mux"},
379 {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
380 {"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
381
382 /* ADC */
383 {"Left ADC", NULL, "Left ADC Mux"},
384 {"Right ADC", NULL, "Right ADC Mux"},
385};
386
387static int wm8971_add_widgets(struct snd_soc_codec *codec)
388{
389 snd_soc_dapm_new_controls(codec, wm8971_dapm_widgets,
390 ARRAY_SIZE(wm8971_dapm_widgets));
391
392 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
393
394 snd_soc_dapm_new_widgets(codec);
395
396 return 0;
397}
398
399struct _coeff_div {
400 u32 mclk;
401 u32 rate;
402 u16 fs;
403 u8 sr:5;
404 u8 usb:1;
405};
406
407/* codec hifi mclk clock divider coefficients */
408static const struct _coeff_div coeff_div[] = {
409 /* 8k */
410 {12288000, 8000, 1536, 0x6, 0x0},
411 {11289600, 8000, 1408, 0x16, 0x0},
412 {18432000, 8000, 2304, 0x7, 0x0},
413 {16934400, 8000, 2112, 0x17, 0x0},
414 {12000000, 8000, 1500, 0x6, 0x1},
415
416 /* 11.025k */
417 {11289600, 11025, 1024, 0x18, 0x0},
418 {16934400, 11025, 1536, 0x19, 0x0},
419 {12000000, 11025, 1088, 0x19, 0x1},
420
421 /* 16k */
422 {12288000, 16000, 768, 0xa, 0x0},
423 {18432000, 16000, 1152, 0xb, 0x0},
424 {12000000, 16000, 750, 0xa, 0x1},
425
426 /* 22.05k */
427 {11289600, 22050, 512, 0x1a, 0x0},
428 {16934400, 22050, 768, 0x1b, 0x0},
429 {12000000, 22050, 544, 0x1b, 0x1},
430
431 /* 32k */
432 {12288000, 32000, 384, 0xc, 0x0},
433 {18432000, 32000, 576, 0xd, 0x0},
434 {12000000, 32000, 375, 0xa, 0x1},
435
436 /* 44.1k */
437 {11289600, 44100, 256, 0x10, 0x0},
438 {16934400, 44100, 384, 0x11, 0x0},
439 {12000000, 44100, 272, 0x11, 0x1},
440
441 /* 48k */
442 {12288000, 48000, 256, 0x0, 0x0},
443 {18432000, 48000, 384, 0x1, 0x0},
444 {12000000, 48000, 250, 0x0, 0x1},
445
446 /* 88.2k */
447 {11289600, 88200, 128, 0x1e, 0x0},
448 {16934400, 88200, 192, 0x1f, 0x0},
449 {12000000, 88200, 136, 0x1f, 0x1},
450
451 /* 96k */
452 {12288000, 96000, 128, 0xe, 0x0},
453 {18432000, 96000, 192, 0xf, 0x0},
454 {12000000, 96000, 125, 0xe, 0x1},
455};
456
457static int get_coeff(int mclk, int rate)
458{
459 int i;
460
461 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
462 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
463 return i;
464 }
465 return -EINVAL;
466}
467
468static int wm8971_set_dai_sysclk(struct snd_soc_dai *codec_dai,
469 int clk_id, unsigned int freq, int dir)
470{
471 struct snd_soc_codec *codec = codec_dai->codec;
472 struct wm8971_priv *wm8971 = codec->private_data;
473
474 switch (freq) {
475 case 11289600:
476 case 12000000:
477 case 12288000:
478 case 16934400:
479 case 18432000:
480 wm8971->sysclk = freq;
481 return 0;
482 }
483 return -EINVAL;
484}
485
486static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
487 unsigned int fmt)
488{
489 struct snd_soc_codec *codec = codec_dai->codec;
490 u16 iface = 0;
491
492 /* set master/slave audio interface */
493 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
494 case SND_SOC_DAIFMT_CBM_CFM:
495 iface = 0x0040;
496 break;
497 case SND_SOC_DAIFMT_CBS_CFS:
498 break;
499 default:
500 return -EINVAL;
501 }
502
503 /* interface format */
504 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
505 case SND_SOC_DAIFMT_I2S:
506 iface |= 0x0002;
507 break;
508 case SND_SOC_DAIFMT_RIGHT_J:
509 break;
510 case SND_SOC_DAIFMT_LEFT_J:
511 iface |= 0x0001;
512 break;
513 case SND_SOC_DAIFMT_DSP_A:
514 iface |= 0x0003;
515 break;
516 case SND_SOC_DAIFMT_DSP_B:
517 iface |= 0x0013;
518 break;
519 default:
520 return -EINVAL;
521 }
522
523 /* clock inversion */
524 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
525 case SND_SOC_DAIFMT_NB_NF:
526 break;
527 case SND_SOC_DAIFMT_IB_IF:
528 iface |= 0x0090;
529 break;
530 case SND_SOC_DAIFMT_IB_NF:
531 iface |= 0x0080;
532 break;
533 case SND_SOC_DAIFMT_NB_IF:
534 iface |= 0x0010;
535 break;
536 default:
537 return -EINVAL;
538 }
539
540 wm8971_write(codec, WM8971_IFACE, iface);
541 return 0;
542}
543
544static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
545 struct snd_pcm_hw_params *params)
546{
547 struct snd_soc_pcm_runtime *rtd = substream->private_data;
548 struct snd_soc_device *socdev = rtd->socdev;
549 struct snd_soc_codec *codec = socdev->codec;
550 struct wm8971_priv *wm8971 = codec->private_data;
551 u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3;
552 u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0;
553 int coeff = get_coeff(wm8971->sysclk, params_rate(params));
554
555 /* bit size */
556 switch (params_format(params)) {
557 case SNDRV_PCM_FORMAT_S16_LE:
558 break;
559 case SNDRV_PCM_FORMAT_S20_3LE:
560 iface |= 0x0004;
561 break;
562 case SNDRV_PCM_FORMAT_S24_LE:
563 iface |= 0x0008;
564 break;
565 case SNDRV_PCM_FORMAT_S32_LE:
566 iface |= 0x000c;
567 break;
568 }
569
570 /* set iface & srate */
571 wm8971_write(codec, WM8971_IFACE, iface);
572 if (coeff >= 0)
573 wm8971_write(codec, WM8971_SRATE, srate |
574 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
575
576 return 0;
577}
578
579static int wm8971_mute(struct snd_soc_dai *dai, int mute)
580{
581 struct snd_soc_codec *codec = dai->codec;
582 u16 mute_reg = wm8971_read_reg_cache(codec, WM8971_ADCDAC) & 0xfff7;
583
584 if (mute)
585 wm8971_write(codec, WM8971_ADCDAC, mute_reg | 0x8);
586 else
587 wm8971_write(codec, WM8971_ADCDAC, mute_reg);
588 return 0;
589}
590
591static int wm8971_set_bias_level(struct snd_soc_codec *codec,
592 enum snd_soc_bias_level level)
593{
594 u16 pwr_reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
595
596 switch (level) {
597 case SND_SOC_BIAS_ON:
598 /* set vmid to 50k and unmute dac */
599 wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
600 break;
601 case SND_SOC_BIAS_PREPARE:
602 break;
603 case SND_SOC_BIAS_STANDBY:
604 /* mute dac and set vmid to 500k, enable VREF */
605 wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
606 break;
607 case SND_SOC_BIAS_OFF:
608 wm8971_write(codec, WM8971_PWR1, 0x0001);
609 break;
610 }
611 codec->bias_level = level;
612 return 0;
613}
614
615#define WM8971_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
616 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
617 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
618
619#define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
620 SNDRV_PCM_FMTBIT_S24_LE)
621
622struct snd_soc_dai wm8971_dai = {
623 .name = "WM8971",
624 .playback = {
625 .stream_name = "Playback",
626 .channels_min = 1,
627 .channels_max = 2,
628 .rates = WM8971_RATES,
629 .formats = WM8971_FORMATS,},
630 .capture = {
631 .stream_name = "Capture",
632 .channels_min = 1,
633 .channels_max = 2,
634 .rates = WM8971_RATES,
635 .formats = WM8971_FORMATS,},
636 .ops = {
637 .hw_params = wm8971_pcm_hw_params,
638 },
639 .dai_ops = {
640 .digital_mute = wm8971_mute,
641 .set_fmt = wm8971_set_dai_fmt,
642 .set_sysclk = wm8971_set_dai_sysclk,
643 },
644};
645EXPORT_SYMBOL_GPL(wm8971_dai);
646
647static void wm8971_work(struct work_struct *work)
648{
649 struct snd_soc_codec *codec =
650 container_of(work, struct snd_soc_codec, delayed_work.work);
651 wm8971_set_bias_level(codec, codec->bias_level);
652}
653
654static int wm8971_suspend(struct platform_device *pdev, pm_message_t state)
655{
656 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
657 struct snd_soc_codec *codec = socdev->codec;
658
659 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
660 return 0;
661}
662
663static int wm8971_resume(struct platform_device *pdev)
664{
665 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
666 struct snd_soc_codec *codec = socdev->codec;
667 int i;
668 u8 data[2];
669 u16 *cache = codec->reg_cache;
670 u16 reg;
671
672 /* Sync reg_cache with the hardware */
673 for (i = 0; i < ARRAY_SIZE(wm8971_reg); i++) {
674 if (i + 1 == WM8971_RESET)
675 continue;
676 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
677 data[1] = cache[i] & 0x00ff;
678 codec->hw_write(codec->control_data, data, 2);
679 }
680
681 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
682
683 /* charge wm8971 caps */
684 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
685 reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
686 wm8971_write(codec, WM8971_PWR1, reg | 0x01c0);
687 codec->bias_level = SND_SOC_BIAS_ON;
688 queue_delayed_work(wm8971_workq, &codec->delayed_work,
689 msecs_to_jiffies(1000));
690 }
691
692 return 0;
693}
694
695static int wm8971_init(struct snd_soc_device *socdev)
696{
697 struct snd_soc_codec *codec = socdev->codec;
698 int reg, ret = 0;
699
700 codec->name = "WM8971";
701 codec->owner = THIS_MODULE;
702 codec->read = wm8971_read_reg_cache;
703 codec->write = wm8971_write;
704 codec->set_bias_level = wm8971_set_bias_level;
705 codec->dai = &wm8971_dai;
706 codec->reg_cache_size = ARRAY_SIZE(wm8971_reg);
707 codec->num_dai = 1;
708 codec->reg_cache = kmemdup(wm8971_reg, sizeof(wm8971_reg), GFP_KERNEL);
709
710 if (codec->reg_cache == NULL)
711 return -ENOMEM;
712
713 wm8971_reset(codec);
714
715 /* register pcms */
716 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
717 if (ret < 0) {
718 printk(KERN_ERR "wm8971: failed to create pcms\n");
719 goto pcm_err;
720 }
721
722 /* charge output caps - set vmid to 5k for quick power up */
723 reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
724 wm8971_write(codec, WM8971_PWR1, reg | 0x01c0);
725 codec->bias_level = SND_SOC_BIAS_STANDBY;
726 queue_delayed_work(wm8971_workq, &codec->delayed_work,
727 msecs_to_jiffies(1000));
728
729 /* set the update bits */
730 reg = wm8971_read_reg_cache(codec, WM8971_LDAC);
731 wm8971_write(codec, WM8971_LDAC, reg | 0x0100);
732 reg = wm8971_read_reg_cache(codec, WM8971_RDAC);
733 wm8971_write(codec, WM8971_RDAC, reg | 0x0100);
734
735 reg = wm8971_read_reg_cache(codec, WM8971_LOUT1V);
736 wm8971_write(codec, WM8971_LOUT1V, reg | 0x0100);
737 reg = wm8971_read_reg_cache(codec, WM8971_ROUT1V);
738 wm8971_write(codec, WM8971_ROUT1V, reg | 0x0100);
739
740 reg = wm8971_read_reg_cache(codec, WM8971_LOUT2V);
741 wm8971_write(codec, WM8971_LOUT2V, reg | 0x0100);
742 reg = wm8971_read_reg_cache(codec, WM8971_ROUT2V);
743 wm8971_write(codec, WM8971_ROUT2V, reg | 0x0100);
744
745 reg = wm8971_read_reg_cache(codec, WM8971_LINVOL);
746 wm8971_write(codec, WM8971_LINVOL, reg | 0x0100);
747 reg = wm8971_read_reg_cache(codec, WM8971_RINVOL);
748 wm8971_write(codec, WM8971_RINVOL, reg | 0x0100);
749
750 wm8971_add_controls(codec);
751 wm8971_add_widgets(codec);
752 ret = snd_soc_register_card(socdev);
753 if (ret < 0) {
754 printk(KERN_ERR "wm8971: failed to register card\n");
755 goto card_err;
756 }
757 return ret;
758
759card_err:
760 snd_soc_free_pcms(socdev);
761 snd_soc_dapm_free(socdev);
762pcm_err:
763 kfree(codec->reg_cache);
764 return ret;
765}
766
767/* If the i2c layer weren't so broken, we could pass this kind of data
768 around */
769static struct snd_soc_device *wm8971_socdev;
770
771#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
772
773static int wm8971_i2c_probe(struct i2c_client *i2c,
774 const struct i2c_device_id *id)
775{
776 struct snd_soc_device *socdev = wm8971_socdev;
777 struct snd_soc_codec *codec = socdev->codec;
778 int ret;
779
780 i2c_set_clientdata(i2c, codec);
781
782 codec->control_data = i2c;
783
784 ret = wm8971_init(socdev);
785 if (ret < 0)
786 pr_err("failed to initialise WM8971\n");
787
788 return ret;
789}
790
791static int wm8971_i2c_remove(struct i2c_client *client)
792{
793 struct snd_soc_codec *codec = i2c_get_clientdata(client);
794 kfree(codec->reg_cache);
795 return 0;
796}
797
798static const struct i2c_device_id wm8971_i2c_id[] = {
799 { "wm8971", 0 },
800 { }
801};
802MODULE_DEVICE_TABLE(i2c, wm8971_i2c_id);
803
804static struct i2c_driver wm8971_i2c_driver = {
805 .driver = {
806 .name = "WM8971 I2C Codec",
807 .owner = THIS_MODULE,
808 },
809 .probe = wm8971_i2c_probe,
810 .remove = wm8971_i2c_remove,
811 .id_table = wm8971_i2c_id,
812};
813
814static int wm8971_add_i2c_device(struct platform_device *pdev,
815 const struct wm8971_setup_data *setup)
816{
817 struct i2c_board_info info;
818 struct i2c_adapter *adapter;
819 struct i2c_client *client;
820 int ret;
821
822 ret = i2c_add_driver(&wm8971_i2c_driver);
823 if (ret != 0) {
824 dev_err(&pdev->dev, "can't add i2c driver\n");
825 return ret;
826 }
827
828 memset(&info, 0, sizeof(struct i2c_board_info));
829 info.addr = setup->i2c_address;
830 strlcpy(info.type, "wm8971", I2C_NAME_SIZE);
831
832 adapter = i2c_get_adapter(setup->i2c_bus);
833 if (!adapter) {
834 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
835 setup->i2c_bus);
836 goto err_driver;
837 }
838
839 client = i2c_new_device(adapter, &info);
840 i2c_put_adapter(adapter);
841 if (!client) {
842 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
843 (unsigned int)info.addr);
844 goto err_driver;
845 }
846
847 return 0;
848
849err_driver:
850 i2c_del_driver(&wm8971_i2c_driver);
851 return -ENODEV;
852}
853
854#endif
855
856static int wm8971_probe(struct platform_device *pdev)
857{
858 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
859 struct wm8971_setup_data *setup;
860 struct snd_soc_codec *codec;
861 struct wm8971_priv *wm8971;
862 int ret = 0;
863
864 pr_info("WM8971 Audio Codec %s", WM8971_VERSION);
865
866 setup = socdev->codec_data;
867 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
868 if (codec == NULL)
869 return -ENOMEM;
870
871 wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL);
872 if (wm8971 == NULL) {
873 kfree(codec);
874 return -ENOMEM;
875 }
876
877 codec->private_data = wm8971;
878 socdev->codec = codec;
879 mutex_init(&codec->mutex);
880 INIT_LIST_HEAD(&codec->dapm_widgets);
881 INIT_LIST_HEAD(&codec->dapm_paths);
882 wm8971_socdev = socdev;
883
884 INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
885 wm8971_workq = create_workqueue("wm8971");
886 if (wm8971_workq == NULL) {
887 kfree(codec->private_data);
888 kfree(codec);
889 return -ENOMEM;
890 }
891
892#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
893 if (setup->i2c_address) {
894 codec->hw_write = (hw_write_t)i2c_master_send;
895 ret = wm8971_add_i2c_device(pdev, setup);
896 }
897#endif
898 /* Add other interfaces here */
899
900 if (ret != 0) {
901 destroy_workqueue(wm8971_workq);
902 kfree(codec->private_data);
903 kfree(codec);
904 }
905
906 return ret;
907}
908
909/* power down chip */
910static int wm8971_remove(struct platform_device *pdev)
911{
912 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
913 struct snd_soc_codec *codec = socdev->codec;
914
915 if (codec->control_data)
916 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
917 if (wm8971_workq)
918 destroy_workqueue(wm8971_workq);
919 snd_soc_free_pcms(socdev);
920 snd_soc_dapm_free(socdev);
921#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
922 i2c_unregister_device(codec->control_data);
923 i2c_del_driver(&wm8971_i2c_driver);
924#endif
925 kfree(codec->private_data);
926 kfree(codec);
927
928 return 0;
929}
930
931struct snd_soc_codec_device soc_codec_dev_wm8971 = {
932 .probe = wm8971_probe,
933 .remove = wm8971_remove,
934 .suspend = wm8971_suspend,
935 .resume = wm8971_resume,
936};
937
938EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971);
939
940MODULE_DESCRIPTION("ASoC WM8971 driver");
941MODULE_AUTHOR("Lab126");
942MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8971.h b/sound/soc/codecs/wm8971.h
new file mode 100644
index 00000000000..ef4f08f9f34
--- /dev/null
+++ b/sound/soc/codecs/wm8971.h
@@ -0,0 +1,64 @@
1/*
2 * wm8971.h -- audio driver for WM8971
3 *
4 * Copyright 2005 Lab126, Inc.
5 *
6 * Author: Kenneth Kiraly <kiraly@lab126.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef _WM8971_H
16#define _WM8971_H
17
18#define WM8971_LINVOL 0x00
19#define WM8971_RINVOL 0x01
20#define WM8971_LOUT1V 0x02
21#define WM8971_ROUT1V 0x03
22#define WM8971_ADCDAC 0x05
23#define WM8971_IFACE 0x07
24#define WM8971_SRATE 0x08
25#define WM8971_LDAC 0x0a
26#define WM8971_RDAC 0x0b
27#define WM8971_BASS 0x0c
28#define WM8971_TREBLE 0x0d
29#define WM8971_RESET 0x0f
30#define WM8971_ALC1 0x11
31#define WM8971_ALC2 0x12
32#define WM8971_ALC3 0x13
33#define WM8971_NGATE 0x14
34#define WM8971_LADC 0x15
35#define WM8971_RADC 0x16
36#define WM8971_ADCTL1 0x17
37#define WM8971_ADCTL2 0x18
38#define WM8971_PWR1 0x19
39#define WM8971_PWR2 0x1a
40#define WM8971_ADCTL3 0x1b
41#define WM8971_ADCIN 0x1f
42#define WM8971_LADCIN 0x20
43#define WM8971_RADCIN 0x21
44#define WM8971_LOUTM1 0x22
45#define WM8971_LOUTM2 0x23
46#define WM8971_ROUTM1 0x24
47#define WM8971_ROUTM2 0x25
48#define WM8971_MOUTM1 0x26
49#define WM8971_MOUTM2 0x27
50#define WM8971_LOUT2V 0x28
51#define WM8971_ROUT2V 0x29
52#define WM8971_MOUTV 0x2A
53
54#define WM8971_SYSCLK 0
55
56struct wm8971_setup_data {
57 int i2c_bus;
58 unsigned short i2c_address;
59};
60
61extern struct snd_soc_dai wm8971_dai;
62extern struct snd_soc_codec_device soc_codec_dev_wm8971;
63
64#endif
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index dd995ef448b..63410d7b5ef 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1477,81 +1477,86 @@ static struct snd_soc_device *wm8990_socdev;
1477 * low = 0x34 1477 * low = 0x34
1478 * high = 0x36 1478 * high = 0x36
1479 */ 1479 */
1480static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1481 1480
1482/* Magic definition of all other variables and things */ 1481static int wm8990_i2c_probe(struct i2c_client *i2c,
1483I2C_CLIENT_INSMOD; 1482 const struct i2c_device_id *id)
1484
1485static struct i2c_driver wm8990_i2c_driver;
1486static struct i2c_client client_template;
1487
1488static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1489{ 1483{
1490 struct snd_soc_device *socdev = wm8990_socdev; 1484 struct snd_soc_device *socdev = wm8990_socdev;
1491 struct wm8990_setup_data *setup = socdev->codec_data;
1492 struct snd_soc_codec *codec = socdev->codec; 1485 struct snd_soc_codec *codec = socdev->codec;
1493 struct i2c_client *i2c;
1494 int ret; 1486 int ret;
1495 1487
1496 if (addr != setup->i2c_address)
1497 return -ENODEV;
1498
1499 client_template.adapter = adap;
1500 client_template.addr = addr;
1501
1502 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1503 if (i2c == NULL)
1504 return -ENOMEM;
1505
1506 i2c_set_clientdata(i2c, codec); 1488 i2c_set_clientdata(i2c, codec);
1507 codec->control_data = i2c; 1489 codec->control_data = i2c;
1508 1490
1509 ret = i2c_attach_client(i2c);
1510 if (ret < 0) {
1511 pr_err("failed to attach codec at addr %x\n", addr);
1512 goto err;
1513 }
1514
1515 ret = wm8990_init(socdev); 1491 ret = wm8990_init(socdev);
1516 if (ret < 0) { 1492 if (ret < 0)
1517 pr_err("failed to initialise WM8990\n"); 1493 pr_err("failed to initialise WM8990\n");
1518 goto err;
1519 }
1520 return ret;
1521 1494
1522err:
1523 kfree(i2c);
1524 return ret; 1495 return ret;
1525} 1496}
1526 1497
1527static int wm8990_i2c_detach(struct i2c_client *client) 1498static int wm8990_i2c_remove(struct i2c_client *client)
1528{ 1499{
1529 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1500 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1530 i2c_detach_client(client);
1531 kfree(codec->reg_cache); 1501 kfree(codec->reg_cache);
1532 kfree(client);
1533 return 0; 1502 return 0;
1534} 1503}
1535 1504
1536static int wm8990_i2c_attach(struct i2c_adapter *adap) 1505static const struct i2c_device_id wm8990_i2c_id[] = {
1537{ 1506 { "wm8990", 0 },
1538 return i2c_probe(adap, &addr_data, wm8990_codec_probe); 1507 { }
1539} 1508};
1509MODULE_DEVICE_TABLE(i2c, wm8990_i2c_id);
1540 1510
1541static struct i2c_driver wm8990_i2c_driver = { 1511static struct i2c_driver wm8990_i2c_driver = {
1542 .driver = { 1512 .driver = {
1543 .name = "WM8990 I2C Codec", 1513 .name = "WM8990 I2C Codec",
1544 .owner = THIS_MODULE, 1514 .owner = THIS_MODULE,
1545 }, 1515 },
1546 .attach_adapter = wm8990_i2c_attach, 1516 .probe = wm8990_i2c_probe,
1547 .detach_client = wm8990_i2c_detach, 1517 .remove = wm8990_i2c_remove,
1548 .command = NULL, 1518 .id_table = wm8990_i2c_id,
1549}; 1519};
1550 1520
1551static struct i2c_client client_template = { 1521static int wm8990_add_i2c_device(struct platform_device *pdev,
1552 .name = "WM8990", 1522 const struct wm8990_setup_data *setup)
1553 .driver = &wm8990_i2c_driver, 1523{
1554}; 1524 struct i2c_board_info info;
1525 struct i2c_adapter *adapter;
1526 struct i2c_client *client;
1527 int ret;
1528
1529 ret = i2c_add_driver(&wm8990_i2c_driver);
1530 if (ret != 0) {
1531 dev_err(&pdev->dev, "can't add i2c driver\n");
1532 return ret;
1533 }
1534
1535 memset(&info, 0, sizeof(struct i2c_board_info));
1536 info.addr = setup->i2c_address;
1537 strlcpy(info.type, "wm8990", I2C_NAME_SIZE);
1538
1539 adapter = i2c_get_adapter(setup->i2c_bus);
1540 if (!adapter) {
1541 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1542 setup->i2c_bus);
1543 goto err_driver;
1544 }
1545
1546 client = i2c_new_device(adapter, &info);
1547 i2c_put_adapter(adapter);
1548 if (!client) {
1549 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1550 (unsigned int)info.addr);
1551 goto err_driver;
1552 }
1553
1554 return 0;
1555
1556err_driver:
1557 i2c_del_driver(&wm8990_i2c_driver);
1558 return -ENODEV;
1559}
1555#endif 1560#endif
1556 1561
1557static int wm8990_probe(struct platform_device *pdev) 1562static int wm8990_probe(struct platform_device *pdev)
@@ -1560,7 +1565,7 @@ static int wm8990_probe(struct platform_device *pdev)
1560 struct wm8990_setup_data *setup; 1565 struct wm8990_setup_data *setup;
1561 struct snd_soc_codec *codec; 1566 struct snd_soc_codec *codec;
1562 struct wm8990_priv *wm8990; 1567 struct wm8990_priv *wm8990;
1563 int ret = 0; 1568 int ret;
1564 1569
1565 pr_info("WM8990 Audio Codec %s\n", WM8990_VERSION); 1570 pr_info("WM8990 Audio Codec %s\n", WM8990_VERSION);
1566 1571
@@ -1582,16 +1587,13 @@ static int wm8990_probe(struct platform_device *pdev)
1582 INIT_LIST_HEAD(&codec->dapm_paths); 1587 INIT_LIST_HEAD(&codec->dapm_paths);
1583 wm8990_socdev = socdev; 1588 wm8990_socdev = socdev;
1584 1589
1590 ret = -ENODEV;
1591
1585#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1592#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1586 if (setup->i2c_address) { 1593 if (setup->i2c_address) {
1587 normal_i2c[0] = setup->i2c_address;
1588 codec->hw_write = (hw_write_t)i2c_master_send; 1594 codec->hw_write = (hw_write_t)i2c_master_send;
1589 ret = i2c_add_driver(&wm8990_i2c_driver); 1595 ret = wm8990_add_i2c_device(pdev, setup);
1590 if (ret != 0)
1591 printk(KERN_ERR "can't add i2c driver");
1592 } 1596 }
1593#else
1594 /* Add other interfaces here */
1595#endif 1597#endif
1596 1598
1597 if (ret != 0) { 1599 if (ret != 0) {
@@ -1612,6 +1614,7 @@ static int wm8990_remove(struct platform_device *pdev)
1612 snd_soc_free_pcms(socdev); 1614 snd_soc_free_pcms(socdev);
1613 snd_soc_dapm_free(socdev); 1615 snd_soc_dapm_free(socdev);
1614#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1616#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1617 i2c_unregister_device(codec->control_data);
1615 i2c_del_driver(&wm8990_i2c_driver); 1618 i2c_del_driver(&wm8990_i2c_driver);
1616#endif 1619#endif
1617 kfree(codec->private_data); 1620 kfree(codec->private_data);
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h
index 0a08325d544..0e192f3b078 100644
--- a/sound/soc/codecs/wm8990.h
+++ b/sound/soc/codecs/wm8990.h
@@ -827,6 +827,7 @@
827#define WM8990_AINRMUX_PWR_BIT 3 827#define WM8990_AINRMUX_PWR_BIT 3
828 828
829struct wm8990_setup_data { 829struct wm8990_setup_data {
830 unsigned i2c_bus;
830 unsigned short i2c_address; 831 unsigned short i2c_address;
831}; 832};
832 833
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 38d1fe0971f..441d0580db1 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -419,8 +419,12 @@ SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
419SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 419SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
420SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1), 420SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1),
421SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1), 421SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1),
422SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", AC97_EXTENDED_MID, 5, 1), 422SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0),
423SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", AC97_EXTENDED_MID, 4, 1), 423SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0),
424SND_SOC_DAPM_ADC("Left HiFi ADC", "Left HiFi Capture", SND_SOC_NOPM, 0, 0),
425SND_SOC_DAPM_ADC("Right HiFi ADC", "Right HiFi Capture", SND_SOC_NOPM, 0, 0),
426SND_SOC_DAPM_ADC("Left Voice ADC", "Left Voice Capture", SND_SOC_NOPM, 0, 0),
427SND_SOC_DAPM_ADC("Right Voice ADC", "Right Voice Capture", SND_SOC_NOPM, 0, 0),
424SND_SOC_DAPM_PGA("Left Headphone", AC97_EXTENDED_MSTATUS, 10, 1, NULL, 0), 428SND_SOC_DAPM_PGA("Left Headphone", AC97_EXTENDED_MSTATUS, 10, 1, NULL, 0),
425SND_SOC_DAPM_PGA("Right Headphone", AC97_EXTENDED_MSTATUS, 9, 1, NULL, 0), 429SND_SOC_DAPM_PGA("Right Headphone", AC97_EXTENDED_MSTATUS, 9, 1, NULL, 0),
426SND_SOC_DAPM_PGA("Left Speaker", AC97_EXTENDED_MSTATUS, 8, 1, NULL, 0), 430SND_SOC_DAPM_PGA("Left Speaker", AC97_EXTENDED_MSTATUS, 8, 1, NULL, 0),
@@ -583,9 +587,13 @@ static const struct snd_soc_dapm_route audio_map[] = {
583 587
584 /* left ADC */ 588 /* left ADC */
585 {"Left ADC", NULL, "Left Capture Source"}, 589 {"Left ADC", NULL, "Left Capture Source"},
590 {"Left Voice ADC", NULL, "Left ADC"},
591 {"Left HiFi ADC", NULL, "Left ADC"},
586 592
587 /* right ADC */ 593 /* right ADC */
588 {"Right ADC", NULL, "Right Capture Source"}, 594 {"Right ADC", NULL, "Right Capture Source"},
595 {"Right Voice ADC", NULL, "Right ADC"},
596 {"Right HiFi ADC", NULL, "Right ADC"},
589 597
590 /* mic */ 598 /* mic */
591 {"Mic A Pre Amp", NULL, "Mic A Source"}, 599 {"Mic A Pre Amp", NULL, "Mic A Source"},
@@ -949,17 +957,17 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
949 957
950static void wm9713_voiceshutdown(struct snd_pcm_substream *substream) 958static void wm9713_voiceshutdown(struct snd_pcm_substream *substream)
951{ 959{
952 struct snd_soc_pcm_runtime *rtd = substream->private_data; 960 struct snd_soc_pcm_runtime *rtd = substream->private_data;
953 struct snd_soc_device *socdev = rtd->socdev; 961 struct snd_soc_device *socdev = rtd->socdev;
954 struct snd_soc_codec *codec = socdev->codec; 962 struct snd_soc_codec *codec = socdev->codec;
955 u16 status; 963 u16 status;
956 964
957 /* Gracefully shut down the voice interface. */ 965 /* Gracefully shut down the voice interface. */
958 status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000; 966 status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000;
959 ac97_write(codec, AC97_HANDSET_RATE, 0x0280); 967 ac97_write(codec, AC97_HANDSET_RATE, 0x0280);
960 schedule_timeout_interruptible(msecs_to_jiffies(1)); 968 schedule_timeout_interruptible(msecs_to_jiffies(1));
961 ac97_write(codec, AC97_HANDSET_RATE, 0x0F80); 969 ac97_write(codec, AC97_HANDSET_RATE, 0x0F80);
962 ac97_write(codec, AC97_EXTENDED_MID, status); 970 ac97_write(codec, AC97_EXTENDED_MID, status);
963} 971}
964 972
965static int ac97_hifi_prepare(struct snd_pcm_substream *substream) 973static int ac97_hifi_prepare(struct snd_pcm_substream *substream)
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 65fdbd81a37..9e6062cd6b5 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ASoC driver for TI DAVINCI EVM platform 2 * ASoC driver for TI DAVINCI EVM platform
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -136,6 +136,7 @@ static struct snd_soc_machine snd_soc_machine_evm = {
136 136
137/* evm audio private data */ 137/* evm audio private data */
138static struct aic3x_setup_data evm_aic3x_setup = { 138static struct aic3x_setup_data evm_aic3x_setup = {
139 .i2c_bus = 0,
139 .i2c_address = 0x1b, 140 .i2c_address = 0x1b,
140}; 141};
141 142
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 5ebf1ff71c4..abb5fedb0b1 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor 2 * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -256,7 +256,7 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
256 mcbsp_word_length = DAVINCI_MCBSP_WORD_32; 256 mcbsp_word_length = DAVINCI_MCBSP_WORD_32;
257 break; 257 break;
258 default: 258 default:
259 printk(KERN_WARNING "davinci-i2s: unsupported PCM format"); 259 printk(KERN_WARNING "davinci-i2s: unsupported PCM format\n");
260 return -EINVAL; 260 return -EINVAL;
261 } 261 }
262 262
diff --git a/sound/soc/davinci/davinci-i2s.h b/sound/soc/davinci/davinci-i2s.h
index c5b091807ee..241648ce887 100644
--- a/sound/soc/davinci/davinci-i2s.h
+++ b/sound/soc/davinci/davinci-i2s.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor 2 * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 6a5e56a782b..76feaa65737 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA PCM interface for the TI DAVINCI processor 2 * ALSA PCM interface for the TI DAVINCI processor
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 8d6a45e75a6..62cb4eb07e3 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA PCM interface for the TI DAVINCI processor 2 * ALSA PCM interface for the TI DAVINCI processor
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 3368ace6097..bba9546ba5f 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -1,3 +1,6 @@
1config SND_SOC_OF_SIMPLE
2 tristate
3
1config SND_SOC_MPC8610 4config SND_SOC_MPC8610
2 bool "ALSA SoC support for the MPC8610 SOC" 5 bool "ALSA SoC support for the MPC8610 SOC"
3 depends on MPC8610_HPCD 6 depends on MPC8610_HPCD
@@ -14,3 +17,10 @@ config SND_SOC_MPC8610_HPCD
14 default y if MPC8610_HPCD 17 default y if MPC8610_HPCD
15 help 18 help
16 Say Y if you want to enable audio on the Freescale MPC8610 HPCD. 19 Say Y if you want to enable audio on the Freescale MPC8610 HPCD.
20
21config SND_SOC_MPC5200_I2S
22 tristate "Freescale MPC5200 PSC in I2S mode driver"
23 select SND_SOC_OF_SIMPLE
24 depends on SND_SOC && PPC_MPC52xx
25 help
26 Say Y here to support the MPC5200 PSCs in I2S mode.
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 62f680a4a77..035da4afec3 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -1,6 +1,11 @@
1# Simple machine driver that extracts configuration from the OF device tree
2obj-$(CONFIG_SND_SOC_OF_SIMPLE) += soc-of-simple.o
3
1# MPC8610 HPCD Machine Support 4# MPC8610 HPCD Machine Support
2obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += mpc8610_hpcd.o 5obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += mpc8610_hpcd.o
3 6
4# MPC8610 Platform Support 7# MPC8610 Platform Support
5obj-$(CONFIG_SND_SOC_MPC8610) += fsl_ssi.o fsl_dma.o 8obj-$(CONFIG_SND_SOC_MPC8610) += fsl_ssi.o fsl_dma.o
6 9
10obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o
11
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
new file mode 100644
index 00000000000..86923299bc1
--- /dev/null
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -0,0 +1,884 @@
1/*
2 * Freescale MPC5200 PSC in I2S mode
3 * ALSA SoC Digital Audio Interface (DAI) driver
4 *
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
6 */
7
8#include <linux/init.h>
9#include <linux/module.h>
10#include <linux/interrupt.h>
11#include <linux/device.h>
12#include <linux/delay.h>
13#include <linux/of_device.h>
14#include <linux/of_platform.h>
15#include <linux/dma-mapping.h>
16
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/initval.h>
21#include <sound/soc.h>
22#include <sound/soc-of-simple.h>
23
24#include <sysdev/bestcomm/bestcomm.h>
25#include <sysdev/bestcomm/gen_bd.h>
26#include <asm/mpc52xx_psc.h>
27
28MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
29MODULE_DESCRIPTION("Freescale MPC5200 PSC in I2S mode ASoC Driver");
30MODULE_LICENSE("GPL");
31
32/**
33 * PSC_I2S_RATES: sample rates supported by the I2S
34 *
35 * This driver currently only supports the PSC running in I2S slave mode,
36 * which means the codec determines the sample rate. Therefore, we tell
37 * ALSA that we support all rates and let the codec driver decide what rates
38 * are really supported.
39 */
40#define PSC_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
41 SNDRV_PCM_RATE_CONTINUOUS)
42
43/**
44 * PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode
45 */
46#define PSC_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \
47 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE | \
48 SNDRV_PCM_FMTBIT_S32_BE)
49
50/**
51 * psc_i2s_stream - Data specific to a single stream (playback or capture)
52 * @active: flag indicating if the stream is active
53 * @psc_i2s: pointer back to parent psc_i2s data structure
54 * @bcom_task: bestcomm task structure
55 * @irq: irq number for bestcomm task
56 * @period_start: physical address of start of DMA region
57 * @period_end: physical address of end of DMA region
58 * @period_next_pt: physical address of next DMA buffer to enqueue
59 * @period_bytes: size of DMA period in bytes
60 */
61struct psc_i2s_stream {
62 int active;
63 struct psc_i2s *psc_i2s;
64 struct bcom_task *bcom_task;
65 int irq;
66 struct snd_pcm_substream *stream;
67 dma_addr_t period_start;
68 dma_addr_t period_end;
69 dma_addr_t period_next_pt;
70 dma_addr_t period_current_pt;
71 int period_bytes;
72};
73
74/**
75 * psc_i2s - Private driver data
76 * @name: short name for this device ("PSC0", "PSC1", etc)
77 * @psc_regs: pointer to the PSC's registers
78 * @fifo_regs: pointer to the PSC's FIFO registers
79 * @irq: IRQ of this PSC
80 * @dev: struct device pointer
81 * @dai: the CPU DAI for this device
82 * @sicr: Base value used in serial interface control register; mode is ORed
83 * with this value.
84 * @playback: Playback stream context data
85 * @capture: Capture stream context data
86 */
87struct psc_i2s {
88 char name[32];
89 struct mpc52xx_psc __iomem *psc_regs;
90 struct mpc52xx_psc_fifo __iomem *fifo_regs;
91 unsigned int irq;
92 struct device *dev;
93 struct snd_soc_dai dai;
94 spinlock_t lock;
95 u32 sicr;
96
97 /* per-stream data */
98 struct psc_i2s_stream playback;
99 struct psc_i2s_stream capture;
100
101 /* Statistics */
102 struct {
103 int overrun_count;
104 int underrun_count;
105 } stats;
106};
107
108/*
109 * Interrupt handlers
110 */
111static irqreturn_t psc_i2s_status_irq(int irq, void *_psc_i2s)
112{
113 struct psc_i2s *psc_i2s = _psc_i2s;
114 struct mpc52xx_psc __iomem *regs = psc_i2s->psc_regs;
115 u16 isr;
116
117 isr = in_be16(&regs->mpc52xx_psc_isr);
118
119 /* Playback underrun error */
120 if (psc_i2s->playback.active && (isr & MPC52xx_PSC_IMR_TXEMP))
121 psc_i2s->stats.underrun_count++;
122
123 /* Capture overrun error */
124 if (psc_i2s->capture.active && (isr & MPC52xx_PSC_IMR_ORERR))
125 psc_i2s->stats.overrun_count++;
126
127 out_8(&regs->command, 4 << 4); /* reset the error status */
128
129 return IRQ_HANDLED;
130}
131
132/**
133 * psc_i2s_bcom_enqueue_next_buffer - Enqueue another audio buffer
134 * @s: pointer to stream private data structure
135 *
136 * Enqueues another audio period buffer into the bestcomm queue.
137 *
138 * Note: The routine must only be called when there is space available in
139 * the queue. Otherwise the enqueue will fail and the audio ring buffer
140 * will get out of sync
141 */
142static void psc_i2s_bcom_enqueue_next_buffer(struct psc_i2s_stream *s)
143{
144 struct bcom_bd *bd;
145
146 /* Prepare and enqueue the next buffer descriptor */
147 bd = bcom_prepare_next_buffer(s->bcom_task);
148 bd->status = s->period_bytes;
149 bd->data[0] = s->period_next_pt;
150 bcom_submit_next_buffer(s->bcom_task, NULL);
151
152 /* Update for next period */
153 s->period_next_pt += s->period_bytes;
154 if (s->period_next_pt >= s->period_end)
155 s->period_next_pt = s->period_start;
156}
157
158/* Bestcomm DMA irq handler */
159static irqreturn_t psc_i2s_bcom_irq(int irq, void *_psc_i2s_stream)
160{
161 struct psc_i2s_stream *s = _psc_i2s_stream;
162
163 /* For each finished period, dequeue the completed period buffer
164 * and enqueue a new one in it's place. */
165 while (bcom_buffer_done(s->bcom_task)) {
166 bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
167 s->period_current_pt += s->period_bytes;
168 if (s->period_current_pt >= s->period_end)
169 s->period_current_pt = s->period_start;
170 psc_i2s_bcom_enqueue_next_buffer(s);
171 bcom_enable(s->bcom_task);
172 }
173
174 /* If the stream is active, then also inform the PCM middle layer
175 * of the period finished event. */
176 if (s->active)
177 snd_pcm_period_elapsed(s->stream);
178
179 return IRQ_HANDLED;
180}
181
182/**
183 * psc_i2s_startup: create a new substream
184 *
185 * This is the first function called when a stream is opened.
186 *
187 * If this is the first stream open, then grab the IRQ and program most of
188 * the PSC registers.
189 */
190static int psc_i2s_startup(struct snd_pcm_substream *substream)
191{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data;
193 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
194 int rc;
195
196 dev_dbg(psc_i2s->dev, "psc_i2s_startup(substream=%p)\n", substream);
197
198 if (!psc_i2s->playback.active &&
199 !psc_i2s->capture.active) {
200 /* Setup the IRQs */
201 rc = request_irq(psc_i2s->irq, &psc_i2s_status_irq, IRQF_SHARED,
202 "psc-i2s-status", psc_i2s);
203 rc |= request_irq(psc_i2s->capture.irq,
204 &psc_i2s_bcom_irq, IRQF_SHARED,
205 "psc-i2s-capture", &psc_i2s->capture);
206 rc |= request_irq(psc_i2s->playback.irq,
207 &psc_i2s_bcom_irq, IRQF_SHARED,
208 "psc-i2s-playback", &psc_i2s->playback);
209 if (rc) {
210 free_irq(psc_i2s->irq, psc_i2s);
211 free_irq(psc_i2s->capture.irq,
212 &psc_i2s->capture);
213 free_irq(psc_i2s->playback.irq,
214 &psc_i2s->playback);
215 return -ENODEV;
216 }
217 }
218
219 return 0;
220}
221
222static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
223 struct snd_pcm_hw_params *params)
224{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data;
226 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
227 u32 mode;
228
229 dev_dbg(psc_i2s->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
230 " periods=%i buffer_size=%i buffer_bytes=%i\n",
231 __func__, substream, params_period_size(params),
232 params_period_bytes(params), params_periods(params),
233 params_buffer_size(params), params_buffer_bytes(params));
234
235 switch (params_format(params)) {
236 case SNDRV_PCM_FORMAT_S8:
237 mode = MPC52xx_PSC_SICR_SIM_CODEC_8;
238 break;
239 case SNDRV_PCM_FORMAT_S16_BE:
240 mode = MPC52xx_PSC_SICR_SIM_CODEC_16;
241 break;
242 case SNDRV_PCM_FORMAT_S24_BE:
243 mode = MPC52xx_PSC_SICR_SIM_CODEC_24;
244 break;
245 case SNDRV_PCM_FORMAT_S32_BE:
246 mode = MPC52xx_PSC_SICR_SIM_CODEC_32;
247 break;
248 default:
249 dev_dbg(psc_i2s->dev, "invalid format\n");
250 return -EINVAL;
251 }
252 out_be32(&psc_i2s->psc_regs->sicr, psc_i2s->sicr | mode);
253
254 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
255
256 return 0;
257}
258
259static int psc_i2s_hw_free(struct snd_pcm_substream *substream)
260{
261 snd_pcm_set_runtime_buffer(substream, NULL);
262 return 0;
263}
264
265/**
266 * psc_i2s_trigger: start and stop the DMA transfer.
267 *
268 * This function is called by ALSA to start, stop, pause, and resume the DMA
269 * transfer of data.
270 */
271static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
272{
273 struct snd_soc_pcm_runtime *rtd = substream->private_data;
274 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
275 struct snd_pcm_runtime *runtime = substream->runtime;
276 struct psc_i2s_stream *s;
277 struct mpc52xx_psc __iomem *regs = psc_i2s->psc_regs;
278 u16 imr;
279 u8 psc_cmd;
280 long flags;
281
282 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
283 s = &psc_i2s->capture;
284 else
285 s = &psc_i2s->playback;
286
287 dev_dbg(psc_i2s->dev, "psc_i2s_trigger(substream=%p, cmd=%i)"
288 " stream_id=%i\n",
289 substream, cmd, substream->pstr->stream);
290
291 switch (cmd) {
292 case SNDRV_PCM_TRIGGER_START:
293 s->period_bytes = frames_to_bytes(runtime,
294 runtime->period_size);
295 s->period_start = virt_to_phys(runtime->dma_area);
296 s->period_end = s->period_start +
297 (s->period_bytes * runtime->periods);
298 s->period_next_pt = s->period_start;
299 s->period_current_pt = s->period_start;
300 s->active = 1;
301
302 /* First; reset everything */
303 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) {
304 out_8(&regs->command, MPC52xx_PSC_RST_RX);
305 out_8(&regs->command, MPC52xx_PSC_RST_ERR_STAT);
306 } else {
307 out_8(&regs->command, MPC52xx_PSC_RST_TX);
308 out_8(&regs->command, MPC52xx_PSC_RST_ERR_STAT);
309 }
310
311 /* Next, fill up the bestcomm bd queue and enable DMA.
312 * This will begin filling the PSC's fifo. */
313 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
314 bcom_gen_bd_rx_reset(s->bcom_task);
315 else
316 bcom_gen_bd_tx_reset(s->bcom_task);
317 while (!bcom_queue_full(s->bcom_task))
318 psc_i2s_bcom_enqueue_next_buffer(s);
319 bcom_enable(s->bcom_task);
320
321 /* Due to errata in the i2s mode; need to line up enabling
322 * the transmitter with a transition on the frame sync
323 * line */
324
325 spin_lock_irqsave(&psc_i2s->lock, flags);
326 /* first make sure it is low */
327 while ((in_8(&regs->ipcr_acr.ipcr) & 0x80) != 0)
328 ;
329 /* then wait for the transition to high */
330 while ((in_8(&regs->ipcr_acr.ipcr) & 0x80) == 0)
331 ;
332 /* Finally, enable the PSC.
333 * Receiver must always be enabled; even when we only want
334 * transmit. (see 15.3.2.3 of MPC5200B User's Guide) */
335 psc_cmd = MPC52xx_PSC_RX_ENABLE;
336 if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK)
337 psc_cmd |= MPC52xx_PSC_TX_ENABLE;
338 out_8(&regs->command, psc_cmd);
339 spin_unlock_irqrestore(&psc_i2s->lock, flags);
340
341 break;
342
343 case SNDRV_PCM_TRIGGER_STOP:
344 /* Turn off the PSC */
345 s->active = 0;
346 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) {
347 if (!psc_i2s->playback.active) {
348 out_8(&regs->command, 2 << 4); /* reset rx */
349 out_8(&regs->command, 3 << 4); /* reset tx */
350 out_8(&regs->command, 4 << 4); /* reset err */
351 }
352 } else {
353 out_8(&regs->command, 3 << 4); /* reset tx */
354 out_8(&regs->command, 4 << 4); /* reset err */
355 if (!psc_i2s->capture.active)
356 out_8(&regs->command, 2 << 4); /* reset rx */
357 }
358
359 bcom_disable(s->bcom_task);
360 while (!bcom_queue_empty(s->bcom_task))
361 bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
362
363 break;
364
365 default:
366 dev_dbg(psc_i2s->dev, "invalid command\n");
367 return -EINVAL;
368 }
369
370 /* Update interrupt enable settings */
371 imr = 0;
372 if (psc_i2s->playback.active)
373 imr |= MPC52xx_PSC_IMR_TXEMP;
374 if (psc_i2s->capture.active)
375 imr |= MPC52xx_PSC_IMR_ORERR;
376 out_be16(&regs->isr_imr.imr, imr);
377
378 return 0;
379}
380
381/**
382 * psc_i2s_shutdown: shutdown the data transfer on a stream
383 *
384 * Shutdown the PSC if there are no other substreams open.
385 */
386static void psc_i2s_shutdown(struct snd_pcm_substream *substream)
387{
388 struct snd_soc_pcm_runtime *rtd = substream->private_data;
389 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
390
391 dev_dbg(psc_i2s->dev, "psc_i2s_shutdown(substream=%p)\n", substream);
392
393 /*
394 * If this is the last active substream, disable the PSC and release
395 * the IRQ.
396 */
397 if (!psc_i2s->playback.active &&
398 !psc_i2s->capture.active) {
399
400 /* Disable all interrupts and reset the PSC */
401 out_be16(&psc_i2s->psc_regs->isr_imr.imr, 0);
402 out_8(&psc_i2s->psc_regs->command, 3 << 4); /* reset tx */
403 out_8(&psc_i2s->psc_regs->command, 2 << 4); /* reset rx */
404 out_8(&psc_i2s->psc_regs->command, 1 << 4); /* reset mode */
405 out_8(&psc_i2s->psc_regs->command, 4 << 4); /* reset error */
406
407 /* Release irqs */
408 free_irq(psc_i2s->irq, psc_i2s);
409 free_irq(psc_i2s->capture.irq, &psc_i2s->capture);
410 free_irq(psc_i2s->playback.irq, &psc_i2s->playback);
411 }
412}
413
414/**
415 * psc_i2s_set_sysclk: set the clock frequency and direction
416 *
417 * This function is called by the machine driver to tell us what the clock
418 * frequency and direction are.
419 *
420 * Currently, we only support operating as a clock slave (SND_SOC_CLOCK_IN),
421 * and we don't care about the frequency. Return an error if the direction
422 * is not SND_SOC_CLOCK_IN.
423 *
424 * @clk_id: reserved, should be zero
425 * @freq: the frequency of the given clock ID, currently ignored
426 * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master)
427 */
428static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
429 int clk_id, unsigned int freq, int dir)
430{
431 struct psc_i2s *psc_i2s = cpu_dai->private_data;
432 dev_dbg(psc_i2s->dev, "psc_i2s_set_sysclk(cpu_dai=%p, dir=%i)\n",
433 cpu_dai, dir);
434 return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL;
435}
436
437/**
438 * psc_i2s_set_fmt: set the serial format.
439 *
440 * This function is called by the machine driver to tell us what serial
441 * format to use.
442 *
443 * This driver only supports I2S mode. Return an error if the format is
444 * not SND_SOC_DAIFMT_I2S.
445 *
446 * @format: one of SND_SOC_DAIFMT_xxx
447 */
448static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
449{
450 struct psc_i2s *psc_i2s = cpu_dai->private_data;
451 dev_dbg(psc_i2s->dev, "psc_i2s_set_fmt(cpu_dai=%p, format=%i)\n",
452 cpu_dai, format);
453 return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL;
454}
455
456/* ---------------------------------------------------------------------
457 * ALSA SoC Bindings
458 *
459 * - Digital Audio Interface (DAI) template
460 * - create/destroy dai hooks
461 */
462
463/**
464 * psc_i2s_dai_template: template CPU Digital Audio Interface
465 */
466static struct snd_soc_dai psc_i2s_dai_template = {
467 .type = SND_SOC_DAI_I2S,
468 .playback = {
469 .channels_min = 2,
470 .channels_max = 2,
471 .rates = PSC_I2S_RATES,
472 .formats = PSC_I2S_FORMATS,
473 },
474 .capture = {
475 .channels_min = 2,
476 .channels_max = 2,
477 .rates = PSC_I2S_RATES,
478 .formats = PSC_I2S_FORMATS,
479 },
480 .ops = {
481 .startup = psc_i2s_startup,
482 .hw_params = psc_i2s_hw_params,
483 .hw_free = psc_i2s_hw_free,
484 .shutdown = psc_i2s_shutdown,
485 .trigger = psc_i2s_trigger,
486 },
487 .dai_ops = {
488 .set_sysclk = psc_i2s_set_sysclk,
489 .set_fmt = psc_i2s_set_fmt,
490 },
491};
492
493/* ---------------------------------------------------------------------
494 * The PSC I2S 'ASoC platform' driver
495 *
496 * Can be referenced by an 'ASoC machine' driver
497 * This driver only deals with the audio bus; it doesn't have any
498 * interaction with the attached codec
499 */
500
501static const struct snd_pcm_hardware psc_i2s_pcm_hardware = {
502 .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
503 SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER,
504 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |
505 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE,
506 .rate_min = 8000,
507 .rate_max = 48000,
508 .channels_min = 2,
509 .channels_max = 2,
510 .period_bytes_max = 1024 * 1024,
511 .period_bytes_min = 32,
512 .periods_min = 2,
513 .periods_max = 256,
514 .buffer_bytes_max = 2 * 1024 * 1024,
515 .fifo_size = 0,
516};
517
518static int psc_i2s_pcm_open(struct snd_pcm_substream *substream)
519{
520 struct snd_soc_pcm_runtime *rtd = substream->private_data;
521 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
522 struct psc_i2s_stream *s;
523
524 dev_dbg(psc_i2s->dev, "psc_i2s_pcm_open(substream=%p)\n", substream);
525
526 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
527 s = &psc_i2s->capture;
528 else
529 s = &psc_i2s->playback;
530
531 snd_soc_set_runtime_hwparams(substream, &psc_i2s_pcm_hardware);
532
533 s->stream = substream;
534 return 0;
535}
536
537static int psc_i2s_pcm_close(struct snd_pcm_substream *substream)
538{
539 struct snd_soc_pcm_runtime *rtd = substream->private_data;
540 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
541 struct psc_i2s_stream *s;
542
543 dev_dbg(psc_i2s->dev, "psc_i2s_pcm_close(substream=%p)\n", substream);
544
545 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
546 s = &psc_i2s->capture;
547 else
548 s = &psc_i2s->playback;
549
550 s->stream = NULL;
551 return 0;
552}
553
554static snd_pcm_uframes_t
555psc_i2s_pcm_pointer(struct snd_pcm_substream *substream)
556{
557 struct snd_soc_pcm_runtime *rtd = substream->private_data;
558 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
559 struct psc_i2s_stream *s;
560 dma_addr_t count;
561
562 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
563 s = &psc_i2s->capture;
564 else
565 s = &psc_i2s->playback;
566
567 count = s->period_current_pt - s->period_start;
568
569 return bytes_to_frames(substream->runtime, count);
570}
571
572static struct snd_pcm_ops psc_i2s_pcm_ops = {
573 .open = psc_i2s_pcm_open,
574 .close = psc_i2s_pcm_close,
575 .ioctl = snd_pcm_lib_ioctl,
576 .pointer = psc_i2s_pcm_pointer,
577};
578
579static u64 psc_i2s_pcm_dmamask = 0xffffffff;
580static int psc_i2s_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
581 struct snd_pcm *pcm)
582{
583 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
584 size_t size = psc_i2s_pcm_hardware.buffer_bytes_max;
585 int rc = 0;
586
587 dev_dbg(rtd->socdev->dev, "psc_i2s_pcm_new(card=%p, dai=%p, pcm=%p)\n",
588 card, dai, pcm);
589
590 if (!card->dev->dma_mask)
591 card->dev->dma_mask = &psc_i2s_pcm_dmamask;
592 if (!card->dev->coherent_dma_mask)
593 card->dev->coherent_dma_mask = 0xffffffff;
594
595 if (pcm->streams[0].substream) {
596 rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->dev, size,
597 &pcm->streams[0].substream->dma_buffer);
598 if (rc)
599 goto playback_alloc_err;
600 }
601
602 if (pcm->streams[1].substream) {
603 rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->dev, size,
604 &pcm->streams[1].substream->dma_buffer);
605 if (rc)
606 goto capture_alloc_err;
607 }
608
609 return 0;
610
611 capture_alloc_err:
612 if (pcm->streams[0].substream)
613 snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer);
614 playback_alloc_err:
615 dev_err(card->dev, "Cannot allocate buffer(s)\n");
616 return -ENOMEM;
617}
618
619static void psc_i2s_pcm_free(struct snd_pcm *pcm)
620{
621 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
622 struct snd_pcm_substream *substream;
623 int stream;
624
625 dev_dbg(rtd->socdev->dev, "psc_i2s_pcm_free(pcm=%p)\n", pcm);
626
627 for (stream = 0; stream < 2; stream++) {
628 substream = pcm->streams[stream].substream;
629 if (substream) {
630 snd_dma_free_pages(&substream->dma_buffer);
631 substream->dma_buffer.area = NULL;
632 substream->dma_buffer.addr = 0;
633 }
634 }
635}
636
637struct snd_soc_platform psc_i2s_pcm_soc_platform = {
638 .name = "mpc5200-psc-audio",
639 .pcm_ops = &psc_i2s_pcm_ops,
640 .pcm_new = &psc_i2s_pcm_new,
641 .pcm_free = &psc_i2s_pcm_free,
642};
643
644/* ---------------------------------------------------------------------
645 * Sysfs attributes for debugging
646 */
647
648static ssize_t psc_i2s_status_show(struct device *dev,
649 struct device_attribute *attr, char *buf)
650{
651 struct psc_i2s *psc_i2s = dev_get_drvdata(dev);
652
653 return sprintf(buf, "status=%.4x sicr=%.8x rfnum=%i rfstat=0x%.4x "
654 "tfnum=%i tfstat=0x%.4x\n",
655 in_be16(&psc_i2s->psc_regs->sr_csr.status),
656 in_be32(&psc_i2s->psc_regs->sicr),
657 in_be16(&psc_i2s->fifo_regs->rfnum) & 0x1ff,
658 in_be16(&psc_i2s->fifo_regs->rfstat),
659 in_be16(&psc_i2s->fifo_regs->tfnum) & 0x1ff,
660 in_be16(&psc_i2s->fifo_regs->tfstat));
661}
662
663static int *psc_i2s_get_stat_attr(struct psc_i2s *psc_i2s, const char *name)
664{
665 if (strcmp(name, "playback_underrun") == 0)
666 return &psc_i2s->stats.underrun_count;
667 if (strcmp(name, "capture_overrun") == 0)
668 return &psc_i2s->stats.overrun_count;
669
670 return NULL;
671}
672
673static ssize_t psc_i2s_stat_show(struct device *dev,
674 struct device_attribute *attr, char *buf)
675{
676 struct psc_i2s *psc_i2s = dev_get_drvdata(dev);
677 int *attrib;
678
679 attrib = psc_i2s_get_stat_attr(psc_i2s, attr->attr.name);
680 if (!attrib)
681 return 0;
682
683 return sprintf(buf, "%i\n", *attrib);
684}
685
686static ssize_t psc_i2s_stat_store(struct device *dev,
687 struct device_attribute *attr,
688 const char *buf,
689 size_t count)
690{
691 struct psc_i2s *psc_i2s = dev_get_drvdata(dev);
692 int *attrib;
693
694 attrib = psc_i2s_get_stat_attr(psc_i2s, attr->attr.name);
695 if (!attrib)
696 return 0;
697
698 *attrib = simple_strtoul(buf, NULL, 0);
699 return count;
700}
701
702DEVICE_ATTR(status, 0644, psc_i2s_status_show, NULL);
703DEVICE_ATTR(playback_underrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store);
704DEVICE_ATTR(capture_overrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store);
705
706/* ---------------------------------------------------------------------
707 * OF platform bus binding code:
708 * - Probe/remove operations
709 * - OF device match table
710 */
711static int __devinit psc_i2s_of_probe(struct of_device *op,
712 const struct of_device_id *match)
713{
714 phys_addr_t fifo;
715 struct psc_i2s *psc_i2s;
716 struct resource res;
717 int size, psc_id, irq, rc;
718 const __be32 *prop;
719 void __iomem *regs;
720
721 dev_dbg(&op->dev, "probing psc i2s device\n");
722
723 /* Get the PSC ID */
724 prop = of_get_property(op->node, "cell-index", &size);
725 if (!prop || size < sizeof *prop)
726 return -ENODEV;
727 psc_id = be32_to_cpu(*prop);
728
729 /* Fetch the registers and IRQ of the PSC */
730 irq = irq_of_parse_and_map(op->node, 0);
731 if (of_address_to_resource(op->node, 0, &res)) {
732 dev_err(&op->dev, "Missing reg property\n");
733 return -ENODEV;
734 }
735 regs = ioremap(res.start, 1 + res.end - res.start);
736 if (!regs) {
737 dev_err(&op->dev, "Could not map registers\n");
738 return -ENODEV;
739 }
740
741 /* Allocate and initialize the driver private data */
742 psc_i2s = kzalloc(sizeof *psc_i2s, GFP_KERNEL);
743 if (!psc_i2s) {
744 iounmap(regs);
745 return -ENOMEM;
746 }
747 spin_lock_init(&psc_i2s->lock);
748 psc_i2s->irq = irq;
749 psc_i2s->psc_regs = regs;
750 psc_i2s->fifo_regs = regs + sizeof *psc_i2s->psc_regs;
751 psc_i2s->dev = &op->dev;
752 psc_i2s->playback.psc_i2s = psc_i2s;
753 psc_i2s->capture.psc_i2s = psc_i2s;
754 snprintf(psc_i2s->name, sizeof psc_i2s->name, "PSC%u", psc_id+1);
755
756 /* Fill out the CPU DAI structure */
757 memcpy(&psc_i2s->dai, &psc_i2s_dai_template, sizeof psc_i2s->dai);
758 psc_i2s->dai.private_data = psc_i2s;
759 psc_i2s->dai.name = psc_i2s->name;
760 psc_i2s->dai.id = psc_id;
761
762 /* Find the address of the fifo data registers and setup the
763 * DMA tasks */
764 fifo = res.start + offsetof(struct mpc52xx_psc, buffer.buffer_32);
765 psc_i2s->capture.bcom_task =
766 bcom_psc_gen_bd_rx_init(psc_id, 10, fifo, 512);
767 psc_i2s->playback.bcom_task =
768 bcom_psc_gen_bd_tx_init(psc_id, 10, fifo);
769 if (!psc_i2s->capture.bcom_task ||
770 !psc_i2s->playback.bcom_task) {
771 dev_err(&op->dev, "Could not allocate bestcomm tasks\n");
772 iounmap(regs);
773 kfree(psc_i2s);
774 return -ENODEV;
775 }
776
777 /* Disable all interrupts and reset the PSC */
778 out_be16(&psc_i2s->psc_regs->isr_imr.imr, 0);
779 out_8(&psc_i2s->psc_regs->command, 3 << 4); /* reset transmitter */
780 out_8(&psc_i2s->psc_regs->command, 2 << 4); /* reset receiver */
781 out_8(&psc_i2s->psc_regs->command, 1 << 4); /* reset mode */
782 out_8(&psc_i2s->psc_regs->command, 4 << 4); /* reset error */
783
784 /* Configure the serial interface mode; defaulting to CODEC8 mode */
785 psc_i2s->sicr = MPC52xx_PSC_SICR_DTS1 | MPC52xx_PSC_SICR_I2S |
786 MPC52xx_PSC_SICR_CLKPOL;
787 if (of_get_property(op->node, "fsl,cellslave", NULL))
788 psc_i2s->sicr |= MPC52xx_PSC_SICR_CELLSLAVE |
789 MPC52xx_PSC_SICR_GENCLK;
790 out_be32(&psc_i2s->psc_regs->sicr,
791 psc_i2s->sicr | MPC52xx_PSC_SICR_SIM_CODEC_8);
792
793 /* Check for the codec handle. If it is not present then we
794 * are done */
795 if (!of_get_property(op->node, "codec-handle", NULL))
796 return 0;
797
798 /* Set up mode register;
799 * First write: RxRdy (FIFO Alarm) generates rx FIFO irq
800 * Second write: register Normal mode for non loopback
801 */
802 out_8(&psc_i2s->psc_regs->mode, 0);
803 out_8(&psc_i2s->psc_regs->mode, 0);
804
805 /* Set the TX and RX fifo alarm thresholds */
806 out_be16(&psc_i2s->fifo_regs->rfalarm, 0x100);
807 out_8(&psc_i2s->fifo_regs->rfcntl, 0x4);
808 out_be16(&psc_i2s->fifo_regs->tfalarm, 0x100);
809 out_8(&psc_i2s->fifo_regs->tfcntl, 0x7);
810
811 /* Lookup the IRQ numbers */
812 psc_i2s->playback.irq =
813 bcom_get_task_irq(psc_i2s->playback.bcom_task);
814 psc_i2s->capture.irq =
815 bcom_get_task_irq(psc_i2s->capture.bcom_task);
816
817 /* Save what we've done so it can be found again later */
818 dev_set_drvdata(&op->dev, psc_i2s);
819
820 /* Register the SYSFS files */
821 rc = device_create_file(psc_i2s->dev, &dev_attr_status);
822 rc = device_create_file(psc_i2s->dev, &dev_attr_capture_overrun);
823 rc = device_create_file(psc_i2s->dev, &dev_attr_playback_underrun);
824 if (rc)
825 dev_info(psc_i2s->dev, "error creating sysfs files\n");
826
827 /* Tell the ASoC OF helpers about it */
828 of_snd_soc_register_platform(&psc_i2s_pcm_soc_platform, op->node,
829 &psc_i2s->dai);
830
831 return 0;
832}
833
834static int __devexit psc_i2s_of_remove(struct of_device *op)
835{
836 struct psc_i2s *psc_i2s = dev_get_drvdata(&op->dev);
837
838 dev_dbg(&op->dev, "psc_i2s_remove()\n");
839
840 bcom_gen_bd_rx_release(psc_i2s->capture.bcom_task);
841 bcom_gen_bd_tx_release(psc_i2s->playback.bcom_task);
842
843 iounmap(psc_i2s->psc_regs);
844 iounmap(psc_i2s->fifo_regs);
845 kfree(psc_i2s);
846 dev_set_drvdata(&op->dev, NULL);
847
848 return 0;
849}
850
851/* Match table for of_platform binding */
852static struct of_device_id psc_i2s_match[] __devinitdata = {
853 { .compatible = "fsl,mpc5200-psc-i2s", },
854 {}
855};
856MODULE_DEVICE_TABLE(of, psc_i2s_match);
857
858static struct of_platform_driver psc_i2s_driver = {
859 .match_table = psc_i2s_match,
860 .probe = psc_i2s_of_probe,
861 .remove = __devexit_p(psc_i2s_of_remove),
862 .driver = {
863 .name = "mpc5200-psc-i2s",
864 .owner = THIS_MODULE,
865 },
866};
867
868/* ---------------------------------------------------------------------
869 * Module setup and teardown; simply register the of_platform driver
870 * for the PSC in I2S mode.
871 */
872static int __init psc_i2s_init(void)
873{
874 return of_register_platform_driver(&psc_i2s_driver);
875}
876module_init(psc_i2s_init);
877
878static void __exit psc_i2s_exit(void)
879{
880 of_unregister_platform_driver(&psc_i2s_driver);
881}
882module_exit(psc_i2s_exit);
883
884
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 4bdc9d8fc90..94f89debde1 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -68,10 +68,6 @@ static int mpc8610_hpcd_machine_probe(struct platform_device *sound_device)
68 guts_set_pmuxcr_dma(machine_data->guts, machine_data->dma_id, 68 guts_set_pmuxcr_dma(machine_data->guts, machine_data->dma_id,
69 machine_data->dma_channel_id[1], 0); 69 machine_data->dma_channel_id[1], 0);
70 70
71 guts_set_pmuxcr_dma(machine_data->guts, 1, 0, 0);
72 guts_set_pmuxcr_dma(machine_data->guts, 1, 3, 0);
73 guts_set_pmuxcr_dma(machine_data->guts, 0, 3, 0);
74
75 switch (machine_data->ssi_id) { 71 switch (machine_data->ssi_id) {
76 case 0: 72 case 0:
77 clrsetbits_be32(&machine_data->guts->pmuxcr, 73 clrsetbits_be32(&machine_data->guts->pmuxcr,
@@ -230,6 +226,8 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
230 struct fsl_ssi_info ssi_info; 226 struct fsl_ssi_info ssi_info;
231 struct fsl_dma_info dma_info; 227 struct fsl_dma_info dma_info;
232 int ret = -ENODEV; 228 int ret = -ENODEV;
229 unsigned int playback_dma_channel;
230 unsigned int capture_dma_channel;
233 231
234 machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL); 232 machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL);
235 if (!machine_data) 233 if (!machine_data)
@@ -381,8 +379,9 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
381 goto error; 379 goto error;
382 } 380 }
383 381
384 /* Find the DMA channels to use. For now, we always use the first DMA 382 /* Find the DMA channels to use. Both SSIs need to use the same DMA
385 controller. */ 383 * controller, so let's use DMA#1.
384 */
386 for_each_compatible_node(dma_np, NULL, "fsl,mpc8610-dma") { 385 for_each_compatible_node(dma_np, NULL, "fsl,mpc8610-dma") {
387 iprop = of_get_property(dma_np, "cell-index", NULL); 386 iprop = of_get_property(dma_np, "cell-index", NULL);
388 if (iprop && (*iprop == 0)) { 387 if (iprop && (*iprop == 0)) {
@@ -397,14 +396,19 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
397 } 396 }
398 machine_data->dma_id = *iprop; 397 machine_data->dma_id = *iprop;
399 398
399 /* SSI1 needs to use DMA Channels 0 and 1, and SSI2 needs to use DMA
400 * channels 2 and 3. This is just how the MPC8610 is wired
401 * internally.
402 */
403 playback_dma_channel = (machine_data->ssi_id == 0) ? 0 : 2;
404 capture_dma_channel = (machine_data->ssi_id == 0) ? 1 : 3;
405
400 /* 406 /*
401 * Find the DMA channels to use. For now, we always use DMA channel 0 407 * Find the DMA channels to use.
402 * for playback, and DMA channel 1 for capture.
403 */ 408 */
404 while ((dma_channel_np = of_get_next_child(dma_np, dma_channel_np))) { 409 while ((dma_channel_np = of_get_next_child(dma_np, dma_channel_np))) {
405 iprop = of_get_property(dma_channel_np, "cell-index", NULL); 410 iprop = of_get_property(dma_channel_np, "cell-index", NULL);
406 /* Is it DMA channel 0? */ 411 if (iprop && (*iprop == playback_dma_channel)) {
407 if (iprop && (*iprop == 0)) {
408 /* dma_channel[0] and dma_irq[0] are for playback */ 412 /* dma_channel[0] and dma_irq[0] are for playback */
409 dma_info.dma_channel[0] = of_iomap(dma_channel_np, 0); 413 dma_info.dma_channel[0] = of_iomap(dma_channel_np, 0);
410 dma_info.dma_irq[0] = 414 dma_info.dma_irq[0] =
@@ -412,7 +416,7 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
412 machine_data->dma_channel_id[0] = *iprop; 416 machine_data->dma_channel_id[0] = *iprop;
413 continue; 417 continue;
414 } 418 }
415 if (iprop && (*iprop == 1)) { 419 if (iprop && (*iprop == capture_dma_channel)) {
416 /* dma_channel[1] and dma_irq[1] are for capture */ 420 /* dma_channel[1] and dma_irq[1] are for capture */
417 dma_info.dma_channel[1] = of_iomap(dma_channel_np, 0); 421 dma_info.dma_channel[1] = of_iomap(dma_channel_np, 0);
418 dma_info.dma_irq[1] = 422 dma_info.dma_irq[1] =
diff --git a/sound/soc/fsl/soc-of-simple.c b/sound/soc/fsl/soc-of-simple.c
new file mode 100644
index 00000000000..0382fdac51c
--- /dev/null
+++ b/sound/soc/fsl/soc-of-simple.c
@@ -0,0 +1,171 @@
1/*
2 * OF helpers for ALSA SoC Layer
3 *
4 * Copyright (C) 2008, Secret Lab Technologies Ltd.
5 */
6
7#include <linux/module.h>
8#include <linux/moduleparam.h>
9#include <linux/init.h>
10#include <linux/delay.h>
11#include <linux/pm.h>
12#include <linux/bitops.h>
13#include <linux/platform_device.h>
14#include <linux/of.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h>
19#include <sound/soc-of-simple.h>
20#include <sound/initval.h>
21
22MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
23MODULE_LICENSE("GPL");
24MODULE_DESCRIPTION("ALSA SoC OpenFirmware bindings");
25
26static DEFINE_MUTEX(of_snd_soc_mutex);
27static LIST_HEAD(of_snd_soc_device_list);
28static int of_snd_soc_next_index;
29
30struct of_snd_soc_device {
31 int id;
32 struct list_head list;
33 struct snd_soc_device device;
34 struct snd_soc_machine machine;
35 struct snd_soc_dai_link dai_link;
36 struct platform_device *pdev;
37 struct device_node *platform_node;
38 struct device_node *codec_node;
39};
40
41static struct snd_soc_ops of_snd_soc_ops = {
42};
43
44static struct of_snd_soc_device *
45of_snd_soc_get_device(struct device_node *codec_node)
46{
47 struct of_snd_soc_device *of_soc;
48
49 list_for_each_entry(of_soc, &of_snd_soc_device_list, list) {
50 if (of_soc->codec_node == codec_node)
51 return of_soc;
52 }
53
54 of_soc = kzalloc(sizeof(struct of_snd_soc_device), GFP_KERNEL);
55 if (!of_soc)
56 return NULL;
57
58 /* Initialize the structure and add it to the global list */
59 of_soc->codec_node = codec_node;
60 of_soc->id = of_snd_soc_next_index++;
61 of_soc->machine.dai_link = &of_soc->dai_link;
62 of_soc->machine.num_links = 1;
63 of_soc->device.machine = &of_soc->machine;
64 of_soc->dai_link.ops = &of_snd_soc_ops;
65 list_add(&of_soc->list, &of_snd_soc_device_list);
66
67 return of_soc;
68}
69
70static void of_snd_soc_register_device(struct of_snd_soc_device *of_soc)
71{
72 struct platform_device *pdev;
73 int rc;
74
75 /* Only register the device if both the codec and platform have
76 * been registered */
77 if ((!of_soc->device.codec_data) || (!of_soc->platform_node))
78 return;
79
80 pr_info("platform<-->codec match achieved; registering machine\n");
81
82 pdev = platform_device_alloc("soc-audio", of_soc->id);
83 if (!pdev) {
84 pr_err("of_soc: platform_device_alloc() failed\n");
85 return;
86 }
87
88 pdev->dev.platform_data = of_soc;
89 platform_set_drvdata(pdev, &of_soc->device);
90 of_soc->device.dev = &pdev->dev;
91
92 /* The ASoC device is complete; register it */
93 rc = platform_device_add(pdev);
94 if (rc) {
95 pr_err("of_soc: platform_device_add() failed\n");
96 return;
97 }
98
99}
100
101int of_snd_soc_register_codec(struct snd_soc_codec_device *codec_dev,
102 void *codec_data, struct snd_soc_dai *dai,
103 struct device_node *node)
104{
105 struct of_snd_soc_device *of_soc;
106 int rc = 0;
107
108 pr_info("registering ASoC codec driver: %s\n", node->full_name);
109
110 mutex_lock(&of_snd_soc_mutex);
111 of_soc = of_snd_soc_get_device(node);
112 if (!of_soc) {
113 rc = -ENOMEM;
114 goto out;
115 }
116
117 /* Store the codec data */
118 of_soc->device.codec_data = codec_data;
119 of_soc->device.codec_dev = codec_dev;
120 of_soc->dai_link.name = (char *)node->name;
121 of_soc->dai_link.stream_name = (char *)node->name;
122 of_soc->dai_link.codec_dai = dai;
123
124 /* Now try to register the SoC device */
125 of_snd_soc_register_device(of_soc);
126
127 out:
128 mutex_unlock(&of_snd_soc_mutex);
129 return rc;
130}
131EXPORT_SYMBOL_GPL(of_snd_soc_register_codec);
132
133int of_snd_soc_register_platform(struct snd_soc_platform *platform,
134 struct device_node *node,
135 struct snd_soc_dai *cpu_dai)
136{
137 struct of_snd_soc_device *of_soc;
138 struct device_node *codec_node;
139 const phandle *handle;
140 int len, rc = 0;
141
142 pr_info("registering ASoC platform driver: %s\n", node->full_name);
143
144 handle = of_get_property(node, "codec-handle", &len);
145 if (!handle || len < sizeof(handle))
146 return -ENODEV;
147 codec_node = of_find_node_by_phandle(*handle);
148 if (!codec_node)
149 return -ENODEV;
150 pr_info("looking for codec: %s\n", codec_node->full_name);
151
152 mutex_lock(&of_snd_soc_mutex);
153 of_soc = of_snd_soc_get_device(codec_node);
154 if (!of_soc) {
155 rc = -ENOMEM;
156 goto out;
157 }
158
159 of_soc->platform_node = node;
160 of_soc->dai_link.cpu_dai = cpu_dai;
161 of_soc->device.platform = platform;
162 of_soc->machine.name = of_soc->dai_link.cpu_dai->name;
163
164 /* Now try to register the SoC device */
165 of_snd_soc_register_device(of_soc);
166
167 out:
168 mutex_unlock(&of_snd_soc_mutex);
169 return rc;
170}
171EXPORT_SYMBOL_GPL(of_snd_soc_register_platform);
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 87d0ed01f65..d166b6b2a60 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -290,6 +290,7 @@ static struct snd_soc_machine snd_soc_machine_n810 = {
290 290
291/* Audio private data */ 291/* Audio private data */
292static struct aic3x_setup_data n810_aic33_setup = { 292static struct aic3x_setup_data n810_aic33_setup = {
293 .i2c_bus = 2,
293 .i2c_address = 0x18, 294 .i2c_address = 0x18,
294 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED, 295 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
295 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT, 296 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 9212c37a33b..f8c1cdd940a 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -1,6 +1,7 @@
1config SND_PXA2XX_SOC 1config SND_PXA2XX_SOC
2 tristate "SoC Audio for the Intel PXA2xx chip" 2 tristate "SoC Audio for the Intel PXA2xx chip"
3 depends on ARCH_PXA 3 depends on ARCH_PXA
4 select SND_PXA2XX_LIB
4 help 5 help
5 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
6 the PXA2xx AC97, I2S or SSP interface. You will also need 7 the PXA2xx AC97, I2S or SSP interface. You will also need
@@ -13,6 +14,8 @@ config SND_PXA2XX_AC97
13config SND_PXA2XX_SOC_AC97 14config SND_PXA2XX_SOC_AC97
14 tristate 15 tristate
15 select AC97_BUS 16 select AC97_BUS
17 select SND_ARM
18 select SND_PXA2XX_LIB_AC97
16 select SND_SOC_AC97_BUS 19 select SND_SOC_AC97_BUS
17 20
18config SND_PXA2XX_SOC_I2S 21config SND_PXA2XX_SOC_I2S
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 0a53f72077f..1a8373de7f3 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -18,13 +18,13 @@
18#include <linux/timer.h> 18#include <linux/timer.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/gpio.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/soc.h> 24#include <sound/soc.h>
24#include <sound/soc-dapm.h> 25#include <sound/soc-dapm.h>
25 26
26#include <asm/mach-types.h> 27#include <asm/mach-types.h>
27#include <asm/hardware/scoop.h>
28#include <mach/pxa-regs.h> 28#include <mach/pxa-regs.h>
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include <mach/corgi.h> 30#include <mach/corgi.h>
@@ -54,8 +54,8 @@ static void corgi_ext_control(struct snd_soc_codec *codec)
54 switch (corgi_jack_func) { 54 switch (corgi_jack_func) {
55 case CORGI_HP: 55 case CORGI_HP:
56 /* set = unmute headphone */ 56 /* set = unmute headphone */
57 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 57 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
58 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 58 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
59 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 59 snd_soc_dapm_disable_pin(codec, "Mic Jack");
60 snd_soc_dapm_disable_pin(codec, "Line Jack"); 60 snd_soc_dapm_disable_pin(codec, "Line Jack");
61 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 61 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
@@ -63,24 +63,24 @@ static void corgi_ext_control(struct snd_soc_codec *codec)
63 break; 63 break;
64 case CORGI_MIC: 64 case CORGI_MIC:
65 /* reset = mute headphone */ 65 /* reset = mute headphone */
66 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 66 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
67 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 67 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
68 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 68 snd_soc_dapm_enable_pin(codec, "Mic Jack");
69 snd_soc_dapm_disable_pin(codec, "Line Jack"); 69 snd_soc_dapm_disable_pin(codec, "Line Jack");
70 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 70 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
71 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 71 snd_soc_dapm_disable_pin(codec, "Headset Jack");
72 break; 72 break;
73 case CORGI_LINE: 73 case CORGI_LINE:
74 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 74 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
75 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 75 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
76 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 76 snd_soc_dapm_disable_pin(codec, "Mic Jack");
77 snd_soc_dapm_enable_pin(codec, "Line Jack"); 77 snd_soc_dapm_enable_pin(codec, "Line Jack");
78 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 78 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
79 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 79 snd_soc_dapm_disable_pin(codec, "Headset Jack");
80 break; 80 break;
81 case CORGI_HEADSET: 81 case CORGI_HEADSET:
82 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 82 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
83 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 83 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
84 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 84 snd_soc_dapm_enable_pin(codec, "Mic Jack");
85 snd_soc_dapm_disable_pin(codec, "Line Jack"); 85 snd_soc_dapm_disable_pin(codec, "Line Jack");
86 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 86 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
@@ -114,8 +114,8 @@ static int corgi_shutdown(struct snd_pcm_substream *substream)
114 struct snd_soc_codec *codec = rtd->socdev->codec; 114 struct snd_soc_codec *codec = rtd->socdev->codec;
115 115
116 /* set = unmute headphone */ 116 /* set = unmute headphone */
117 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 117 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
118 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 118 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
119 return 0; 119 return 0;
120} 120}
121 121
@@ -218,22 +218,14 @@ static int corgi_set_spk(struct snd_kcontrol *kcontrol,
218static int corgi_amp_event(struct snd_soc_dapm_widget *w, 218static int corgi_amp_event(struct snd_soc_dapm_widget *w,
219 struct snd_kcontrol *k, int event) 219 struct snd_kcontrol *k, int event)
220{ 220{
221 if (SND_SOC_DAPM_EVENT_ON(event)) 221 gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
222 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
223 else
224 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
225
226 return 0; 222 return 0;
227} 223}
228 224
229static int corgi_mic_event(struct snd_soc_dapm_widget *w, 225static int corgi_mic_event(struct snd_soc_dapm_widget *w,
230 struct snd_kcontrol *k, int event) 226 struct snd_kcontrol *k, int event)
231{ 227{
232 if (SND_SOC_DAPM_EVENT_ON(event)) 228 gpio_set_value(CORGI_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
233 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
234 else
235 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
236
237 return 0; 229 return 0;
238} 230}
239 231
@@ -330,6 +322,7 @@ static struct snd_soc_machine snd_soc_machine_corgi = {
330 322
331/* corgi audio private data */ 323/* corgi audio private data */
332static struct wm8731_setup_data corgi_wm8731_setup = { 324static struct wm8731_setup_data corgi_wm8731_setup = {
325 .i2c_bus = 0,
333 .i2c_address = 0x1b, 326 .i2c_address = 0x1b,
334}; 327};
335 328
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index a4697f7e292..f84f7d8db09 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -284,6 +284,7 @@ static struct snd_soc_machine snd_soc_machine_poodle = {
284 284
285/* poodle audio private data */ 285/* poodle audio private data */
286static struct wm8731_setup_data poodle_wm8731_setup = { 286static struct wm8731_setup_data poodle_wm8731_setup = {
287 .i2c_bus = 0,
287 .i2c_address = 0x1b, 288 .i2c_address = 0x1b,
288}; 289};
289 290
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index d94a495bd6b..a7a3a9c5c6f 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -13,225 +13,30 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/interrupt.h>
17#include <linux/wait.h>
18#include <linux/clk.h>
19#include <linux/delay.h>
20 16
21#include <sound/core.h> 17#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/ac97_codec.h> 18#include <sound/ac97_codec.h>
24#include <sound/initval.h>
25#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/pxa2xx-lib.h>
26 21
27#include <asm/irq.h>
28#include <linux/mutex.h>
29#include <mach/hardware.h> 22#include <mach/hardware.h>
30#include <mach/pxa-regs.h> 23#include <mach/pxa-regs.h>
31#include <mach/pxa2xx-gpio.h>
32#include <mach/audio.h>
33 24
34#include "pxa2xx-pcm.h" 25#include "pxa2xx-pcm.h"
35#include "pxa2xx-ac97.h" 26#include "pxa2xx-ac97.h"
36 27
37static DEFINE_MUTEX(car_mutex);
38static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
39static volatile long gsr_bits;
40static struct clk *ac97_clk;
41#ifdef CONFIG_PXA27x
42static struct clk *ac97conf_clk;
43#endif
44
45/*
46 * Beware PXA27x bugs:
47 *
48 * o Slot 12 read from modem space will hang controller.
49 * o CDONE, SDONE interrupt fails after any slot 12 IO.
50 *
51 * We therefore have an hybrid approach for waiting on SDONE (interrupt or
52 * 1 jiffy timeout if interrupt never comes).
53 */
54
55static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97,
56 unsigned short reg)
57{
58 unsigned short val = -1;
59 volatile u32 *reg_addr;
60
61 mutex_lock(&car_mutex);
62
63 /* set up primary or secondary codec/modem space */
64#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
65 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
66#else
67 if (reg == AC97_GPIO_STATUS)
68 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
69 else
70 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
71#endif
72 reg_addr += (reg >> 1);
73
74#ifndef CONFIG_PXA27x
75 if (reg == AC97_GPIO_STATUS) {
76 /* read from controller cache */
77 val = *reg_addr;
78 goto out;
79 }
80#endif
81
82 /* start read access across the ac97 link */
83 GSR = GSR_CDONE | GSR_SDONE;
84 gsr_bits = 0;
85 val = *reg_addr;
86
87 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
88 if (!((GSR | gsr_bits) & GSR_SDONE)) {
89 printk(KERN_ERR "%s: read error (ac97_reg=%x GSR=%#lx)\n",
90 __func__, reg, GSR | gsr_bits);
91 val = -1;
92 goto out;
93 }
94
95 /* valid data now */
96 GSR = GSR_CDONE | GSR_SDONE;
97 gsr_bits = 0;
98 val = *reg_addr;
99 /* but we've just started another cycle... */
100 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
101
102out: mutex_unlock(&car_mutex);
103 return val;
104}
105
106static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
107 unsigned short val)
108{
109 volatile u32 *reg_addr;
110
111 mutex_lock(&car_mutex);
112
113 /* set up primary or secondary codec/modem space */
114#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
115 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
116#else
117 if (reg == AC97_GPIO_STATUS)
118 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
119 else
120 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
121#endif
122 reg_addr += (reg >> 1);
123
124 GSR = GSR_CDONE | GSR_SDONE;
125 gsr_bits = 0;
126 *reg_addr = val;
127 wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1);
128 if (!((GSR | gsr_bits) & GSR_CDONE))
129 printk(KERN_ERR "%s: write error (ac97_reg=%x GSR=%#lx)\n",
130 __func__, reg, GSR | gsr_bits);
131
132 mutex_unlock(&car_mutex);
133}
134
135static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97) 28static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97)
136{ 29{
137#ifdef CONFIG_PXA3xx 30 pxa2xx_ac97_try_warm_reset(ac97);
138 int timeout = 100;
139#endif
140 gsr_bits = 0;
141
142#ifdef CONFIG_PXA27x
143 /* warm reset broken on Bulverde,
144 so manually keep AC97 reset high */
145 pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH);
146 udelay(10);
147 GCR |= GCR_WARM_RST;
148 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
149 udelay(500);
150#elif defined(CONFIG_PXA3xx)
151 /* Can't use interrupts */
152 GCR |= GCR_WARM_RST;
153 while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
154 mdelay(1);
155#else
156 GCR |= GCR_WARM_RST | GCR_PRIRDY_IEN | GCR_SECRDY_IEN;
157 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
158#endif
159
160 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
161 printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
162 __func__, gsr_bits);
163 31
164 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); 32 pxa2xx_ac97_finish_reset(ac97);
165 GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
166} 33}
167 34
168static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97) 35static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)
169{ 36{
170#ifdef CONFIG_PXA3xx 37 pxa2xx_ac97_try_cold_reset(ac97);
171 int timeout = 1000;
172
173 /* Hold CLKBPB for 100us */
174 GCR = 0;
175 GCR = GCR_CLKBPB;
176 udelay(100);
177 GCR = 0;
178#endif
179 38
180 GCR &= GCR_COLD_RST; /* clear everything but nCRST */ 39 pxa2xx_ac97_finish_reset(ac97);
181 GCR &= ~GCR_COLD_RST; /* then assert nCRST */
182
183 gsr_bits = 0;
184#ifdef CONFIG_PXA27x
185 /* PXA27x Developers Manual section 13.5.2.2.1 */
186 clk_enable(ac97conf_clk);
187 udelay(5);
188 clk_disable(ac97conf_clk);
189 GCR = GCR_COLD_RST;
190 udelay(50);
191#elif defined(CONFIG_PXA3xx)
192 /* Can't use interrupts on PXA3xx */
193 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
194
195 GCR = GCR_WARM_RST | GCR_COLD_RST;
196 while (!(GSR & (GSR_PCR | GSR_SCR)) && timeout--)
197 mdelay(10);
198#else
199 GCR = GCR_COLD_RST;
200 GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
201 wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
202#endif
203
204 if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
205 printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
206 __func__, gsr_bits);
207
208 GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
209 GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
210}
211
212static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
213{
214 long status;
215
216 status = GSR;
217 if (status) {
218 GSR = status;
219 gsr_bits |= status;
220 wake_up(&gsr_wq);
221
222#ifdef CONFIG_PXA27x
223 /* Although we don't use those we still need to clear them
224 since they tend to spuriously trigger when MMC is used
225 (hardware bug? go figure)... */
226 MISR = MISR_EOC;
227 PISR = PISR_EOC;
228 MCSR = MCSR_EOC;
229#endif
230
231 return IRQ_HANDLED;
232 }
233
234 return IRQ_NONE;
235} 40}
236 41
237struct snd_ac97_bus_ops soc_ac97_ops = { 42struct snd_ac97_bus_ops soc_ac97_ops = {
@@ -244,7 +49,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
244static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { 49static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
245 .name = "AC97 PCM Stereo out", 50 .name = "AC97 PCM Stereo out",
246 .dev_addr = __PREG(PCDR), 51 .dev_addr = __PREG(PCDR),
247 .drcmr = &DRCMRTXPCDR, 52 .drcmr = &DRCMR(12),
248 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 53 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
249 DCMD_BURST32 | DCMD_WIDTH4, 54 DCMD_BURST32 | DCMD_WIDTH4,
250}; 55};
@@ -252,7 +57,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
252static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = { 57static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
253 .name = "AC97 PCM Stereo in", 58 .name = "AC97 PCM Stereo in",
254 .dev_addr = __PREG(PCDR), 59 .dev_addr = __PREG(PCDR),
255 .drcmr = &DRCMRRXPCDR, 60 .drcmr = &DRCMR(11),
256 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 61 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
257 DCMD_BURST32 | DCMD_WIDTH4, 62 DCMD_BURST32 | DCMD_WIDTH4,
258}; 63};
@@ -260,7 +65,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
260static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = { 65static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
261 .name = "AC97 Aux PCM (Slot 5) Mono out", 66 .name = "AC97 Aux PCM (Slot 5) Mono out",
262 .dev_addr = __PREG(MODR), 67 .dev_addr = __PREG(MODR),
263 .drcmr = &DRCMRTXMODR, 68 .drcmr = &DRCMR(10),
264 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 69 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
265 DCMD_BURST16 | DCMD_WIDTH2, 70 DCMD_BURST16 | DCMD_WIDTH2,
266}; 71};
@@ -268,7 +73,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
268static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = { 73static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
269 .name = "AC97 Aux PCM (Slot 5) Mono in", 74 .name = "AC97 Aux PCM (Slot 5) Mono in",
270 .dev_addr = __PREG(MODR), 75 .dev_addr = __PREG(MODR),
271 .drcmr = &DRCMRRXMODR, 76 .drcmr = &DRCMR(9),
272 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 77 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
273 DCMD_BURST16 | DCMD_WIDTH2, 78 DCMD_BURST16 | DCMD_WIDTH2,
274}; 79};
@@ -276,7 +81,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
276static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = { 81static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
277 .name = "AC97 Mic PCM (Slot 6) Mono in", 82 .name = "AC97 Mic PCM (Slot 6) Mono in",
278 .dev_addr = __PREG(MCDR), 83 .dev_addr = __PREG(MCDR),
279 .drcmr = &DRCMRRXMCDR, 84 .drcmr = &DRCMR(8),
280 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 85 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
281 DCMD_BURST16 | DCMD_WIDTH2, 86 DCMD_BURST16 | DCMD_WIDTH2,
282}; 87};
@@ -285,24 +90,13 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
285static int pxa2xx_ac97_suspend(struct platform_device *pdev, 90static int pxa2xx_ac97_suspend(struct platform_device *pdev,
286 struct snd_soc_dai *dai) 91 struct snd_soc_dai *dai)
287{ 92{
288 GCR |= GCR_ACLINK_OFF; 93 return pxa2xx_ac97_hw_suspend();
289 clk_disable(ac97_clk);
290 return 0;
291} 94}
292 95
293static int pxa2xx_ac97_resume(struct platform_device *pdev, 96static int pxa2xx_ac97_resume(struct platform_device *pdev,
294 struct snd_soc_dai *dai) 97 struct snd_soc_dai *dai)
295{ 98{
296 pxa_gpio_mode(GPIO31_SYNC_AC97_MD); 99 return pxa2xx_ac97_hw_resume();
297 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
298 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
299 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
300#ifdef CONFIG_PXA27x
301 /* Use GPIO 113 as AC97 Reset on Bulverde */
302 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
303#endif
304 clk_enable(ac97_clk);
305 return 0;
306} 100}
307 101
308#else 102#else
@@ -313,61 +107,13 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev,
313static int pxa2xx_ac97_probe(struct platform_device *pdev, 107static int pxa2xx_ac97_probe(struct platform_device *pdev,
314 struct snd_soc_dai *dai) 108 struct snd_soc_dai *dai)
315{ 109{
316 int ret; 110 return pxa2xx_ac97_hw_probe(pdev);
317
318 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL);
319 if (ret < 0)
320 goto err;
321
322 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
323 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
324 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
325 pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
326#ifdef CONFIG_PXA27x
327 /* Use GPIO 113 as AC97 Reset on Bulverde */
328 pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
329
330 ac97conf_clk = clk_get(&pdev->dev, "AC97CONFCLK");
331 if (IS_ERR(ac97conf_clk)) {
332 ret = PTR_ERR(ac97conf_clk);
333 ac97conf_clk = NULL;
334 goto err_irq;
335 }
336#endif
337 ac97_clk = clk_get(&pdev->dev, "AC97CLK");
338 if (IS_ERR(ac97_clk)) {
339 ret = PTR_ERR(ac97_clk);
340 ac97_clk = NULL;
341 goto err_irq;
342 }
343 clk_enable(ac97_clk);
344 return 0;
345
346 err_irq:
347 GCR |= GCR_ACLINK_OFF;
348#ifdef CONFIG_PXA27x
349 if (ac97conf_clk) {
350 clk_put(ac97conf_clk);
351 ac97conf_clk = NULL;
352 }
353#endif
354 free_irq(IRQ_AC97, NULL);
355 err:
356 return ret;
357} 111}
358 112
359static void pxa2xx_ac97_remove(struct platform_device *pdev, 113static void pxa2xx_ac97_remove(struct platform_device *pdev,
360 struct snd_soc_dai *dai) 114 struct snd_soc_dai *dai)
361{ 115{
362 GCR |= GCR_ACLINK_OFF; 116 pxa2xx_ac97_hw_remove(pdev);
363 free_irq(IRQ_AC97, NULL);
364#ifdef CONFIG_PXA27x
365 clk_put(ac97conf_clk);
366 ac97conf_clk = NULL;
367#endif
368 clk_disable(ac97_clk);
369 clk_put(ac97_clk);
370 ac97_clk = NULL;
371} 117}
372 118
373static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 119static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index c796b188277..2fb58298513 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -21,6 +21,7 @@
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/pxa2xx-lib.h>
24 25
25#include <mach/hardware.h> 26#include <mach/hardware.h>
26#include <mach/pxa-regs.h> 27#include <mach/pxa-regs.h>
@@ -30,6 +31,54 @@
30#include "pxa2xx-pcm.h" 31#include "pxa2xx-pcm.h"
31#include "pxa2xx-i2s.h" 32#include "pxa2xx-i2s.h"
32 33
34struct pxa2xx_gpio {
35 u32 sys;
36 u32 rx;
37 u32 tx;
38 u32 clk;
39 u32 frm;
40};
41
42/*
43 * I2S Controller Register and Bit Definitions
44 */
45#define SACR0 __REG(0x40400000) /* Global Control Register */
46#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */
47#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
48#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */
49#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */
50#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */
51#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */
52
53#define SACR0_RFTH(x) ((x) << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */
54#define SACR0_TFTH(x) ((x) << 8) /* Tx FIFO Interrupt or DMA Trigger Threshold */
55#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */
56#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */
57#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */
58#define SACR0_BCKD (1 << 2) /* Bit Clock Direction */
59#define SACR0_ENB (1 << 0) /* Enable I2S Link */
60#define SACR1_ENLBF (1 << 5) /* Enable Loopback */
61#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */
62#define SACR1_DREC (1 << 3) /* Disable Recording Function */
63#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */
64
65#define SASR0_I2SOFF (1 << 7) /* Controller Status */
66#define SASR0_ROR (1 << 6) /* Rx FIFO Overrun */
67#define SASR0_TUR (1 << 5) /* Tx FIFO Underrun */
68#define SASR0_RFS (1 << 4) /* Rx FIFO Service Request */
69#define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */
70#define SASR0_BSY (1 << 2) /* I2S Busy */
71#define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */
72#define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */
73
74#define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */
75#define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */
76
77#define SAIMR_ROR (1 << 6) /* Enable Rx FIFO Overrun Condition Interrupt */
78#define SAIMR_TUR (1 << 5) /* Enable Tx FIFO Underrun Condition Interrupt */
79#define SAIMR_RFS (1 << 4) /* Enable Rx FIFO Service Interrupt */
80#define SAIMR_TFS (1 << 3) /* Enable Tx FIFO Service Interrupt */
81
33struct pxa_i2s_port { 82struct pxa_i2s_port {
34 u32 sadiv; 83 u32 sadiv;
35 u32 sacr0; 84 u32 sacr0;
@@ -44,7 +93,7 @@ static struct clk *clk_i2s;
44static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { 93static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
45 .name = "I2S PCM Stereo out", 94 .name = "I2S PCM Stereo out",
46 .dev_addr = __PREG(SADR), 95 .dev_addr = __PREG(SADR),
47 .drcmr = &DRCMRTXSADR, 96 .drcmr = &DRCMR(3),
48 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 97 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
49 DCMD_BURST32 | DCMD_WIDTH4, 98 DCMD_BURST32 | DCMD_WIDTH4,
50}; 99};
@@ -52,7 +101,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
52static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = { 101static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = {
53 .name = "I2S PCM Stereo in", 102 .name = "I2S PCM Stereo in",
54 .dev_addr = __PREG(SADR), 103 .dev_addr = __PREG(SADR),
55 .drcmr = &DRCMRRXSADR, 104 .drcmr = &DRCMR(2),
56 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 105 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
57 DCMD_BURST32 | DCMD_WIDTH4, 106 DCMD_BURST32 | DCMD_WIDTH4,
58}; 107};
@@ -65,11 +114,6 @@ static struct pxa2xx_gpio gpio_bus[] = {
65 .frm = GPIO31_SYNC_I2S_MD, 114 .frm = GPIO31_SYNC_I2S_MD,
66 }, 115 },
67 { /* I2S SoC Master */ 116 { /* I2S SoC Master */
68#ifdef CONFIG_PXA27x
69 .sys = GPIO113_I2S_SYSCLK_MD,
70#else
71 .sys = GPIO32_SYSCLK_I2S_MD,
72#endif
73 .rx = GPIO29_SDATA_IN_I2S_MD, 117 .rx = GPIO29_SDATA_IN_I2S_MD,
74 .tx = GPIO30_SDATA_OUT_I2S_MD, 118 .tx = GPIO30_SDATA_OUT_I2S_MD,
75 .clk = GPIO28_BITCLK_OUT_I2S_MD, 119 .clk = GPIO28_BITCLK_OUT_I2S_MD,
@@ -343,6 +387,11 @@ static struct platform_driver pxa2xx_i2s_driver = {
343 387
344static int __init pxa2xx_i2s_init(void) 388static int __init pxa2xx_i2s_init(void)
345{ 389{
390 if (cpu_is_pxa27x())
391 gpio_bus[1].sys = GPIO113_I2S_SYSCLK_MD;
392 else
393 gpio_bus[1].sys = GPIO32_SYSCLK_I2S_MD;
394
346 clk_i2s = ERR_PTR(-ENOENT); 395 clk_i2s = ERR_PTR(-ENOENT);
347 return platform_driver_register(&pxa2xx_i2s_driver); 396 return platform_driver_register(&pxa2xx_i2s_driver);
348} 397}
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index 4345f387fe4..afcd892cd2f 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -10,64 +10,14 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17#include <linux/dma-mapping.h> 13#include <linux/dma-mapping.h>
18 14
19#include <sound/core.h> 15#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h> 16#include <sound/soc.h>
23 17#include <sound/pxa2xx-lib.h>
24#include <asm/dma.h>
25#include <mach/hardware.h>
26#include <mach/pxa-regs.h>
27#include <mach/audio.h>
28 18
29#include "pxa2xx-pcm.h" 19#include "pxa2xx-pcm.h"
30 20#include "../../arm/pxa2xx-pcm.h"
31static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
32 .info = SNDRV_PCM_INFO_MMAP |
33 SNDRV_PCM_INFO_MMAP_VALID |
34 SNDRV_PCM_INFO_INTERLEAVED |
35 SNDRV_PCM_INFO_PAUSE |
36 SNDRV_PCM_INFO_RESUME,
37 .formats = SNDRV_PCM_FMTBIT_S16_LE |
38 SNDRV_PCM_FMTBIT_S24_LE |
39 SNDRV_PCM_FMTBIT_S32_LE,
40 .period_bytes_min = 32,
41 .period_bytes_max = 8192 - 32,
42 .periods_min = 1,
43 .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc),
44 .buffer_bytes_max = 128 * 1024,
45 .fifo_size = 32,
46};
47
48struct pxa2xx_runtime_data {
49 int dma_ch;
50 struct pxa2xx_pcm_dma_params *params;
51 pxa_dma_desc *dma_desc_array;
52 dma_addr_t dma_desc_array_phys;
53};
54
55static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
56{
57 struct snd_pcm_substream *substream = dev_id;
58 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
59 int dcsr;
60
61 dcsr = DCSR(dma_ch);
62 DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
63
64 if (dcsr & DCSR_ENDINTR) {
65 snd_pcm_period_elapsed(substream);
66 } else {
67 printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
68 prtd->params->name, dma_ch, dcsr);
69 }
70}
71 21
72static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, 22static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
73 struct snd_pcm_hw_params *params) 23 struct snd_pcm_hw_params *params)
@@ -76,10 +26,6 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
76 struct pxa2xx_runtime_data *prtd = runtime->private_data; 26 struct pxa2xx_runtime_data *prtd = runtime->private_data;
77 struct snd_soc_pcm_runtime *rtd = substream->private_data; 27 struct snd_soc_pcm_runtime *rtd = substream->private_data;
78 struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; 28 struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
79 size_t totsize = params_buffer_bytes(params);
80 size_t period = params_period_bytes(params);
81 pxa_dma_desc *dma_desc;
82 dma_addr_t dma_buff_phys, next_desc_phys;
83 int ret; 29 int ret;
84 30
85 /* return if this is a bufferless transfer e.g. 31 /* return if this is a bufferless transfer e.g.
@@ -106,42 +52,16 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
106 prtd->dma_ch = ret; 52 prtd->dma_ch = ret;
107 } 53 }
108 54
109 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 55 return __pxa2xx_pcm_hw_params(substream, params);
110 runtime->dma_bytes = totsize;
111
112 dma_desc = prtd->dma_desc_array;
113 next_desc_phys = prtd->dma_desc_array_phys;
114 dma_buff_phys = runtime->dma_addr;
115 do {
116 next_desc_phys += sizeof(pxa_dma_desc);
117 dma_desc->ddadr = next_desc_phys;
118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
119 dma_desc->dsadr = dma_buff_phys;
120 dma_desc->dtadr = prtd->params->dev_addr;
121 } else {
122 dma_desc->dsadr = prtd->params->dev_addr;
123 dma_desc->dtadr = dma_buff_phys;
124 }
125 if (period > totsize)
126 period = totsize;
127 dma_desc->dcmd = prtd->params->dcmd | period | DCMD_ENDIRQEN;
128 dma_desc++;
129 dma_buff_phys += period;
130 } while (totsize -= period);
131 dma_desc[-1].ddadr = prtd->dma_desc_array_phys;
132
133 return 0;
134} 56}
135 57
136static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) 58static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
137{ 59{
138 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; 60 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
139 61
140 if (prtd && prtd->params) 62 __pxa2xx_pcm_hw_free(substream);
141 *prtd->params->drcmr = 0;
142 63
143 if (prtd->dma_ch) { 64 if (prtd->dma_ch) {
144 snd_pcm_set_runtime_buffer(substream, NULL);
145 pxa_free_dma(prtd->dma_ch); 65 pxa_free_dma(prtd->dma_ch);
146 prtd->dma_ch = 0; 66 prtd->dma_ch = 0;
147 } 67 }
@@ -149,188 +69,21 @@ static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
149 return 0; 69 return 0;
150} 70}
151 71
152static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
153{
154 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
155
156 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
157 DCSR(prtd->dma_ch) = 0;
158 DCMD(prtd->dma_ch) = 0;
159 *prtd->params->drcmr = prtd->dma_ch | DRCMR_MAPVLD;
160
161 return 0;
162}
163
164static int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
165{
166 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
167 int ret = 0;
168
169 switch (cmd) {
170 case SNDRV_PCM_TRIGGER_START:
171 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
172 DCSR(prtd->dma_ch) = DCSR_RUN;
173 break;
174
175 case SNDRV_PCM_TRIGGER_STOP:
176 case SNDRV_PCM_TRIGGER_SUSPEND:
177 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
178 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
179 break;
180
181 case SNDRV_PCM_TRIGGER_RESUME:
182 DCSR(prtd->dma_ch) |= DCSR_RUN;
183 break;
184 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
185 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
186 DCSR(prtd->dma_ch) |= DCSR_RUN;
187 break;
188
189 default:
190 ret = -EINVAL;
191 }
192
193 return ret;
194}
195
196static snd_pcm_uframes_t
197pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
198{
199 struct snd_pcm_runtime *runtime = substream->runtime;
200 struct pxa2xx_runtime_data *prtd = runtime->private_data;
201
202 dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
203 DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch);
204 snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
205
206 if (x == runtime->buffer_size)
207 x = 0;
208 return x;
209}
210
211static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
212{
213 struct snd_pcm_runtime *runtime = substream->runtime;
214 struct pxa2xx_runtime_data *prtd;
215 int ret;
216
217 snd_soc_set_runtime_hwparams(substream, &pxa2xx_pcm_hardware);
218
219 /*
220 * For mysterious reasons (and despite what the manual says)
221 * playback samples are lost if the DMA count is not a multiple
222 * of the DMA burst size. Let's add a rule to enforce that.
223 */
224 ret = snd_pcm_hw_constraint_step(runtime, 0,
225 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
226 if (ret)
227 goto out;
228
229 ret = snd_pcm_hw_constraint_step(runtime, 0,
230 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
231 if (ret)
232 goto out;
233
234 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
235 if (ret < 0)
236 goto out;
237
238 prtd = kzalloc(sizeof(struct pxa2xx_runtime_data), GFP_KERNEL);
239 if (prtd == NULL) {
240 ret = -ENOMEM;
241 goto out;
242 }
243
244 prtd->dma_desc_array =
245 dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
246 &prtd->dma_desc_array_phys, GFP_KERNEL);
247 if (!prtd->dma_desc_array) {
248 ret = -ENOMEM;
249 goto err1;
250 }
251
252 runtime->private_data = prtd;
253 return 0;
254
255 err1:
256 kfree(prtd);
257 out:
258 return ret;
259}
260
261static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
262{
263 struct snd_pcm_runtime *runtime = substream->runtime;
264 struct pxa2xx_runtime_data *prtd = runtime->private_data;
265
266 dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
267 prtd->dma_desc_array, prtd->dma_desc_array_phys);
268 kfree(prtd);
269 return 0;
270}
271
272static int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
273 struct vm_area_struct *vma)
274{
275 struct snd_pcm_runtime *runtime = substream->runtime;
276 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
277 runtime->dma_area,
278 runtime->dma_addr,
279 runtime->dma_bytes);
280}
281
282struct snd_pcm_ops pxa2xx_pcm_ops = { 72struct snd_pcm_ops pxa2xx_pcm_ops = {
283 .open = pxa2xx_pcm_open, 73 .open = __pxa2xx_pcm_open,
284 .close = pxa2xx_pcm_close, 74 .close = __pxa2xx_pcm_close,
285 .ioctl = snd_pcm_lib_ioctl, 75 .ioctl = snd_pcm_lib_ioctl,
286 .hw_params = pxa2xx_pcm_hw_params, 76 .hw_params = pxa2xx_pcm_hw_params,
287 .hw_free = pxa2xx_pcm_hw_free, 77 .hw_free = pxa2xx_pcm_hw_free,
288 .prepare = pxa2xx_pcm_prepare, 78 .prepare = __pxa2xx_pcm_prepare,
289 .trigger = pxa2xx_pcm_trigger, 79 .trigger = pxa2xx_pcm_trigger,
290 .pointer = pxa2xx_pcm_pointer, 80 .pointer = pxa2xx_pcm_pointer,
291 .mmap = pxa2xx_pcm_mmap, 81 .mmap = pxa2xx_pcm_mmap,
292}; 82};
293 83
294static int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
295{
296 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
297 struct snd_dma_buffer *buf = &substream->dma_buffer;
298 size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
299 buf->dev.type = SNDRV_DMA_TYPE_DEV;
300 buf->dev.dev = pcm->card->dev;
301 buf->private_data = NULL;
302 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
303 &buf->addr, GFP_KERNEL);
304 if (!buf->area)
305 return -ENOMEM;
306 buf->bytes = size;
307 return 0;
308}
309
310static void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
311{
312 struct snd_pcm_substream *substream;
313 struct snd_dma_buffer *buf;
314 int stream;
315
316 for (stream = 0; stream < 2; stream++) {
317 substream = pcm->streams[stream].substream;
318 if (!substream)
319 continue;
320
321 buf = &substream->dma_buffer;
322 if (!buf->area)
323 continue;
324
325 dma_free_writecombine(pcm->card->dev, buf->bytes,
326 buf->area, buf->addr);
327 buf->area = NULL;
328 }
329}
330
331static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK; 84static u64 pxa2xx_pcm_dmamask = DMA_32BIT_MASK;
332 85
333int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, 86static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
334 struct snd_pcm *pcm) 87 struct snd_pcm *pcm)
335{ 88{
336 int ret = 0; 89 int ret = 0;
@@ -360,7 +113,7 @@ int pxa2xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
360struct snd_soc_platform pxa2xx_soc_platform = { 113struct snd_soc_platform pxa2xx_soc_platform = {
361 .name = "pxa2xx-audio", 114 .name = "pxa2xx-audio",
362 .pcm_ops = &pxa2xx_pcm_ops, 115 .pcm_ops = &pxa2xx_pcm_ops,
363 .pcm_new = pxa2xx_pcm_new, 116 .pcm_new = pxa2xx_soc_pcm_new,
364 .pcm_free = pxa2xx_pcm_free_dma_buffers, 117 .pcm_free = pxa2xx_pcm_free_dma_buffers,
365}; 118};
366EXPORT_SYMBOL_GPL(pxa2xx_soc_platform); 119EXPORT_SYMBOL_GPL(pxa2xx_soc_platform);
diff --git a/sound/soc/pxa/pxa2xx-pcm.h b/sound/soc/pxa/pxa2xx-pcm.h
index 54c9c755e50..60c3b20aeeb 100644
--- a/sound/soc/pxa/pxa2xx-pcm.h
+++ b/sound/soc/pxa/pxa2xx-pcm.h
@@ -13,21 +13,6 @@
13#ifndef _PXA2XX_PCM_H 13#ifndef _PXA2XX_PCM_H
14#define _PXA2XX_PCM_H 14#define _PXA2XX_PCM_H
15 15
16struct pxa2xx_pcm_dma_params {
17 char *name; /* stream identifier */
18 u32 dcmd; /* DMA descriptor dcmd field */
19 volatile u32 *drcmr; /* the DMA request channel to use */
20 u32 dev_addr; /* device physical address for DMA */
21};
22
23struct pxa2xx_gpio {
24 u32 sys;
25 u32 rx;
26 u32 tx;
27 u32 clk;
28 u32 frm;
29};
30
31/* platform data */ 16/* platform data */
32extern struct snd_soc_platform pxa2xx_soc_platform; 17extern struct snd_soc_platform pxa2xx_soc_platform;
33 18
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 37cb768fc93..9a70b00fc30 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -19,16 +19,15 @@
19#include <linux/timer.h> 19#include <linux/timer.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/gpio.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/soc.h> 25#include <sound/soc.h>
25#include <sound/soc-dapm.h> 26#include <sound/soc-dapm.h>
26 27
27#include <asm/mach-types.h> 28#include <asm/mach-types.h>
28#include <asm/hardware/scoop.h>
29#include <mach/pxa-regs.h> 29#include <mach/pxa-regs.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/akita.h>
32#include <mach/spitz.h> 31#include <mach/spitz.h>
33#include "../codecs/wm8750.h" 32#include "../codecs/wm8750.h"
34#include "pxa2xx-pcm.h" 33#include "pxa2xx-pcm.h"
@@ -63,8 +62,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
63 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 62 snd_soc_dapm_disable_pin(codec, "Mic Jack");
64 snd_soc_dapm_disable_pin(codec, "Line Jack"); 63 snd_soc_dapm_disable_pin(codec, "Line Jack");
65 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 64 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
66 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 65 gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
67 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 66 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
68 break; 67 break;
69 case SPITZ_MIC: 68 case SPITZ_MIC:
70 /* enable mic jack and bias, mute hp */ 69 /* enable mic jack and bias, mute hp */
@@ -72,8 +71,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
72 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 71 snd_soc_dapm_disable_pin(codec, "Headset Jack");
73 snd_soc_dapm_disable_pin(codec, "Line Jack"); 72 snd_soc_dapm_disable_pin(codec, "Line Jack");
74 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 73 snd_soc_dapm_enable_pin(codec, "Mic Jack");
75 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 74 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
76 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 75 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
77 break; 76 break;
78 case SPITZ_LINE: 77 case SPITZ_LINE:
79 /* enable line jack, disable mic bias and mute hp */ 78 /* enable line jack, disable mic bias and mute hp */
@@ -81,8 +80,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
81 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 80 snd_soc_dapm_disable_pin(codec, "Headset Jack");
82 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 81 snd_soc_dapm_disable_pin(codec, "Mic Jack");
83 snd_soc_dapm_enable_pin(codec, "Line Jack"); 82 snd_soc_dapm_enable_pin(codec, "Line Jack");
84 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 83 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
85 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 84 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
86 break; 85 break;
87 case SPITZ_HEADSET: 86 case SPITZ_HEADSET:
88 /* enable and unmute headset jack enable mic bias, mute L hp */ 87 /* enable and unmute headset jack enable mic bias, mute L hp */
@@ -90,8 +89,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
90 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 89 snd_soc_dapm_enable_pin(codec, "Mic Jack");
91 snd_soc_dapm_disable_pin(codec, "Line Jack"); 90 snd_soc_dapm_disable_pin(codec, "Line Jack");
92 snd_soc_dapm_enable_pin(codec, "Headset Jack"); 91 snd_soc_dapm_enable_pin(codec, "Headset Jack");
93 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 92 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
94 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 93 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
95 break; 94 break;
96 case SPITZ_HP_OFF: 95 case SPITZ_HP_OFF:
97 96
@@ -100,8 +99,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
100 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 99 snd_soc_dapm_disable_pin(codec, "Headset Jack");
101 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 100 snd_soc_dapm_disable_pin(codec, "Mic Jack");
102 snd_soc_dapm_disable_pin(codec, "Line Jack"); 101 snd_soc_dapm_disable_pin(codec, "Line Jack");
103 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 102 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
104 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 103 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
105 break; 104 break;
106 } 105 }
107 snd_soc_dapm_sync(codec); 106 snd_soc_dapm_sync(codec);
@@ -215,23 +214,14 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol,
215static int spitz_mic_bias(struct snd_soc_dapm_widget *w, 214static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
216 struct snd_kcontrol *k, int event) 215 struct snd_kcontrol *k, int event)
217{ 216{
218 if (machine_is_borzoi() || machine_is_spitz()) { 217 if (machine_is_borzoi() || machine_is_spitz())
219 if (SND_SOC_DAPM_EVENT_ON(event)) 218 gpio_set_value(SPITZ_GPIO_MIC_BIAS,
220 set_scoop_gpio(&spitzscoop2_device.dev, 219 SND_SOC_DAPM_EVENT_ON(event));
221 SPITZ_SCP2_MIC_BIAS); 220
222 else 221 if (machine_is_akita())
223 reset_scoop_gpio(&spitzscoop2_device.dev, 222 gpio_set_value(AKITA_GPIO_MIC_BIAS,
224 SPITZ_SCP2_MIC_BIAS); 223 SND_SOC_DAPM_EVENT_ON(event));
225 }
226 224
227 if (machine_is_akita()) {
228 if (SND_SOC_DAPM_EVENT_ON(event))
229 akita_set_ioexp(&akitaioexp_device.dev,
230 AKITA_IOEXP_MIC_BIAS);
231 else
232 akita_reset_ioexp(&akitaioexp_device.dev,
233 AKITA_IOEXP_MIC_BIAS);
234 }
235 return 0; 225 return 0;
236} 226}
237 227
@@ -337,6 +327,7 @@ static struct snd_soc_machine snd_soc_machine_spitz = {
337 327
338/* spitz audio private data */ 328/* spitz audio private data */
339static struct wm8750_setup_data spitz_wm8750_setup = { 329static struct wm8750_setup_data spitz_wm8750_setup = {
330 .i2c_bus = 0,
340 .i2c_address = 0x1b, 331 .i2c_address = 0x1b,
341}; 332};
342 333
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 8089f8ee05c..73a50e93a9a 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -24,6 +24,7 @@
24#include <sound/soc-dapm.h> 24#include <sound/soc-dapm.h>
25#include <sound/tlv.h> 25#include <sound/tlv.h>
26 26
27#include <asm/mach-types.h>
27#include <asm/hardware/scoop.h> 28#include <asm/hardware/scoop.h>
28#include <mach/regs-clock.h> 29#include <mach/regs-clock.h>
29#include <mach/regs-gpio.h> 30#include <mach/regs-gpio.h>
@@ -586,6 +587,7 @@ static struct snd_soc_machine neo1973 = {
586}; 587};
587 588
588static struct wm8753_setup_data neo1973_wm8753_setup = { 589static struct wm8753_setup_data neo1973_wm8753_setup = {
590 .i2c_bus = 0,
589 .i2c_address = 0x1a, 591 .i2c_address = 0x1a,
590}; 592};
591 593
@@ -596,54 +598,20 @@ static struct snd_soc_device neo1973_snd_devdata = {
596 .codec_data = &neo1973_wm8753_setup, 598 .codec_data = &neo1973_wm8753_setup,
597}; 599};
598 600
599static struct i2c_client client_template; 601static int lm4857_i2c_probe(struct i2c_client *client,
600 602 const struct i2c_device_id *id)
601static const unsigned short normal_i2c[] = { 0x7C, I2C_CLIENT_END };
602
603/* Magic definition of all other variables and things */
604I2C_CLIENT_INSMOD;
605
606static int lm4857_amp_probe(struct i2c_adapter *adap, int addr, int kind)
607{ 603{
608 int ret;
609
610 DBG("Entered %s\n", __func__); 604 DBG("Entered %s\n", __func__);
611 605
612 client_template.adapter = adap;
613 client_template.addr = addr;
614
615 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
616 if (i2c == NULL)
617 return -ENOMEM;
618
619 ret = i2c_attach_client(i2c);
620 if (ret < 0) {
621 printk(KERN_ERR "LM4857 failed to attach at addr %x\n", addr);
622 goto exit_err;
623 }
624
625 lm4857_write_regs(); 606 lm4857_write_regs();
626 return ret;
627
628exit_err:
629 kfree(i2c);
630 return ret;
631}
632
633static int lm4857_i2c_detach(struct i2c_client *client)
634{
635 DBG("Entered %s\n", __func__);
636
637 i2c_detach_client(client);
638 kfree(client);
639 return 0; 607 return 0;
640} 608}
641 609
642static int lm4857_i2c_attach(struct i2c_adapter *adap) 610static int lm4857_i2c_remove(struct i2c_client *client)
643{ 611{
644 DBG("Entered %s\n", __func__); 612 DBG("Entered %s\n", __func__);
645 613
646 return i2c_probe(adap, &addr_data, lm4857_amp_probe); 614 return 0;
647} 615}
648 616
649static u8 lm4857_state; 617static u8 lm4857_state;
@@ -681,27 +649,67 @@ static void lm4857_shutdown(struct i2c_client *dev)
681 lm4857_write_regs(); 649 lm4857_write_regs();
682} 650}
683 651
684/* corgi i2c codec control layer */ 652static const struct i2c_device_id lm4857_i2c_id[] = {
653 { "neo1973_lm4857", 0 }
654 { }
655};
656
685static struct i2c_driver lm4857_i2c_driver = { 657static struct i2c_driver lm4857_i2c_driver = {
686 .driver = { 658 .driver = {
687 .name = "LM4857 I2C Amp", 659 .name = "LM4857 I2C Amp",
688 .owner = THIS_MODULE, 660 .owner = THIS_MODULE,
689 }, 661 },
690 .id = I2C_DRIVERID_LM4857,
691 .suspend = lm4857_suspend, 662 .suspend = lm4857_suspend,
692 .resume = lm4857_resume, 663 .resume = lm4857_resume,
693 .shutdown = lm4857_shutdown, 664 .shutdown = lm4857_shutdown,
694 .attach_adapter = lm4857_i2c_attach, 665 .probe = lm4857_i2c_probe,
695 .detach_client = lm4857_i2c_detach, 666 .remove = lm4857_i2c_remove,
696 .command = NULL, 667 .id_table = lm4857_i2c_id,
697};
698
699static struct i2c_client client_template = {
700 .name = "LM4857",
701 .driver = &lm4857_i2c_driver,
702}; 668};
703 669
704static struct platform_device *neo1973_snd_device; 670static struct platform_device *neo1973_snd_device;
671static struct i2c_client *lm4857_client;
672
673static int __init neo1973_add_lm4857_device(struct platform_device *pdev,
674 int i2c_bus,
675 unsigned short i2c_address)
676{
677 struct i2c_board_info info;
678 struct i2c_adapter *adapter;
679 struct i2c_client *client;
680 int ret;
681
682 ret = i2c_add_driver(&lm4857_i2c_driver);
683 if (ret != 0) {
684 dev_err(&pdev->dev, "can't add lm4857 driver\n");
685 return ret;
686 }
687
688 memset(&info, 0, sizeof(struct i2c_board_info));
689 info.addr = i2c_address;
690 strlcpy(info.type, "neo1973_lm4857", I2C_NAME_SIZE);
691
692 adapter = i2c_get_adapter(i2c_bus);
693 if (!adapter) {
694 dev_err(&pdev->dev, "can't get i2c adapter %d\n", i2c_bus);
695 goto err_driver;
696 }
697
698 client = i2c_new_device(adapter, &info);
699 i2c_put_adapter(adapter);
700 if (!client) {
701 dev_err(&pdev->dev, "can't add lm4857 device at 0x%x\n",
702 (unsigned int)info.addr);
703 goto err_driver;
704 }
705
706 lm4857_client = client;
707 return 0;
708
709err_driver:
710 i2c_del_driver(&lm4857_i2c_driver);
711 return -ENODEV;
712}
705 713
706static int __init neo1973_init(void) 714static int __init neo1973_init(void)
707{ 715{
@@ -709,6 +717,12 @@ static int __init neo1973_init(void)
709 717
710 DBG("Entered %s\n", __func__); 718 DBG("Entered %s\n", __func__);
711 719
720 if (!machine_is_neo1973_gta01()) {
721 printk(KERN_INFO
722 "Only GTA01 hardware supported by ASoC driver\n");
723 return -ENODEV;
724 }
725
712 neo1973_snd_device = platform_device_alloc("soc-audio", -1); 726 neo1973_snd_device = platform_device_alloc("soc-audio", -1);
713 if (!neo1973_snd_device) 727 if (!neo1973_snd_device)
714 return -ENOMEM; 728 return -ENOMEM;
@@ -717,12 +731,15 @@ static int __init neo1973_init(void)
717 neo1973_snd_devdata.dev = &neo1973_snd_device->dev; 731 neo1973_snd_devdata.dev = &neo1973_snd_device->dev;
718 ret = platform_device_add(neo1973_snd_device); 732 ret = platform_device_add(neo1973_snd_device);
719 733
720 if (ret) 734 if (ret) {
721 platform_device_put(neo1973_snd_device); 735 platform_device_put(neo1973_snd_device);
736 return ret;
737 }
722 738
723 ret = i2c_add_driver(&lm4857_i2c_driver); 739 ret = neo1973_add_lm4857_device(neo1973_snd_device,
740 neo1973_wm8753_setup, 0x7C);
724 if (ret != 0) 741 if (ret != 0)
725 printk(KERN_ERR "can't add i2c driver"); 742 platform_device_unregister(neo1973_snd_device);
726 743
727 return ret; 744 return ret;
728} 745}
@@ -731,6 +748,7 @@ static void __exit neo1973_exit(void)
731{ 748{
732 DBG("Entered %s\n", __func__); 749 DBG("Entered %s\n", __func__);
733 750
751 i2c_unregister_device(lm4857_client);
734 i2c_del_driver(&lm4857_i2c_driver); 752 i2c_del_driver(&lm4857_i2c_driver);
735 platform_device_unregister(neo1973_snd_device); 753 platform_device_unregister(neo1973_snd_device);
736} 754}
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 83f1190293a..ad381138fc2 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -340,6 +340,12 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
340 } 340 }
341 codec->active--; 341 codec->active--;
342 342
343 /* Muting the DAC suppresses artifacts caused during digital
344 * shutdown, for example from stopping clocks.
345 */
346 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
347 snd_soc_dai_digital_mute(codec_dai, 1);
348
343 if (cpu_dai->ops.shutdown) 349 if (cpu_dai->ops.shutdown)
344 cpu_dai->ops.shutdown(substream); 350 cpu_dai->ops.shutdown(substream);
345 351
@@ -970,9 +976,29 @@ static ssize_t codec_reg_show(struct device *dev,
970 step = codec->reg_cache_step; 976 step = codec->reg_cache_step;
971 977
972 count += sprintf(buf, "%s registers\n", codec->name); 978 count += sprintf(buf, "%s registers\n", codec->name);
973 for (i = 0; i < codec->reg_cache_size; i += step) 979 for (i = 0; i < codec->reg_cache_size; i += step) {
974 count += sprintf(buf + count, "%2x: %4x\n", i, 980 count += sprintf(buf + count, "%2x: ", i);
975 codec->read(codec, i)); 981 if (count >= PAGE_SIZE - 1)
982 break;
983
984 if (codec->display_register)
985 count += codec->display_register(codec, buf + count,
986 PAGE_SIZE - count, i);
987 else
988 count += snprintf(buf + count, PAGE_SIZE - count,
989 "%4x", codec->read(codec, i));
990
991 if (count >= PAGE_SIZE - 1)
992 break;
993
994 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
995 if (count >= PAGE_SIZE - 1)
996 break;
997 }
998
999 /* Truncate count; min() would cause a warning */
1000 if (count >= PAGE_SIZE)
1001 count = PAGE_SIZE - 1;
976 1002
977 return count; 1003 return count;
978} 1004}
@@ -1296,10 +1322,10 @@ int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
1296 1322
1297 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1323 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1298 uinfo->count = e->shift_l == e->shift_r ? 1 : 2; 1324 uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
1299 uinfo->value.enumerated.items = e->mask; 1325 uinfo->value.enumerated.items = e->max;
1300 1326
1301 if (uinfo->value.enumerated.item > e->mask - 1) 1327 if (uinfo->value.enumerated.item > e->max - 1)
1302 uinfo->value.enumerated.item = e->mask - 1; 1328 uinfo->value.enumerated.item = e->max - 1;
1303 strcpy(uinfo->value.enumerated.name, 1329 strcpy(uinfo->value.enumerated.name,
1304 e->texts[uinfo->value.enumerated.item]); 1330 e->texts[uinfo->value.enumerated.item]);
1305 return 0; 1331 return 0;
@@ -1322,7 +1348,7 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
1322 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1348 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1323 unsigned short val, bitmask; 1349 unsigned short val, bitmask;
1324 1350
1325 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 1351 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1326 ; 1352 ;
1327 val = snd_soc_read(codec, e->reg); 1353 val = snd_soc_read(codec, e->reg);
1328 ucontrol->value.enumerated.item[0] 1354 ucontrol->value.enumerated.item[0]
@@ -1352,14 +1378,14 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1352 unsigned short val; 1378 unsigned short val;
1353 unsigned short mask, bitmask; 1379 unsigned short mask, bitmask;
1354 1380
1355 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 1381 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1356 ; 1382 ;
1357 if (ucontrol->value.enumerated.item[0] > e->mask - 1) 1383 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1358 return -EINVAL; 1384 return -EINVAL;
1359 val = ucontrol->value.enumerated.item[0] << e->shift_l; 1385 val = ucontrol->value.enumerated.item[0] << e->shift_l;
1360 mask = (bitmask - 1) << e->shift_l; 1386 mask = (bitmask - 1) << e->shift_l;
1361 if (e->shift_l != e->shift_r) { 1387 if (e->shift_l != e->shift_r) {
1362 if (ucontrol->value.enumerated.item[1] > e->mask - 1) 1388 if (ucontrol->value.enumerated.item[1] > e->max - 1)
1363 return -EINVAL; 1389 return -EINVAL;
1364 val |= ucontrol->value.enumerated.item[1] << e->shift_r; 1390 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1365 mask |= (bitmask - 1) << e->shift_r; 1391 mask |= (bitmask - 1) << e->shift_r;
@@ -1386,10 +1412,10 @@ int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
1386 1412
1387 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1413 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1388 uinfo->count = 1; 1414 uinfo->count = 1;
1389 uinfo->value.enumerated.items = e->mask; 1415 uinfo->value.enumerated.items = e->max;
1390 1416
1391 if (uinfo->value.enumerated.item > e->mask - 1) 1417 if (uinfo->value.enumerated.item > e->max - 1)
1392 uinfo->value.enumerated.item = e->mask - 1; 1418 uinfo->value.enumerated.item = e->max - 1;
1393 strcpy(uinfo->value.enumerated.name, 1419 strcpy(uinfo->value.enumerated.name,
1394 e->texts[uinfo->value.enumerated.item]); 1420 e->texts[uinfo->value.enumerated.item]);
1395 return 0; 1421 return 0;
@@ -1434,9 +1460,11 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext);
1434int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, 1460int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
1435 struct snd_ctl_elem_info *uinfo) 1461 struct snd_ctl_elem_info *uinfo)
1436{ 1462{
1437 int max = (kcontrol->private_value >> 16) & 0xff; 1463 struct soc_mixer_control *mc =
1438 int shift = (kcontrol->private_value >> 8) & 0x0f; 1464 (struct soc_mixer_control *)kcontrol->private_value;
1439 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1465 int max = mc->max;
1466 unsigned int shift = mc->min;
1467 unsigned int rshift = mc->rshift;
1440 1468
1441 if (max == 1) 1469 if (max == 1)
1442 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1470 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
@@ -1462,13 +1490,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
1462int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, 1490int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
1463 struct snd_ctl_elem_value *ucontrol) 1491 struct snd_ctl_elem_value *ucontrol)
1464{ 1492{
1493 struct soc_mixer_control *mc =
1494 (struct soc_mixer_control *)kcontrol->private_value;
1465 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1495 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1466 int reg = kcontrol->private_value & 0xff; 1496 unsigned int reg = mc->reg;
1467 int shift = (kcontrol->private_value >> 8) & 0x0f; 1497 unsigned int shift = mc->shift;
1468 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1498 unsigned int rshift = mc->rshift;
1469 int max = (kcontrol->private_value >> 16) & 0xff; 1499 int max = mc->max;
1470 int mask = (1 << fls(max)) - 1; 1500 unsigned int mask = (1 << fls(max)) - 1;
1471 int invert = (kcontrol->private_value >> 24) & 0x01; 1501 unsigned int invert = mc->invert;
1472 1502
1473 ucontrol->value.integer.value[0] = 1503 ucontrol->value.integer.value[0] =
1474 (snd_soc_read(codec, reg) >> shift) & mask; 1504 (snd_soc_read(codec, reg) >> shift) & mask;
@@ -1499,13 +1529,15 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw);
1499int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, 1529int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
1500 struct snd_ctl_elem_value *ucontrol) 1530 struct snd_ctl_elem_value *ucontrol)
1501{ 1531{
1532 struct soc_mixer_control *mc =
1533 (struct soc_mixer_control *)kcontrol->private_value;
1502 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1534 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1503 int reg = kcontrol->private_value & 0xff; 1535 unsigned int reg = mc->reg;
1504 int shift = (kcontrol->private_value >> 8) & 0x0f; 1536 unsigned int shift = mc->shift;
1505 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1537 unsigned int rshift = mc->rshift;
1506 int max = (kcontrol->private_value >> 16) & 0xff; 1538 int max = mc->max;
1507 int mask = (1 << fls(max)) - 1; 1539 unsigned int mask = (1 << fls(max)) - 1;
1508 int invert = (kcontrol->private_value >> 24) & 0x01; 1540 unsigned int invert = mc->invert;
1509 unsigned short val, val2, val_mask; 1541 unsigned short val, val2, val_mask;
1510 1542
1511 val = (ucontrol->value.integer.value[0] & mask); 1543 val = (ucontrol->value.integer.value[0] & mask);
@@ -1537,7 +1569,9 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
1537int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, 1569int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
1538 struct snd_ctl_elem_info *uinfo) 1570 struct snd_ctl_elem_info *uinfo)
1539{ 1571{
1540 int max = (kcontrol->private_value >> 12) & 0xff; 1572 struct soc_mixer_control *mc =
1573 (struct soc_mixer_control *)kcontrol->private_value;
1574 int max = mc->max;
1541 1575
1542 if (max == 1) 1576 if (max == 1)
1543 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 1577 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
@@ -1563,13 +1597,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r);
1563int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, 1597int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
1564 struct snd_ctl_elem_value *ucontrol) 1598 struct snd_ctl_elem_value *ucontrol)
1565{ 1599{
1600 struct soc_mixer_control *mc =
1601 (struct soc_mixer_control *)kcontrol->private_value;
1566 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1602 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1567 int reg = kcontrol->private_value & 0xff; 1603 unsigned int reg = mc->reg;
1568 int reg2 = (kcontrol->private_value >> 24) & 0xff; 1604 unsigned int reg2 = mc->rreg;
1569 int shift = (kcontrol->private_value >> 8) & 0x0f; 1605 unsigned int shift = mc->shift;
1570 int max = (kcontrol->private_value >> 12) & 0xff; 1606 int max = mc->max;
1571 int mask = (1<<fls(max))-1; 1607 unsigned int mask = (1<<fls(max))-1;
1572 int invert = (kcontrol->private_value >> 20) & 0x01; 1608 unsigned int invert = mc->invert;
1573 1609
1574 ucontrol->value.integer.value[0] = 1610 ucontrol->value.integer.value[0] =
1575 (snd_soc_read(codec, reg) >> shift) & mask; 1611 (snd_soc_read(codec, reg) >> shift) & mask;
@@ -1598,13 +1634,15 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r);
1598int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, 1634int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
1599 struct snd_ctl_elem_value *ucontrol) 1635 struct snd_ctl_elem_value *ucontrol)
1600{ 1636{
1637 struct soc_mixer_control *mc =
1638 (struct soc_mixer_control *)kcontrol->private_value;
1601 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1639 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1602 int reg = kcontrol->private_value & 0xff; 1640 unsigned int reg = mc->reg;
1603 int reg2 = (kcontrol->private_value >> 24) & 0xff; 1641 unsigned int reg2 = mc->rreg;
1604 int shift = (kcontrol->private_value >> 8) & 0x0f; 1642 unsigned int shift = mc->shift;
1605 int max = (kcontrol->private_value >> 12) & 0xff; 1643 int max = mc->max;
1606 int mask = (1 << fls(max)) - 1; 1644 unsigned int mask = (1 << fls(max)) - 1;
1607 int invert = (kcontrol->private_value >> 20) & 0x01; 1645 unsigned int invert = mc->invert;
1608 int err; 1646 int err;
1609 unsigned short val, val2, val_mask; 1647 unsigned short val, val2, val_mask;
1610 1648
@@ -1641,8 +1679,10 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r);
1641int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, 1679int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_info *uinfo) 1680 struct snd_ctl_elem_info *uinfo)
1643{ 1681{
1644 int max = (signed char)((kcontrol->private_value >> 16) & 0xff); 1682 struct soc_mixer_control *mc =
1645 int min = (signed char)((kcontrol->private_value >> 24) & 0xff); 1683 (struct soc_mixer_control *)kcontrol->private_value;
1684 int max = mc->max;
1685 int min = mc->min;
1646 1686
1647 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1687 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1648 uinfo->count = 2; 1688 uinfo->count = 2;
@@ -1664,9 +1704,11 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8);
1664int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, 1704int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
1665 struct snd_ctl_elem_value *ucontrol) 1705 struct snd_ctl_elem_value *ucontrol)
1666{ 1706{
1707 struct soc_mixer_control *mc =
1708 (struct soc_mixer_control *)kcontrol->private_value;
1667 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1709 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1668 int reg = kcontrol->private_value & 0xff; 1710 unsigned int reg = mc->reg;
1669 int min = (signed char)((kcontrol->private_value >> 24) & 0xff); 1711 int min = mc->min;
1670 int val = snd_soc_read(codec, reg); 1712 int val = snd_soc_read(codec, reg);
1671 1713
1672 ucontrol->value.integer.value[0] = 1714 ucontrol->value.integer.value[0] =
@@ -1689,9 +1731,11 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8);
1689int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, 1731int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
1690 struct snd_ctl_elem_value *ucontrol) 1732 struct snd_ctl_elem_value *ucontrol)
1691{ 1733{
1734 struct soc_mixer_control *mc =
1735 (struct soc_mixer_control *)kcontrol->private_value;
1692 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1736 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1693 int reg = kcontrol->private_value & 0xff; 1737 unsigned int reg = mc->reg;
1694 int min = (signed char)((kcontrol->private_value >> 24) & 0xff); 1738 int min = mc->min;
1695 unsigned short val; 1739 unsigned short val;
1696 1740
1697 val = (ucontrol->value.integer.value[0]+min) & 0xff; 1741 val = (ucontrol->value.integer.value[0]+min) & 0xff;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f9d100bc847..9ca9c08610f 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -38,6 +38,7 @@
38#include <linux/bitops.h> 38#include <linux/bitops.h>
39#include <linux/platform_device.h> 39#include <linux/platform_device.h>
40#include <linux/jiffies.h> 40#include <linux/jiffies.h>
41#include <linux/debugfs.h>
41#include <sound/core.h> 42#include <sound/core.h>
42#include <sound/pcm.h> 43#include <sound/pcm.h>
43#include <sound/pcm_params.h> 44#include <sound/pcm_params.h>
@@ -67,7 +68,9 @@ static int dapm_status = 1;
67module_param(dapm_status, int, 0); 68module_param(dapm_status, int, 0);
68MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries"); 69MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries");
69 70
70static unsigned int pop_time; 71static struct dentry *asoc_debugfs;
72
73static u32 pop_time;
71 74
72static void pop_wait(void) 75static void pop_wait(void)
73{ 76{
@@ -104,10 +107,13 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
104 case snd_soc_dapm_switch: 107 case snd_soc_dapm_switch:
105 case snd_soc_dapm_mixer: { 108 case snd_soc_dapm_mixer: {
106 int val; 109 int val;
107 int reg = w->kcontrols[i].private_value & 0xff; 110 struct soc_mixer_control *mc = (struct soc_mixer_control *)
108 int shift = (w->kcontrols[i].private_value >> 8) & 0x0f; 111 w->kcontrols[i].private_value;
109 int mask = (w->kcontrols[i].private_value >> 16) & 0xff; 112 unsigned int reg = mc->reg;
110 int invert = (w->kcontrols[i].private_value >> 24) & 0x01; 113 unsigned int shift = mc->shift;
114 int max = mc->max;
115 unsigned int mask = (1 << fls(max)) - 1;
116 unsigned int invert = mc->invert;
111 117
112 val = snd_soc_read(w->codec, reg); 118 val = snd_soc_read(w->codec, reg);
113 val = (val >> shift) & mask; 119 val = (val >> shift) & mask;
@@ -122,13 +128,13 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
122 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value; 128 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value;
123 int val, item, bitmask; 129 int val, item, bitmask;
124 130
125 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 131 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
126 ; 132 ;
127 val = snd_soc_read(w->codec, e->reg); 133 val = snd_soc_read(w->codec, e->reg);
128 item = (val >> e->shift_l) & (bitmask - 1); 134 item = (val >> e->shift_l) & (bitmask - 1);
129 135
130 p->connect = 0; 136 p->connect = 0;
131 for (i = 0; i < e->mask; i++) { 137 for (i = 0; i < e->max; i++) {
132 if (!(strcmp(p->name, e->texts[i])) && item == i) 138 if (!(strcmp(p->name, e->texts[i])) && item == i)
133 p->connect = 1; 139 p->connect = 1;
134 } 140 }
@@ -165,7 +171,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
165 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 171 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
166 int i; 172 int i;
167 173
168 for (i = 0; i < e->mask; i++) { 174 for (i = 0; i < e->max; i++) {
169 if (!(strcmp(control_name, e->texts[i]))) { 175 if (!(strcmp(control_name, e->texts[i]))) {
170 list_add(&path->list, &codec->dapm_paths); 176 list_add(&path->list, &codec->dapm_paths);
171 list_add(&path->list_sink, &dest->sources); 177 list_add(&path->list_sink, &dest->sources);
@@ -247,16 +253,19 @@ static int dapm_set_pga(struct snd_soc_dapm_widget *widget, int power)
247 return 0; 253 return 0;
248 254
249 if (widget->num_kcontrols && k) { 255 if (widget->num_kcontrols && k) {
250 int reg = k->private_value & 0xff; 256 struct soc_mixer_control *mc =
251 int shift = (k->private_value >> 8) & 0x0f; 257 (struct soc_mixer_control *)k->private_value;
252 int mask = (k->private_value >> 16) & 0xff; 258 unsigned int reg = mc->reg;
253 int invert = (k->private_value >> 24) & 0x01; 259 unsigned int shift = mc->shift;
260 int max = mc->max;
261 unsigned int mask = (1 << fls(max)) - 1;
262 unsigned int invert = mc->invert;
254 263
255 if (power) { 264 if (power) {
256 int i; 265 int i;
257 /* power up has happended, increase volume to last level */ 266 /* power up has happended, increase volume to last level */
258 if (invert) { 267 if (invert) {
259 for (i = mask; i > widget->saved_value; i--) 268 for (i = max; i > widget->saved_value; i--)
260 snd_soc_update_bits(widget->codec, reg, mask, i); 269 snd_soc_update_bits(widget->codec, reg, mask, i);
261 } else { 270 } else {
262 for (i = 0; i < widget->saved_value; i++) 271 for (i = 0; i < widget->saved_value; i++)
@@ -684,7 +693,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
684/* test and update the power status of a mux widget */ 693/* test and update the power status of a mux widget */
685static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 694static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
686 struct snd_kcontrol *kcontrol, int mask, 695 struct snd_kcontrol *kcontrol, int mask,
687 int val, struct soc_enum* e) 696 int mux, int val, struct soc_enum *e)
688{ 697{
689 struct snd_soc_dapm_path *path; 698 struct snd_soc_dapm_path *path;
690 int found = 0; 699 int found = 0;
@@ -700,12 +709,12 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
700 if (path->kcontrol != kcontrol) 709 if (path->kcontrol != kcontrol)
701 continue; 710 continue;
702 711
703 if (!path->name || ! e->texts[val]) 712 if (!path->name || !e->texts[mux])
704 continue; 713 continue;
705 714
706 found = 1; 715 found = 1;
707 /* we now need to match the string in the enum to the path */ 716 /* we now need to match the string in the enum to the path */
708 if (!(strcmp(path->name, e->texts[val]))) 717 if (!(strcmp(path->name, e->texts[mux])))
709 path->connect = 1; /* new connection */ 718 path->connect = 1; /* new connection */
710 else 719 else
711 path->connect = 0; /* old connection must be powered down */ 720 path->connect = 0; /* old connection must be powered down */
@@ -811,51 +820,35 @@ static ssize_t dapm_widget_show(struct device *dev,
811 820
812static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); 821static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
813 822
814/* pop/click delay times */
815static ssize_t dapm_pop_time_show(struct device *dev,
816 struct device_attribute *attr, char *buf)
817{
818 return sprintf(buf, "%d\n", pop_time);
819}
820
821static ssize_t dapm_pop_time_store(struct device *dev,
822 struct device_attribute *attr,
823 const char *buf, size_t count)
824
825{
826 unsigned long val;
827
828 if (strict_strtoul(buf, 10, &val) >= 0)
829 pop_time = val;
830 else
831 printk(KERN_ERR "Unable to parse pop_time setting\n");
832
833 return count;
834}
835
836static DEVICE_ATTR(dapm_pop_time, 0744, dapm_pop_time_show,
837 dapm_pop_time_store);
838
839int snd_soc_dapm_sys_add(struct device *dev) 823int snd_soc_dapm_sys_add(struct device *dev)
840{ 824{
841 int ret = 0; 825 int ret = 0;
842 826
843 if (dapm_status) { 827 if (!dapm_status)
844 ret = device_create_file(dev, &dev_attr_dapm_widget); 828 return 0;
845 829
846 if (ret == 0) 830 ret = device_create_file(dev, &dev_attr_dapm_widget);
847 ret = device_create_file(dev, &dev_attr_dapm_pop_time); 831 if (ret != 0)
848 } 832 return ret;
849 833
850 return ret; 834 asoc_debugfs = debugfs_create_dir("asoc", NULL);
835 if (!IS_ERR(asoc_debugfs))
836 debugfs_create_u32("dapm_pop_time", 0744, asoc_debugfs,
837 &pop_time);
838 else
839 asoc_debugfs = NULL;
840
841 return 0;
851} 842}
852 843
853static void snd_soc_dapm_sys_remove(struct device *dev) 844static void snd_soc_dapm_sys_remove(struct device *dev)
854{ 845{
855 if (dapm_status) { 846 if (dapm_status) {
856 device_remove_file(dev, &dev_attr_dapm_pop_time);
857 device_remove_file(dev, &dev_attr_dapm_widget); 847 device_remove_file(dev, &dev_attr_dapm_widget);
858 } 848 }
849
850 if (asoc_debugfs)
851 debugfs_remove_recursive(asoc_debugfs);
859} 852}
860 853
861/* free all dapm widgets and resources */ 854/* free all dapm widgets and resources */
@@ -1133,12 +1126,14 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
1133 struct snd_ctl_elem_value *ucontrol) 1126 struct snd_ctl_elem_value *ucontrol)
1134{ 1127{
1135 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1128 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1136 int reg = kcontrol->private_value & 0xff; 1129 struct soc_mixer_control *mc =
1137 int shift = (kcontrol->private_value >> 8) & 0x0f; 1130 (struct soc_mixer_control *)kcontrol->private_value;
1138 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1131 unsigned int reg = mc->reg;
1139 int max = (kcontrol->private_value >> 16) & 0xff; 1132 unsigned int shift = mc->shift;
1140 int invert = (kcontrol->private_value >> 24) & 0x01; 1133 unsigned int rshift = mc->rshift;
1141 int mask = (1 << fls(max)) - 1; 1134 int max = mc->max;
1135 unsigned int invert = mc->invert;
1136 unsigned int mask = (1 << fls(max)) - 1;
1142 1137
1143 /* return the saved value if we are powered down */ 1138 /* return the saved value if we are powered down */
1144 if (widget->id == snd_soc_dapm_pga && !widget->power) { 1139 if (widget->id == snd_soc_dapm_pga && !widget->power) {
@@ -1176,12 +1171,14 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1176 struct snd_ctl_elem_value *ucontrol) 1171 struct snd_ctl_elem_value *ucontrol)
1177{ 1172{
1178 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1173 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1179 int reg = kcontrol->private_value & 0xff; 1174 struct soc_mixer_control *mc =
1180 int shift = (kcontrol->private_value >> 8) & 0x0f; 1175 (struct soc_mixer_control *)kcontrol->private_value;
1181 int rshift = (kcontrol->private_value >> 12) & 0x0f; 1176 unsigned int reg = mc->reg;
1182 int max = (kcontrol->private_value >> 16) & 0xff; 1177 unsigned int shift = mc->shift;
1183 int mask = (1 << fls(max)) - 1; 1178 unsigned int rshift = mc->rshift;
1184 int invert = (kcontrol->private_value >> 24) & 0x01; 1179 int max = mc->max;
1180 unsigned int mask = (1 << fls(max)) - 1;
1181 unsigned int invert = mc->invert;
1185 unsigned short val, val2, val_mask; 1182 unsigned short val, val2, val_mask;
1186 int ret; 1183 int ret;
1187 1184
@@ -1248,7 +1245,7 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
1248 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1245 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1249 unsigned short val, bitmask; 1246 unsigned short val, bitmask;
1250 1247
1251 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 1248 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1252 ; 1249 ;
1253 val = snd_soc_read(widget->codec, e->reg); 1250 val = snd_soc_read(widget->codec, e->reg);
1254 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1); 1251 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
@@ -1278,15 +1275,15 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1278 unsigned short mask, bitmask; 1275 unsigned short mask, bitmask;
1279 int ret = 0; 1276 int ret = 0;
1280 1277
1281 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) 1278 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1282 ; 1279 ;
1283 if (ucontrol->value.enumerated.item[0] > e->mask - 1) 1280 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1284 return -EINVAL; 1281 return -EINVAL;
1285 mux = ucontrol->value.enumerated.item[0]; 1282 mux = ucontrol->value.enumerated.item[0];
1286 val = mux << e->shift_l; 1283 val = mux << e->shift_l;
1287 mask = (bitmask - 1) << e->shift_l; 1284 mask = (bitmask - 1) << e->shift_l;
1288 if (e->shift_l != e->shift_r) { 1285 if (e->shift_l != e->shift_r) {
1289 if (ucontrol->value.enumerated.item[1] > e->mask - 1) 1286 if (ucontrol->value.enumerated.item[1] > e->max - 1)
1290 return -EINVAL; 1287 return -EINVAL;
1291 val |= ucontrol->value.enumerated.item[1] << e->shift_r; 1288 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1292 mask |= (bitmask - 1) << e->shift_r; 1289 mask |= (bitmask - 1) << e->shift_r;
@@ -1294,7 +1291,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1294 1291
1295 mutex_lock(&widget->codec->mutex); 1292 mutex_lock(&widget->codec->mutex);
1296 widget->value = val; 1293 widget->value = val;
1297 dapm_mux_update_power(widget, kcontrol, mask, mux, e); 1294 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e);
1298 if (widget->event) { 1295 if (widget->event) {
1299 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1296 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1300 ret = widget->event(widget, 1297 ret = widget->event(widget,