aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-05-20 06:00:43 -0400
committerTakashi Iwai <tiwai@suse.de>2010-05-20 06:00:43 -0400
commitd71f4cece4bd97d05592836202fc04ff2e7817e3 (patch)
tree6c877c7a938758b1323d9c97d46b9c536e618c69
parent19008bdacb9f7841166ebafe0aef361ee582ffbf (diff)
parentad8332c1302bcb4f80d593fd3eb477be9d7f5604 (diff)
Merge branch 'topic/asoc' into for-linus
Conflicts: sound/soc/codecs/ad1938.c
-rw-r--r--arch/arm/mach-davinci/board-dm365-evm.c4
-rw-r--r--arch/arm/mach-omap2/mcbsp.c12
-rw-r--r--arch/arm/mach-s3c2412/dma.c3
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h6
-rw-r--r--arch/arm/plat-omap/mcbsp.c89
-rw-r--r--drivers/gpio/wm8994-gpio.c12
-rw-r--r--drivers/mfd/Kconfig8
-rw-r--r--drivers/mfd/Makefile3
-rw-r--r--drivers/mfd/davinci_voicecodec.c190
-rw-r--r--drivers/mfd/twl-core.c4
-rw-r--r--drivers/mfd/wm831x-irq.c30
-rw-r--r--drivers/mfd/wm8994-core.c43
-rw-r--r--drivers/mfd/wm8994-irq.c310
-rw-r--r--include/linux/i2c/twl.h6
-rw-r--r--include/linux/mfd/davinci_voicecodec.h126
-rw-r--r--include/linux/mfd/wm8350/audio.h2
-rw-r--r--include/linux/mfd/wm8994/core.h53
-rw-r--r--include/linux/mfd/wm8994/pdata.h1
-rw-r--r--include/sound/soc-dai.h7
-rw-r--r--include/sound/soc-dapm.h8
-rw-r--r--include/sound/soc.h61
-rw-r--r--include/sound/tlv320aic3x.h17
-rw-r--r--include/sound/tlv320dac33-plat.h1
-rw-r--r--include/sound/uda134x.h1
-rw-r--r--include/sound/wm8903.h249
-rw-r--r--include/sound/wm8904.h110
-rw-r--r--include/sound/wm8960.h24
-rw-r--r--include/sound/wm9090.h28
-rw-r--r--sound/soc/atmel/atmel-pcm.c14
-rw-r--r--sound/soc/blackfin/Kconfig9
-rw-r--r--sound/soc/blackfin/Makefile4
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c (renamed from sound/soc/blackfin/bf5xx-ad1938.c)66
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h28
-rw-r--r--sound/soc/codecs/Kconfig16
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/ad1836.c2
-rw-r--r--sound/soc/codecs/ad1938.c522
-rw-r--r--sound/soc/codecs/ad1938.h100
-rw-r--r--sound/soc/codecs/ad193x.c547
-rw-r--r--sound/soc/codecs/ad193x.h81
-rw-r--r--sound/soc/codecs/ak4104.c2
-rw-r--r--sound/soc/codecs/ak4535.c11
-rw-r--r--sound/soc/codecs/ak4642.c177
-rw-r--r--sound/soc/codecs/ak4671.c2
-rw-r--r--sound/soc/codecs/cq93vc.c299
-rw-r--r--sound/soc/codecs/cq93vc.h29
-rw-r--r--sound/soc/codecs/cs4270.c20
-rw-r--r--sound/soc/codecs/cx20442.c2
-rw-r--r--sound/soc/codecs/da7210.c157
-rw-r--r--sound/soc/codecs/ssm2602.c17
-rw-r--r--sound/soc/codecs/stac9766.c5
-rw-r--r--sound/soc/codecs/tlv320aic23.c1
-rw-r--r--sound/soc/codecs/tlv320aic26.c14
-rw-r--r--sound/soc/codecs/tlv320aic3x.c118
-rw-r--r--sound/soc/codecs/tlv320dac33.c543
-rw-r--r--sound/soc/codecs/tpa6130a2.c103
-rw-r--r--sound/soc/codecs/twl4030.c203
-rw-r--r--sound/soc/codecs/twl6040.c1246
-rw-r--r--sound/soc/codecs/twl6040.h141
-rw-r--r--sound/soc/codecs/uda134x.c29
-rw-r--r--sound/soc/codecs/uda1380.c5
-rw-r--r--sound/soc/codecs/wm8350.c103
-rw-r--r--sound/soc/codecs/wm8350.h3
-rw-r--r--sound/soc/codecs/wm8400.c16
-rw-r--r--sound/soc/codecs/wm8510.c2
-rw-r--r--sound/soc/codecs/wm8523.c10
-rw-r--r--sound/soc/codecs/wm8580.c4
-rw-r--r--sound/soc/codecs/wm8711.c8
-rw-r--r--sound/soc/codecs/wm8728.c2
-rw-r--r--sound/soc/codecs/wm8731.c66
-rw-r--r--sound/soc/codecs/wm8750.c347
-rw-r--r--sound/soc/codecs/wm8753.c8
-rw-r--r--sound/soc/codecs/wm8776.c6
-rw-r--r--sound/soc/codecs/wm8900.c10
-rw-r--r--sound/soc/codecs/wm8903.c217
-rw-r--r--sound/soc/codecs/wm8903.h221
-rw-r--r--sound/soc/codecs/wm8904.c59
-rw-r--r--sound/soc/codecs/wm8904.h97
-rw-r--r--sound/soc/codecs/wm8940.c5
-rw-r--r--sound/soc/codecs/wm8955.c16
-rw-r--r--sound/soc/codecs/wm8960.c215
-rw-r--r--sound/soc/codecs/wm8960.h11
-rw-r--r--sound/soc/codecs/wm8961.c6
-rw-r--r--sound/soc/codecs/wm8971.c12
-rw-r--r--sound/soc/codecs/wm8974.c6
-rw-r--r--sound/soc/codecs/wm8978.c12
-rw-r--r--sound/soc/codecs/wm8988.c8
-rw-r--r--sound/soc/codecs/wm8990.c8
-rw-r--r--sound/soc/codecs/wm8993.c24
-rw-r--r--sound/soc/codecs/wm8994.c264
-rw-r--r--sound/soc/codecs/wm8994.h8
-rw-r--r--sound/soc/codecs/wm9081.c18
-rw-r--r--sound/soc/codecs/wm9090.c773
-rw-r--r--sound/soc/codecs/wm9090.h715
-rw-r--r--sound/soc/codecs/wm9712.c3
-rw-r--r--sound/soc/codecs/wm9713.c16
-rw-r--r--sound/soc/codecs/wm_hubs.c18
-rw-r--r--sound/soc/davinci/Kconfig27
-rw-r--r--sound/soc/davinci/Makefile2
-rw-r--r--sound/soc/davinci/davinci-evm.c61
-rw-r--r--sound/soc/davinci/davinci-vcif.c274
-rw-r--r--sound/soc/davinci/davinci-vcif.h28
-rw-r--r--sound/soc/imx/Kconfig8
-rw-r--r--sound/soc/imx/Makefile3
-rw-r--r--sound/soc/imx/wm1133-ev1.c308
-rw-r--r--sound/soc/omap/Kconfig19
-rw-r--r--sound/soc/omap/Makefile4
-rw-r--r--sound/soc/omap/mcpdm.c548
-rw-r--r--sound/soc/omap/omap-mcbsp.c66
-rw-r--r--sound/soc/omap/omap3pandora.c2
-rw-r--r--sound/soc/omap/rx51.c294
-rw-r--r--sound/soc/omap/sdp4430.c233
-rw-r--r--sound/soc/omap/zoom2.c3
-rw-r--r--sound/soc/pxa/Kconfig8
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/spitz.c43
-rw-r--r--sound/soc/pxa/z2.c246
-rw-r--r--sound/soc/s3c24xx/Kconfig12
-rw-r--r--sound/soc/s3c24xx/Makefile2
-rw-r--r--sound/soc/s3c24xx/jive_wm8750.c7
-rw-r--r--sound/soc/s3c24xx/neo1973_gta02_wm8753.c8
-rw-r--r--sound/soc/s3c24xx/regs-i2s-v2.h (renamed from arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h)51
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c205
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.h15
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c77
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.h6
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s-v4.c209
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c69
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h18
-rw-r--r--sound/soc/s3c24xx/smdk64xx_wm8580.c6
-rw-r--r--sound/soc/sh/Kconfig3
-rw-r--r--sound/soc/sh/fsi-ak4642.c14
-rw-r--r--sound/soc/sh/fsi.c191
-rw-r--r--sound/soc/soc-cache.c134
-rw-r--r--sound/soc/soc-core.c255
-rw-r--r--sound/soc/soc-dapm.c217
-rw-r--r--sound/soc/soc-jack.c43
137 files changed, 10250 insertions, 2719 deletions
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index df4ab2105869..e78d8110b12e 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -605,7 +605,11 @@ static __init void dm365_evm_init(void)
605 /* maybe setup mmc1/etc ... _after_ mmc0 */ 605 /* maybe setup mmc1/etc ... _after_ mmc0 */
606 evm_init_cpld(); 606 evm_init_cpld();
607 607
608#ifdef CONFIG_SND_DM365_AIC3X_CODEC
608 dm365_init_asp(&dm365_evm_snd_data); 609 dm365_init_asp(&dm365_evm_snd_data);
610#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
611 dm365_init_vc(&dm365_evm_snd_data);
612#endif
609 dm365_init_rtc(); 613 dm365_init_rtc();
610 dm365_init_ks(&dm365evm_ks_data); 614 dm365_init_ks(&dm365evm_ks_data);
611 615
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 2f3cad6f9402..c29337074ad3 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -187,32 +187,28 @@ static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
187 .phys_base = OMAP44XX_MCBSP1_BASE, 187 .phys_base = OMAP44XX_MCBSP1_BASE,
188 .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX, 188 .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX,
189 .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX, 189 .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX,
190 .rx_irq = INT_24XX_MCBSP1_IRQ_RX, 190 .tx_irq = OMAP44XX_IRQ_MCBSP1,
191 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
192 .ops = &omap2_mcbsp_ops, 191 .ops = &omap2_mcbsp_ops,
193 }, 192 },
194 { 193 {
195 .phys_base = OMAP44XX_MCBSP2_BASE, 194 .phys_base = OMAP44XX_MCBSP2_BASE,
196 .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX, 195 .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX,
197 .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX, 196 .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX,
198 .rx_irq = INT_24XX_MCBSP2_IRQ_RX, 197 .tx_irq = OMAP44XX_IRQ_MCBSP2,
199 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
200 .ops = &omap2_mcbsp_ops, 198 .ops = &omap2_mcbsp_ops,
201 }, 199 },
202 { 200 {
203 .phys_base = OMAP44XX_MCBSP3_BASE, 201 .phys_base = OMAP44XX_MCBSP3_BASE,
204 .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX, 202 .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX,
205 .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX, 203 .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX,
206 .rx_irq = INT_24XX_MCBSP3_IRQ_RX, 204 .tx_irq = OMAP44XX_IRQ_MCBSP3,
207 .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
208 .ops = &omap2_mcbsp_ops, 205 .ops = &omap2_mcbsp_ops,
209 }, 206 },
210 { 207 {
211 .phys_base = OMAP44XX_MCBSP4_BASE, 208 .phys_base = OMAP44XX_MCBSP4_BASE,
212 .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX, 209 .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX,
213 .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX, 210 .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX,
214 .rx_irq = INT_24XX_MCBSP4_IRQ_RX, 211 .tx_irq = OMAP44XX_IRQ_MCBSP4,
215 .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
216 .ops = &omap2_mcbsp_ops, 212 .ops = &omap2_mcbsp_ops,
217 }, 213 },
218}; 214};
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index e880524904eb..7abecfca0b7e 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -30,7 +30,6 @@
30#include <mach/regs-mem.h> 30#include <mach/regs-mem.h>
31#include <mach/regs-lcd.h> 31#include <mach/regs-lcd.h>
32#include <mach/regs-sdi.h> 32#include <mach/regs-sdi.h>
33#include <plat/regs-s3c2412-iis.h>
34#include <plat/regs-iis.h> 33#include <plat/regs-iis.h>
35#include <plat/regs-spi.h> 34#include <plat/regs-spi.h>
36 35
@@ -119,13 +118,11 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
119 .name = "i2s-sdi", 118 .name = "i2s-sdi",
120 .channels = MAP(S3C2412_DMAREQSEL_I2SRX), 119 .channels = MAP(S3C2412_DMAREQSEL_I2SRX),
121 .channels_rx = MAP(S3C2412_DMAREQSEL_I2SRX), 120 .channels_rx = MAP(S3C2412_DMAREQSEL_I2SRX),
122 .hw_addr.from = S3C2410_PA_IIS + S3C2412_IISRXD,
123 }, 121 },
124 [DMACH_I2S_OUT] = { 122 [DMACH_I2S_OUT] = {
125 .name = "i2s-sdo", 123 .name = "i2s-sdo",
126 .channels = MAP(S3C2412_DMAREQSEL_I2STX), 124 .channels = MAP(S3C2412_DMAREQSEL_I2STX),
127 .channels_rx = MAP(S3C2412_DMAREQSEL_I2STX), 125 .channels_rx = MAP(S3C2412_DMAREQSEL_I2STX),
128 .hw_addr.to = S3C2410_PA_IIS + S3C2412_IISTXD,
129 }, 126 },
130 [DMACH_USB_EP1] = { 127 [DMACH_USB_EP1] = {
131 .name = "usb-ep1", 128 .name = "usb-ep1",
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index 7de903d7c1ce..975744f10a58 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -149,6 +149,8 @@
149#define OMAP_MCBSP_REG_WAKEUPEN 0xA8 149#define OMAP_MCBSP_REG_WAKEUPEN 0xA8
150#define OMAP_MCBSP_REG_XCCR 0xAC 150#define OMAP_MCBSP_REG_XCCR 0xAC
151#define OMAP_MCBSP_REG_RCCR 0xB0 151#define OMAP_MCBSP_REG_RCCR 0xB0
152#define OMAP_MCBSP_REG_XBUFFSTAT 0xB4
153#define OMAP_MCBSP_REG_RBUFFSTAT 0xB8
152#define OMAP_MCBSP_REG_SSELCR 0xBC 154#define OMAP_MCBSP_REG_SSELCR 0xBC
153 155
154#define OMAP_ST_REG_REV 0x00 156#define OMAP_ST_REG_REV 0x00
@@ -471,6 +473,8 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
471void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); 473void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
472u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); 474u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
473u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); 475u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
476u16 omap_mcbsp_get_tx_delay(unsigned int id);
477u16 omap_mcbsp_get_rx_delay(unsigned int id);
474int omap_mcbsp_get_dma_op_mode(unsigned int id); 478int omap_mcbsp_get_dma_op_mode(unsigned int id);
475#else 479#else
476static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) 480static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
@@ -479,6 +483,8 @@ static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
479{ } 483{ }
480static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } 484static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
481static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; } 485static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
486static inline u16 omap_mcbsp_get_tx_delay(unsigned int id) { return 0; }
487static inline u16 omap_mcbsp_get_rx_delay(unsigned int id) { return 0; }
482static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; } 488static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
483#endif 489#endif
484int omap_mcbsp_request(unsigned int id); 490int omap_mcbsp_request(unsigned int id);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index e1d0440fd4a8..7e669c9744d8 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -489,7 +489,7 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
489{ 489{
490 struct omap_mcbsp *mcbsp; 490 struct omap_mcbsp *mcbsp;
491 491
492 if (!cpu_is_omap34xx()) 492 if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
493 return; 493 return;
494 494
495 if (!omap_mcbsp_check_valid_id(id)) { 495 if (!omap_mcbsp_check_valid_id(id)) {
@@ -511,7 +511,7 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
511{ 511{
512 struct omap_mcbsp *mcbsp; 512 struct omap_mcbsp *mcbsp;
513 513
514 if (!cpu_is_omap34xx()) 514 if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
515 return; 515 return;
516 516
517 if (!omap_mcbsp_check_valid_id(id)) { 517 if (!omap_mcbsp_check_valid_id(id)) {
@@ -560,6 +560,61 @@ u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
560} 560}
561EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold); 561EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
562 562
563#define MCBSP2_FIFO_SIZE 0x500 /* 1024 + 256 locations */
564#define MCBSP1345_FIFO_SIZE 0x80 /* 128 locations */
565/*
566 * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO
567 */
568u16 omap_mcbsp_get_tx_delay(unsigned int id)
569{
570 struct omap_mcbsp *mcbsp;
571 u16 buffstat;
572
573 if (!omap_mcbsp_check_valid_id(id)) {
574 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
575 return -ENODEV;
576 }
577 mcbsp = id_to_mcbsp_ptr(id);
578
579 /* Returns the number of free locations in the buffer */
580 buffstat = MCBSP_READ(mcbsp, XBUFFSTAT);
581
582 /* Number of slots are different in McBSP ports */
583 if (mcbsp->id == 2)
584 return MCBSP2_FIFO_SIZE - buffstat;
585 else
586 return MCBSP1345_FIFO_SIZE - buffstat;
587}
588EXPORT_SYMBOL(omap_mcbsp_get_tx_delay);
589
590/*
591 * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO
592 * to reach the threshold value (when the DMA will be triggered to read it)
593 */
594u16 omap_mcbsp_get_rx_delay(unsigned int id)
595{
596 struct omap_mcbsp *mcbsp;
597 u16 buffstat, threshold;
598
599 if (!omap_mcbsp_check_valid_id(id)) {
600 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
601 return -ENODEV;
602 }
603 mcbsp = id_to_mcbsp_ptr(id);
604
605 /* Returns the number of used locations in the buffer */
606 buffstat = MCBSP_READ(mcbsp, RBUFFSTAT);
607 /* RX threshold */
608 threshold = MCBSP_READ(mcbsp, THRSH1);
609
610 /* Return the number of location till we reach the threshold limit */
611 if (threshold <= buffstat)
612 return 0;
613 else
614 return threshold - buffstat;
615}
616EXPORT_SYMBOL(omap_mcbsp_get_rx_delay);
617
563/* 618/*
564 * omap_mcbsp_get_dma_op_mode just return the current configured 619 * omap_mcbsp_get_dma_op_mode just return the current configured
565 * operating mode for the mcbsp channel 620 * operating mode for the mcbsp channel
@@ -587,7 +642,7 @@ static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
587 * Enable wakup behavior, smart idle and all wakeups 642 * Enable wakup behavior, smart idle and all wakeups
588 * REVISIT: some wakeups may be unnecessary 643 * REVISIT: some wakeups may be unnecessary
589 */ 644 */
590 if (cpu_is_omap34xx()) { 645 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
591 u16 syscon; 646 u16 syscon;
592 647
593 syscon = MCBSP_READ(mcbsp, SYSCON); 648 syscon = MCBSP_READ(mcbsp, SYSCON);
@@ -610,7 +665,7 @@ static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
610 /* 665 /*
611 * Disable wakup behavior, smart idle and all wakeups 666 * Disable wakup behavior, smart idle and all wakeups
612 */ 667 */
613 if (cpu_is_omap34xx()) { 668 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
614 u16 syscon; 669 u16 syscon;
615 670
616 syscon = MCBSP_READ(mcbsp, SYSCON); 671 syscon = MCBSP_READ(mcbsp, SYSCON);
@@ -724,14 +779,17 @@ int omap_mcbsp_request(unsigned int id)
724 goto err_clk_disable; 779 goto err_clk_disable;
725 } 780 }
726 781
727 init_completion(&mcbsp->rx_irq_completion); 782 if (mcbsp->rx_irq) {
728 err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler, 783 init_completion(&mcbsp->rx_irq_completion);
784 err = request_irq(mcbsp->rx_irq,
785 omap_mcbsp_rx_irq_handler,
729 0, "McBSP", (void *)mcbsp); 786 0, "McBSP", (void *)mcbsp);
730 if (err != 0) { 787 if (err != 0) {
731 dev_err(mcbsp->dev, "Unable to request RX IRQ %d " 788 dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
732 "for McBSP%d\n", mcbsp->rx_irq, 789 "for McBSP%d\n", mcbsp->rx_irq,
733 mcbsp->id); 790 mcbsp->id);
734 goto err_free_irq; 791 goto err_free_irq;
792 }
735 } 793 }
736 } 794 }
737 795
@@ -781,7 +839,8 @@ void omap_mcbsp_free(unsigned int id)
781 839
782 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { 840 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
783 /* Free IRQs */ 841 /* Free IRQs */
784 free_irq(mcbsp->rx_irq, (void *)mcbsp); 842 if (mcbsp->rx_irq)
843 free_irq(mcbsp->rx_irq, (void *)mcbsp);
785 free_irq(mcbsp->tx_irq, (void *)mcbsp); 844 free_irq(mcbsp->tx_irq, (void *)mcbsp);
786 } 845 }
787 846
@@ -855,7 +914,7 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
855 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7)); 914 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
856 } 915 }
857 916
858 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 917 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
859 /* Release the transmitter and receiver */ 918 /* Release the transmitter and receiver */
860 w = MCBSP_READ_CACHE(mcbsp, XCCR); 919 w = MCBSP_READ_CACHE(mcbsp, XCCR);
861 w &= ~(tx ? XDISABLE : 0); 920 w &= ~(tx ? XDISABLE : 0);
@@ -885,7 +944,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
885 944
886 /* Reset transmitter */ 945 /* Reset transmitter */
887 tx &= 1; 946 tx &= 1;
888 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 947 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
889 w = MCBSP_READ_CACHE(mcbsp, XCCR); 948 w = MCBSP_READ_CACHE(mcbsp, XCCR);
890 w |= (tx ? XDISABLE : 0); 949 w |= (tx ? XDISABLE : 0);
891 MCBSP_WRITE(mcbsp, XCCR, w); 950 MCBSP_WRITE(mcbsp, XCCR, w);
@@ -895,7 +954,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
895 954
896 /* Reset receiver */ 955 /* Reset receiver */
897 rx &= 1; 956 rx &= 1;
898 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 957 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
899 w = MCBSP_READ_CACHE(mcbsp, RCCR); 958 w = MCBSP_READ_CACHE(mcbsp, RCCR);
900 w |= (rx ? RDISABLE : 0); 959 w |= (rx ? RDISABLE : 0);
901 MCBSP_WRITE(mcbsp, RCCR, w); 960 MCBSP_WRITE(mcbsp, RCCR, w);
diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/wm8994-gpio.c
index 7607cc61e1dd..2ac9a16d3daa 100644
--- a/drivers/gpio/wm8994-gpio.c
+++ b/drivers/gpio/wm8994-gpio.c
@@ -81,6 +81,18 @@ static void wm8994_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
81 wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, WM8994_GPN_LVL, value); 81 wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, WM8994_GPN_LVL, value);
82} 82}
83 83
84static int wm8994_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
85{
86 struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
87 struct wm8994 *wm8994 = wm8994_gpio->wm8994;
88
89 if (!wm8994->irq_base)
90 return -EINVAL;
91
92 return wm8994->irq_base + offset;
93}
94
95
84#ifdef CONFIG_DEBUG_FS 96#ifdef CONFIG_DEBUG_FS
85static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 97static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
86{ 98{
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 2a5a0b78f84e..de3e74cde51c 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -53,6 +53,10 @@ config MFD_SH_MOBILE_SDHI
53 This driver supports the SDHI hardware block found in many 53 This driver supports the SDHI hardware block found in many
54 SuperH Mobile SoCs. 54 SuperH Mobile SoCs.
55 55
56config MFD_DAVINCI_VOICECODEC
57 tristate
58 select MFD_CORE
59
56config MFD_DM355EVM_MSP 60config MFD_DM355EVM_MSP
57 bool "DaVinci DM355 EVM microcontroller" 61 bool "DaVinci DM355 EVM microcontroller"
58 depends on I2C && MACH_DAVINCI_DM355_EVM 62 depends on I2C && MACH_DAVINCI_DM355_EVM
@@ -297,9 +301,9 @@ config MFD_WM8350_I2C
297 selected to enable support for the functionality of the chip. 301 selected to enable support for the functionality of the chip.
298 302
299config MFD_WM8994 303config MFD_WM8994
300 tristate "Support Wolfson Microelectronics WM8994" 304 bool "Support Wolfson Microelectronics WM8994"
301 select MFD_CORE 305 select MFD_CORE
302 depends on I2C 306 depends on I2C=y && GENERIC_HARDIRQS
303 help 307 help
304 The WM8994 is a highly integrated hi-fi CODEC designed for 308 The WM8994 is a highly integrated hi-fi CODEC designed for
305 smartphone applicatiosn. As well as audio functionality it 309 smartphone applicatiosn. As well as audio functionality it
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 22715add99a7..87935f967aa0 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
12obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o 12obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
13obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o 13obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
14 14
15obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o
15obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o 16obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
16 17
17obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o 18obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o
@@ -25,7 +26,7 @@ wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o
25wm8350-objs += wm8350-irq.o 26wm8350-objs += wm8350-irq.o
26obj-$(CONFIG_MFD_WM8350) += wm8350.o 27obj-$(CONFIG_MFD_WM8350) += wm8350.o
27obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o 28obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
28obj-$(CONFIG_MFD_WM8994) += wm8994-core.o 29obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o
29 30
30obj-$(CONFIG_TPS65010) += tps65010.o 31obj-$(CONFIG_TPS65010) += tps65010.o
31obj-$(CONFIG_MENELAUS) += menelaus.o 32obj-$(CONFIG_MENELAUS) += menelaus.o
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c
new file mode 100644
index 000000000000..3e75f02e4778
--- /dev/null
+++ b/drivers/mfd/davinci_voicecodec.c
@@ -0,0 +1,190 @@
1/*
2 * DaVinci Voice Codec Core Interface for TI platforms
3 *
4 * Copyright (C) 2010 Texas Instruments, Inc
5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/device.h>
26#include <linux/slab.h>
27#include <linux/delay.h>
28#include <linux/io.h>
29#include <linux/clk.h>
30
31#include <sound/pcm.h>
32
33#include <linux/mfd/davinci_voicecodec.h>
34
35u32 davinci_vc_read(struct davinci_vc *davinci_vc, int reg)
36{
37 return __raw_readl(davinci_vc->base + reg);
38}
39
40void davinci_vc_write(struct davinci_vc *davinci_vc,
41 int reg, u32 val)
42{
43 __raw_writel(val, davinci_vc->base + reg);
44}
45
46static int __init davinci_vc_probe(struct platform_device *pdev)
47{
48 struct davinci_vc *davinci_vc;
49 struct resource *res, *mem;
50 struct mfd_cell *cell = NULL;
51 int ret;
52
53 davinci_vc = kzalloc(sizeof(struct davinci_vc), GFP_KERNEL);
54 if (!davinci_vc) {
55 dev_dbg(&pdev->dev,
56 "could not allocate memory for private data\n");
57 return -ENOMEM;
58 }
59
60 davinci_vc->clk = clk_get(&pdev->dev, NULL);
61 if (IS_ERR(davinci_vc->clk)) {
62 dev_dbg(&pdev->dev,
63 "could not get the clock for voice codec\n");
64 ret = -ENODEV;
65 goto fail1;
66 }
67 clk_enable(davinci_vc->clk);
68
69 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
70 if (!res) {
71 dev_err(&pdev->dev, "no mem resource\n");
72 ret = -ENODEV;
73 goto fail2;
74 }
75
76 davinci_vc->pbase = res->start;
77 davinci_vc->base_size = resource_size(res);
78
79 mem = request_mem_region(davinci_vc->pbase, davinci_vc->base_size,
80 pdev->name);
81 if (!mem) {
82 dev_err(&pdev->dev, "VCIF region already claimed\n");
83 ret = -EBUSY;
84 goto fail2;
85 }
86
87 davinci_vc->base = ioremap(davinci_vc->pbase, davinci_vc->base_size);
88 if (!davinci_vc->base) {
89 dev_err(&pdev->dev, "can't ioremap mem resource.\n");
90 ret = -ENOMEM;
91 goto fail3;
92 }
93
94 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
95 if (!res) {
96 dev_err(&pdev->dev, "no DMA resource\n");
97 return -ENXIO;
98 }
99
100 davinci_vc->davinci_vcif.dma_tx_channel = res->start;
101 davinci_vc->davinci_vcif.dma_tx_addr =
102 (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO);
103
104 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
105 if (!res) {
106 dev_err(&pdev->dev, "no DMA resource\n");
107 return -ENXIO;
108 }
109
110 davinci_vc->davinci_vcif.dma_rx_channel = res->start;
111 davinci_vc->davinci_vcif.dma_rx_addr =
112 (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO);
113
114 davinci_vc->dev = &pdev->dev;
115 davinci_vc->pdev = pdev;
116
117 /* Voice codec interface client */
118 cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL];
119 cell->name = "davinci_vcif";
120 cell->driver_data = davinci_vc;
121
122 /* Voice codec CQ93VC client */
123 cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL];
124 cell->name = "cq93vc";
125 cell->driver_data = davinci_vc;
126
127 ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells,
128 DAVINCI_VC_CELLS, NULL, 0);
129 if (ret != 0) {
130 dev_err(&pdev->dev, "fail to register client devices\n");
131 goto fail4;
132 }
133
134 return 0;
135
136fail4:
137 iounmap(davinci_vc->base);
138fail3:
139 release_mem_region(davinci_vc->pbase, davinci_vc->base_size);
140fail2:
141 clk_disable(davinci_vc->clk);
142 clk_put(davinci_vc->clk);
143 davinci_vc->clk = NULL;
144fail1:
145 kfree(davinci_vc);
146
147 return ret;
148}
149
150static int __devexit davinci_vc_remove(struct platform_device *pdev)
151{
152 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
153
154 mfd_remove_devices(&pdev->dev);
155
156 iounmap(davinci_vc->base);
157 release_mem_region(davinci_vc->pbase, davinci_vc->base_size);
158
159 clk_disable(davinci_vc->clk);
160 clk_put(davinci_vc->clk);
161 davinci_vc->clk = NULL;
162
163 kfree(davinci_vc);
164
165 return 0;
166}
167
168static struct platform_driver davinci_vc_driver = {
169 .driver = {
170 .name = "davinci_voicecodec",
171 .owner = THIS_MODULE,
172 },
173 .remove = __devexit_p(davinci_vc_remove),
174};
175
176static int __init davinci_vc_init(void)
177{
178 return platform_driver_probe(&davinci_vc_driver, davinci_vc_probe);
179}
180module_init(davinci_vc_init);
181
182static void __exit davinci_vc_exit(void)
183{
184 platform_driver_unregister(&davinci_vc_driver);
185}
186module_exit(davinci_vc_exit);
187
188MODULE_AUTHOR("Miguel Aguilar");
189MODULE_DESCRIPTION("Texas Instruments DaVinci Voice Codec Core Interface");
190MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 562cd4935e17..720e099e506d 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -109,7 +109,7 @@
109#endif 109#endif
110 110
111#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) ||\ 111#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) ||\
112 defined(CONFIG_SND_SOC_TWL6030) || defined(CONFIG_SND_SOC_TWL6030_MODULE) 112 defined(CONFIG_SND_SOC_TWL6040) || defined(CONFIG_SND_SOC_TWL6040_MODULE)
113#define twl_has_codec() true 113#define twl_has_codec() true
114#else 114#else
115#define twl_has_codec() false 115#define twl_has_codec() false
@@ -708,7 +708,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
708 /* Phoenix*/ 708 /* Phoenix*/
709 if (twl_has_codec() && pdata->codec && twl_class_is_6030()) { 709 if (twl_has_codec() && pdata->codec && twl_class_is_6030()) {
710 sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; 710 sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
711 child = add_child(sub_chip_id, "twl6030_codec", 711 child = add_child(sub_chip_id, "twl6040_codec",
712 pdata->codec, sizeof(*pdata->codec), 712 pdata->codec, sizeof(*pdata->codec),
713 false, 0, 0); 713 false, 0, 0);
714 if (IS_ERR(child)) 714 if (IS_ERR(child))
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index 301327697117..4c1122ceb443 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -21,6 +21,7 @@
21 21
22#include <linux/mfd/wm831x/core.h> 22#include <linux/mfd/wm831x/core.h>
23#include <linux/mfd/wm831x/pdata.h> 23#include <linux/mfd/wm831x/pdata.h>
24#include <linux/mfd/wm831x/gpio.h>
24#include <linux/mfd/wm831x/irq.h> 25#include <linux/mfd/wm831x/irq.h>
25 26
26#include <linux/delay.h> 27#include <linux/delay.h>
@@ -388,12 +389,41 @@ static void wm831x_irq_mask(unsigned int irq)
388 wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; 389 wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
389} 390}
390 391
392static int wm831x_irq_set_type(unsigned int irq, unsigned int type)
393{
394 struct wm831x *wm831x = get_irq_chip_data(irq);
395 int val;
396
397 irq = irq - wm831x->irq_base;
398
399 if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11)
400 return -EINVAL;
401
402 switch (type) {
403 case IRQ_TYPE_EDGE_BOTH:
404 val = WM831X_GPN_INT_MODE;
405 break;
406 case IRQ_TYPE_EDGE_RISING:
407 val = WM831X_GPN_POL;
408 break;
409 case IRQ_TYPE_EDGE_FALLING:
410 val = 0;
411 break;
412 default:
413 return -EINVAL;
414 }
415
416 return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + irq,
417 WM831X_GPN_INT_MODE | WM831X_GPN_POL, val);
418}
419
391static struct irq_chip wm831x_irq_chip = { 420static struct irq_chip wm831x_irq_chip = {
392 .name = "wm831x", 421 .name = "wm831x",
393 .bus_lock = wm831x_irq_lock, 422 .bus_lock = wm831x_irq_lock,
394 .bus_sync_unlock = wm831x_irq_sync_unlock, 423 .bus_sync_unlock = wm831x_irq_sync_unlock,
395 .mask = wm831x_irq_mask, 424 .mask = wm831x_irq_mask,
396 .unmask = wm831x_irq_unmask, 425 .unmask = wm831x_irq_unmask,
426 .set_type = wm831x_irq_set_type,
397}; 427};
398 428
399/* The processing of the primary interrupt occurs in a thread so that 429/* The processing of the primary interrupt occurs in a thread so that
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index cc524df10aa1..ec71c9368906 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -173,9 +173,34 @@ static struct mfd_cell wm8994_regulator_devs[] = {
173 { .name = "wm8994-ldo", .id = 2 }, 173 { .name = "wm8994-ldo", .id = 2 },
174}; 174};
175 175
176static struct resource wm8994_codec_resources[] = {
177 {
178 .start = WM8994_IRQ_TEMP_SHUT,
179 .end = WM8994_IRQ_TEMP_WARN,
180 .flags = IORESOURCE_IRQ,
181 },
182};
183
184static struct resource wm8994_gpio_resources[] = {
185 {
186 .start = WM8994_IRQ_GPIO(1),
187 .end = WM8994_IRQ_GPIO(11),
188 .flags = IORESOURCE_IRQ,
189 },
190};
191
176static struct mfd_cell wm8994_devs[] = { 192static struct mfd_cell wm8994_devs[] = {
177 { .name = "wm8994-codec" }, 193 {
178 { .name = "wm8994-gpio" }, 194 .name = "wm8994-codec",
195 .num_resources = ARRAY_SIZE(wm8994_codec_resources),
196 .resources = wm8994_codec_resources,
197 },
198
199 {
200 .name = "wm8994-gpio",
201 .num_resources = ARRAY_SIZE(wm8994_gpio_resources),
202 .resources = wm8994_gpio_resources,
203 },
179}; 204};
180 205
181/* 206/*
@@ -236,6 +261,11 @@ static int wm8994_device_resume(struct device *dev)
236 return ret; 261 return ret;
237 } 262 }
238 263
264 ret = wm8994_write(wm8994, WM8994_INTERRUPT_STATUS_1_MASK,
265 WM8994_NUM_IRQ_REGS * 2, &wm8994->irq_masks_cur);
266 if (ret < 0)
267 dev_err(dev, "Failed to restore interrupt masks: %d\n", ret);
268
239 ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2, 269 ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
240 &wm8994->ldo_regs); 270 &wm8994->ldo_regs);
241 if (ret < 0) 271 if (ret < 0)
@@ -348,6 +378,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
348 378
349 379
350 if (pdata) { 380 if (pdata) {
381 wm8994->irq_base = pdata->irq_base;
351 wm8994->gpio_base = pdata->gpio_base; 382 wm8994->gpio_base = pdata->gpio_base;
352 383
353 /* GPIO configuration is only applied if it's non-zero */ 384 /* GPIO configuration is only applied if it's non-zero */
@@ -375,16 +406,20 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
375 WM8994_LDO1_DISCH, 0); 406 WM8994_LDO1_DISCH, 0);
376 } 407 }
377 408
409 wm8994_irq_init(wm8994);
410
378 ret = mfd_add_devices(wm8994->dev, -1, 411 ret = mfd_add_devices(wm8994->dev, -1,
379 wm8994_devs, ARRAY_SIZE(wm8994_devs), 412 wm8994_devs, ARRAY_SIZE(wm8994_devs),
380 NULL, 0); 413 NULL, 0);
381 if (ret != 0) { 414 if (ret != 0) {
382 dev_err(wm8994->dev, "Failed to add children: %d\n", ret); 415 dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
383 goto err_enable; 416 goto err_irq;
384 } 417 }
385 418
386 return 0; 419 return 0;
387 420
421err_irq:
422 wm8994_irq_exit(wm8994);
388err_enable: 423err_enable:
389 regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), 424 regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
390 wm8994->supplies); 425 wm8994->supplies);
@@ -401,6 +436,7 @@ err:
401static void wm8994_device_exit(struct wm8994 *wm8994) 436static void wm8994_device_exit(struct wm8994 *wm8994)
402{ 437{
403 mfd_remove_devices(wm8994->dev); 438 mfd_remove_devices(wm8994->dev);
439 wm8994_irq_exit(wm8994);
404 regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), 440 regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
405 wm8994->supplies); 441 wm8994->supplies);
406 regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); 442 regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
@@ -469,6 +505,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
469 wm8994->control_data = i2c; 505 wm8994->control_data = i2c;
470 wm8994->read_dev = wm8994_i2c_read_device; 506 wm8994->read_dev = wm8994_i2c_read_device;
471 wm8994->write_dev = wm8994_i2c_write_device; 507 wm8994->write_dev = wm8994_i2c_write_device;
508 wm8994->irq = i2c->irq;
472 509
473 return wm8994_device_init(wm8994, id->driver_data, i2c->irq); 510 return wm8994_device_init(wm8994, id->driver_data, i2c->irq);
474} 511}
diff --git a/drivers/mfd/wm8994-irq.c b/drivers/mfd/wm8994-irq.c
new file mode 100644
index 000000000000..8400eb1ee5db
--- /dev/null
+++ b/drivers/mfd/wm8994-irq.c
@@ -0,0 +1,310 @@
1/*
2 * wm8994-irq.c -- Interrupt controller support for Wolfson WM8994
3 *
4 * Copyright 2010 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 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#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/i2c.h>
18#include <linux/irq.h>
19#include <linux/mfd/core.h>
20#include <linux/interrupt.h>
21
22#include <linux/mfd/wm8994/core.h>
23#include <linux/mfd/wm8994/registers.h>
24
25#include <linux/delay.h>
26
27struct wm8994_irq_data {
28 int reg;
29 int mask;
30};
31
32static struct wm8994_irq_data wm8994_irqs[] = {
33 [WM8994_IRQ_TEMP_SHUT] = {
34 .reg = 2,
35 .mask = WM8994_TEMP_SHUT_EINT,
36 },
37 [WM8994_IRQ_MIC1_DET] = {
38 .reg = 2,
39 .mask = WM8994_MIC1_DET_EINT,
40 },
41 [WM8994_IRQ_MIC1_SHRT] = {
42 .reg = 2,
43 .mask = WM8994_MIC1_SHRT_EINT,
44 },
45 [WM8994_IRQ_MIC2_DET] = {
46 .reg = 2,
47 .mask = WM8994_MIC2_DET_EINT,
48 },
49 [WM8994_IRQ_MIC2_SHRT] = {
50 .reg = 2,
51 .mask = WM8994_MIC2_SHRT_EINT,
52 },
53 [WM8994_IRQ_FLL1_LOCK] = {
54 .reg = 2,
55 .mask = WM8994_FLL1_LOCK_EINT,
56 },
57 [WM8994_IRQ_FLL2_LOCK] = {
58 .reg = 2,
59 .mask = WM8994_FLL2_LOCK_EINT,
60 },
61 [WM8994_IRQ_SRC1_LOCK] = {
62 .reg = 2,
63 .mask = WM8994_SRC1_LOCK_EINT,
64 },
65 [WM8994_IRQ_SRC2_LOCK] = {
66 .reg = 2,
67 .mask = WM8994_SRC2_LOCK_EINT,
68 },
69 [WM8994_IRQ_AIF1DRC1_SIG_DET] = {
70 .reg = 2,
71 .mask = WM8994_AIF1DRC1_SIG_DET,
72 },
73 [WM8994_IRQ_AIF1DRC2_SIG_DET] = {
74 .reg = 2,
75 .mask = WM8994_AIF1DRC2_SIG_DET_EINT,
76 },
77 [WM8994_IRQ_AIF2DRC_SIG_DET] = {
78 .reg = 2,
79 .mask = WM8994_AIF2DRC_SIG_DET_EINT,
80 },
81 [WM8994_IRQ_FIFOS_ERR] = {
82 .reg = 2,
83 .mask = WM8994_FIFOS_ERR_EINT,
84 },
85 [WM8994_IRQ_WSEQ_DONE] = {
86 .reg = 2,
87 .mask = WM8994_WSEQ_DONE_EINT,
88 },
89 [WM8994_IRQ_DCS_DONE] = {
90 .reg = 2,
91 .mask = WM8994_DCS_DONE_EINT,
92 },
93 [WM8994_IRQ_TEMP_WARN] = {
94 .reg = 2,
95 .mask = WM8994_TEMP_WARN_EINT,
96 },
97 [WM8994_IRQ_GPIO(1)] = {
98 .reg = 1,
99 .mask = WM8994_GP1_EINT,
100 },
101 [WM8994_IRQ_GPIO(2)] = {
102 .reg = 1,
103 .mask = WM8994_GP2_EINT,
104 },
105 [WM8994_IRQ_GPIO(3)] = {
106 .reg = 1,
107 .mask = WM8994_GP3_EINT,
108 },
109 [WM8994_IRQ_GPIO(4)] = {
110 .reg = 1,
111 .mask = WM8994_GP4_EINT,
112 },
113 [WM8994_IRQ_GPIO(5)] = {
114 .reg = 1,
115 .mask = WM8994_GP5_EINT,
116 },
117 [WM8994_IRQ_GPIO(6)] = {
118 .reg = 1,
119 .mask = WM8994_GP6_EINT,
120 },
121 [WM8994_IRQ_GPIO(7)] = {
122 .reg = 1,
123 .mask = WM8994_GP7_EINT,
124 },
125 [WM8994_IRQ_GPIO(8)] = {
126 .reg = 1,
127 .mask = WM8994_GP8_EINT,
128 },
129 [WM8994_IRQ_GPIO(9)] = {
130 .reg = 1,
131 .mask = WM8994_GP8_EINT,
132 },
133 [WM8994_IRQ_GPIO(10)] = {
134 .reg = 1,
135 .mask = WM8994_GP10_EINT,
136 },
137 [WM8994_IRQ_GPIO(11)] = {
138 .reg = 1,
139 .mask = WM8994_GP11_EINT,
140 },
141};
142
143static inline int irq_data_to_status_reg(struct wm8994_irq_data *irq_data)
144{
145 return WM8994_INTERRUPT_STATUS_1 - 1 + irq_data->reg;
146}
147
148static inline int irq_data_to_mask_reg(struct wm8994_irq_data *irq_data)
149{
150 return WM8994_INTERRUPT_STATUS_1_MASK - 1 + irq_data->reg;
151}
152
153static inline struct wm8994_irq_data *irq_to_wm8994_irq(struct wm8994 *wm8994,
154 int irq)
155{
156 return &wm8994_irqs[irq - wm8994->irq_base];
157}
158
159static void wm8994_irq_lock(unsigned int irq)
160{
161 struct wm8994 *wm8994 = get_irq_chip_data(irq);
162
163 mutex_lock(&wm8994->irq_lock);
164}
165
166static void wm8994_irq_sync_unlock(unsigned int irq)
167{
168 struct wm8994 *wm8994 = get_irq_chip_data(irq);
169 int i;
170
171 for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) {
172 /* If there's been a change in the mask write it back
173 * to the hardware. */
174 if (wm8994->irq_masks_cur[i] != wm8994->irq_masks_cache[i]) {
175 wm8994->irq_masks_cache[i] = wm8994->irq_masks_cur[i];
176 wm8994_reg_write(wm8994,
177 WM8994_INTERRUPT_STATUS_1_MASK + i,
178 wm8994->irq_masks_cur[i]);
179 }
180 }
181
182 mutex_unlock(&wm8994->irq_lock);
183}
184
185static void wm8994_irq_unmask(unsigned int irq)
186{
187 struct wm8994 *wm8994 = get_irq_chip_data(irq);
188 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, irq);
189
190 wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
191}
192
193static void wm8994_irq_mask(unsigned int irq)
194{
195 struct wm8994 *wm8994 = get_irq_chip_data(irq);
196 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, irq);
197
198 wm8994->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
199}
200
201static struct irq_chip wm8994_irq_chip = {
202 .name = "wm8994",
203 .bus_lock = wm8994_irq_lock,
204 .bus_sync_unlock = wm8994_irq_sync_unlock,
205 .mask = wm8994_irq_mask,
206 .unmask = wm8994_irq_unmask,
207};
208
209/* The processing of the primary interrupt occurs in a thread so that
210 * we can interact with the device over I2C or SPI. */
211static irqreturn_t wm8994_irq_thread(int irq, void *data)
212{
213 struct wm8994 *wm8994 = data;
214 unsigned int i;
215 u16 status[WM8994_NUM_IRQ_REGS];
216 int ret;
217
218 ret = wm8994_bulk_read(wm8994, WM8994_INTERRUPT_STATUS_1,
219 WM8994_NUM_IRQ_REGS, status);
220 if (ret < 0) {
221 dev_err(wm8994->dev, "Failed to read interrupt status: %d\n",
222 ret);
223 return IRQ_NONE;
224 }
225
226 /* Apply masking */
227 for (i = 0; i < WM8994_NUM_IRQ_REGS; i++)
228 status[i] &= ~wm8994->irq_masks_cur[i];
229
230 /* Report */
231 for (i = 0; i < ARRAY_SIZE(wm8994_irqs); i++) {
232 if (status[wm8994_irqs[i].reg - 1] & wm8994_irqs[i].mask)
233 handle_nested_irq(wm8994->irq_base + i);
234 }
235
236 /* Ack any unmasked IRQs */
237 for (i = 0; i < ARRAY_SIZE(status); i++) {
238 if (status[i])
239 wm8994_reg_write(wm8994, WM8994_INTERRUPT_STATUS_1 + i,
240 status[i]);
241 }
242
243 return IRQ_HANDLED;
244}
245
246int wm8994_irq_init(struct wm8994 *wm8994)
247{
248 int i, cur_irq, ret;
249
250 mutex_init(&wm8994->irq_lock);
251
252 /* Mask the individual interrupt sources */
253 for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) {
254 wm8994->irq_masks_cur[i] = 0xffff;
255 wm8994->irq_masks_cache[i] = 0xffff;
256 wm8994_reg_write(wm8994, WM8994_INTERRUPT_STATUS_1_MASK + i,
257 0xffff);
258 }
259
260 if (!wm8994->irq) {
261 dev_warn(wm8994->dev,
262 "No interrupt specified, no interrupts\n");
263 wm8994->irq_base = 0;
264 return 0;
265 }
266
267 if (!wm8994->irq_base) {
268 dev_err(wm8994->dev,
269 "No interrupt base specified, no interrupts\n");
270 return 0;
271 }
272
273 /* Register them with genirq */
274 for (cur_irq = wm8994->irq_base;
275 cur_irq < ARRAY_SIZE(wm8994_irqs) + wm8994->irq_base;
276 cur_irq++) {
277 set_irq_chip_data(cur_irq, wm8994);
278 set_irq_chip_and_handler(cur_irq, &wm8994_irq_chip,
279 handle_edge_irq);
280 set_irq_nested_thread(cur_irq, 1);
281
282 /* ARM needs us to explicitly flag the IRQ as valid
283 * and will set them noprobe when we do so. */
284#ifdef CONFIG_ARM
285 set_irq_flags(cur_irq, IRQF_VALID);
286#else
287 set_irq_noprobe(cur_irq);
288#endif
289 }
290
291 ret = request_threaded_irq(wm8994->irq, NULL, wm8994_irq_thread,
292 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
293 "wm8994", wm8994);
294 if (ret != 0) {
295 dev_err(wm8994->dev, "Failed to request IRQ %d: %d\n",
296 wm8994->irq, ret);
297 return ret;
298 }
299
300 /* Enable top level interrupt if it was masked */
301 wm8994_reg_write(wm8994, WM8994_INTERRUPT_CONTROL, 0);
302
303 return 0;
304}
305
306void wm8994_irq_exit(struct wm8994 *wm8994)
307{
308 if (wm8994->irq)
309 free_irq(wm8994->irq, wm8994);
310}
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index fb6784e86d5f..ebd90ce58ca2 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -569,9 +569,9 @@ struct twl4030_codec_data {
569 struct twl4030_codec_audio_data *audio; 569 struct twl4030_codec_audio_data *audio;
570 struct twl4030_codec_vibra_data *vibra; 570 struct twl4030_codec_vibra_data *vibra;
571 571
572 /* twl6030 */ 572 /* twl6040 */
573 int audpwron_gpio; /* audio power-on gpio */ 573 int audpwron_gpio; /* audio power-on gpio */
574 int naudint_irq; /* audio interrupt */ 574 int naudint_irq; /* audio interrupt */
575}; 575};
576 576
577struct twl4030_platform_data { 577struct twl4030_platform_data {
diff --git a/include/linux/mfd/davinci_voicecodec.h b/include/linux/mfd/davinci_voicecodec.h
new file mode 100644
index 000000000000..0ab61320ffa8
--- /dev/null
+++ b/include/linux/mfd/davinci_voicecodec.h
@@ -0,0 +1,126 @@
1/*
2 * DaVinci Voice Codec Core Interface for TI platforms
3 *
4 * Copyright (C) 2010 Texas Instruments, Inc
5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __LINUX_MFD_DAVINCI_VOICECODEC_H_
24#define __LINUX_MFD_DAVINIC_VOICECODEC_H_
25
26#include <linux/kernel.h>
27#include <linux/platform_device.h>
28#include <linux/mfd/core.h>
29
30#include <mach/edma.h>
31
32/*
33 * Register values.
34 */
35#define DAVINCI_VC_PID 0x00
36#define DAVINCI_VC_CTRL 0x04
37#define DAVINCI_VC_INTEN 0x08
38#define DAVINCI_VC_INTSTATUS 0x0c
39#define DAVINCI_VC_INTCLR 0x10
40#define DAVINCI_VC_EMUL_CTRL 0x14
41#define DAVINCI_VC_RFIFO 0x20
42#define DAVINCI_VC_WFIFO 0x24
43#define DAVINCI_VC_FIFOSTAT 0x28
44#define DAVINCI_VC_TST_CTRL 0x2C
45#define DAVINCI_VC_REG05 0x94
46#define DAVINCI_VC_REG09 0xA4
47#define DAVINCI_VC_REG12 0xB0
48
49/* DAVINCI_VC_CTRL bit fields */
50#define DAVINCI_VC_CTRL_MASK 0x5500
51#define DAVINCI_VC_CTRL_RSTADC BIT(0)
52#define DAVINCI_VC_CTRL_RSTDAC BIT(1)
53#define DAVINCI_VC_CTRL_RD_BITS_8 BIT(4)
54#define DAVINCI_VC_CTRL_RD_UNSIGNED BIT(5)
55#define DAVINCI_VC_CTRL_WD_BITS_8 BIT(6)
56#define DAVINCI_VC_CTRL_WD_UNSIGNED BIT(7)
57#define DAVINCI_VC_CTRL_RFIFOEN BIT(8)
58#define DAVINCI_VC_CTRL_RFIFOCL BIT(9)
59#define DAVINCI_VC_CTRL_RFIFOMD_WORD_1 BIT(10)
60#define DAVINCI_VC_CTRL_WFIFOEN BIT(12)
61#define DAVINCI_VC_CTRL_WFIFOCL BIT(13)
62#define DAVINCI_VC_CTRL_WFIFOMD_WORD_1 BIT(14)
63
64/* DAVINCI_VC_INT bit fields */
65#define DAVINCI_VC_INT_MASK 0x3F
66#define DAVINCI_VC_INT_RDRDY_MASK BIT(0)
67#define DAVINCI_VC_INT_RERROVF_MASK BIT(1)
68#define DAVINCI_VC_INT_RERRUDR_MASK BIT(2)
69#define DAVINCI_VC_INT_WDREQ_MASK BIT(3)
70#define DAVINCI_VC_INT_WERROVF_MASKBIT BIT(4)
71#define DAVINCI_VC_INT_WERRUDR_MASK BIT(5)
72
73/* DAVINCI_VC_REG05 bit fields */
74#define DAVINCI_VC_REG05_PGA_GAIN 0x07
75
76/* DAVINCI_VC_REG09 bit fields */
77#define DAVINCI_VC_REG09_MUTE 0x40
78#define DAVINCI_VC_REG09_DIG_ATTEN 0x3F
79
80/* DAVINCI_VC_REG12 bit fields */
81#define DAVINCI_VC_REG12_POWER_ALL_ON 0xFD
82#define DAVINCI_VC_REG12_POWER_ALL_OFF 0x00
83
84#define DAVINCI_VC_CELLS 2
85
86enum davinci_vc_cells {
87 DAVINCI_VC_VCIF_CELL,
88 DAVINCI_VC_CQ93VC_CELL,
89};
90
91struct davinci_vcif {
92 struct platform_device *pdev;
93 u32 dma_tx_channel;
94 u32 dma_rx_channel;
95 dma_addr_t dma_tx_addr;
96 dma_addr_t dma_rx_addr;
97};
98
99struct cq93vc {
100 struct platform_device *pdev;
101 struct snd_soc_codec *codec;
102 u32 sysclk;
103};
104
105struct davinci_vc;
106
107struct davinci_vc {
108 /* Device data */
109 struct device *dev;
110 struct platform_device *pdev;
111 struct clk *clk;
112
113 /* Memory resources */
114 void __iomem *base;
115 resource_size_t pbase;
116 size_t base_size;
117
118 /* MFD cells */
119 struct mfd_cell cells[DAVINCI_VC_CELLS];
120
121 /* Client devices */
122 struct davinci_vcif davinci_vcif;
123 struct cq93vc cq93vc;
124};
125
126#endif
diff --git a/include/linux/mfd/wm8350/audio.h b/include/linux/mfd/wm8350/audio.h
index d899dc0223ba..a95141eafce3 100644
--- a/include/linux/mfd/wm8350/audio.h
+++ b/include/linux/mfd/wm8350/audio.h
@@ -492,6 +492,8 @@
492 */ 492 */
493#define WM8350_JACK_L_LVL 0x0800 493#define WM8350_JACK_L_LVL 0x0800
494#define WM8350_JACK_R_LVL 0x0400 494#define WM8350_JACK_R_LVL 0x0400
495#define WM8350_JACK_MICSCD_LVL 0x0200
496#define WM8350_JACK_MICSD_LVL 0x0100
495 497
496/* 498/*
497 * WM8350 Platform setup 499 * WM8350 Platform setup
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
index b06ff2846748..de79baee4925 100644
--- a/include/linux/mfd/wm8994/core.h
+++ b/include/linux/mfd/wm8994/core.h
@@ -15,14 +15,38 @@
15#ifndef __MFD_WM8994_CORE_H__ 15#ifndef __MFD_WM8994_CORE_H__
16#define __MFD_WM8994_CORE_H__ 16#define __MFD_WM8994_CORE_H__
17 17
18#include <linux/interrupt.h>
19
18struct regulator_dev; 20struct regulator_dev;
19struct regulator_bulk_data; 21struct regulator_bulk_data;
20 22
21#define WM8994_NUM_GPIO_REGS 11 23#define WM8994_NUM_GPIO_REGS 11
22#define WM8994_NUM_LDO_REGS 2 24#define WM8994_NUM_LDO_REGS 2
25#define WM8994_NUM_IRQ_REGS 2
26
27#define WM8994_IRQ_TEMP_SHUT 0
28#define WM8994_IRQ_MIC1_DET 1
29#define WM8994_IRQ_MIC1_SHRT 2
30#define WM8994_IRQ_MIC2_DET 3
31#define WM8994_IRQ_MIC2_SHRT 4
32#define WM8994_IRQ_FLL1_LOCK 5
33#define WM8994_IRQ_FLL2_LOCK 6
34#define WM8994_IRQ_SRC1_LOCK 7
35#define WM8994_IRQ_SRC2_LOCK 8
36#define WM8994_IRQ_AIF1DRC1_SIG_DET 9
37#define WM8994_IRQ_AIF1DRC2_SIG_DET 10
38#define WM8994_IRQ_AIF2DRC_SIG_DET 11
39#define WM8994_IRQ_FIFOS_ERR 12
40#define WM8994_IRQ_WSEQ_DONE 13
41#define WM8994_IRQ_DCS_DONE 14
42#define WM8994_IRQ_TEMP_WARN 15
43
44/* GPIOs in the chip are numbered from 1-11 */
45#define WM8994_IRQ_GPIO(x) (x + WM8994_IRQ_TEMP_WARN)
23 46
24struct wm8994 { 47struct wm8994 {
25 struct mutex io_lock; 48 struct mutex io_lock;
49 struct mutex irq_lock;
26 50
27 struct device *dev; 51 struct device *dev;
28 int (*read_dev)(struct wm8994 *wm8994, unsigned short reg, 52 int (*read_dev)(struct wm8994 *wm8994, unsigned short reg,
@@ -33,6 +57,11 @@ struct wm8994 {
33 void *control_data; 57 void *control_data;
34 58
35 int gpio_base; 59 int gpio_base;
60 int irq_base;
61
62 int irq;
63 u16 irq_masks_cur[WM8994_NUM_IRQ_REGS];
64 u16 irq_masks_cache[WM8994_NUM_IRQ_REGS];
36 65
37 /* Used over suspend/resume */ 66 /* Used over suspend/resume */
38 u16 ldo_regs[WM8994_NUM_LDO_REGS]; 67 u16 ldo_regs[WM8994_NUM_LDO_REGS];
@@ -51,4 +80,26 @@ int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
51int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, 80int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
52 int count, u16 *buf); 81 int count, u16 *buf);
53 82
83
84/* Helper to save on boilerplate */
85static inline int wm8994_request_irq(struct wm8994 *wm8994, int irq,
86 irq_handler_t handler, const char *name,
87 void *data)
88{
89 if (!wm8994->irq_base)
90 return -EINVAL;
91 return request_threaded_irq(wm8994->irq_base + irq, NULL, handler,
92 IRQF_TRIGGER_RISING, name,
93 data);
94}
95static inline void wm8994_free_irq(struct wm8994 *wm8994, int irq, void *data)
96{
97 if (!wm8994->irq_base)
98 return;
99 free_irq(wm8994->irq_base + irq, data);
100}
101
102int wm8994_irq_init(struct wm8994 *wm8994);
103void wm8994_irq_exit(struct wm8994 *wm8994);
104
54#endif 105#endif
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index 70d6a8687dc5..5c51f367c061 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -70,6 +70,7 @@ struct wm8994_pdata {
70 70
71 struct wm8994_ldo_pdata ldo[WM8994_NUM_LDO]; 71 struct wm8994_ldo_pdata ldo[WM8994_NUM_LDO];
72 72
73 int irq_base; /** Base IRQ number for WM8994, required for IRQs */
73 74
74 int num_drc_cfgs; 75 int num_drc_cfgs;
75 struct wm8994_drc_cfg *drc_cfgs; 76 struct wm8994_drc_cfg *drc_cfgs;
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 0a0b019d41ad..377693a14385 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -182,6 +182,12 @@ struct snd_soc_dai_ops {
182 struct snd_soc_dai *); 182 struct snd_soc_dai *);
183 int (*trigger)(struct snd_pcm_substream *, int, 183 int (*trigger)(struct snd_pcm_substream *, int,
184 struct snd_soc_dai *); 184 struct snd_soc_dai *);
185 /*
186 * For hardware based FIFO caused delay reporting.
187 * Optional.
188 */
189 snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
190 struct snd_soc_dai *);
185}; 191};
186 192
187/* 193/*
@@ -215,7 +221,6 @@ struct snd_soc_dai {
215 unsigned int symmetric_rates:1; 221 unsigned int symmetric_rates:1;
216 222
217 /* DAI runtime info */ 223 /* DAI runtime info */
218 struct snd_pcm_runtime *runtime;
219 struct snd_soc_codec *codec; 224 struct snd_soc_codec *codec;
220 unsigned int active; 225 unsigned int active;
221 unsigned char pop_wait:1; 226 unsigned char pop_wait:1;
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index c0922a034223..66ff4c124dbd 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -339,6 +339,9 @@ int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin);
339int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin); 339int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin);
340int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin); 340int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin);
341int snd_soc_dapm_sync(struct snd_soc_codec *codec); 341int snd_soc_dapm_sync(struct snd_soc_codec *codec);
342int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec,
343 const char *pin);
344int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin);
342 345
343/* dapm widget types */ 346/* dapm widget types */
344enum snd_soc_dapm_type { 347enum snd_soc_dapm_type {
@@ -425,9 +428,8 @@ struct snd_soc_dapm_widget {
425 unsigned char connected:1; /* connected codec pin */ 428 unsigned char connected:1; /* connected codec pin */
426 unsigned char new:1; /* cnew complete */ 429 unsigned char new:1; /* cnew complete */
427 unsigned char ext:1; /* has external widgets */ 430 unsigned char ext:1; /* has external widgets */
428 unsigned char muted:1; /* muted for pop reduction */ 431 unsigned char force:1; /* force state */
429 unsigned char suspend:1; /* was active before suspend */ 432 unsigned char ignore_suspend:1; /* kept enabled over suspend */
430 unsigned char pmdown:1; /* waiting for timeout */
431 433
432 int (*power_check)(struct snd_soc_dapm_widget *w); 434 int (*power_check)(struct snd_soc_dapm_widget *w);
433 435
diff --git a/include/sound/soc.h b/include/sound/soc.h
index a57fbfcd4c8f..697e7ffe39d7 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -15,6 +15,7 @@
15 15
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/notifier.h>
18#include <linux/workqueue.h> 19#include <linux/workqueue.h>
19#include <linux/interrupt.h> 20#include <linux/interrupt.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
@@ -29,10 +30,10 @@
29#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ 30#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \
30 ((unsigned long)&(struct soc_mixer_control) \ 31 ((unsigned long)&(struct soc_mixer_control) \
31 {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \ 32 {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \
32 .invert = xinvert}) 33 .platform_max = xmax, .invert = xinvert})
33#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ 34#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \
34 ((unsigned long)&(struct soc_mixer_control) \ 35 ((unsigned long)&(struct soc_mixer_control) \
35 {.reg = xreg, .max = xmax, .invert = xinvert}) 36 {.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert})
36#define SOC_SINGLE(xname, reg, shift, max, invert) \ 37#define SOC_SINGLE(xname, reg, shift, max, invert) \
37{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 38{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
38 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ 39 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
@@ -52,14 +53,14 @@
52 .put = snd_soc_put_volsw, \ 53 .put = snd_soc_put_volsw, \
53 .private_value = (unsigned long)&(struct soc_mixer_control) \ 54 .private_value = (unsigned long)&(struct soc_mixer_control) \
54 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 55 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \
55 .max = xmax, .invert = xinvert} } 56 .max = xmax, .platform_max = xmax, .invert = xinvert} }
56#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ 57#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
57{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 58{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
58 .info = snd_soc_info_volsw_2r, \ 59 .info = snd_soc_info_volsw_2r, \
59 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 60 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
60 .private_value = (unsigned long)&(struct soc_mixer_control) \ 61 .private_value = (unsigned long)&(struct soc_mixer_control) \
61 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 62 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
62 .max = xmax, .invert = xinvert} } 63 .max = xmax, .platform_max = xmax, .invert = xinvert} }
63#define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \ 64#define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \
64{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 65{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
65 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 66 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
@@ -69,7 +70,7 @@
69 .put = snd_soc_put_volsw, \ 70 .put = snd_soc_put_volsw, \
70 .private_value = (unsigned long)&(struct soc_mixer_control) \ 71 .private_value = (unsigned long)&(struct soc_mixer_control) \
71 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ 72 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
72 .max = xmax, .invert = xinvert} } 73 .max = xmax, .platform_max = xmax, .invert = xinvert} }
73#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ 74#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
74{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 75{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
75 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 76 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
@@ -79,7 +80,7 @@
79 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 80 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
80 .private_value = (unsigned long)&(struct soc_mixer_control) \ 81 .private_value = (unsigned long)&(struct soc_mixer_control) \
81 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 82 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
82 .max = xmax, .invert = xinvert} } 83 .max = xmax, .platform_max = xmax, .invert = xinvert} }
83#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \ 84#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
84{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 85{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
85 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 86 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
@@ -88,7 +89,8 @@
88 .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \ 89 .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \
89 .put = snd_soc_put_volsw_s8, \ 90 .put = snd_soc_put_volsw_s8, \
90 .private_value = (unsigned long)&(struct soc_mixer_control) \ 91 .private_value = (unsigned long)&(struct soc_mixer_control) \
91 {.reg = xreg, .min = xmin, .max = xmax} } 92 {.reg = xreg, .min = xmin, .max = xmax, \
93 .platform_max = xmax} }
92#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \ 94#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \
93{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ 95{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
94 .max = xmax, .texts = xtexts } 96 .max = xmax, .texts = xtexts }
@@ -125,7 +127,7 @@
125 .get = xhandler_get, .put = xhandler_put, \ 127 .get = xhandler_get, .put = xhandler_put, \
126 .private_value = (unsigned long)&(struct soc_mixer_control) \ 128 .private_value = (unsigned long)&(struct soc_mixer_control) \
127 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 129 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \
128 .max = xmax, .invert = xinvert} } 130 .max = xmax, .platform_max = xmax, .invert = xinvert} }
129#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ 131#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
130 xhandler_get, xhandler_put, tlv_array) \ 132 xhandler_get, xhandler_put, tlv_array) \
131{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 133{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -145,7 +147,7 @@
145 .get = xhandler_get, .put = xhandler_put, \ 147 .get = xhandler_get, .put = xhandler_put, \
146 .private_value = (unsigned long)&(struct soc_mixer_control) \ 148 .private_value = (unsigned long)&(struct soc_mixer_control) \
147 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 149 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \
148 .max = xmax, .invert = xinvert} } 150 .max = xmax, .platform_max = xmax, .invert = xinvert} }
149#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\ 151#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\
150 xhandler_get, xhandler_put, tlv_array) \ 152 xhandler_get, xhandler_put, tlv_array) \
151{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 153{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
@@ -156,7 +158,7 @@
156 .get = xhandler_get, .put = xhandler_put, \ 158 .get = xhandler_get, .put = xhandler_put, \
157 .private_value = (unsigned long)&(struct soc_mixer_control) \ 159 .private_value = (unsigned long)&(struct soc_mixer_control) \
158 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 160 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
159 .max = xmax, .invert = xinvert} } 161 .max = xmax, .platform_max = xmax, .invert = xinvert} }
160#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ 162#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
161{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 163{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
162 .info = snd_soc_info_bool_ext, \ 164 .info = snd_soc_info_bool_ext, \
@@ -212,6 +214,7 @@ struct snd_soc_dai_mode;
212struct snd_soc_pcm_runtime; 214struct snd_soc_pcm_runtime;
213struct snd_soc_dai; 215struct snd_soc_dai;
214struct snd_soc_platform; 216struct snd_soc_platform;
217struct snd_soc_dai_link;
215struct snd_soc_codec; 218struct snd_soc_codec;
216struct soc_enum; 219struct soc_enum;
217struct snd_soc_ac97_ops; 220struct snd_soc_ac97_ops;
@@ -260,6 +263,10 @@ int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type,
260void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask); 263void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask);
261int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, 264int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
262 struct snd_soc_jack_pin *pins); 265 struct snd_soc_jack_pin *pins);
266void snd_soc_jack_notifier_register(struct snd_soc_jack *jack,
267 struct notifier_block *nb);
268void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack,
269 struct notifier_block *nb);
263#ifdef CONFIG_GPIOLIB 270#ifdef CONFIG_GPIOLIB
264int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, 271int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
265 struct snd_soc_jack_gpio *gpios); 272 struct snd_soc_jack_gpio *gpios);
@@ -320,6 +327,8 @@ int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
320 struct snd_ctl_elem_value *ucontrol); 327 struct snd_ctl_elem_value *ucontrol);
321int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, 328int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
322 struct snd_ctl_elem_value *ucontrol); 329 struct snd_ctl_elem_value *ucontrol);
330int snd_soc_limit_volume(struct snd_soc_codec *codec,
331 const char *name, int max);
323 332
324/** 333/**
325 * struct snd_soc_jack_pin - Describes a pin to update based on jack detection 334 * struct snd_soc_jack_pin - Describes a pin to update based on jack detection
@@ -363,6 +372,7 @@ struct snd_soc_jack {
363 struct snd_soc_card *card; 372 struct snd_soc_card *card;
364 struct list_head pins; 373 struct list_head pins;
365 int status; 374 int status;
375 struct blocking_notifier_head notifier;
366}; 376};
367 377
368/* SoC PCM stream information */ 378/* SoC PCM stream information */
@@ -374,7 +384,7 @@ struct snd_soc_pcm_stream {
374 unsigned int rate_max; /* max rate */ 384 unsigned int rate_max; /* max rate */
375 unsigned int channels_min; /* min channels */ 385 unsigned int channels_min; /* min channels */
376 unsigned int channels_max; /* max channels */ 386 unsigned int channels_max; /* max channels */
377 unsigned int active:1; /* stream is in use */ 387 unsigned int active; /* stream is in use */
378 void *dma_data; /* used by platform code */ 388 void *dma_data; /* used by platform code */
379}; 389};
380 390
@@ -407,7 +417,7 @@ struct snd_soc_codec {
407 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ 417 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
408 unsigned int active; 418 unsigned int active;
409 unsigned int pcm_devs; 419 unsigned int pcm_devs;
410 void *private_data; 420 void *drvdata;
411 421
412 /* codec IO */ 422 /* codec IO */
413 void *control_data; /* codec control (i2c/3wire) data */ 423 void *control_data; /* codec control (i2c/3wire) data */
@@ -462,14 +472,21 @@ struct snd_soc_platform {
462 472
463 int (*probe)(struct platform_device *pdev); 473 int (*probe)(struct platform_device *pdev);
464 int (*remove)(struct platform_device *pdev); 474 int (*remove)(struct platform_device *pdev);
465 int (*suspend)(struct snd_soc_dai *dai); 475 int (*suspend)(struct snd_soc_dai_link *dai_link);
466 int (*resume)(struct snd_soc_dai *dai); 476 int (*resume)(struct snd_soc_dai_link *dai_link);
467 477
468 /* pcm creation and destruction */ 478 /* pcm creation and destruction */
469 int (*pcm_new)(struct snd_card *, struct snd_soc_dai *, 479 int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
470 struct snd_pcm *); 480 struct snd_pcm *);
471 void (*pcm_free)(struct snd_pcm *); 481 void (*pcm_free)(struct snd_pcm *);
472 482
483 /*
484 * For platform caused delay reporting.
485 * Optional.
486 */
487 snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
488 struct snd_soc_dai *);
489
473 /* platform stream ops */ 490 /* platform stream ops */
474 struct snd_pcm_ops *pcm_ops; 491 struct snd_pcm_ops *pcm_ops;
475}; 492};
@@ -489,6 +506,9 @@ struct snd_soc_dai_link {
489 /* codec/machine specific init - e.g. add machine controls */ 506 /* codec/machine specific init - e.g. add machine controls */
490 int (*init)(struct snd_soc_codec *codec); 507 int (*init)(struct snd_soc_codec *codec);
491 508
509 /* Keep DAI active over suspend */
510 unsigned int ignore_suspend:1;
511
492 /* Symmetry requirements */ 512 /* Symmetry requirements */
493 unsigned int symmetric_rates:1; 513 unsigned int symmetric_rates:1;
494 514
@@ -553,7 +573,7 @@ struct snd_soc_pcm_runtime {
553 573
554/* mixer control */ 574/* mixer control */
555struct soc_mixer_control { 575struct soc_mixer_control {
556 int min, max; 576 int min, max, platform_max;
557 unsigned int reg, rreg, shift, rshift, invert; 577 unsigned int reg, rreg, shift, rshift, invert;
558}; 578};
559 579
@@ -583,6 +603,17 @@ static inline unsigned int snd_soc_write(struct snd_soc_codec *codec,
583 return codec->write(codec, reg, val); 603 return codec->write(codec, reg, val);
584} 604}
585 605
606static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
607 void *data)
608{
609 codec->drvdata = data;
610}
611
612static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
613{
614 return codec->drvdata;
615}
616
586#include <sound/soc-dai.h> 617#include <sound/soc-dai.h>
587 618
588#endif 619#endif
diff --git a/include/sound/tlv320aic3x.h b/include/sound/tlv320aic3x.h
new file mode 100644
index 000000000000..b1a5f34e5cfa
--- /dev/null
+++ b/include/sound/tlv320aic3x.h
@@ -0,0 +1,17 @@
1/*
2 * Platform data for Texas Instruments TLV320AIC3x codec
3 *
4 * Author: Jarkko Nikula <jhnikula@gmail.com>
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#ifndef __TLV320AIC3x_H__
11#define __TLV320AIC3x_H__
12
13struct aic3x_pdata {
14 int gpio_reset; /* < 0 if not used */
15};
16
17#endif \ No newline at end of file
diff --git a/include/sound/tlv320dac33-plat.h b/include/sound/tlv320dac33-plat.h
index ac0665264bdf..3f428d53195b 100644
--- a/include/sound/tlv320dac33-plat.h
+++ b/include/sound/tlv320dac33-plat.h
@@ -15,6 +15,7 @@
15 15
16struct tlv320dac33_platform_data { 16struct tlv320dac33_platform_data {
17 int power_gpio; 17 int power_gpio;
18 int keep_bclk; /* Keep the BCLK running in FIFO modes */
18 u8 burst_bclkdiv; 19 u8 burst_bclkdiv;
19}; 20};
20 21
diff --git a/include/sound/uda134x.h b/include/sound/uda134x.h
index 475ef8bb7dcd..509efb050176 100644
--- a/include/sound/uda134x.h
+++ b/include/sound/uda134x.h
@@ -21,6 +21,7 @@ struct uda134x_platform_data {
21#define UDA134X_UDA1340 1 21#define UDA134X_UDA1340 1
22#define UDA134X_UDA1341 2 22#define UDA134X_UDA1341 2
23#define UDA134X_UDA1344 3 23#define UDA134X_UDA1344 3
24#define UDA134X_UDA1345 4
24}; 25};
25 26
26#endif /* _UDA134X_H */ 27#endif /* _UDA134X_H */
diff --git a/include/sound/wm8903.h b/include/sound/wm8903.h
new file mode 100644
index 000000000000..b4a0db2307ef
--- /dev/null
+++ b/include/sound/wm8903.h
@@ -0,0 +1,249 @@
1/*
2 * linux/sound/wm8903.h -- Platform data for WM8903
3 *
4 * Copyright 2010 Wolfson Microelectronics. PLC.
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 __LINUX_SND_WM8903_H
12#define __LINUX_SND_WM8903_H
13
14/* Used to enable configuration of a GPIO to all zeros */
15#define WM8903_GPIO_NO_CONFIG 0x8000
16
17/*
18 * R6 (0x06) - Mic Bias Control 0
19 */
20#define WM8903_MICDET_HYST_ENA 0x0080 /* MICDET_HYST_ENA */
21#define WM8903_MICDET_HYST_ENA_MASK 0x0080 /* MICDET_HYST_ENA */
22#define WM8903_MICDET_HYST_ENA_SHIFT 7 /* MICDET_HYST_ENA */
23#define WM8903_MICDET_HYST_ENA_WIDTH 1 /* MICDET_HYST_ENA */
24#define WM8903_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
25#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
26#define WM8903_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
27#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
28#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
29#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
30#define WM8903_MICDET_ENA 0x0002 /* MICDET_ENA */
31#define WM8903_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
32#define WM8903_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
33#define WM8903_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
34#define WM8903_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
35#define WM8903_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
36#define WM8903_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
37#define WM8903_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
38
39/*
40 * R116 (0x74) - GPIO Control 1
41 */
42#define WM8903_GP1_FN_MASK 0x1F00 /* GP1_FN - [12:8] */
43#define WM8903_GP1_FN_SHIFT 8 /* GP1_FN - [12:8] */
44#define WM8903_GP1_FN_WIDTH 5 /* GP1_FN - [12:8] */
45#define WM8903_GP1_DIR 0x0080 /* GP1_DIR */
46#define WM8903_GP1_DIR_MASK 0x0080 /* GP1_DIR */
47#define WM8903_GP1_DIR_SHIFT 7 /* GP1_DIR */
48#define WM8903_GP1_DIR_WIDTH 1 /* GP1_DIR */
49#define WM8903_GP1_OP_CFG 0x0040 /* GP1_OP_CFG */
50#define WM8903_GP1_OP_CFG_MASK 0x0040 /* GP1_OP_CFG */
51#define WM8903_GP1_OP_CFG_SHIFT 6 /* GP1_OP_CFG */
52#define WM8903_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
53#define WM8903_GP1_IP_CFG 0x0020 /* GP1_IP_CFG */
54#define WM8903_GP1_IP_CFG_MASK 0x0020 /* GP1_IP_CFG */
55#define WM8903_GP1_IP_CFG_SHIFT 5 /* GP1_IP_CFG */
56#define WM8903_GP1_IP_CFG_WIDTH 1 /* GP1_IP_CFG */
57#define WM8903_GP1_LVL 0x0010 /* GP1_LVL */
58#define WM8903_GP1_LVL_MASK 0x0010 /* GP1_LVL */
59#define WM8903_GP1_LVL_SHIFT 4 /* GP1_LVL */
60#define WM8903_GP1_LVL_WIDTH 1 /* GP1_LVL */
61#define WM8903_GP1_PD 0x0008 /* GP1_PD */
62#define WM8903_GP1_PD_MASK 0x0008 /* GP1_PD */
63#define WM8903_GP1_PD_SHIFT 3 /* GP1_PD */
64#define WM8903_GP1_PD_WIDTH 1 /* GP1_PD */
65#define WM8903_GP1_PU 0x0004 /* GP1_PU */
66#define WM8903_GP1_PU_MASK 0x0004 /* GP1_PU */
67#define WM8903_GP1_PU_SHIFT 2 /* GP1_PU */
68#define WM8903_GP1_PU_WIDTH 1 /* GP1_PU */
69#define WM8903_GP1_INTMODE 0x0002 /* GP1_INTMODE */
70#define WM8903_GP1_INTMODE_MASK 0x0002 /* GP1_INTMODE */
71#define WM8903_GP1_INTMODE_SHIFT 1 /* GP1_INTMODE */
72#define WM8903_GP1_INTMODE_WIDTH 1 /* GP1_INTMODE */
73#define WM8903_GP1_DB 0x0001 /* GP1_DB */
74#define WM8903_GP1_DB_MASK 0x0001 /* GP1_DB */
75#define WM8903_GP1_DB_SHIFT 0 /* GP1_DB */
76#define WM8903_GP1_DB_WIDTH 1 /* GP1_DB */
77
78/*
79 * R117 (0x75) - GPIO Control 2
80 */
81#define WM8903_GP2_FN_MASK 0x1F00 /* GP2_FN - [12:8] */
82#define WM8903_GP2_FN_SHIFT 8 /* GP2_FN - [12:8] */
83#define WM8903_GP2_FN_WIDTH 5 /* GP2_FN - [12:8] */
84#define WM8903_GP2_DIR 0x0080 /* GP2_DIR */
85#define WM8903_GP2_DIR_MASK 0x0080 /* GP2_DIR */
86#define WM8903_GP2_DIR_SHIFT 7 /* GP2_DIR */
87#define WM8903_GP2_DIR_WIDTH 1 /* GP2_DIR */
88#define WM8903_GP2_OP_CFG 0x0040 /* GP2_OP_CFG */
89#define WM8903_GP2_OP_CFG_MASK 0x0040 /* GP2_OP_CFG */
90#define WM8903_GP2_OP_CFG_SHIFT 6 /* GP2_OP_CFG */
91#define WM8903_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
92#define WM8903_GP2_IP_CFG 0x0020 /* GP2_IP_CFG */
93#define WM8903_GP2_IP_CFG_MASK 0x0020 /* GP2_IP_CFG */
94#define WM8903_GP2_IP_CFG_SHIFT 5 /* GP2_IP_CFG */
95#define WM8903_GP2_IP_CFG_WIDTH 1 /* GP2_IP_CFG */
96#define WM8903_GP2_LVL 0x0010 /* GP2_LVL */
97#define WM8903_GP2_LVL_MASK 0x0010 /* GP2_LVL */
98#define WM8903_GP2_LVL_SHIFT 4 /* GP2_LVL */
99#define WM8903_GP2_LVL_WIDTH 1 /* GP2_LVL */
100#define WM8903_GP2_PD 0x0008 /* GP2_PD */
101#define WM8903_GP2_PD_MASK 0x0008 /* GP2_PD */
102#define WM8903_GP2_PD_SHIFT 3 /* GP2_PD */
103#define WM8903_GP2_PD_WIDTH 1 /* GP2_PD */
104#define WM8903_GP2_PU 0x0004 /* GP2_PU */
105#define WM8903_GP2_PU_MASK 0x0004 /* GP2_PU */
106#define WM8903_GP2_PU_SHIFT 2 /* GP2_PU */
107#define WM8903_GP2_PU_WIDTH 1 /* GP2_PU */
108#define WM8903_GP2_INTMODE 0x0002 /* GP2_INTMODE */
109#define WM8903_GP2_INTMODE_MASK 0x0002 /* GP2_INTMODE */
110#define WM8903_GP2_INTMODE_SHIFT 1 /* GP2_INTMODE */
111#define WM8903_GP2_INTMODE_WIDTH 1 /* GP2_INTMODE */
112#define WM8903_GP2_DB 0x0001 /* GP2_DB */
113#define WM8903_GP2_DB_MASK 0x0001 /* GP2_DB */
114#define WM8903_GP2_DB_SHIFT 0 /* GP2_DB */
115#define WM8903_GP2_DB_WIDTH 1 /* GP2_DB */
116
117/*
118 * R118 (0x76) - GPIO Control 3
119 */
120#define WM8903_GP3_FN_MASK 0x1F00 /* GP3_FN - [12:8] */
121#define WM8903_GP3_FN_SHIFT 8 /* GP3_FN - [12:8] */
122#define WM8903_GP3_FN_WIDTH 5 /* GP3_FN - [12:8] */
123#define WM8903_GP3_DIR 0x0080 /* GP3_DIR */
124#define WM8903_GP3_DIR_MASK 0x0080 /* GP3_DIR */
125#define WM8903_GP3_DIR_SHIFT 7 /* GP3_DIR */
126#define WM8903_GP3_DIR_WIDTH 1 /* GP3_DIR */
127#define WM8903_GP3_OP_CFG 0x0040 /* GP3_OP_CFG */
128#define WM8903_GP3_OP_CFG_MASK 0x0040 /* GP3_OP_CFG */
129#define WM8903_GP3_OP_CFG_SHIFT 6 /* GP3_OP_CFG */
130#define WM8903_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
131#define WM8903_GP3_IP_CFG 0x0020 /* GP3_IP_CFG */
132#define WM8903_GP3_IP_CFG_MASK 0x0020 /* GP3_IP_CFG */
133#define WM8903_GP3_IP_CFG_SHIFT 5 /* GP3_IP_CFG */
134#define WM8903_GP3_IP_CFG_WIDTH 1 /* GP3_IP_CFG */
135#define WM8903_GP3_LVL 0x0010 /* GP3_LVL */
136#define WM8903_GP3_LVL_MASK 0x0010 /* GP3_LVL */
137#define WM8903_GP3_LVL_SHIFT 4 /* GP3_LVL */
138#define WM8903_GP3_LVL_WIDTH 1 /* GP3_LVL */
139#define WM8903_GP3_PD 0x0008 /* GP3_PD */
140#define WM8903_GP3_PD_MASK 0x0008 /* GP3_PD */
141#define WM8903_GP3_PD_SHIFT 3 /* GP3_PD */
142#define WM8903_GP3_PD_WIDTH 1 /* GP3_PD */
143#define WM8903_GP3_PU 0x0004 /* GP3_PU */
144#define WM8903_GP3_PU_MASK 0x0004 /* GP3_PU */
145#define WM8903_GP3_PU_SHIFT 2 /* GP3_PU */
146#define WM8903_GP3_PU_WIDTH 1 /* GP3_PU */
147#define WM8903_GP3_INTMODE 0x0002 /* GP3_INTMODE */
148#define WM8903_GP3_INTMODE_MASK 0x0002 /* GP3_INTMODE */
149#define WM8903_GP3_INTMODE_SHIFT 1 /* GP3_INTMODE */
150#define WM8903_GP3_INTMODE_WIDTH 1 /* GP3_INTMODE */
151#define WM8903_GP3_DB 0x0001 /* GP3_DB */
152#define WM8903_GP3_DB_MASK 0x0001 /* GP3_DB */
153#define WM8903_GP3_DB_SHIFT 0 /* GP3_DB */
154#define WM8903_GP3_DB_WIDTH 1 /* GP3_DB */
155
156/*
157 * R119 (0x77) - GPIO Control 4
158 */
159#define WM8903_GP4_FN_MASK 0x1F00 /* GP4_FN - [12:8] */
160#define WM8903_GP4_FN_SHIFT 8 /* GP4_FN - [12:8] */
161#define WM8903_GP4_FN_WIDTH 5 /* GP4_FN - [12:8] */
162#define WM8903_GP4_DIR 0x0080 /* GP4_DIR */
163#define WM8903_GP4_DIR_MASK 0x0080 /* GP4_DIR */
164#define WM8903_GP4_DIR_SHIFT 7 /* GP4_DIR */
165#define WM8903_GP4_DIR_WIDTH 1 /* GP4_DIR */
166#define WM8903_GP4_OP_CFG 0x0040 /* GP4_OP_CFG */
167#define WM8903_GP4_OP_CFG_MASK 0x0040 /* GP4_OP_CFG */
168#define WM8903_GP4_OP_CFG_SHIFT 6 /* GP4_OP_CFG */
169#define WM8903_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
170#define WM8903_GP4_IP_CFG 0x0020 /* GP4_IP_CFG */
171#define WM8903_GP4_IP_CFG_MASK 0x0020 /* GP4_IP_CFG */
172#define WM8903_GP4_IP_CFG_SHIFT 5 /* GP4_IP_CFG */
173#define WM8903_GP4_IP_CFG_WIDTH 1 /* GP4_IP_CFG */
174#define WM8903_GP4_LVL 0x0010 /* GP4_LVL */
175#define WM8903_GP4_LVL_MASK 0x0010 /* GP4_LVL */
176#define WM8903_GP4_LVL_SHIFT 4 /* GP4_LVL */
177#define WM8903_GP4_LVL_WIDTH 1 /* GP4_LVL */
178#define WM8903_GP4_PD 0x0008 /* GP4_PD */
179#define WM8903_GP4_PD_MASK 0x0008 /* GP4_PD */
180#define WM8903_GP4_PD_SHIFT 3 /* GP4_PD */
181#define WM8903_GP4_PD_WIDTH 1 /* GP4_PD */
182#define WM8903_GP4_PU 0x0004 /* GP4_PU */
183#define WM8903_GP4_PU_MASK 0x0004 /* GP4_PU */
184#define WM8903_GP4_PU_SHIFT 2 /* GP4_PU */
185#define WM8903_GP4_PU_WIDTH 1 /* GP4_PU */
186#define WM8903_GP4_INTMODE 0x0002 /* GP4_INTMODE */
187#define WM8903_GP4_INTMODE_MASK 0x0002 /* GP4_INTMODE */
188#define WM8903_GP4_INTMODE_SHIFT 1 /* GP4_INTMODE */
189#define WM8903_GP4_INTMODE_WIDTH 1 /* GP4_INTMODE */
190#define WM8903_GP4_DB 0x0001 /* GP4_DB */
191#define WM8903_GP4_DB_MASK 0x0001 /* GP4_DB */
192#define WM8903_GP4_DB_SHIFT 0 /* GP4_DB */
193#define WM8903_GP4_DB_WIDTH 1 /* GP4_DB */
194
195/*
196 * R120 (0x78) - GPIO Control 5
197 */
198#define WM8903_GP5_FN_MASK 0x1F00 /* GP5_FN - [12:8] */
199#define WM8903_GP5_FN_SHIFT 8 /* GP5_FN - [12:8] */
200#define WM8903_GP5_FN_WIDTH 5 /* GP5_FN - [12:8] */
201#define WM8903_GP5_DIR 0x0080 /* GP5_DIR */
202#define WM8903_GP5_DIR_MASK 0x0080 /* GP5_DIR */
203#define WM8903_GP5_DIR_SHIFT 7 /* GP5_DIR */
204#define WM8903_GP5_DIR_WIDTH 1 /* GP5_DIR */
205#define WM8903_GP5_OP_CFG 0x0040 /* GP5_OP_CFG */
206#define WM8903_GP5_OP_CFG_MASK 0x0040 /* GP5_OP_CFG */
207#define WM8903_GP5_OP_CFG_SHIFT 6 /* GP5_OP_CFG */
208#define WM8903_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
209#define WM8903_GP5_IP_CFG 0x0020 /* GP5_IP_CFG */
210#define WM8903_GP5_IP_CFG_MASK 0x0020 /* GP5_IP_CFG */
211#define WM8903_GP5_IP_CFG_SHIFT 5 /* GP5_IP_CFG */
212#define WM8903_GP5_IP_CFG_WIDTH 1 /* GP5_IP_CFG */
213#define WM8903_GP5_LVL 0x0010 /* GP5_LVL */
214#define WM8903_GP5_LVL_MASK 0x0010 /* GP5_LVL */
215#define WM8903_GP5_LVL_SHIFT 4 /* GP5_LVL */
216#define WM8903_GP5_LVL_WIDTH 1 /* GP5_LVL */
217#define WM8903_GP5_PD 0x0008 /* GP5_PD */
218#define WM8903_GP5_PD_MASK 0x0008 /* GP5_PD */
219#define WM8903_GP5_PD_SHIFT 3 /* GP5_PD */
220#define WM8903_GP5_PD_WIDTH 1 /* GP5_PD */
221#define WM8903_GP5_PU 0x0004 /* GP5_PU */
222#define WM8903_GP5_PU_MASK 0x0004 /* GP5_PU */
223#define WM8903_GP5_PU_SHIFT 2 /* GP5_PU */
224#define WM8903_GP5_PU_WIDTH 1 /* GP5_PU */
225#define WM8903_GP5_INTMODE 0x0002 /* GP5_INTMODE */
226#define WM8903_GP5_INTMODE_MASK 0x0002 /* GP5_INTMODE */
227#define WM8903_GP5_INTMODE_SHIFT 1 /* GP5_INTMODE */
228#define WM8903_GP5_INTMODE_WIDTH 1 /* GP5_INTMODE */
229#define WM8903_GP5_DB 0x0001 /* GP5_DB */
230#define WM8903_GP5_DB_MASK 0x0001 /* GP5_DB */
231#define WM8903_GP5_DB_SHIFT 0 /* GP5_DB */
232#define WM8903_GP5_DB_WIDTH 1 /* GP5_DB */
233
234struct wm8903_platform_data {
235 bool irq_active_low; /* Set if IRQ active low, default high */
236
237 /* Default register value for R6 (Mic bias), used to configure
238 * microphone detection. In conjunction with gpio_cfg this
239 * can be used to route the microphone status signals out onto
240 * the GPIOs for use with snd_soc_jack_add_gpios().
241 */
242 u16 micdet_cfg;
243
244 int micdet_delay; /* Delay after microphone detection (ms) */
245
246 u32 gpio_cfg[5]; /* Default register values for GPIO pin mux */
247};
248
249#endif
diff --git a/include/sound/wm8904.h b/include/sound/wm8904.h
index d66575a601be..898be3a8db9a 100644
--- a/include/sound/wm8904.h
+++ b/include/sound/wm8904.h
@@ -15,8 +15,111 @@
15#ifndef __MFD_WM8994_PDATA_H__ 15#ifndef __MFD_WM8994_PDATA_H__
16#define __MFD_WM8994_PDATA_H__ 16#define __MFD_WM8994_PDATA_H__
17 17
18#define WM8904_DRC_REGS 4 18/* Used to enable configuration of a GPIO to all zeros */
19#define WM8904_EQ_REGS 25 19#define WM8904_GPIO_NO_CONFIG 0x8000
20
21/*
22 * R6 (0x06) - Mic Bias Control 0
23 */
24#define WM8904_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
25#define WM8904_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
26#define WM8904_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
27#define WM8904_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
28#define WM8904_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
29#define WM8904_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
30#define WM8904_MICDET_ENA 0x0002 /* MICDET_ENA */
31#define WM8904_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
32#define WM8904_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
33#define WM8904_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
34#define WM8904_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
35#define WM8904_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
36#define WM8904_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
37#define WM8904_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
38
39/*
40 * R7 (0x07) - Mic Bias Control 1
41 */
42#define WM8904_MIC_DET_FILTER_ENA 0x8000 /* MIC_DET_FILTER_ENA */
43#define WM8904_MIC_DET_FILTER_ENA_MASK 0x8000 /* MIC_DET_FILTER_ENA */
44#define WM8904_MIC_DET_FILTER_ENA_SHIFT 15 /* MIC_DET_FILTER_ENA */
45#define WM8904_MIC_DET_FILTER_ENA_WIDTH 1 /* MIC_DET_FILTER_ENA */
46#define WM8904_MIC_SHORT_FILTER_ENA 0x4000 /* MIC_SHORT_FILTER_ENA */
47#define WM8904_MIC_SHORT_FILTER_ENA_MASK 0x4000 /* MIC_SHORT_FILTER_ENA */
48#define WM8904_MIC_SHORT_FILTER_ENA_SHIFT 14 /* MIC_SHORT_FILTER_ENA */
49#define WM8904_MIC_SHORT_FILTER_ENA_WIDTH 1 /* MIC_SHORT_FILTER_ENA */
50#define WM8904_MICBIAS_SEL_MASK 0x0007 /* MICBIAS_SEL - [2:0] */
51#define WM8904_MICBIAS_SEL_SHIFT 0 /* MICBIAS_SEL - [2:0] */
52#define WM8904_MICBIAS_SEL_WIDTH 3 /* MICBIAS_SEL - [2:0] */
53
54
55/*
56 * R121 (0x79) - GPIO Control 1
57 */
58#define WM8904_GPIO1_PU 0x0020 /* GPIO1_PU */
59#define WM8904_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */
60#define WM8904_GPIO1_PU_SHIFT 5 /* GPIO1_PU */
61#define WM8904_GPIO1_PU_WIDTH 1 /* GPIO1_PU */
62#define WM8904_GPIO1_PD 0x0010 /* GPIO1_PD */
63#define WM8904_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */
64#define WM8904_GPIO1_PD_SHIFT 4 /* GPIO1_PD */
65#define WM8904_GPIO1_PD_WIDTH 1 /* GPIO1_PD */
66#define WM8904_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
67#define WM8904_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */
68#define WM8904_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */
69
70/*
71 * R122 (0x7A) - GPIO Control 2
72 */
73#define WM8904_GPIO2_PU 0x0020 /* GPIO2_PU */
74#define WM8904_GPIO2_PU_MASK 0x0020 /* GPIO2_PU */
75#define WM8904_GPIO2_PU_SHIFT 5 /* GPIO2_PU */
76#define WM8904_GPIO2_PU_WIDTH 1 /* GPIO2_PU */
77#define WM8904_GPIO2_PD 0x0010 /* GPIO2_PD */
78#define WM8904_GPIO2_PD_MASK 0x0010 /* GPIO2_PD */
79#define WM8904_GPIO2_PD_SHIFT 4 /* GPIO2_PD */
80#define WM8904_GPIO2_PD_WIDTH 1 /* GPIO2_PD */
81#define WM8904_GPIO2_SEL_MASK 0x000F /* GPIO2_SEL - [3:0] */
82#define WM8904_GPIO2_SEL_SHIFT 0 /* GPIO2_SEL - [3:0] */
83#define WM8904_GPIO2_SEL_WIDTH 4 /* GPIO2_SEL - [3:0] */
84
85/*
86 * R123 (0x7B) - GPIO Control 3
87 */
88#define WM8904_GPIO3_PU 0x0020 /* GPIO3_PU */
89#define WM8904_GPIO3_PU_MASK 0x0020 /* GPIO3_PU */
90#define WM8904_GPIO3_PU_SHIFT 5 /* GPIO3_PU */
91#define WM8904_GPIO3_PU_WIDTH 1 /* GPIO3_PU */
92#define WM8904_GPIO3_PD 0x0010 /* GPIO3_PD */
93#define WM8904_GPIO3_PD_MASK 0x0010 /* GPIO3_PD */
94#define WM8904_GPIO3_PD_SHIFT 4 /* GPIO3_PD */
95#define WM8904_GPIO3_PD_WIDTH 1 /* GPIO3_PD */
96#define WM8904_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
97#define WM8904_GPIO3_SEL_SHIFT 0 /* GPIO3_SEL - [3:0] */
98#define WM8904_GPIO3_SEL_WIDTH 4 /* GPIO3_SEL - [3:0] */
99
100/*
101 * R124 (0x7C) - GPIO Control 4
102 */
103#define WM8904_GPI7_ENA 0x0200 /* GPI7_ENA */
104#define WM8904_GPI7_ENA_MASK 0x0200 /* GPI7_ENA */
105#define WM8904_GPI7_ENA_SHIFT 9 /* GPI7_ENA */
106#define WM8904_GPI7_ENA_WIDTH 1 /* GPI7_ENA */
107#define WM8904_GPI8_ENA 0x0100 /* GPI8_ENA */
108#define WM8904_GPI8_ENA_MASK 0x0100 /* GPI8_ENA */
109#define WM8904_GPI8_ENA_SHIFT 8 /* GPI8_ENA */
110#define WM8904_GPI8_ENA_WIDTH 1 /* GPI8_ENA */
111#define WM8904_GPIO_BCLK_MODE_ENA 0x0080 /* GPIO_BCLK_MODE_ENA */
112#define WM8904_GPIO_BCLK_MODE_ENA_MASK 0x0080 /* GPIO_BCLK_MODE_ENA */
113#define WM8904_GPIO_BCLK_MODE_ENA_SHIFT 7 /* GPIO_BCLK_MODE_ENA */
114#define WM8904_GPIO_BCLK_MODE_ENA_WIDTH 1 /* GPIO_BCLK_MODE_ENA */
115#define WM8904_GPIO_BCLK_SEL_MASK 0x000F /* GPIO_BCLK_SEL - [3:0] */
116#define WM8904_GPIO_BCLK_SEL_SHIFT 0 /* GPIO_BCLK_SEL - [3:0] */
117#define WM8904_GPIO_BCLK_SEL_WIDTH 4 /* GPIO_BCLK_SEL - [3:0] */
118
119#define WM8904_MIC_REGS 2
120#define WM8904_GPIO_REGS 4
121#define WM8904_DRC_REGS 4
122#define WM8904_EQ_REGS 25
20 123
21/** 124/**
22 * DRC configurations are specified with a label and a set of register 125 * DRC configurations are specified with a label and a set of register
@@ -52,6 +155,9 @@ struct wm8904_pdata {
52 155
53 int num_retune_mobile_cfgs; 156 int num_retune_mobile_cfgs;
54 struct wm8904_retune_mobile_cfg *retune_mobile_cfgs; 157 struct wm8904_retune_mobile_cfg *retune_mobile_cfgs;
158
159 u32 gpio_cfg[WM8904_GPIO_REGS];
160 u32 mic_cfg[WM8904_MIC_REGS];
55}; 161};
56 162
57#endif 163#endif
diff --git a/include/sound/wm8960.h b/include/sound/wm8960.h
new file mode 100644
index 000000000000..74e9a95529c5
--- /dev/null
+++ b/include/sound/wm8960.h
@@ -0,0 +1,24 @@
1/*
2 * wm8960.h -- WM8960 Soc Audio driver platform data
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 _WM8960_PDATA_H
10#define _WM8960_PDATA_H
11
12#define WM8960_DRES_400R 0
13#define WM8960_DRES_200R 1
14#define WM8960_DRES_600R 2
15#define WM8960_DRES_150R 3
16#define WM8960_DRES_MAX 3
17
18struct wm8960_data {
19 bool capless; /* Headphone outputs configured in capless mode */
20
21 int dres; /* Discharge resistance for headphone outputs */
22};
23
24#endif
diff --git a/include/sound/wm9090.h b/include/sound/wm9090.h
new file mode 100644
index 000000000000..3718928cde1a
--- /dev/null
+++ b/include/sound/wm9090.h
@@ -0,0 +1,28 @@
1/*
2 * linux/sound/wm9090.h -- Platform data for WM9090
3 *
4 * Copyright 2009, 2010 Wolfson Microelectronics. PLC.
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 __LINUX_SND_WM9090_H
12#define __LINUX_SND_WM9090_H
13
14struct wm9090_platform_data {
15 /* Line inputs 1 & 2 can optionally be differential */
16 unsigned int lin1_diff:1;
17 unsigned int lin2_diff:1;
18
19 /* AGC configuration. This is intended to protect the speaker
20 * against overdriving and will therefore depend on the
21 * hardware setup with incorrect runtime configuration
22 * potentially causing hardware damage.
23 */
24 unsigned int agc_ena:1;
25 u16 agc[3];
26};
27
28#endif
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 3e6628c8e665..f6b3cc04b34b 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -415,9 +415,12 @@ static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
415} 415}
416 416
417#ifdef CONFIG_PM 417#ifdef CONFIG_PM
418static int atmel_pcm_suspend(struct snd_soc_dai *dai) 418static int atmel_pcm_suspend(struct snd_soc_dai_link *dai_link)
419{ 419{
420 struct snd_pcm_runtime *runtime = dai->runtime; 420 struct snd_pcm *pcm = dai_link->pcm;
421 struct snd_pcm_str *stream = &pcm->streams[0];
422 struct snd_pcm_substream *substream = stream->substream;
423 struct snd_pcm_runtime *runtime = substream->runtime;
421 struct atmel_runtime_data *prtd; 424 struct atmel_runtime_data *prtd;
422 struct atmel_pcm_dma_params *params; 425 struct atmel_pcm_dma_params *params;
423 426
@@ -439,9 +442,12 @@ static int atmel_pcm_suspend(struct snd_soc_dai *dai)
439 return 0; 442 return 0;
440} 443}
441 444
442static int atmel_pcm_resume(struct snd_soc_dai *dai) 445static int atmel_pcm_resume(struct snd_soc_dai_link *dai_link)
443{ 446{
444 struct snd_pcm_runtime *runtime = dai->runtime; 447 struct snd_pcm *pcm = dai_link->pcm;
448 struct snd_pcm_str *stream = &pcm->streams[0];
449 struct snd_pcm_substream *substream = stream->substream;
450 struct snd_pcm_runtime *runtime = substream->runtime;
445 struct atmel_runtime_data *prtd; 451 struct atmel_runtime_data *prtd;
446 struct atmel_pcm_dma_params *params; 452 struct atmel_pcm_dma_params *params;
447 453
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 97f1a251e446..8ef25025f3dc 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -49,13 +49,14 @@ config SND_BF5XX_SOC_AD1836
49 help 49 help
50 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT. 50 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
51 51
52config SND_BF5XX_SOC_AD1938 52config SND_BF5XX_SOC_AD193X
53 tristate "SoC AD1938 Audio support for Blackfin" 53 tristate "SoC AD193X Audio support for Blackfin"
54 depends on SND_BF5XX_TDM 54 depends on SND_BF5XX_TDM
55 select SND_BF5XX_SOC_TDM 55 select SND_BF5XX_SOC_TDM
56 select SND_SOC_AD1938 56 select SND_SOC_AD193X
57 help 57 help
58 Say Y if you want to add support for AD1938 codec on Blackfin. 58 Say Y if you want to add support for AD193X codec on Blackfin.
59 This driver supports AD1936, AD1937, AD1938 and AD1939.
59 60
60config SND_BF5XX_AC97 61config SND_BF5XX_AC97
61 tristate "SoC AC97 Audio for the ADI BF5xx chip" 62 tristate "SoC AC97 Audio for the ADI BF5xx chip"
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index 87e30423912f..49af3f32aec8 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -20,10 +20,10 @@ snd-ad1836-objs := bf5xx-ad1836.o
20snd-ad1980-objs := bf5xx-ad1980.o 20snd-ad1980-objs := bf5xx-ad1980.o
21snd-ssm2602-objs := bf5xx-ssm2602.o 21snd-ssm2602-objs := bf5xx-ssm2602.o
22snd-ad73311-objs := bf5xx-ad73311.o 22snd-ad73311-objs := bf5xx-ad73311.o
23snd-ad1938-objs := bf5xx-ad1938.o 23snd-ad193x-objs := bf5xx-ad193x.o
24 24
25obj-$(CONFIG_SND_BF5XX_SOC_AD1836) += snd-ad1836.o 25obj-$(CONFIG_SND_BF5XX_SOC_AD1836) += snd-ad1836.o
26obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o 26obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
27obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o 27obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
28obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o 28obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
29obj-$(CONFIG_SND_BF5XX_SOC_AD1938) += snd-ad1938.o 29obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o
diff --git a/sound/soc/blackfin/bf5xx-ad1938.c b/sound/soc/blackfin/bf5xx-ad193x.c
index 2ef1e5013b8c..b8c9060cfd8e 100644
--- a/sound/soc/blackfin/bf5xx-ad1938.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * File: sound/soc/blackfin/bf5xx-ad1938.c 2 * File: sound/soc/blackfin/bf5xx-ad193x.c
3 * Author: Barry Song <Barry.Song@analog.com> 3 * Author: Barry Song <Barry.Song@analog.com>
4 * 4 *
5 * Created: Thur June 4 2009 5 * Created: Thur June 4 2009
6 * Description: Board driver for ad1938 sound chip 6 * Description: Board driver for ad193x sound chip
7 * 7 *
8 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 8 * Bugs: Enter bugs at http://blackfin.uclinux.org/
9 * 9 *
@@ -38,15 +38,15 @@
38#include <asm/dma.h> 38#include <asm/dma.h>
39#include <asm/portmux.h> 39#include <asm/portmux.h>
40 40
41#include "../codecs/ad1938.h" 41#include "../codecs/ad193x.h"
42#include "bf5xx-sport.h" 42#include "bf5xx-sport.h"
43 43
44#include "bf5xx-tdm-pcm.h" 44#include "bf5xx-tdm-pcm.h"
45#include "bf5xx-tdm.h" 45#include "bf5xx-tdm.h"
46 46
47static struct snd_soc_card bf5xx_ad1938; 47static struct snd_soc_card bf5xx_ad193x;
48 48
49static int bf5xx_ad1938_startup(struct snd_pcm_substream *substream) 49static int bf5xx_ad193x_startup(struct snd_pcm_substream *substream)
50{ 50{
51 struct snd_soc_pcm_runtime *rtd = substream->private_data; 51 struct snd_soc_pcm_runtime *rtd = substream->private_data;
52 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 52 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -55,7 +55,7 @@ static int bf5xx_ad1938_startup(struct snd_pcm_substream *substream)
55 return 0; 55 return 0;
56} 56}
57 57
58static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream, 58static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
59 struct snd_pcm_hw_params *params) 59 struct snd_pcm_hw_params *params)
60{ 60{
61 struct snd_soc_pcm_runtime *rtd = substream->private_data; 61 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -89,61 +89,61 @@ static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream,
89 return 0; 89 return 0;
90} 90}
91 91
92static struct snd_soc_ops bf5xx_ad1938_ops = { 92static struct snd_soc_ops bf5xx_ad193x_ops = {
93 .startup = bf5xx_ad1938_startup, 93 .startup = bf5xx_ad193x_startup,
94 .hw_params = bf5xx_ad1938_hw_params, 94 .hw_params = bf5xx_ad193x_hw_params,
95}; 95};
96 96
97static struct snd_soc_dai_link bf5xx_ad1938_dai = { 97static struct snd_soc_dai_link bf5xx_ad193x_dai = {
98 .name = "ad1938", 98 .name = "ad193x",
99 .stream_name = "AD1938", 99 .stream_name = "AD193X",
100 .cpu_dai = &bf5xx_tdm_dai, 100 .cpu_dai = &bf5xx_tdm_dai,
101 .codec_dai = &ad1938_dai, 101 .codec_dai = &ad193x_dai,
102 .ops = &bf5xx_ad1938_ops, 102 .ops = &bf5xx_ad193x_ops,
103}; 103};
104 104
105static struct snd_soc_card bf5xx_ad1938 = { 105static struct snd_soc_card bf5xx_ad193x = {
106 .name = "bf5xx_ad1938", 106 .name = "bf5xx_ad193x",
107 .platform = &bf5xx_tdm_soc_platform, 107 .platform = &bf5xx_tdm_soc_platform,
108 .dai_link = &bf5xx_ad1938_dai, 108 .dai_link = &bf5xx_ad193x_dai,
109 .num_links = 1, 109 .num_links = 1,
110}; 110};
111 111
112static struct snd_soc_device bf5xx_ad1938_snd_devdata = { 112static struct snd_soc_device bf5xx_ad193x_snd_devdata = {
113 .card = &bf5xx_ad1938, 113 .card = &bf5xx_ad193x,
114 .codec_dev = &soc_codec_dev_ad1938, 114 .codec_dev = &soc_codec_dev_ad193x,
115}; 115};
116 116
117static struct platform_device *bfxx_ad1938_snd_device; 117static struct platform_device *bfxx_ad193x_snd_device;
118 118
119static int __init bf5xx_ad1938_init(void) 119static int __init bf5xx_ad193x_init(void)
120{ 120{
121 int ret; 121 int ret;
122 122
123 bfxx_ad1938_snd_device = platform_device_alloc("soc-audio", -1); 123 bfxx_ad193x_snd_device = platform_device_alloc("soc-audio", -1);
124 if (!bfxx_ad1938_snd_device) 124 if (!bfxx_ad193x_snd_device)
125 return -ENOMEM; 125 return -ENOMEM;
126 126
127 platform_set_drvdata(bfxx_ad1938_snd_device, &bf5xx_ad1938_snd_devdata); 127 platform_set_drvdata(bfxx_ad193x_snd_device, &bf5xx_ad193x_snd_devdata);
128 bf5xx_ad1938_snd_devdata.dev = &bfxx_ad1938_snd_device->dev; 128 bf5xx_ad193x_snd_devdata.dev = &bfxx_ad193x_snd_device->dev;
129 ret = platform_device_add(bfxx_ad1938_snd_device); 129 ret = platform_device_add(bfxx_ad193x_snd_device);
130 130
131 if (ret) 131 if (ret)
132 platform_device_put(bfxx_ad1938_snd_device); 132 platform_device_put(bfxx_ad193x_snd_device);
133 133
134 return ret; 134 return ret;
135} 135}
136 136
137static void __exit bf5xx_ad1938_exit(void) 137static void __exit bf5xx_ad193x_exit(void)
138{ 138{
139 platform_device_unregister(bfxx_ad1938_snd_device); 139 platform_device_unregister(bfxx_ad193x_snd_device);
140} 140}
141 141
142module_init(bf5xx_ad1938_init); 142module_init(bf5xx_ad193x_init);
143module_exit(bf5xx_ad1938_exit); 143module_exit(bf5xx_ad193x_exit);
144 144
145/* Module information */ 145/* Module information */
146MODULE_AUTHOR("Barry Song"); 146MODULE_AUTHOR("Barry Song");
147MODULE_DESCRIPTION("ALSA SoC AD1938 board driver"); 147MODULE_DESCRIPTION("ALSA SoC AD193X board driver");
148MODULE_LICENSE("GPL"); 148MODULE_LICENSE("GPL");
149 149
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
index 2e63dea73e9c..a86e8cc0b2d3 100644
--- a/sound/soc/blackfin/bf5xx-sport.h
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -34,33 +34,7 @@
34#include <linux/wait.h> 34#include <linux/wait.h>
35#include <linux/workqueue.h> 35#include <linux/workqueue.h>
36#include <asm/dma.h> 36#include <asm/dma.h>
37 37#include <asm/bfin_sport.h>
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 38
65#define DESC_ELEMENT_COUNT 9 39#define DESC_ELEMENT_COUNT 9
66 40
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1743d565e996..31ac5538fe7e 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -13,7 +13,7 @@ config SND_SOC_ALL_CODECS
13 select SND_SOC_L3 13 select SND_SOC_L3
14 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS 14 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
15 select SND_SOC_AD1836 if SPI_MASTER 15 select SND_SOC_AD1836 if SPI_MASTER
16 select SND_SOC_AD1938 if SPI_MASTER 16 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
18 select SND_SOC_ADS117X 18 select SND_SOC_ADS117X
19 select SND_SOC_AD73311 if I2C 19 select SND_SOC_AD73311 if I2C
@@ -21,6 +21,7 @@ config SND_SOC_ALL_CODECS
21 select SND_SOC_AK4535 if I2C 21 select SND_SOC_AK4535 if I2C
22 select SND_SOC_AK4642 if I2C 22 select SND_SOC_AK4642 if I2C
23 select SND_SOC_AK4671 if I2C 23 select SND_SOC_AK4671 if I2C
24 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
24 select SND_SOC_CS4270 if I2C 25 select SND_SOC_CS4270 if I2C
25 select SND_SOC_MAX9877 if I2C 26 select SND_SOC_MAX9877 if I2C
26 select SND_SOC_DA7210 if I2C 27 select SND_SOC_DA7210 if I2C
@@ -34,6 +35,7 @@ config SND_SOC_ALL_CODECS
34 select SND_SOC_TPA6130A2 if I2C 35 select SND_SOC_TPA6130A2 if I2C
35 select SND_SOC_TLV320DAC33 if I2C 36 select SND_SOC_TLV320DAC33 if I2C
36 select SND_SOC_TWL4030 if TWL4030_CORE 37 select SND_SOC_TWL4030 if TWL4030_CORE
38 select SND_SOC_TWL6040 if TWL4030_CORE
37 select SND_SOC_UDA134X 39 select SND_SOC_UDA134X
38 select SND_SOC_UDA1380 if I2C 40 select SND_SOC_UDA1380 if I2C
39 select SND_SOC_WM2000 if I2C 41 select SND_SOC_WM2000 if I2C
@@ -64,6 +66,7 @@ config SND_SOC_ALL_CODECS
64 select SND_SOC_WM8993 if I2C 66 select SND_SOC_WM8993 if I2C
65 select SND_SOC_WM8994 if MFD_WM8994 67 select SND_SOC_WM8994 if MFD_WM8994
66 select SND_SOC_WM9081 if I2C 68 select SND_SOC_WM9081 if I2C
69 select SND_SOC_WM9090 if I2C
67 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 70 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
68 select SND_SOC_WM9712 if SND_SOC_AC97_BUS 71 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
69 select SND_SOC_WM9713 if SND_SOC_AC97_BUS 72 select SND_SOC_WM9713 if SND_SOC_AC97_BUS
@@ -90,7 +93,7 @@ config SND_SOC_AC97_CODEC
90config SND_SOC_AD1836 93config SND_SOC_AD1836
91 tristate 94 tristate
92 95
93config SND_SOC_AD1938 96config SND_SOC_AD193X
94 tristate 97 tristate
95 98
96config SND_SOC_AD1980 99config SND_SOC_AD1980
@@ -114,6 +117,9 @@ config SND_SOC_AK4642
114config SND_SOC_AK4671 117config SND_SOC_AK4671
115 tristate 118 tristate
116 119
120config SND_SOC_CQ0093VC
121 tristate
122
117# Cirrus Logic CS4270 Codec 123# Cirrus Logic CS4270 Codec
118config SND_SOC_CS4270 124config SND_SOC_CS4270
119 tristate 125 tristate
@@ -164,6 +170,9 @@ config SND_SOC_TWL4030
164 select TWL4030_CODEC 170 select TWL4030_CODEC
165 tristate 171 tristate
166 172
173config SND_SOC_TWL6040
174 tristate
175
167config SND_SOC_UDA134X 176config SND_SOC_UDA134X
168 tristate 177 tristate
169 178
@@ -269,3 +278,6 @@ config SND_SOC_TPA6130A2
269 278
270config SND_SOC_WM2000 279config SND_SOC_WM2000
271 tristate 280 tristate
281
282config SND_SOC_WM9090
283 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index dd5ce6df6292..91429eab0707 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,6 +1,6 @@
1snd-soc-ac97-objs := ac97.o 1snd-soc-ac97-objs := ac97.o
2snd-soc-ad1836-objs := ad1836.o 2snd-soc-ad1836-objs := ad1836.o
3snd-soc-ad1938-objs := ad1938.o 3snd-soc-ad193x-objs := ad193x.o
4snd-soc-ad1980-objs := ad1980.o 4snd-soc-ad1980-objs := ad1980.o
5snd-soc-ad73311-objs := ad73311.o 5snd-soc-ad73311-objs := ad73311.o
6snd-soc-ads117x-objs := ads117x.o 6snd-soc-ads117x-objs := ads117x.o
@@ -8,6 +8,7 @@ snd-soc-ak4104-objs := ak4104.o
8snd-soc-ak4535-objs := ak4535.o 8snd-soc-ak4535-objs := ak4535.o
9snd-soc-ak4642-objs := ak4642.o 9snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o 10snd-soc-ak4671-objs := ak4671.o
11snd-soc-cq93vc-objs := cq93vc.o
11snd-soc-cs4270-objs := cs4270.o 12snd-soc-cs4270-objs := cs4270.o
12snd-soc-cx20442-objs := cx20442.o 13snd-soc-cx20442-objs := cx20442.o
13snd-soc-da7210-objs := da7210.o 14snd-soc-da7210-objs := da7210.o
@@ -21,6 +22,7 @@ snd-soc-tlv320aic26-objs := tlv320aic26.o
21snd-soc-tlv320aic3x-objs := tlv320aic3x.o 22snd-soc-tlv320aic3x-objs := tlv320aic3x.o
22snd-soc-tlv320dac33-objs := tlv320dac33.o 23snd-soc-tlv320dac33-objs := tlv320dac33.o
23snd-soc-twl4030-objs := twl4030.o 24snd-soc-twl4030-objs := twl4030.o
25snd-soc-twl6040-objs := twl6040.o
24snd-soc-uda134x-objs := uda134x.o 26snd-soc-uda134x-objs := uda134x.o
25snd-soc-uda1380-objs := uda1380.o 27snd-soc-uda1380-objs := uda1380.o
26snd-soc-wm8350-objs := wm8350.o 28snd-soc-wm8350-objs := wm8350.o
@@ -59,10 +61,11 @@ snd-soc-wm-hubs-objs := wm_hubs.o
59snd-soc-max9877-objs := max9877.o 61snd-soc-max9877-objs := max9877.o
60snd-soc-tpa6130a2-objs := tpa6130a2.o 62snd-soc-tpa6130a2-objs := tpa6130a2.o
61snd-soc-wm2000-objs := wm2000.o 63snd-soc-wm2000-objs := wm2000.o
64snd-soc-wm9090-objs := wm9090.o
62 65
63obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 66obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
64obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 67obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
65obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o 68obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
66obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 69obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
67obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 70obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
68obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 71obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
@@ -70,6 +73,7 @@ obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
70obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 73obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
71obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 74obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
72obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 75obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
76obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
73obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 77obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
74obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 78obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
75obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 79obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
@@ -83,6 +87,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
83obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 87obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
84obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o 88obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
85obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 89obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
90obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
86obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 91obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
87obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 92obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
88obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 93obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
@@ -121,3 +126,4 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
121obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 126obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
122obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 127obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
123obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o 128obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
129obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 11b62dee842c..217538423225 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -278,7 +278,7 @@ static int ad1836_register(struct ad1836_priv *ad1836)
278 mutex_init(&codec->mutex); 278 mutex_init(&codec->mutex);
279 INIT_LIST_HEAD(&codec->dapm_widgets); 279 INIT_LIST_HEAD(&codec->dapm_widgets);
280 INIT_LIST_HEAD(&codec->dapm_paths); 280 INIT_LIST_HEAD(&codec->dapm_paths);
281 codec->private_data = ad1836; 281 snd_soc_codec_set_drvdata(codec, ad1836);
282 codec->reg_cache = ad1836->reg_cache; 282 codec->reg_cache = ad1836->reg_cache;
283 codec->reg_cache_size = AD1836_NUM_REGS; 283 codec->reg_cache_size = AD1836_NUM_REGS;
284 codec->name = "AD1836"; 284 codec->name = "AD1836";
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
deleted file mode 100644
index 240cd155b313..000000000000
--- a/sound/soc/codecs/ad1938.c
+++ /dev/null
@@ -1,522 +0,0 @@
1/*
2 * File: sound/soc/codecs/ad1938.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: June 04 2009
6 * Description: Driver for AD1938 sound chip
7 *
8 * Modified:
9 * Copyright 2009 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/slab.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/device.h>
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/pcm_params.h>
37#include <sound/initval.h>
38#include <sound/soc.h>
39#include <sound/tlv.h>
40#include <sound/soc-dapm.h>
41#include <linux/spi/spi.h>
42#include "ad1938.h"
43
44/* codec private data */
45struct ad1938_priv {
46 struct snd_soc_codec codec;
47 u8 reg_cache[AD1938_NUM_REGS];
48};
49
50/* ad1938 register cache & default register settings */
51static const u8 ad1938_reg[AD1938_NUM_REGS] = {
52 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
53};
54
55static struct snd_soc_codec *ad1938_codec;
56struct snd_soc_codec_device soc_codec_dev_ad1938;
57static int ad1938_register(struct ad1938_priv *ad1938);
58static void ad1938_unregister(struct ad1938_priv *ad1938);
59
60/*
61 * AD1938 volume/mute/de-emphasis etc. controls
62 */
63static const char *ad1938_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
64
65static const struct soc_enum ad1938_deemp_enum =
66 SOC_ENUM_SINGLE(AD1938_DAC_CTRL2, 1, 4, ad1938_deemp);
67
68static const struct snd_kcontrol_new ad1938_snd_controls[] = {
69 /* DAC volume control */
70 SOC_DOUBLE_R("DAC1 Volume", AD1938_DAC_L1_VOL,
71 AD1938_DAC_R1_VOL, 0, 0xFF, 1),
72 SOC_DOUBLE_R("DAC2 Volume", AD1938_DAC_L2_VOL,
73 AD1938_DAC_R2_VOL, 0, 0xFF, 1),
74 SOC_DOUBLE_R("DAC3 Volume", AD1938_DAC_L3_VOL,
75 AD1938_DAC_R3_VOL, 0, 0xFF, 1),
76 SOC_DOUBLE_R("DAC4 Volume", AD1938_DAC_L4_VOL,
77 AD1938_DAC_R4_VOL, 0, 0xFF, 1),
78
79 /* ADC switch control */
80 SOC_DOUBLE("ADC1 Switch", AD1938_ADC_CTRL0, AD1938_ADCL1_MUTE,
81 AD1938_ADCR1_MUTE, 1, 1),
82 SOC_DOUBLE("ADC2 Switch", AD1938_ADC_CTRL0, AD1938_ADCL2_MUTE,
83 AD1938_ADCR2_MUTE, 1, 1),
84
85 /* DAC switch control */
86 SOC_DOUBLE("DAC1 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL1_MUTE,
87 AD1938_DACR1_MUTE, 1, 1),
88 SOC_DOUBLE("DAC2 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL2_MUTE,
89 AD1938_DACR2_MUTE, 1, 1),
90 SOC_DOUBLE("DAC3 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL3_MUTE,
91 AD1938_DACR3_MUTE, 1, 1),
92 SOC_DOUBLE("DAC4 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL4_MUTE,
93 AD1938_DACR4_MUTE, 1, 1),
94
95 /* ADC high-pass filter */
96 SOC_SINGLE("ADC High Pass Filter Switch", AD1938_ADC_CTRL0,
97 AD1938_ADC_HIGHPASS_FILTER, 1, 0),
98
99 /* DAC de-emphasis */
100 SOC_ENUM("Playback Deemphasis", ad1938_deemp_enum),
101};
102
103static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
104 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1),
105 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
106 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD1938_PLL_CLK_CTRL0, 0, 1, NULL, 0),
107 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0),
108 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
109 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
110 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
111 SND_SOC_DAPM_OUTPUT("DAC4OUT"),
112 SND_SOC_DAPM_INPUT("ADC1IN"),
113 SND_SOC_DAPM_INPUT("ADC2IN"),
114};
115
116static const struct snd_soc_dapm_route audio_paths[] = {
117 { "DAC", NULL, "PLL_PWR" },
118 { "ADC", NULL, "PLL_PWR" },
119 { "DAC", NULL, "ADC_PWR" },
120 { "ADC", NULL, "ADC_PWR" },
121 { "DAC1OUT", "DAC1 Switch", "DAC" },
122 { "DAC2OUT", "DAC2 Switch", "DAC" },
123 { "DAC3OUT", "DAC3 Switch", "DAC" },
124 { "DAC4OUT", "DAC4 Switch", "DAC" },
125 { "ADC", "ADC1 Switch", "ADC1IN" },
126 { "ADC", "ADC2 Switch", "ADC2IN" },
127};
128
129/*
130 * DAI ops entries
131 */
132
133static int ad1938_mute(struct snd_soc_dai *dai, int mute)
134{
135 struct snd_soc_codec *codec = dai->codec;
136 int reg;
137
138 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
139 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg &
140 (~AD1938_DAC_MASTER_MUTE);
141 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
142
143 return 0;
144}
145
146static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
147 unsigned int rx_mask, int slots, int width)
148{
149 struct snd_soc_codec *codec = dai->codec;
150 int dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
151 int adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
152
153 dac_reg &= ~AD1938_DAC_CHAN_MASK;
154 adc_reg &= ~AD1938_ADC_CHAN_MASK;
155
156 switch (slots) {
157 case 2:
158 dac_reg |= AD1938_DAC_2_CHANNELS << AD1938_DAC_CHAN_SHFT;
159 adc_reg |= AD1938_ADC_2_CHANNELS << AD1938_ADC_CHAN_SHFT;
160 break;
161 case 4:
162 dac_reg |= AD1938_DAC_4_CHANNELS << AD1938_DAC_CHAN_SHFT;
163 adc_reg |= AD1938_ADC_4_CHANNELS << AD1938_ADC_CHAN_SHFT;
164 break;
165 case 8:
166 dac_reg |= AD1938_DAC_8_CHANNELS << AD1938_DAC_CHAN_SHFT;
167 adc_reg |= AD1938_ADC_8_CHANNELS << AD1938_ADC_CHAN_SHFT;
168 break;
169 case 16:
170 dac_reg |= AD1938_DAC_16_CHANNELS << AD1938_DAC_CHAN_SHFT;
171 adc_reg |= AD1938_ADC_16_CHANNELS << AD1938_ADC_CHAN_SHFT;
172 break;
173 default:
174 return -EINVAL;
175 }
176
177 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
178 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
179
180 return 0;
181}
182
183static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
184 unsigned int fmt)
185{
186 struct snd_soc_codec *codec = codec_dai->codec;
187 int adc_reg, dac_reg;
188
189 adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
190 dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
191
192 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
193 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
194 */
195 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
196 case SND_SOC_DAIFMT_I2S:
197 adc_reg &= ~AD1938_ADC_SERFMT_MASK;
198 adc_reg |= AD1938_ADC_SERFMT_TDM;
199 break;
200 case SND_SOC_DAIFMT_DSP_A:
201 adc_reg &= ~AD1938_ADC_SERFMT_MASK;
202 adc_reg |= AD1938_ADC_SERFMT_AUX;
203 break;
204 default:
205 return -EINVAL;
206 }
207
208 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
209 case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
210 adc_reg &= ~AD1938_ADC_LEFT_HIGH;
211 adc_reg &= ~AD1938_ADC_BCLK_INV;
212 dac_reg &= ~AD1938_DAC_LEFT_HIGH;
213 dac_reg &= ~AD1938_DAC_BCLK_INV;
214 break;
215 case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
216 adc_reg |= AD1938_ADC_LEFT_HIGH;
217 adc_reg &= ~AD1938_ADC_BCLK_INV;
218 dac_reg |= AD1938_DAC_LEFT_HIGH;
219 dac_reg &= ~AD1938_DAC_BCLK_INV;
220 break;
221 case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
222 adc_reg &= ~AD1938_ADC_LEFT_HIGH;
223 adc_reg |= AD1938_ADC_BCLK_INV;
224 dac_reg &= ~AD1938_DAC_LEFT_HIGH;
225 dac_reg |= AD1938_DAC_BCLK_INV;
226 break;
227
228 case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
229 adc_reg |= AD1938_ADC_LEFT_HIGH;
230 adc_reg |= AD1938_ADC_BCLK_INV;
231 dac_reg |= AD1938_DAC_LEFT_HIGH;
232 dac_reg |= AD1938_DAC_BCLK_INV;
233 break;
234 default:
235 return -EINVAL;
236 }
237
238 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
239 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
240 adc_reg |= AD1938_ADC_LCR_MASTER;
241 adc_reg |= AD1938_ADC_BCLK_MASTER;
242 dac_reg |= AD1938_DAC_LCR_MASTER;
243 dac_reg |= AD1938_DAC_BCLK_MASTER;
244 break;
245 case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */
246 adc_reg |= AD1938_ADC_LCR_MASTER;
247 adc_reg &= ~AD1938_ADC_BCLK_MASTER;
248 dac_reg |= AD1938_DAC_LCR_MASTER;
249 dac_reg &= ~AD1938_DAC_BCLK_MASTER;
250 break;
251 case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
252 adc_reg &= ~AD1938_ADC_LCR_MASTER;
253 adc_reg |= AD1938_ADC_BCLK_MASTER;
254 dac_reg &= ~AD1938_DAC_LCR_MASTER;
255 dac_reg |= AD1938_DAC_BCLK_MASTER;
256 break;
257 case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */
258 adc_reg &= ~AD1938_ADC_LCR_MASTER;
259 adc_reg &= ~AD1938_ADC_BCLK_MASTER;
260 dac_reg &= ~AD1938_DAC_LCR_MASTER;
261 dac_reg &= ~AD1938_DAC_BCLK_MASTER;
262 break;
263 default:
264 return -EINVAL;
265 }
266
267 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
268 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
269
270 return 0;
271}
272
273static int ad1938_hw_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai)
276{
277 int word_len = 0, reg = 0;
278
279 struct snd_soc_pcm_runtime *rtd = substream->private_data;
280 struct snd_soc_device *socdev = rtd->socdev;
281 struct snd_soc_codec *codec = socdev->card->codec;
282
283 /* bit size */
284 switch (params_format(params)) {
285 case SNDRV_PCM_FORMAT_S16_LE:
286 word_len = 3;
287 break;
288 case SNDRV_PCM_FORMAT_S20_3LE:
289 word_len = 1;
290 break;
291 case SNDRV_PCM_FORMAT_S24_LE:
292 case SNDRV_PCM_FORMAT_S32_LE:
293 word_len = 0;
294 break;
295 }
296
297 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
298 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len;
299 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
300
301 reg = snd_soc_read(codec, AD1938_ADC_CTRL1);
302 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len;
303 snd_soc_write(codec, AD1938_ADC_CTRL1, reg);
304
305 return 0;
306}
307
308static int __devinit ad1938_spi_probe(struct spi_device *spi)
309{
310 struct snd_soc_codec *codec;
311 struct ad1938_priv *ad1938;
312
313 ad1938 = kzalloc(sizeof(struct ad1938_priv), GFP_KERNEL);
314 if (ad1938 == NULL)
315 return -ENOMEM;
316
317 codec = &ad1938->codec;
318 codec->control_data = spi;
319 codec->dev = &spi->dev;
320
321 dev_set_drvdata(&spi->dev, ad1938);
322
323 return ad1938_register(ad1938);
324}
325
326static int __devexit ad1938_spi_remove(struct spi_device *spi)
327{
328 struct ad1938_priv *ad1938 = dev_get_drvdata(&spi->dev);
329
330 ad1938_unregister(ad1938);
331 return 0;
332}
333
334static struct spi_driver ad1938_spi_driver = {
335 .driver = {
336 .name = "ad1938",
337 .owner = THIS_MODULE,
338 },
339 .probe = ad1938_spi_probe,
340 .remove = __devexit_p(ad1938_spi_remove),
341};
342
343static struct snd_soc_dai_ops ad1938_dai_ops = {
344 .hw_params = ad1938_hw_params,
345 .digital_mute = ad1938_mute,
346 .set_tdm_slot = ad1938_set_tdm_slot,
347 .set_fmt = ad1938_set_dai_fmt,
348};
349
350/* codec DAI instance */
351struct snd_soc_dai ad1938_dai = {
352 .name = "AD1938",
353 .playback = {
354 .stream_name = "Playback",
355 .channels_min = 2,
356 .channels_max = 8,
357 .rates = SNDRV_PCM_RATE_48000,
358 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
359 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
360 },
361 .capture = {
362 .stream_name = "Capture",
363 .channels_min = 2,
364 .channels_max = 4,
365 .rates = SNDRV_PCM_RATE_48000,
366 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
367 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
368 },
369 .ops = &ad1938_dai_ops,
370};
371EXPORT_SYMBOL_GPL(ad1938_dai);
372
373static int ad1938_register(struct ad1938_priv *ad1938)
374{
375 int ret;
376 struct snd_soc_codec *codec = &ad1938->codec;
377
378 if (ad1938_codec) {
379 dev_err(codec->dev, "Another ad1938 is registered\n");
380 return -EINVAL;
381 }
382
383 mutex_init(&codec->mutex);
384 INIT_LIST_HEAD(&codec->dapm_widgets);
385 INIT_LIST_HEAD(&codec->dapm_paths);
386 codec->private_data = ad1938;
387 codec->reg_cache = ad1938->reg_cache;
388 codec->reg_cache_size = AD1938_NUM_REGS;
389 codec->name = "AD1938";
390 codec->owner = THIS_MODULE;
391 codec->dai = &ad1938_dai;
392 codec->num_dai = 1;
393 INIT_LIST_HEAD(&codec->dapm_widgets);
394 INIT_LIST_HEAD(&codec->dapm_paths);
395
396 ad1938_dai.dev = codec->dev;
397 ad1938_codec = codec;
398
399 memcpy(codec->reg_cache, ad1938_reg, AD1938_NUM_REGS);
400
401 ret = snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_SPI);
402 if (ret < 0) {
403 dev_err(codec->dev, "failed to set cache I/O: %d\n",
404 ret);
405 kfree(ad1938);
406 return ret;
407 }
408
409 /* default setting for ad1938 */
410
411 /* unmute dac channels */
412 snd_soc_write(codec, AD1938_DAC_CHNL_MUTE, 0x0);
413 /* de-emphasis: 48kHz, powedown dac */
414 snd_soc_write(codec, AD1938_DAC_CTRL2, 0x1A);
415 /* powerdown dac, dac in tdm mode */
416 snd_soc_write(codec, AD1938_DAC_CTRL0, 0x41);
417 /* high-pass filter enable */
418 snd_soc_write(codec, AD1938_ADC_CTRL0, 0x3);
419 /* sata delay=1, adc aux mode */
420 snd_soc_write(codec, AD1938_ADC_CTRL1, 0x43);
421 /* pll input: mclki/xi */
422 snd_soc_write(codec, AD1938_PLL_CLK_CTRL0, 0x9D);
423 snd_soc_write(codec, AD1938_PLL_CLK_CTRL1, 0x04);
424
425 ret = snd_soc_register_codec(codec);
426 if (ret != 0) {
427 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
428 kfree(ad1938);
429 return ret;
430 }
431
432 ret = snd_soc_register_dai(&ad1938_dai);
433 if (ret != 0) {
434 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
435 snd_soc_unregister_codec(codec);
436 kfree(ad1938);
437 return ret;
438 }
439
440 return 0;
441}
442
443static void ad1938_unregister(struct ad1938_priv *ad1938)
444{
445 snd_soc_unregister_dai(&ad1938_dai);
446 snd_soc_unregister_codec(&ad1938->codec);
447 kfree(ad1938);
448 ad1938_codec = NULL;
449}
450
451static int ad1938_probe(struct platform_device *pdev)
452{
453 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
454 struct snd_soc_codec *codec;
455 int ret = 0;
456
457 if (ad1938_codec == NULL) {
458 dev_err(&pdev->dev, "Codec device not registered\n");
459 return -ENODEV;
460 }
461
462 socdev->card->codec = ad1938_codec;
463 codec = ad1938_codec;
464
465 /* register pcms */
466 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
467 if (ret < 0) {
468 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
469 goto pcm_err;
470 }
471
472 snd_soc_add_controls(codec, ad1938_snd_controls,
473 ARRAY_SIZE(ad1938_snd_controls));
474 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets,
475 ARRAY_SIZE(ad1938_dapm_widgets));
476 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
477
478
479pcm_err:
480 return ret;
481}
482
483/* power down chip */
484static int ad1938_remove(struct platform_device *pdev)
485{
486 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
487
488 snd_soc_free_pcms(socdev);
489 snd_soc_dapm_free(socdev);
490
491 return 0;
492}
493
494struct snd_soc_codec_device soc_codec_dev_ad1938 = {
495 .probe = ad1938_probe,
496 .remove = ad1938_remove,
497};
498EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938);
499
500static int __init ad1938_init(void)
501{
502 int ret;
503
504 ret = spi_register_driver(&ad1938_spi_driver);
505 if (ret != 0) {
506 printk(KERN_ERR "Failed to register ad1938 SPI driver: %d\n",
507 ret);
508 }
509
510 return ret;
511}
512module_init(ad1938_init);
513
514static void __exit ad1938_exit(void)
515{
516 spi_unregister_driver(&ad1938_spi_driver);
517}
518module_exit(ad1938_exit);
519
520MODULE_DESCRIPTION("ASoC ad1938 driver");
521MODULE_AUTHOR("Barry Song ");
522MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad1938.h b/sound/soc/codecs/ad1938.h
deleted file mode 100644
index fe3c48cd2d5b..000000000000
--- a/sound/soc/codecs/ad1938.h
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * File: sound/soc/codecs/ad1836.h
3 * Based on:
4 * Author: Barry Song <Barry.Song@analog.com>
5 *
6 * Created: May 25, 2009
7 * Description: definitions for AD1938 registers
8 *
9 * Modified:
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#ifndef __AD1938_H__
30#define __AD1938_H__
31
32#define AD1938_PLL_CLK_CTRL0 0
33#define AD1938_PLL_POWERDOWN 0x01
34#define AD1938_PLL_CLK_CTRL1 1
35#define AD1938_DAC_CTRL0 2
36#define AD1938_DAC_POWERDOWN 0x01
37#define AD1938_DAC_SERFMT_MASK 0xC0
38#define AD1938_DAC_SERFMT_STEREO (0 << 6)
39#define AD1938_DAC_SERFMT_TDM (1 << 6)
40#define AD1938_DAC_CTRL1 3
41#define AD1938_DAC_2_CHANNELS 0
42#define AD1938_DAC_4_CHANNELS 1
43#define AD1938_DAC_8_CHANNELS 2
44#define AD1938_DAC_16_CHANNELS 3
45#define AD1938_DAC_CHAN_SHFT 1
46#define AD1938_DAC_CHAN_MASK (3 << AD1938_DAC_CHAN_SHFT)
47#define AD1938_DAC_LCR_MASTER (1 << 4)
48#define AD1938_DAC_BCLK_MASTER (1 << 5)
49#define AD1938_DAC_LEFT_HIGH (1 << 3)
50#define AD1938_DAC_BCLK_INV (1 << 7)
51#define AD1938_DAC_CTRL2 4
52#define AD1938_DAC_WORD_LEN_MASK 0xC
53#define AD1938_DAC_MASTER_MUTE 1
54#define AD1938_DAC_CHNL_MUTE 5
55#define AD1938_DACL1_MUTE 0
56#define AD1938_DACR1_MUTE 1
57#define AD1938_DACL2_MUTE 2
58#define AD1938_DACR2_MUTE 3
59#define AD1938_DACL3_MUTE 4
60#define AD1938_DACR3_MUTE 5
61#define AD1938_DACL4_MUTE 6
62#define AD1938_DACR4_MUTE 7
63#define AD1938_DAC_L1_VOL 6
64#define AD1938_DAC_R1_VOL 7
65#define AD1938_DAC_L2_VOL 8
66#define AD1938_DAC_R2_VOL 9
67#define AD1938_DAC_L3_VOL 10
68#define AD1938_DAC_R3_VOL 11
69#define AD1938_DAC_L4_VOL 12
70#define AD1938_DAC_R4_VOL 13
71#define AD1938_ADC_CTRL0 14
72#define AD1938_ADC_POWERDOWN 0x01
73#define AD1938_ADC_HIGHPASS_FILTER 1
74#define AD1938_ADCL1_MUTE 2
75#define AD1938_ADCR1_MUTE 3
76#define AD1938_ADCL2_MUTE 4
77#define AD1938_ADCR2_MUTE 5
78#define AD1938_ADC_CTRL1 15
79#define AD1938_ADC_SERFMT_MASK 0x60
80#define AD1938_ADC_SERFMT_STEREO (0 << 5)
81#define AD1938_ADC_SERFMT_TDM (1 << 2)
82#define AD1938_ADC_SERFMT_AUX (2 << 5)
83#define AD1938_ADC_WORD_LEN_MASK 0x3
84#define AD1938_ADC_CTRL2 16
85#define AD1938_ADC_2_CHANNELS 0
86#define AD1938_ADC_4_CHANNELS 1
87#define AD1938_ADC_8_CHANNELS 2
88#define AD1938_ADC_16_CHANNELS 3
89#define AD1938_ADC_CHAN_SHFT 4
90#define AD1938_ADC_CHAN_MASK (3 << AD1938_ADC_CHAN_SHFT)
91#define AD1938_ADC_LCR_MASTER (1 << 3)
92#define AD1938_ADC_BCLK_MASTER (1 << 6)
93#define AD1938_ADC_LEFT_HIGH (1 << 2)
94#define AD1938_ADC_BCLK_INV (1 << 1)
95
96#define AD1938_NUM_REGS 17
97
98extern struct snd_soc_dai ad1938_dai;
99extern struct snd_soc_codec_device soc_codec_dev_ad1938;
100#endif
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
new file mode 100644
index 000000000000..c8ca1142b2f4
--- /dev/null
+++ b/sound/soc/codecs/ad193x.c
@@ -0,0 +1,547 @@
1/*
2 * AD193X Audio Codec driver supporting AD1936/7/8/9
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/kernel.h>
12#include <linux/device.h>
13#include <linux/i2c.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h>
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/pcm_params.h>
19#include <sound/initval.h>
20#include <sound/soc.h>
21#include <sound/tlv.h>
22#include <sound/soc-dapm.h>
23#include "ad193x.h"
24
25/* codec private data */
26struct ad193x_priv {
27 struct snd_soc_codec codec;
28 u8 reg_cache[AD193X_NUM_REGS];
29};
30
31/* ad193x register cache & default register settings */
32static const u8 ad193x_reg[AD193X_NUM_REGS] = {
33 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
34};
35
36static struct snd_soc_codec *ad193x_codec;
37struct snd_soc_codec_device soc_codec_dev_ad193x;
38
39/*
40 * AD193X volume/mute/de-emphasis etc. controls
41 */
42static const char *ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
43
44static const struct soc_enum ad193x_deemp_enum =
45 SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp);
46
47static const struct snd_kcontrol_new ad193x_snd_controls[] = {
48 /* DAC volume control */
49 SOC_DOUBLE_R("DAC1 Volume", AD193X_DAC_L1_VOL,
50 AD193X_DAC_R1_VOL, 0, 0xFF, 1),
51 SOC_DOUBLE_R("DAC2 Volume", AD193X_DAC_L2_VOL,
52 AD193X_DAC_R2_VOL, 0, 0xFF, 1),
53 SOC_DOUBLE_R("DAC3 Volume", AD193X_DAC_L3_VOL,
54 AD193X_DAC_R3_VOL, 0, 0xFF, 1),
55 SOC_DOUBLE_R("DAC4 Volume", AD193X_DAC_L4_VOL,
56 AD193X_DAC_R4_VOL, 0, 0xFF, 1),
57
58 /* ADC switch control */
59 SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
60 AD193X_ADCR1_MUTE, 1, 1),
61 SOC_DOUBLE("ADC2 Switch", AD193X_ADC_CTRL0, AD193X_ADCL2_MUTE,
62 AD193X_ADCR2_MUTE, 1, 1),
63
64 /* DAC switch control */
65 SOC_DOUBLE("DAC1 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL1_MUTE,
66 AD193X_DACR1_MUTE, 1, 1),
67 SOC_DOUBLE("DAC2 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL2_MUTE,
68 AD193X_DACR2_MUTE, 1, 1),
69 SOC_DOUBLE("DAC3 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL3_MUTE,
70 AD193X_DACR3_MUTE, 1, 1),
71 SOC_DOUBLE("DAC4 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL4_MUTE,
72 AD193X_DACR4_MUTE, 1, 1),
73
74 /* ADC high-pass filter */
75 SOC_SINGLE("ADC High Pass Filter Switch", AD193X_ADC_CTRL0,
76 AD193X_ADC_HIGHPASS_FILTER, 1, 0),
77
78 /* DAC de-emphasis */
79 SOC_ENUM("Playback Deemphasis", ad193x_deemp_enum),
80};
81
82static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = {
83 SND_SOC_DAPM_DAC("DAC", "Playback", AD193X_DAC_CTRL0, 0, 1),
84 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
85 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0),
86 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
87 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
88 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
89 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
90 SND_SOC_DAPM_OUTPUT("DAC4OUT"),
91 SND_SOC_DAPM_INPUT("ADC1IN"),
92 SND_SOC_DAPM_INPUT("ADC2IN"),
93};
94
95static const struct snd_soc_dapm_route audio_paths[] = {
96 { "DAC", NULL, "PLL_PWR" },
97 { "ADC", NULL, "PLL_PWR" },
98 { "DAC", NULL, "ADC_PWR" },
99 { "ADC", NULL, "ADC_PWR" },
100 { "DAC1OUT", "DAC1 Switch", "DAC" },
101 { "DAC2OUT", "DAC2 Switch", "DAC" },
102 { "DAC3OUT", "DAC3 Switch", "DAC" },
103 { "DAC4OUT", "DAC4 Switch", "DAC" },
104 { "ADC", "ADC1 Switch", "ADC1IN" },
105 { "ADC", "ADC2 Switch", "ADC2IN" },
106};
107
108/*
109 * DAI ops entries
110 */
111
112static int ad193x_mute(struct snd_soc_dai *dai, int mute)
113{
114 struct snd_soc_codec *codec = dai->codec;
115 int reg;
116
117 reg = snd_soc_read(codec, AD193X_DAC_CTRL2);
118 reg = (mute > 0) ? reg | AD193X_DAC_MASTER_MUTE : reg &
119 (~AD193X_DAC_MASTER_MUTE);
120 snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
121
122 return 0;
123}
124
125static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
126 unsigned int rx_mask, int slots, int width)
127{
128 struct snd_soc_codec *codec = dai->codec;
129 int dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1);
130 int adc_reg = snd_soc_read(codec, AD193X_ADC_CTRL2);
131
132 dac_reg &= ~AD193X_DAC_CHAN_MASK;
133 adc_reg &= ~AD193X_ADC_CHAN_MASK;
134
135 switch (slots) {
136 case 2:
137 dac_reg |= AD193X_DAC_2_CHANNELS << AD193X_DAC_CHAN_SHFT;
138 adc_reg |= AD193X_ADC_2_CHANNELS << AD193X_ADC_CHAN_SHFT;
139 break;
140 case 4:
141 dac_reg |= AD193X_DAC_4_CHANNELS << AD193X_DAC_CHAN_SHFT;
142 adc_reg |= AD193X_ADC_4_CHANNELS << AD193X_ADC_CHAN_SHFT;
143 break;
144 case 8:
145 dac_reg |= AD193X_DAC_8_CHANNELS << AD193X_DAC_CHAN_SHFT;
146 adc_reg |= AD193X_ADC_8_CHANNELS << AD193X_ADC_CHAN_SHFT;
147 break;
148 case 16:
149 dac_reg |= AD193X_DAC_16_CHANNELS << AD193X_DAC_CHAN_SHFT;
150 adc_reg |= AD193X_ADC_16_CHANNELS << AD193X_ADC_CHAN_SHFT;
151 break;
152 default:
153 return -EINVAL;
154 }
155
156 snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg);
157 snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg);
158
159 return 0;
160}
161
162static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
163 unsigned int fmt)
164{
165 struct snd_soc_codec *codec = codec_dai->codec;
166 int adc_reg1, adc_reg2, dac_reg;
167
168 adc_reg1 = snd_soc_read(codec, AD193X_ADC_CTRL1);
169 adc_reg2 = snd_soc_read(codec, AD193X_ADC_CTRL2);
170 dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1);
171
172 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
173 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
174 */
175 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
176 case SND_SOC_DAIFMT_I2S:
177 adc_reg1 &= ~AD193X_ADC_SERFMT_MASK;
178 adc_reg1 |= AD193X_ADC_SERFMT_TDM;
179 break;
180 case SND_SOC_DAIFMT_DSP_A:
181 adc_reg1 &= ~AD193X_ADC_SERFMT_MASK;
182 adc_reg1 |= AD193X_ADC_SERFMT_AUX;
183 break;
184 default:
185 return -EINVAL;
186 }
187
188 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
189 case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
190 adc_reg2 &= ~AD193X_ADC_LEFT_HIGH;
191 adc_reg2 &= ~AD193X_ADC_BCLK_INV;
192 dac_reg &= ~AD193X_DAC_LEFT_HIGH;
193 dac_reg &= ~AD193X_DAC_BCLK_INV;
194 break;
195 case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
196 adc_reg2 |= AD193X_ADC_LEFT_HIGH;
197 adc_reg2 &= ~AD193X_ADC_BCLK_INV;
198 dac_reg |= AD193X_DAC_LEFT_HIGH;
199 dac_reg &= ~AD193X_DAC_BCLK_INV;
200 break;
201 case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
202 adc_reg2 &= ~AD193X_ADC_LEFT_HIGH;
203 adc_reg2 |= AD193X_ADC_BCLK_INV;
204 dac_reg &= ~AD193X_DAC_LEFT_HIGH;
205 dac_reg |= AD193X_DAC_BCLK_INV;
206 break;
207
208 case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
209 adc_reg2 |= AD193X_ADC_LEFT_HIGH;
210 adc_reg2 |= AD193X_ADC_BCLK_INV;
211 dac_reg |= AD193X_DAC_LEFT_HIGH;
212 dac_reg |= AD193X_DAC_BCLK_INV;
213 break;
214 default:
215 return -EINVAL;
216 }
217
218 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
219 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
220 adc_reg2 |= AD193X_ADC_LCR_MASTER;
221 adc_reg2 |= AD193X_ADC_BCLK_MASTER;
222 dac_reg |= AD193X_DAC_LCR_MASTER;
223 dac_reg |= AD193X_DAC_BCLK_MASTER;
224 break;
225 case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */
226 adc_reg2 |= AD193X_ADC_LCR_MASTER;
227 adc_reg2 &= ~AD193X_ADC_BCLK_MASTER;
228 dac_reg |= AD193X_DAC_LCR_MASTER;
229 dac_reg &= ~AD193X_DAC_BCLK_MASTER;
230 break;
231 case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
232 adc_reg2 &= ~AD193X_ADC_LCR_MASTER;
233 adc_reg2 |= AD193X_ADC_BCLK_MASTER;
234 dac_reg &= ~AD193X_DAC_LCR_MASTER;
235 dac_reg |= AD193X_DAC_BCLK_MASTER;
236 break;
237 case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */
238 adc_reg2 &= ~AD193X_ADC_LCR_MASTER;
239 adc_reg2 &= ~AD193X_ADC_BCLK_MASTER;
240 dac_reg &= ~AD193X_DAC_LCR_MASTER;
241 dac_reg &= ~AD193X_DAC_BCLK_MASTER;
242 break;
243 default:
244 return -EINVAL;
245 }
246
247 snd_soc_write(codec, AD193X_ADC_CTRL1, adc_reg1);
248 snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg2);
249 snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg);
250
251 return 0;
252}
253
254static int ad193x_hw_params(struct snd_pcm_substream *substream,
255 struct snd_pcm_hw_params *params,
256 struct snd_soc_dai *dai)
257{
258 int word_len = 0, reg = 0;
259
260 struct snd_soc_pcm_runtime *rtd = substream->private_data;
261 struct snd_soc_device *socdev = rtd->socdev;
262 struct snd_soc_codec *codec = socdev->card->codec;
263
264 /* bit size */
265 switch (params_format(params)) {
266 case SNDRV_PCM_FORMAT_S16_LE:
267 word_len = 3;
268 break;
269 case SNDRV_PCM_FORMAT_S20_3LE:
270 word_len = 1;
271 break;
272 case SNDRV_PCM_FORMAT_S24_LE:
273 case SNDRV_PCM_FORMAT_S32_LE:
274 word_len = 0;
275 break;
276 }
277
278 reg = snd_soc_read(codec, AD193X_DAC_CTRL2);
279 reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | word_len;
280 snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
281
282 reg = snd_soc_read(codec, AD193X_ADC_CTRL1);
283 reg = (reg & (~AD193X_ADC_WORD_LEN_MASK)) | word_len;
284 snd_soc_write(codec, AD193X_ADC_CTRL1, reg);
285
286 return 0;
287}
288
289static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
290{
291 struct snd_soc_codec *codec;
292 struct ad193x_priv *ad193x;
293 int ret;
294
295 if (ad193x_codec) {
296 dev_err(dev, "Another ad193x is registered\n");
297 return -EINVAL;
298 }
299
300 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
301 if (ad193x == NULL)
302 return -ENOMEM;
303
304 dev_set_drvdata(dev, ad193x);
305
306 codec = &ad193x->codec;
307 mutex_init(&codec->mutex);
308 codec->control_data = ctrl_data;
309 codec->dev = dev;
310 snd_soc_codec_set_drvdata(codec, ad193x);
311 codec->reg_cache = ad193x->reg_cache;
312 codec->reg_cache_size = AD193X_NUM_REGS;
313 codec->name = "AD193X";
314 codec->owner = THIS_MODULE;
315 codec->dai = &ad193x_dai;
316 codec->num_dai = 1;
317 INIT_LIST_HEAD(&codec->dapm_widgets);
318 INIT_LIST_HEAD(&codec->dapm_paths);
319
320 ad193x_dai.dev = codec->dev;
321 ad193x_codec = codec;
322
323 memcpy(codec->reg_cache, ad193x_reg, AD193X_NUM_REGS);
324
325 if (bus_type == SND_SOC_I2C)
326 ret = snd_soc_codec_set_cache_io(codec, 8, 8, bus_type);
327 else
328 ret = snd_soc_codec_set_cache_io(codec, 16, 8, bus_type);
329 if (ret < 0) {
330 dev_err(codec->dev, "failed to set cache I/O: %d\n",
331 ret);
332 kfree(ad193x);
333 return ret;
334 }
335
336 /* default setting for ad193x */
337
338 /* unmute dac channels */
339 snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
340 /* de-emphasis: 48kHz, powedown dac */
341 snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
342 /* powerdown dac, dac in tdm mode */
343 snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
344 /* high-pass filter enable */
345 snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
346 /* sata delay=1, adc aux mode */
347 snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
348 /* pll input: mclki/xi */
349 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
350 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
351
352 ret = snd_soc_register_codec(codec);
353 if (ret != 0) {
354 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
355 kfree(ad193x);
356 return ret;
357 }
358
359 ret = snd_soc_register_dai(&ad193x_dai);
360 if (ret != 0) {
361 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
362 snd_soc_unregister_codec(codec);
363 kfree(ad193x);
364 return ret;
365 }
366
367 return 0;
368}
369
370static int ad193x_bus_remove(struct device *dev)
371{
372 struct ad193x_priv *ad193x = dev_get_drvdata(dev);
373
374 snd_soc_unregister_dai(&ad193x_dai);
375 snd_soc_unregister_codec(&ad193x->codec);
376 kfree(ad193x);
377 ad193x_codec = NULL;
378
379 return 0;
380}
381
382static struct snd_soc_dai_ops ad193x_dai_ops = {
383 .hw_params = ad193x_hw_params,
384 .digital_mute = ad193x_mute,
385 .set_tdm_slot = ad193x_set_tdm_slot,
386 .set_fmt = ad193x_set_dai_fmt,
387};
388
389/* codec DAI instance */
390struct snd_soc_dai ad193x_dai = {
391 .name = "AD193X",
392 .playback = {
393 .stream_name = "Playback",
394 .channels_min = 2,
395 .channels_max = 8,
396 .rates = SNDRV_PCM_RATE_48000,
397 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
398 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
399 },
400 .capture = {
401 .stream_name = "Capture",
402 .channels_min = 2,
403 .channels_max = 4,
404 .rates = SNDRV_PCM_RATE_48000,
405 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
406 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
407 },
408 .ops = &ad193x_dai_ops,
409};
410EXPORT_SYMBOL_GPL(ad193x_dai);
411
412static int ad193x_probe(struct platform_device *pdev)
413{
414 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
415 struct snd_soc_codec *codec;
416 int ret = 0;
417
418 if (ad193x_codec == NULL) {
419 dev_err(&pdev->dev, "Codec device not registered\n");
420 return -ENODEV;
421 }
422
423 socdev->card->codec = ad193x_codec;
424 codec = ad193x_codec;
425
426 /* register pcms */
427 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
428 if (ret < 0) {
429 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
430 goto pcm_err;
431 }
432
433 snd_soc_add_controls(codec, ad193x_snd_controls,
434 ARRAY_SIZE(ad193x_snd_controls));
435 snd_soc_dapm_new_controls(codec, ad193x_dapm_widgets,
436 ARRAY_SIZE(ad193x_dapm_widgets));
437 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
438
439pcm_err:
440 return ret;
441}
442
443/* power down chip */
444static int ad193x_remove(struct platform_device *pdev)
445{
446 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
447
448 snd_soc_free_pcms(socdev);
449 snd_soc_dapm_free(socdev);
450
451 return 0;
452}
453
454struct snd_soc_codec_device soc_codec_dev_ad193x = {
455 .probe = ad193x_probe,
456 .remove = ad193x_remove,
457};
458EXPORT_SYMBOL_GPL(soc_codec_dev_ad193x);
459
460#if defined(CONFIG_SPI_MASTER)
461static int __devinit ad193x_spi_probe(struct spi_device *spi)
462{
463 return ad193x_bus_probe(&spi->dev, spi, SND_SOC_SPI);
464}
465
466static int __devexit ad193x_spi_remove(struct spi_device *spi)
467{
468 return ad193x_bus_remove(&spi->dev);
469}
470
471static struct spi_driver ad193x_spi_driver = {
472 .driver = {
473 .name = "ad193x",
474 .owner = THIS_MODULE,
475 },
476 .probe = ad193x_spi_probe,
477 .remove = __devexit_p(ad193x_spi_remove),
478};
479#endif
480
481#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
482static const struct i2c_device_id ad193x_id[] = {
483 { "ad1936", 0 },
484 { "ad1937", 0 },
485 { }
486};
487MODULE_DEVICE_TABLE(i2c, ad193x_id);
488
489static int __devinit ad193x_i2c_probe(struct i2c_client *client,
490 const struct i2c_device_id *id)
491{
492 return ad193x_bus_probe(&client->dev, client, SND_SOC_I2C);
493}
494
495static int __devexit ad193x_i2c_remove(struct i2c_client *client)
496{
497 return ad193x_bus_remove(&client->dev);
498}
499
500static struct i2c_driver ad193x_i2c_driver = {
501 .driver = {
502 .name = "ad193x",
503 },
504 .probe = ad193x_i2c_probe,
505 .remove = __devexit_p(ad193x_i2c_remove),
506 .id_table = ad193x_id,
507};
508#endif
509
510static int __init ad193x_modinit(void)
511{
512 int ret;
513
514#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
515 ret = i2c_add_driver(&ad193x_i2c_driver);
516 if (ret != 0) {
517 printk(KERN_ERR "Failed to register AD193X I2C driver: %d\n",
518 ret);
519 }
520#endif
521
522#if defined(CONFIG_SPI_MASTER)
523 ret = spi_register_driver(&ad193x_spi_driver);
524 if (ret != 0) {
525 printk(KERN_ERR "Failed to register AD193X SPI driver: %d\n",
526 ret);
527 }
528#endif
529 return ret;
530}
531module_init(ad193x_modinit);
532
533static void __exit ad193x_modexit(void)
534{
535#if defined(CONFIG_SPI_MASTER)
536 spi_unregister_driver(&ad193x_spi_driver);
537#endif
538
539#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
540 i2c_del_driver(&ad193x_i2c_driver);
541#endif
542}
543module_exit(ad193x_modexit);
544
545MODULE_DESCRIPTION("ASoC ad193x driver");
546MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
547MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
new file mode 100644
index 000000000000..a03c880d52f9
--- /dev/null
+++ b/sound/soc/codecs/ad193x.h
@@ -0,0 +1,81 @@
1/*
2 * AD193X Audio Codec driver
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#ifndef __AD193X_H__
10#define __AD193X_H__
11
12#define AD193X_PLL_CLK_CTRL0 0x800
13#define AD193X_PLL_POWERDOWN 0x01
14#define AD193X_PLL_CLK_CTRL1 0x801
15#define AD193X_DAC_CTRL0 0x802
16#define AD193X_DAC_POWERDOWN 0x01
17#define AD193X_DAC_SERFMT_MASK 0xC0
18#define AD193X_DAC_SERFMT_STEREO (0 << 6)
19#define AD193X_DAC_SERFMT_TDM (1 << 6)
20#define AD193X_DAC_CTRL1 0x803
21#define AD193X_DAC_2_CHANNELS 0
22#define AD193X_DAC_4_CHANNELS 1
23#define AD193X_DAC_8_CHANNELS 2
24#define AD193X_DAC_16_CHANNELS 3
25#define AD193X_DAC_CHAN_SHFT 1
26#define AD193X_DAC_CHAN_MASK (3 << AD193X_DAC_CHAN_SHFT)
27#define AD193X_DAC_LCR_MASTER (1 << 4)
28#define AD193X_DAC_BCLK_MASTER (1 << 5)
29#define AD193X_DAC_LEFT_HIGH (1 << 3)
30#define AD193X_DAC_BCLK_INV (1 << 7)
31#define AD193X_DAC_CTRL2 0x804
32#define AD193X_DAC_WORD_LEN_MASK 0xC
33#define AD193X_DAC_MASTER_MUTE 1
34#define AD193X_DAC_CHNL_MUTE 0x805
35#define AD193X_DACL1_MUTE 0
36#define AD193X_DACR1_MUTE 1
37#define AD193X_DACL2_MUTE 2
38#define AD193X_DACR2_MUTE 3
39#define AD193X_DACL3_MUTE 4
40#define AD193X_DACR3_MUTE 5
41#define AD193X_DACL4_MUTE 6
42#define AD193X_DACR4_MUTE 7
43#define AD193X_DAC_L1_VOL 0x806
44#define AD193X_DAC_R1_VOL 0x807
45#define AD193X_DAC_L2_VOL 0x808
46#define AD193X_DAC_R2_VOL 0x809
47#define AD193X_DAC_L3_VOL 0x80a
48#define AD193X_DAC_R3_VOL 0x80b
49#define AD193X_DAC_L4_VOL 0x80c
50#define AD193X_DAC_R4_VOL 0x80d
51#define AD193X_ADC_CTRL0 0x80e
52#define AD193X_ADC_POWERDOWN 0x01
53#define AD193X_ADC_HIGHPASS_FILTER 1
54#define AD193X_ADCL1_MUTE 2
55#define AD193X_ADCR1_MUTE 3
56#define AD193X_ADCL2_MUTE 4
57#define AD193X_ADCR2_MUTE 5
58#define AD193X_ADC_CTRL1 0x80f
59#define AD193X_ADC_SERFMT_MASK 0x60
60#define AD193X_ADC_SERFMT_STEREO (0 << 5)
61#define AD193X_ADC_SERFMT_TDM (1 << 2)
62#define AD193X_ADC_SERFMT_AUX (2 << 5)
63#define AD193X_ADC_WORD_LEN_MASK 0x3
64#define AD193X_ADC_CTRL2 0x810
65#define AD193X_ADC_2_CHANNELS 0
66#define AD193X_ADC_4_CHANNELS 1
67#define AD193X_ADC_8_CHANNELS 2
68#define AD193X_ADC_16_CHANNELS 3
69#define AD193X_ADC_CHAN_SHFT 4
70#define AD193X_ADC_CHAN_MASK (3 << AD193X_ADC_CHAN_SHFT)
71#define AD193X_ADC_LCR_MASTER (1 << 3)
72#define AD193X_ADC_BCLK_MASTER (1 << 6)
73#define AD193X_ADC_LEFT_HIGH (1 << 2)
74#define AD193X_ADC_BCLK_INV (1 << 1)
75
76#define AD193X_NUM_REGS 17
77
78extern struct snd_soc_dai ad193x_dai;
79extern struct snd_soc_codec_device soc_codec_dev_ad193x;
80
81#endif
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index bdeb10dfd887..192aebda3029 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -222,7 +222,7 @@ static int ak4104_spi_probe(struct spi_device *spi)
222 codec->owner = THIS_MODULE; 222 codec->owner = THIS_MODULE;
223 codec->dai = &ak4104_dai; 223 codec->dai = &ak4104_dai;
224 codec->num_dai = 1; 224 codec->num_dai = 1;
225 codec->private_data = ak4104; 225 snd_soc_codec_set_drvdata(codec, ak4104);
226 codec->control_data = spi; 226 codec->control_data = spi;
227 codec->reg_cache = ak4104->reg_cache; 227 codec->reg_cache = ak4104->reg_cache;
228 codec->reg_cache_size = AK4104_NUM_REGS; 228 codec->reg_cache_size = AK4104_NUM_REGS;
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 352d1d08dbd9..d4253675b2d3 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -302,7 +302,7 @@ static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
302 int clk_id, unsigned int freq, int dir) 302 int clk_id, unsigned int freq, int dir)
303{ 303{
304 struct snd_soc_codec *codec = codec_dai->codec; 304 struct snd_soc_codec *codec = codec_dai->codec;
305 struct ak4535_priv *ak4535 = codec->private_data; 305 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
306 306
307 ak4535->sysclk = freq; 307 ak4535->sysclk = freq;
308 return 0; 308 return 0;
@@ -315,7 +315,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
315 struct snd_soc_pcm_runtime *rtd = substream->private_data; 315 struct snd_soc_pcm_runtime *rtd = substream->private_data;
316 struct snd_soc_device *socdev = rtd->socdev; 316 struct snd_soc_device *socdev = rtd->socdev;
317 struct snd_soc_codec *codec = socdev->card->codec; 317 struct snd_soc_codec *codec = socdev->card->codec;
318 struct ak4535_priv *ak4535 = codec->private_data; 318 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
319 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); 319 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5);
320 int rate = params_rate(params), fs = 256; 320 int rate = params_rate(params), fs = 256;
321 321
@@ -446,7 +446,6 @@ static int ak4535_resume(struct platform_device *pdev)
446 struct snd_soc_codec *codec = socdev->card->codec; 446 struct snd_soc_codec *codec = socdev->card->codec;
447 ak4535_sync(codec); 447 ak4535_sync(codec);
448 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 448 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
449 ak4535_set_bias_level(codec, codec->suspend_bias_level);
450 return 0; 449 return 0;
451} 450}
452 451
@@ -600,7 +599,7 @@ static int ak4535_probe(struct platform_device *pdev)
600 return -ENOMEM; 599 return -ENOMEM;
601 } 600 }
602 601
603 codec->private_data = ak4535; 602 snd_soc_codec_set_drvdata(codec, ak4535);
604 socdev->card->codec = codec; 603 socdev->card->codec = codec;
605 mutex_init(&codec->mutex); 604 mutex_init(&codec->mutex);
606 INIT_LIST_HEAD(&codec->dapm_widgets); 605 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -617,7 +616,7 @@ static int ak4535_probe(struct platform_device *pdev)
617#endif 616#endif
618 617
619 if (ret != 0) { 618 if (ret != 0) {
620 kfree(codec->private_data); 619 kfree(snd_soc_codec_get_drvdata(codec));
621 kfree(codec); 620 kfree(codec);
622 } 621 }
623 return ret; 622 return ret;
@@ -639,7 +638,7 @@ static int ak4535_remove(struct platform_device *pdev)
639 i2c_unregister_device(codec->control_data); 638 i2c_unregister_device(codec->control_data);
640 i2c_del_driver(&ak4535_i2c_driver); 639 i2c_del_driver(&ak4535_i2c_driver);
641#endif 640#endif
642 kfree(codec->private_data); 641 kfree(snd_soc_codec_get_drvdata(codec));
643 kfree(codec); 642 kfree(codec);
644 643
645 return 0; 644 return 0;
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 729859cf6ca8..7528a54102b5 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -81,12 +81,39 @@
81 81
82#define AK4642_CACHEREGNUM 0x25 82#define AK4642_CACHEREGNUM 0x25
83 83
84/* PW_MGMT2 */
85#define HPMTN (1 << 6)
86#define PMHPL (1 << 5)
87#define PMHPR (1 << 4)
88#define MS (1 << 3) /* master/slave select */
89#define MCKO (1 << 1)
90#define PMPLL (1 << 0)
91
92#define PMHP_MASK (PMHPL | PMHPR)
93#define PMHP PMHP_MASK
94
95/* MD_CTL1 */
96#define PLL3 (1 << 7)
97#define PLL2 (1 << 6)
98#define PLL1 (1 << 5)
99#define PLL0 (1 << 4)
100#define PLL_MASK (PLL3 | PLL2 | PLL1 | PLL0)
101
102#define BCKO_MASK (1 << 3)
103#define BCKO_64 BCKO_MASK
104
105/* MD_CTL2 */
106#define FS0 (1 << 0)
107#define FS1 (1 << 1)
108#define FS2 (1 << 2)
109#define FS3 (1 << 5)
110#define FS_MASK (FS0 | FS1 | FS2 | FS3)
111
84struct snd_soc_codec_device soc_codec_dev_ak4642; 112struct snd_soc_codec_device soc_codec_dev_ak4642;
85 113
86/* codec private data */ 114/* codec private data */
87struct ak4642_priv { 115struct ak4642_priv {
88 struct snd_soc_codec codec; 116 struct snd_soc_codec codec;
89 unsigned int sysclk;
90}; 117};
91 118
92static struct snd_soc_codec *ak4642_codec; 119static struct snd_soc_codec *ak4642_codec;
@@ -177,17 +204,12 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
177 * 204 *
178 * PLL, Master Mode 205 * PLL, Master Mode
179 * Audio I/F Format :MSB justified (ADC & DAC) 206 * Audio I/F Format :MSB justified (ADC & DAC)
180 * Sampling Frequency: 44.1kHz 207 * Digital Volume: -8dB
181 * Digital Volume: −8dB
182 * Bass Boost Level : Middle 208 * Bass Boost Level : Middle
183 * 209 *
184 * This operation came from example code of 210 * This operation came from example code of
185 * "ASAHI KASEI AK4642" (japanese) manual p97. 211 * "ASAHI KASEI AK4642" (japanese) manual p97.
186 *
187 * Example code use 0x39, 0x79 value for 0x01 address,
188 * But we need MCKO (0x02) bit now
189 */ 212 */
190 ak4642_write(codec, 0x05, 0x27);
191 ak4642_write(codec, 0x0f, 0x09); 213 ak4642_write(codec, 0x0f, 0x09);
192 ak4642_write(codec, 0x0e, 0x19); 214 ak4642_write(codec, 0x0e, 0x19);
193 ak4642_write(codec, 0x09, 0x91); 215 ak4642_write(codec, 0x09, 0x91);
@@ -195,15 +217,14 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
195 ak4642_write(codec, 0x0a, 0x28); 217 ak4642_write(codec, 0x0a, 0x28);
196 ak4642_write(codec, 0x0d, 0x28); 218 ak4642_write(codec, 0x0d, 0x28);
197 ak4642_write(codec, 0x00, 0x64); 219 ak4642_write(codec, 0x00, 0x64);
198 ak4642_write(codec, 0x01, 0x3b); /* + MCKO bit */ 220 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
199 ak4642_write(codec, 0x01, 0x7b); /* + MCKO bit */ 221 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN);
200 } else { 222 } else {
201 /* 223 /*
202 * start stereo input 224 * start stereo input
203 * 225 *
204 * PLL Master Mode 226 * PLL Master Mode
205 * Audio I/F Format:MSB justified (ADC & DAC) 227 * Audio I/F Format:MSB justified (ADC & DAC)
206 * Sampling Frequency:44.1kHz
207 * Pre MIC AMP:+20dB 228 * Pre MIC AMP:+20dB
208 * MIC Power On 229 * MIC Power On
209 * ALC setting:Refer to Table 35 230 * ALC setting:Refer to Table 35
@@ -212,7 +233,6 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
212 * This operation came from example code of 233 * This operation came from example code of
213 * "ASAHI KASEI AK4642" (japanese) manual p94. 234 * "ASAHI KASEI AK4642" (japanese) manual p94.
214 */ 235 */
215 ak4642_write(codec, 0x05, 0x27);
216 ak4642_write(codec, 0x02, 0x05); 236 ak4642_write(codec, 0x02, 0x05);
217 ak4642_write(codec, 0x06, 0x3c); 237 ak4642_write(codec, 0x06, 0x3c);
218 ak4642_write(codec, 0x08, 0xe1); 238 ak4642_write(codec, 0x08, 0xe1);
@@ -233,8 +253,8 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
233 253
234 if (is_play) { 254 if (is_play) {
235 /* stop headphone output */ 255 /* stop headphone output */
236 ak4642_write(codec, 0x01, 0x3b); 256 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, 0);
237 ak4642_write(codec, 0x01, 0x0b); 257 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, 0);
238 ak4642_write(codec, 0x00, 0x40); 258 ak4642_write(codec, 0x00, 0x40);
239 ak4642_write(codec, 0x0e, 0x11); 259 ak4642_write(codec, 0x0e, 0x11);
240 ak4642_write(codec, 0x0f, 0x08); 260 ak4642_write(codec, 0x0f, 0x08);
@@ -250,9 +270,111 @@ static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
250 int clk_id, unsigned int freq, int dir) 270 int clk_id, unsigned int freq, int dir)
251{ 271{
252 struct snd_soc_codec *codec = codec_dai->codec; 272 struct snd_soc_codec *codec = codec_dai->codec;
253 struct ak4642_priv *ak4642 = codec->private_data; 273 u8 pll;
274
275 switch (freq) {
276 case 11289600:
277 pll = PLL2;
278 break;
279 case 12288000:
280 pll = PLL2 | PLL0;
281 break;
282 case 12000000:
283 pll = PLL2 | PLL1;
284 break;
285 case 24000000:
286 pll = PLL2 | PLL1 | PLL0;
287 break;
288 case 13500000:
289 pll = PLL3 | PLL2;
290 break;
291 case 27000000:
292 pll = PLL3 | PLL2 | PLL0;
293 break;
294 default:
295 return -EINVAL;
296 }
297 snd_soc_update_bits(codec, MD_CTL1, PLL_MASK, pll);
298
299 return 0;
300}
301
302static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
303{
304 struct snd_soc_codec *codec = dai->codec;
305 u8 data;
306 u8 bcko;
307
308 data = MCKO | PMPLL; /* use MCKO */
309 bcko = 0;
310
311 /* set master/slave audio interface */
312 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
313 case SND_SOC_DAIFMT_CBM_CFM:
314 data |= MS;
315 bcko = BCKO_64;
316 break;
317 case SND_SOC_DAIFMT_CBS_CFS:
318 break;
319 default:
320 return -EINVAL;
321 }
322 snd_soc_update_bits(codec, PW_MGMT2, MS, data);
323 snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
324
325 return 0;
326}
327
328static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
329 struct snd_pcm_hw_params *params,
330 struct snd_soc_dai *dai)
331{
332 struct snd_soc_codec *codec = dai->codec;
333 u8 rate;
334
335 switch (params_rate(params)) {
336 case 7350:
337 rate = FS2;
338 break;
339 case 8000:
340 rate = 0;
341 break;
342 case 11025:
343 rate = FS2 | FS0;
344 break;
345 case 12000:
346 rate = FS0;
347 break;
348 case 14700:
349 rate = FS2 | FS1;
350 break;
351 case 16000:
352 rate = FS1;
353 break;
354 case 22050:
355 rate = FS2 | FS1 | FS0;
356 break;
357 case 24000:
358 rate = FS1 | FS0;
359 break;
360 case 29400:
361 rate = FS3 | FS2 | FS1;
362 break;
363 case 32000:
364 rate = FS3 | FS1;
365 break;
366 case 44100:
367 rate = FS3 | FS2 | FS1 | FS0;
368 break;
369 case 48000:
370 rate = FS3 | FS1 | FS0;
371 break;
372 default:
373 return -EINVAL;
374 break;
375 }
376 snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate);
254 377
255 ak4642->sysclk = freq;
256 return 0; 378 return 0;
257} 379}
258 380
@@ -260,6 +382,8 @@ static struct snd_soc_dai_ops ak4642_dai_ops = {
260 .startup = ak4642_dai_startup, 382 .startup = ak4642_dai_startup,
261 .shutdown = ak4642_dai_shutdown, 383 .shutdown = ak4642_dai_shutdown,
262 .set_sysclk = ak4642_dai_set_sysclk, 384 .set_sysclk = ak4642_dai_set_sysclk,
385 .set_fmt = ak4642_dai_set_fmt,
386 .hw_params = ak4642_dai_hw_params,
263}; 387};
264 388
265struct snd_soc_dai ak4642_dai = { 389struct snd_soc_dai ak4642_dai = {
@@ -277,6 +401,7 @@ struct snd_soc_dai ak4642_dai = {
277 .rates = SNDRV_PCM_RATE_8000_48000, 401 .rates = SNDRV_PCM_RATE_8000_48000,
278 .formats = SNDRV_PCM_FMTBIT_S16_LE }, 402 .formats = SNDRV_PCM_FMTBIT_S16_LE },
279 .ops = &ak4642_dai_ops, 403 .ops = &ak4642_dai_ops,
404 .symmetric_rates = 1,
280}; 405};
281EXPORT_SYMBOL_GPL(ak4642_dai); 406EXPORT_SYMBOL_GPL(ak4642_dai);
282 407
@@ -307,7 +432,7 @@ static int ak4642_init(struct ak4642_priv *ak4642)
307 INIT_LIST_HEAD(&codec->dapm_widgets); 432 INIT_LIST_HEAD(&codec->dapm_widgets);
308 INIT_LIST_HEAD(&codec->dapm_paths); 433 INIT_LIST_HEAD(&codec->dapm_paths);
309 434
310 codec->private_data = ak4642; 435 snd_soc_codec_set_drvdata(codec, ak4642);
311 codec->name = "AK4642"; 436 codec->name = "AK4642";
312 codec->owner = THIS_MODULE; 437 codec->owner = THIS_MODULE;
313 codec->read = ak4642_read_reg_cache; 438 codec->read = ak4642_read_reg_cache;
@@ -338,26 +463,6 @@ static int ak4642_init(struct ak4642_priv *ak4642)
338 goto reg_cache_err; 463 goto reg_cache_err;
339 } 464 }
340 465
341 /*
342 * clock setting
343 *
344 * Audio I/F Format: MSB justified (ADC & DAC)
345 * BICK frequency at Master Mode: 64fs
346 * Input Master Clock Select at PLL Mode: 11.2896MHz
347 * MCKO: Enable
348 * Sampling Frequency: 44.1kHz
349 *
350 * This operation came from example code of
351 * "ASAHI KASEI AK4642" (japanese) manual p89.
352 *
353 * please fix-me
354 */
355 ak4642_write(codec, 0x01, 0x08);
356 ak4642_write(codec, 0x04, 0x4a);
357 ak4642_write(codec, 0x05, 0x27);
358 ak4642_write(codec, 0x00, 0x40);
359 ak4642_write(codec, 0x01, 0x0b);
360
361 return ret; 466 return ret;
362 467
363reg_cache_err: 468reg_cache_err:
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 926797a014c7..87566932a3b1 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -702,7 +702,7 @@ static int ak4671_register(struct ak4671_priv *ak4671,
702 INIT_LIST_HEAD(&codec->dapm_widgets); 702 INIT_LIST_HEAD(&codec->dapm_widgets);
703 INIT_LIST_HEAD(&codec->dapm_paths); 703 INIT_LIST_HEAD(&codec->dapm_paths);
704 704
705 codec->private_data = ak4671; 705 snd_soc_codec_set_drvdata(codec, ak4671);
706 codec->name = "AK4671"; 706 codec->name = "AK4671";
707 codec->owner = THIS_MODULE; 707 codec->owner = THIS_MODULE;
708 codec->bias_level = SND_SOC_BIAS_OFF; 708 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
new file mode 100644
index 000000000000..a320fb5a0e26
--- /dev/null
+++ b/sound/soc/codecs/cq93vc.c
@@ -0,0 +1,299 @@
1/*
2 * ALSA SoC CQ0093 Voice Codec Driver for DaVinci platforms
3 *
4 * Copyright (C) 2010 Texas Instruments, Inc
5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/io.h>
26#include <linux/delay.h>
27#include <linux/pm.h>
28#include <linux/platform_device.h>
29#include <linux/device.h>
30#include <linux/slab.h>
31#include <linux/clk.h>
32#include <linux/mfd/davinci_voicecodec.h>
33
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/pcm_params.h>
37#include <sound/soc.h>
38#include <sound/soc-dai.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h>
41
42#include <mach/dm365.h>
43
44#include "cq93vc.h"
45
46static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
47 unsigned int reg)
48{
49 struct davinci_vc *davinci_vc = codec->control_data;
50
51 return readl(davinci_vc->base + reg);
52}
53
54static inline int cq93vc_write(struct snd_soc_codec *codec, unsigned int reg,
55 unsigned int value)
56{
57 struct davinci_vc *davinci_vc = codec->control_data;
58
59 writel(value, davinci_vc->base + reg);
60
61 return 0;
62}
63
64static const struct snd_kcontrol_new cq93vc_snd_controls[] = {
65 SOC_SINGLE("PGA Capture Volume", DAVINCI_VC_REG05, 0, 0x03, 0),
66 SOC_SINGLE("Mono DAC Playback Volume", DAVINCI_VC_REG09, 0, 0x3f, 0),
67};
68
69static int cq93vc_mute(struct snd_soc_dai *dai, int mute)
70{
71 struct snd_soc_codec *codec = dai->codec;
72 u8 reg = cq93vc_read(codec, DAVINCI_VC_REG09) & ~DAVINCI_VC_REG09_MUTE;
73
74 if (mute)
75 cq93vc_write(codec, DAVINCI_VC_REG09,
76 reg | DAVINCI_VC_REG09_MUTE);
77 else
78 cq93vc_write(codec, DAVINCI_VC_REG09, reg);
79
80 return 0;
81}
82
83static int cq93vc_set_dai_sysclk(struct snd_soc_dai *codec_dai,
84 int clk_id, unsigned int freq, int dir)
85{
86 struct snd_soc_codec *codec = codec_dai->codec;
87 struct davinci_vc *davinci_vc = codec->control_data;
88
89 switch (freq) {
90 case 22579200:
91 case 27000000:
92 case 33868800:
93 davinci_vc->cq93vc.sysclk = freq;
94 return 0;
95 }
96
97 return -EINVAL;
98}
99
100static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
101 enum snd_soc_bias_level level)
102{
103 switch (level) {
104 case SND_SOC_BIAS_ON:
105 cq93vc_write(codec, DAVINCI_VC_REG12,
106 DAVINCI_VC_REG12_POWER_ALL_ON);
107 break;
108 case SND_SOC_BIAS_PREPARE:
109 break;
110 case SND_SOC_BIAS_STANDBY:
111 cq93vc_write(codec, DAVINCI_VC_REG12,
112 DAVINCI_VC_REG12_POWER_ALL_OFF);
113 break;
114 case SND_SOC_BIAS_OFF:
115 /* force all power off */
116 cq93vc_write(codec, DAVINCI_VC_REG12,
117 DAVINCI_VC_REG12_POWER_ALL_OFF);
118 break;
119 }
120 codec->bias_level = level;
121
122 return 0;
123}
124
125#define CQ93VC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
126#define CQ93VC_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
127
128static struct snd_soc_dai_ops cq93vc_dai_ops = {
129 .digital_mute = cq93vc_mute,
130 .set_sysclk = cq93vc_set_dai_sysclk,
131};
132
133struct snd_soc_dai cq93vc_dai = {
134 .name = "CQ93VC",
135 .playback = {
136 .stream_name = "Playback",
137 .channels_min = 1,
138 .channels_max = 2,
139 .rates = CQ93VC_RATES,
140 .formats = CQ93VC_FORMATS,},
141 .capture = {
142 .stream_name = "Capture",
143 .channels_min = 1,
144 .channels_max = 2,
145 .rates = CQ93VC_RATES,
146 .formats = CQ93VC_FORMATS,},
147 .ops = &cq93vc_dai_ops,
148};
149EXPORT_SYMBOL_GPL(cq93vc_dai);
150
151static int cq93vc_resume(struct platform_device *pdev)
152{
153 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
154 struct snd_soc_codec *codec = socdev->card->codec;
155
156 cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
157
158 return 0;
159}
160
161static struct snd_soc_codec *cq93vc_codec;
162
163static int cq93vc_probe(struct platform_device *pdev)
164{
165 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
166 struct device *dev = &pdev->dev;
167 struct snd_soc_codec *codec;
168 int ret;
169
170 socdev->card->codec = cq93vc_codec;
171 codec = socdev->card->codec;
172
173 /* Register pcms */
174 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
175 if (ret < 0) {
176 dev_err(dev, "%s: failed to create pcms\n", pdev->name);
177 return ret;
178 }
179
180 /* Set controls */
181 snd_soc_add_controls(codec, cq93vc_snd_controls,
182 ARRAY_SIZE(cq93vc_snd_controls));
183
184 /* Off, with power on */
185 cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
186
187 return 0;
188}
189
190static int cq93vc_remove(struct platform_device *pdev)
191{
192 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
193
194 snd_soc_free_pcms(socdev);
195 snd_soc_dapm_free(socdev);
196
197 return 0;
198}
199
200struct snd_soc_codec_device soc_codec_dev_cq93vc = {
201 .probe = cq93vc_probe,
202 .remove = cq93vc_remove,
203 .resume = cq93vc_resume,
204};
205EXPORT_SYMBOL_GPL(soc_codec_dev_cq93vc);
206
207static __init int cq93vc_codec_probe(struct platform_device *pdev)
208{
209 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
210 struct snd_soc_codec *codec;
211 int ret;
212
213 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
214 if (codec == NULL) {
215 dev_dbg(davinci_vc->dev,
216 "could not allocate memory for codec data\n");
217 return -ENOMEM;
218 }
219
220 davinci_vc->cq93vc.codec = codec;
221
222 cq93vc_dai.dev = &pdev->dev;
223
224 mutex_init(&codec->mutex);
225 INIT_LIST_HEAD(&codec->dapm_widgets);
226 INIT_LIST_HEAD(&codec->dapm_paths);
227 codec->dev = &pdev->dev;
228 codec->name = "CQ93VC";
229 codec->owner = THIS_MODULE;
230 codec->read = cq93vc_read;
231 codec->write = cq93vc_write;
232 codec->set_bias_level = cq93vc_set_bias_level;
233 codec->dai = &cq93vc_dai;
234 codec->num_dai = 1;
235 codec->control_data = davinci_vc;
236
237 cq93vc_codec = codec;
238
239 ret = snd_soc_register_codec(codec);
240 if (ret) {
241 dev_err(davinci_vc->dev, "failed to register codec\n");
242 goto fail1;
243 }
244
245 ret = snd_soc_register_dai(&cq93vc_dai);
246 if (ret) {
247 dev_err(davinci_vc->dev, "could register dai\n");
248 goto fail2;
249 }
250 return 0;
251
252fail2:
253 snd_soc_unregister_codec(codec);
254
255fail1:
256 kfree(codec);
257 cq93vc_codec = NULL;
258
259 return ret;
260}
261
262static int __devexit cq93vc_codec_remove(struct platform_device *pdev)
263{
264 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
265 struct snd_soc_codec *codec = socdev->card->codec;
266
267 snd_soc_unregister_dai(&cq93vc_dai);
268 snd_soc_unregister_codec(&codec);
269
270 kfree(codec);
271 cq93vc_codec = NULL;
272
273 return 0;
274}
275
276static struct platform_driver cq93vc_codec_driver = {
277 .driver = {
278 .name = "cq93vc",
279 .owner = THIS_MODULE,
280 },
281 .probe = cq93vc_codec_probe,
282 .remove = __devexit_p(cq93vc_codec_remove),
283};
284
285static __init int cq93vc_init(void)
286{
287 return platform_driver_probe(&cq93vc_codec_driver, cq93vc_codec_probe);
288}
289module_init(cq93vc_init);
290
291static __exit void cq93vc_exit(void)
292{
293 platform_driver_unregister(&cq93vc_codec_driver);
294}
295module_exit(cq93vc_exit);
296
297MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC CQ0093 Voice Codec Driver");
298MODULE_AUTHOR("Miguel Aguilar");
299MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cq93vc.h b/sound/soc/codecs/cq93vc.h
new file mode 100644
index 000000000000..845b1968ef9c
--- /dev/null
+++ b/sound/soc/codecs/cq93vc.h
@@ -0,0 +1,29 @@
1/*
2 * ALSA SoC CQ0093 Voice Codec Driver for DaVinci platforms
3 *
4 * Copyright (C) 2010 Texas Instruments, Inc
5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef _CQ93VC_H
24#define _CQ93VC_H
25
26extern struct snd_soc_dai cq93vc_dai;
27extern struct snd_soc_codec_device soc_codec_dev_cq93vc;
28
29#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 81a62d198b70..30d949239def 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -211,7 +211,7 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
211 int clk_id, unsigned int freq, int dir) 211 int clk_id, unsigned int freq, int dir)
212{ 212{
213 struct snd_soc_codec *codec = codec_dai->codec; 213 struct snd_soc_codec *codec = codec_dai->codec;
214 struct cs4270_private *cs4270 = codec->private_data; 214 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
215 unsigned int rates = 0; 215 unsigned int rates = 0;
216 unsigned int rate_min = -1; 216 unsigned int rate_min = -1;
217 unsigned int rate_max = 0; 217 unsigned int rate_max = 0;
@@ -270,7 +270,7 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
270 unsigned int format) 270 unsigned int format)
271{ 271{
272 struct snd_soc_codec *codec = codec_dai->codec; 272 struct snd_soc_codec *codec = codec_dai->codec;
273 struct cs4270_private *cs4270 = codec->private_data; 273 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
274 int ret = 0; 274 int ret = 0;
275 275
276 /* set DAI format */ 276 /* set DAI format */
@@ -412,7 +412,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
412 struct snd_soc_pcm_runtime *rtd = substream->private_data; 412 struct snd_soc_pcm_runtime *rtd = substream->private_data;
413 struct snd_soc_device *socdev = rtd->socdev; 413 struct snd_soc_device *socdev = rtd->socdev;
414 struct snd_soc_codec *codec = socdev->card->codec; 414 struct snd_soc_codec *codec = socdev->card->codec;
415 struct cs4270_private *cs4270 = codec->private_data; 415 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
416 int ret; 416 int ret;
417 unsigned int i; 417 unsigned int i;
418 unsigned int rate; 418 unsigned int rate;
@@ -491,7 +491,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
491static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute) 491static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
492{ 492{
493 struct snd_soc_codec *codec = dai->codec; 493 struct snd_soc_codec *codec = dai->codec;
494 struct cs4270_private *cs4270 = codec->private_data; 494 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
495 int reg6; 495 int reg6;
496 496
497 reg6 = snd_soc_read(codec, CS4270_MUTE); 497 reg6 = snd_soc_read(codec, CS4270_MUTE);
@@ -524,7 +524,7 @@ static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol) 524 struct snd_ctl_elem_value *ucontrol)
525{ 525{
526 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 526 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct cs4270_private *cs4270 = codec->private_data; 527 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
528 int left = !ucontrol->value.integer.value[0]; 528 int left = !ucontrol->value.integer.value[0];
529 int right = !ucontrol->value.integer.value[1]; 529 int right = !ucontrol->value.integer.value[1];
530 530
@@ -600,7 +600,7 @@ static int cs4270_probe(struct platform_device *pdev)
600{ 600{
601 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 601 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
602 struct snd_soc_codec *codec = cs4270_codec; 602 struct snd_soc_codec *codec = cs4270_codec;
603 struct cs4270_private *cs4270 = codec->private_data; 603 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
604 int i, ret; 604 int i, ret;
605 605
606 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ 606 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
@@ -657,7 +657,7 @@ static int cs4270_remove(struct platform_device *pdev)
657{ 657{
658 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 658 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
659 struct snd_soc_codec *codec = cs4270_codec; 659 struct snd_soc_codec *codec = cs4270_codec;
660 struct cs4270_private *cs4270 = codec->private_data; 660 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
661 661
662 snd_soc_free_pcms(socdev); 662 snd_soc_free_pcms(socdev);
663 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies); 663 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
@@ -730,7 +730,7 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
730 codec->owner = THIS_MODULE; 730 codec->owner = THIS_MODULE;
731 codec->dai = &cs4270_dai; 731 codec->dai = &cs4270_dai;
732 codec->num_dai = 1; 732 codec->num_dai = 1;
733 codec->private_data = cs4270; 733 snd_soc_codec_set_drvdata(codec, cs4270);
734 codec->control_data = i2c_client; 734 codec->control_data = i2c_client;
735 codec->read = cs4270_read_reg_cache; 735 codec->read = cs4270_read_reg_cache;
736 codec->write = cs4270_i2c_write; 736 codec->write = cs4270_i2c_write;
@@ -843,7 +843,7 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
843static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 843static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
844{ 844{
845 struct snd_soc_codec *codec = cs4270_codec; 845 struct snd_soc_codec *codec = cs4270_codec;
846 struct cs4270_private *cs4270 = codec->private_data; 846 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
847 int reg, ret; 847 int reg, ret;
848 848
849 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; 849 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
@@ -863,7 +863,7 @@ static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
863static int cs4270_soc_resume(struct platform_device *pdev) 863static int cs4270_soc_resume(struct platform_device *pdev)
864{ 864{
865 struct snd_soc_codec *codec = cs4270_codec; 865 struct snd_soc_codec *codec = cs4270_codec;
866 struct cs4270_private *cs4270 = codec->private_data; 866 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
867 struct i2c_client *i2c_client = codec->control_data; 867 struct i2c_client *i2c_client = codec->control_data;
868 int reg; 868 int reg;
869 869
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 9f169c477108..f07a415c753f 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -387,7 +387,7 @@ static int cx20442_register(struct cx20442_priv *cx20442)
387 387
388 codec->name = "CX20442"; 388 codec->name = "CX20442";
389 codec->owner = THIS_MODULE; 389 codec->owner = THIS_MODULE;
390 codec->private_data = cx20442; 390 snd_soc_codec_set_drvdata(codec, cx20442);
391 391
392 codec->dai = &cx20442_dai; 392 codec->dai = &cx20442_dai;
393 codec->num_dai = 1; 393 codec->num_dai = 1;
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 366daf1d044e..75af2d6e0e78 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -56,8 +56,14 @@
56#define DA7210_DAI_SRC_SEL 0x25 56#define DA7210_DAI_SRC_SEL 0x25
57#define DA7210_DAI_CFG1 0x26 57#define DA7210_DAI_CFG1 0x26
58#define DA7210_DAI_CFG3 0x28 58#define DA7210_DAI_CFG3 0x28
59#define DA7210_PLL_DIV1 0x29
60#define DA7210_PLL_DIV2 0x2A
59#define DA7210_PLL_DIV3 0x2B 61#define DA7210_PLL_DIV3 0x2B
60#define DA7210_PLL 0x2C 62#define DA7210_PLL 0x2C
63#define DA7210_A_HID_UNLOCK 0x8A
64#define DA7210_A_TEST_UNLOCK 0x8B
65#define DA7210_A_PLL1 0x90
66#define DA7210_A_CP_MODE 0xA7
61 67
62/* STARTUP1 bit fields */ 68/* STARTUP1 bit fields */
63#define DA7210_SC_MST_EN (1 << 0) 69#define DA7210_SC_MST_EN (1 << 0)
@@ -75,15 +81,14 @@
75/* INMIX_R bit fields */ 81/* INMIX_R bit fields */
76#define DA7210_IN_R_EN (1 << 7) 82#define DA7210_IN_R_EN (1 << 7)
77 83
78/* ADC_HPF bit fields */
79#define DA7210_ADC_VOICE_EN (1 << 7)
80
81/* ADC bit fields */ 84/* ADC bit fields */
82#define DA7210_ADC_L_EN (1 << 3) 85#define DA7210_ADC_L_EN (1 << 3)
83#define DA7210_ADC_R_EN (1 << 7) 86#define DA7210_ADC_R_EN (1 << 7)
84 87
85/* DAC_HPF fields */ 88/* DAC/ADC HPF fields */
86#define DA7210_DAC_VOICE_EN (1 << 7) 89#define DA7210_VOICE_F0_MASK (0x7 << 4)
90#define DA7210_VOICE_F0_25 (1 << 4)
91#define DA7210_VOICE_EN (1 << 7)
87 92
88/* DAC_SEL bit fields */ 93/* DAC_SEL bit fields */
89#define DA7210_DAC_L_SRC_DAI_L (4 << 0) 94#define DA7210_DAC_L_SRC_DAI_L (4 << 0)
@@ -124,7 +129,19 @@
124#define DA7210_PLL_BYP (1 << 6) 129#define DA7210_PLL_BYP (1 << 6)
125 130
126/* PLL bit fields */ 131/* PLL bit fields */
127#define DA7210_PLL_FS_48000 (11 << 0) 132#define DA7210_PLL_FS_MASK (0xF << 0)
133#define DA7210_PLL_FS_8000 (0x1 << 0)
134#define DA7210_PLL_FS_11025 (0x2 << 0)
135#define DA7210_PLL_FS_12000 (0x3 << 0)
136#define DA7210_PLL_FS_16000 (0x5 << 0)
137#define DA7210_PLL_FS_22050 (0x6 << 0)
138#define DA7210_PLL_FS_24000 (0x7 << 0)
139#define DA7210_PLL_FS_32000 (0x9 << 0)
140#define DA7210_PLL_FS_44100 (0xA << 0)
141#define DA7210_PLL_FS_48000 (0xB << 0)
142#define DA7210_PLL_FS_88200 (0xE << 0)
143#define DA7210_PLL_FS_96000 (0xF << 0)
144#define DA7210_PLL_EN (0x1 << 7)
128 145
129#define DA7210_VERSION "0.0.1" 146#define DA7210_VERSION "0.0.1"
130 147
@@ -165,7 +182,7 @@ static const u8 da7210_reg[] = {
165static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg) 182static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg)
166{ 183{
167 u8 *cache = codec->reg_cache; 184 u8 *cache = codec->reg_cache;
168 BUG_ON(reg > ARRAY_SIZE(da7210_reg)); 185 BUG_ON(reg >= ARRAY_SIZE(da7210_reg));
169 return cache[reg]; 186 return cache[reg];
170} 187}
171 188
@@ -242,7 +259,8 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
242 struct snd_soc_device *socdev = rtd->socdev; 259 struct snd_soc_device *socdev = rtd->socdev;
243 struct snd_soc_codec *codec = socdev->card->codec; 260 struct snd_soc_codec *codec = socdev->card->codec;
244 u32 dai_cfg1; 261 u32 dai_cfg1;
245 u32 reg, mask; 262 u32 hpf_reg, hpf_mask, hpf_value;
263 u32 fs, bypass;
246 264
247 /* set DAI source to Left and Right ADC */ 265 /* set DAI source to Left and Right ADC */
248 da7210_write(codec, DA7210_DAI_SRC_SEL, 266 da7210_write(codec, DA7210_DAI_SRC_SEL,
@@ -266,25 +284,84 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
266 284
267 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1); 285 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
268 286
269 /* FIXME 287 hpf_reg = (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) ?
270 * 288 DA7210_DAC_HPF : DA7210_ADC_HPF;
271 * It support 48K only now 289
272 */
273 switch (params_rate(params)) { 290 switch (params_rate(params)) {
291 case 8000:
292 fs = DA7210_PLL_FS_8000;
293 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
294 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
295 bypass = DA7210_PLL_BYP;
296 break;
297 case 11025:
298 fs = DA7210_PLL_FS_11025;
299 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
300 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
301 bypass = 0;
302 break;
303 case 12000:
304 fs = DA7210_PLL_FS_12000;
305 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
306 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
307 bypass = DA7210_PLL_BYP;
308 break;
309 case 16000:
310 fs = DA7210_PLL_FS_16000;
311 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
312 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
313 bypass = DA7210_PLL_BYP;
314 break;
315 case 22050:
316 fs = DA7210_PLL_FS_22050;
317 hpf_mask = DA7210_VOICE_EN;
318 hpf_value = 0;
319 bypass = 0;
320 break;
321 case 32000:
322 fs = DA7210_PLL_FS_32000;
323 hpf_mask = DA7210_VOICE_EN;
324 hpf_value = 0;
325 bypass = DA7210_PLL_BYP;
326 break;
327 case 44100:
328 fs = DA7210_PLL_FS_44100;
329 hpf_mask = DA7210_VOICE_EN;
330 hpf_value = 0;
331 bypass = 0;
332 break;
274 case 48000: 333 case 48000:
275 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { 334 fs = DA7210_PLL_FS_48000;
276 reg = DA7210_DAC_HPF; 335 hpf_mask = DA7210_VOICE_EN;
277 mask = DA7210_DAC_VOICE_EN; 336 hpf_value = 0;
278 } else { 337 bypass = DA7210_PLL_BYP;
279 reg = DA7210_ADC_HPF; 338 break;
280 mask = DA7210_ADC_VOICE_EN; 339 case 88200:
281 } 340 fs = DA7210_PLL_FS_88200;
341 hpf_mask = DA7210_VOICE_EN;
342 hpf_value = 0;
343 bypass = 0;
344 break;
345 case 96000:
346 fs = DA7210_PLL_FS_96000;
347 hpf_mask = DA7210_VOICE_EN;
348 hpf_value = 0;
349 bypass = DA7210_PLL_BYP;
282 break; 350 break;
283 default: 351 default:
284 return -EINVAL; 352 return -EINVAL;
285 } 353 }
286 354
287 snd_soc_update_bits(codec, reg, mask, 0); 355 /* Disable active mode */
356 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
357
358 snd_soc_update_bits(codec, hpf_reg, hpf_mask, hpf_value);
359 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
360 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass);
361
362 /* Enable active mode */
363 snd_soc_update_bits(codec, DA7210_STARTUP1,
364 DA7210_SC_MST_EN, DA7210_SC_MST_EN);
288 365
289 return 0; 366 return 0;
290} 367}
@@ -362,6 +439,7 @@ struct snd_soc_dai da7210_dai = {
362 .formats = DA7210_FORMATS, 439 .formats = DA7210_FORMATS,
363 }, 440 },
364 .ops = &da7210_dai_ops, 441 .ops = &da7210_dai_ops,
442 .symmetric_rates = 1,
365}; 443};
366EXPORT_SYMBOL_GPL(da7210_dai); 444EXPORT_SYMBOL_GPL(da7210_dai);
367 445
@@ -383,7 +461,7 @@ static int da7210_init(struct da7210_priv *da7210)
383 INIT_LIST_HEAD(&codec->dapm_widgets); 461 INIT_LIST_HEAD(&codec->dapm_widgets);
384 INIT_LIST_HEAD(&codec->dapm_paths); 462 INIT_LIST_HEAD(&codec->dapm_paths);
385 463
386 codec->private_data = da7210; 464 snd_soc_codec_set_drvdata(codec, da7210);
387 codec->name = "DA7210"; 465 codec->name = "DA7210";
388 codec->owner = THIS_MODULE; 466 codec->owner = THIS_MODULE;
389 codec->read = da7210_read; 467 codec->read = da7210_read;
@@ -416,9 +494,23 @@ static int da7210_init(struct da7210_priv *da7210)
416 /* FIXME 494 /* FIXME
417 * 495 *
418 * This driver use fixed value here 496 * This driver use fixed value here
497 * And below settings expects MCLK = 12.288MHz
498 *
499 * When you select different MCLK, please check...
500 * DA7210_PLL_DIV1 val
501 * DA7210_PLL_DIV2 val
502 * DA7210_PLL_DIV3 val
503 * DA7210_PLL_DIV3 :: DA7210_MCLK_RANGExxx
419 */ 504 */
420 505
421 /* 506 /*
507 * make sure that DA7210 use bypass mode before start up
508 */
509 da7210_write(codec, DA7210_STARTUP1, 0);
510 da7210_write(codec, DA7210_PLL_DIV3,
511 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
512
513 /*
422 * ADC settings 514 * ADC settings
423 */ 515 */
424 516
@@ -454,9 +546,28 @@ static int da7210_init(struct da7210_priv *da7210)
454 /* Diable PLL and bypass it */ 546 /* Diable PLL and bypass it */
455 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); 547 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
456 548
457 /* Bypass PLL and set MCLK freq rang to 10-20MHz */ 549 /*
458 da7210_write(codec, DA7210_PLL_DIV3, 550 * If 48kHz sound came, it use bypass mode,
551 * and when it is 44.1kHz, it use PLL.
552 *
553 * This time, this driver sets PLL always ON
554 * and controls bypass/PLL mode by switching
555 * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit.
556 * see da7210_hw_params
557 */
558 da7210_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */
559 da7210_write(codec, DA7210_PLL_DIV2, 0x99);
560 da7210_write(codec, DA7210_PLL_DIV3, 0x0A |
459 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); 561 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
562 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
563
564 /* As suggested by Dialog */
565 da7210_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */
566 da7210_write(codec, DA7210_A_TEST_UNLOCK, 0xB4);
567 da7210_write(codec, DA7210_A_PLL1, 0x01);
568 da7210_write(codec, DA7210_A_CP_MODE, 0x7C);
569 da7210_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */
570 da7210_write(codec, DA7210_A_TEST_UNLOCK, 0x00);
460 571
461 /* Activate all enabled subsystem */ 572 /* Activate all enabled subsystem */
462 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 573 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 29d0906a924a..b47ed4f6ab20 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -140,6 +140,7 @@ SOC_DOUBLE_R("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 31, 0),
140SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1), 140SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1),
141 141
142SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0), 142SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
143SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 7, 1, 0),
143SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1), 144SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
144 145
145SOC_SINGLE("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1), 146SOC_SINGLE("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1),
@@ -277,7 +278,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
277 struct snd_soc_pcm_runtime *rtd = substream->private_data; 278 struct snd_soc_pcm_runtime *rtd = substream->private_data;
278 struct snd_soc_device *socdev = rtd->socdev; 279 struct snd_soc_device *socdev = rtd->socdev;
279 struct snd_soc_codec *codec = socdev->card->codec; 280 struct snd_soc_codec *codec = socdev->card->codec;
280 struct ssm2602_priv *ssm2602 = codec->private_data; 281 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
281 struct i2c_client *i2c = codec->control_data; 282 struct i2c_client *i2c = codec->control_data;
282 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; 283 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
283 int i = get_coeff(ssm2602->sysclk, params_rate(params)); 284 int i = get_coeff(ssm2602->sysclk, params_rate(params));
@@ -322,7 +323,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
322 struct snd_soc_pcm_runtime *rtd = substream->private_data; 323 struct snd_soc_pcm_runtime *rtd = substream->private_data;
323 struct snd_soc_device *socdev = rtd->socdev; 324 struct snd_soc_device *socdev = rtd->socdev;
324 struct snd_soc_codec *codec = socdev->card->codec; 325 struct snd_soc_codec *codec = socdev->card->codec;
325 struct ssm2602_priv *ssm2602 = codec->private_data; 326 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
326 struct i2c_client *i2c = codec->control_data; 327 struct i2c_client *i2c = codec->control_data;
327 struct snd_pcm_runtime *master_runtime; 328 struct snd_pcm_runtime *master_runtime;
328 329
@@ -373,7 +374,7 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
373 struct snd_soc_pcm_runtime *rtd = substream->private_data; 374 struct snd_soc_pcm_runtime *rtd = substream->private_data;
374 struct snd_soc_device *socdev = rtd->socdev; 375 struct snd_soc_device *socdev = rtd->socdev;
375 struct snd_soc_codec *codec = socdev->card->codec; 376 struct snd_soc_codec *codec = socdev->card->codec;
376 struct ssm2602_priv *ssm2602 = codec->private_data; 377 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
377 378
378 /* deactivate */ 379 /* deactivate */
379 if (!codec->active) 380 if (!codec->active)
@@ -401,7 +402,7 @@ static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
401 int clk_id, unsigned int freq, int dir) 402 int clk_id, unsigned int freq, int dir)
402{ 403{
403 struct snd_soc_codec *codec = codec_dai->codec; 404 struct snd_soc_codec *codec = codec_dai->codec;
404 struct ssm2602_priv *ssm2602 = codec->private_data; 405 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
405 switch (freq) { 406 switch (freq) {
406 case 11289600: 407 case 11289600:
407 case 12000000: 408 case 12000000:
@@ -559,7 +560,6 @@ static int ssm2602_resume(struct platform_device *pdev)
559 codec->hw_write(codec->control_data, data, 2); 560 codec->hw_write(codec->control_data, data, 2);
560 } 561 }
561 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 562 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
562 ssm2602_set_bias_level(codec, codec->suspend_bias_level);
563 return 0; 563 return 0;
564} 564}
565 565
@@ -605,8 +605,7 @@ static int ssm2602_init(struct snd_soc_device *socdev)
605 reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V); 605 reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V);
606 ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH); 606 ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
607 /*select Line in as default input*/ 607 /*select Line in as default input*/
608 ssm2602_write(codec, SSM2602_APANA, 608 ssm2602_write(codec, SSM2602_APANA, APANA_SELECT_DAC |
609 APANA_ENABLE_MIC_BOOST2 | APANA_SELECT_DAC |
610 APANA_ENABLE_MIC_BOOST); 609 APANA_ENABLE_MIC_BOOST);
611 ssm2602_write(codec, SSM2602_PWR, 0); 610 ssm2602_write(codec, SSM2602_PWR, 0);
612 611
@@ -727,7 +726,7 @@ static int ssm2602_probe(struct platform_device *pdev)
727 return -ENOMEM; 726 return -ENOMEM;
728 } 727 }
729 728
730 codec->private_data = ssm2602; 729 snd_soc_codec_set_drvdata(codec, ssm2602);
731 socdev->card->codec = codec; 730 socdev->card->codec = codec;
732 mutex_init(&codec->mutex); 731 mutex_init(&codec->mutex);
733 INIT_LIST_HEAD(&codec->dapm_widgets); 732 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -760,7 +759,7 @@ static int ssm2602_remove(struct platform_device *pdev)
760 i2c_unregister_device(codec->control_data); 759 i2c_unregister_device(codec->control_data);
761 i2c_del_driver(&ssm2602_i2c_driver); 760 i2c_del_driver(&ssm2602_i2c_driver);
762#endif 761#endif
763 kfree(codec->private_data); 762 kfree(snd_soc_codec_get_drvdata(codec));
764 kfree(codec); 763 kfree(codec);
765 764
766 return 0; 765 return 0;
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 3293629dcb3b..ee86568545c2 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -289,9 +289,6 @@ reset:
289 } 289 }
290 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 290 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
291 291
292 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
293 stac9766_set_bias_level(codec, SND_SOC_BIAS_ON);
294
295 return 0; 292 return 0;
296} 293}
297 294
@@ -410,7 +407,7 @@ reset_err:
410pcm_err: 407pcm_err:
411 snd_soc_free_ac97_codec(codec); 408 snd_soc_free_ac97_codec(codec);
412codec_err: 409codec_err:
413 kfree(codec->private_data); 410 kfree(snd_soc_codec_get_drvdata(codec));
414cache_err: 411cache_err:
415 kfree(socdev->card->codec); 412 kfree(socdev->card->codec);
416 socdev->card->codec = NULL; 413 socdev->card->codec = NULL;
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 776b79cde904..b0bae3508b29 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -634,7 +634,6 @@ static int tlv320aic23_resume(struct platform_device *pdev)
634 } 634 }
635 635
636 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 636 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
637 tlv320aic23_set_bias_level(codec, codec->suspend_bias_level);
638 637
639 return 0; 638 return 0;
640} 639}
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index b5b7d6a03844..f0e00fd4b435 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -49,7 +49,7 @@ struct aic26 {
49static unsigned int aic26_reg_read(struct snd_soc_codec *codec, 49static unsigned int aic26_reg_read(struct snd_soc_codec *codec,
50 unsigned int reg) 50 unsigned int reg)
51{ 51{
52 struct aic26 *aic26 = codec->private_data; 52 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
53 u16 *cache = codec->reg_cache; 53 u16 *cache = codec->reg_cache;
54 u16 cmd, value; 54 u16 cmd, value;
55 u8 buffer[2]; 55 u8 buffer[2];
@@ -93,7 +93,7 @@ static unsigned int aic26_reg_read_cache(struct snd_soc_codec *codec,
93static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg, 93static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
94 unsigned int value) 94 unsigned int value)
95{ 95{
96 struct aic26 *aic26 = codec->private_data; 96 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
97 u16 *cache = codec->reg_cache; 97 u16 *cache = codec->reg_cache;
98 u16 cmd; 98 u16 cmd;
99 u8 buffer[4]; 99 u8 buffer[4];
@@ -132,7 +132,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
132 struct snd_soc_pcm_runtime *rtd = substream->private_data; 132 struct snd_soc_pcm_runtime *rtd = substream->private_data;
133 struct snd_soc_device *socdev = rtd->socdev; 133 struct snd_soc_device *socdev = rtd->socdev;
134 struct snd_soc_codec *codec = socdev->card->codec; 134 struct snd_soc_codec *codec = socdev->card->codec;
135 struct aic26 *aic26 = codec->private_data; 135 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
136 int fsref, divisor, wlen, pval, jval, dval, qval; 136 int fsref, divisor, wlen, pval, jval, dval, qval;
137 u16 reg; 137 u16 reg;
138 138
@@ -199,7 +199,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
199static int aic26_mute(struct snd_soc_dai *dai, int mute) 199static int aic26_mute(struct snd_soc_dai *dai, int mute)
200{ 200{
201 struct snd_soc_codec *codec = dai->codec; 201 struct snd_soc_codec *codec = dai->codec;
202 struct aic26 *aic26 = codec->private_data; 202 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
203 u16 reg = aic26_reg_read_cache(codec, AIC26_REG_DAC_GAIN); 203 u16 reg = aic26_reg_read_cache(codec, AIC26_REG_DAC_GAIN);
204 204
205 dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n", 205 dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n",
@@ -218,7 +218,7 @@ static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
218 int clk_id, unsigned int freq, int dir) 218 int clk_id, unsigned int freq, int dir)
219{ 219{
220 struct snd_soc_codec *codec = codec_dai->codec; 220 struct snd_soc_codec *codec = codec_dai->codec;
221 struct aic26 *aic26 = codec->private_data; 221 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
222 222
223 dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i," 223 dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i,"
224 " freq=%i, dir=%i)\n", 224 " freq=%i, dir=%i)\n",
@@ -235,7 +235,7 @@ static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
235static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 235static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
236{ 236{
237 struct snd_soc_codec *codec = codec_dai->codec; 237 struct snd_soc_codec *codec = codec_dai->codec;
238 struct aic26 *aic26 = codec->private_data; 238 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
239 239
240 dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n", 240 dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n",
241 codec_dai, fmt); 241 codec_dai, fmt);
@@ -431,7 +431,7 @@ static int aic26_spi_probe(struct spi_device *spi)
431 /* Setup what we can in the codec structure so that the register 431 /* Setup what we can in the codec structure so that the register
432 * access functions will work as expected. More will be filled 432 * access functions will work as expected. More will be filled
433 * out when it is probed by the SoC CODEC part of this driver */ 433 * out when it is probed by the SoC CODEC part of this driver */
434 aic26->codec.private_data = aic26; 434 snd_soc_codec_set_drvdata(&aic26->codec, aic26);
435 aic26->codec.name = "aic26"; 435 aic26->codec.name = "aic26";
436 aic26->codec.owner = THIS_MODULE; 436 aic26->codec.owner = THIS_MODULE;
437 aic26->codec.dai = &aic26_dai; 437 aic26->codec.dai = &aic26_dai;
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 4a6d56c3fed9..71a69908ccf6 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -38,6 +38,8 @@
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/pm.h> 39#include <linux/pm.h>
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/gpio.h>
42#include <linux/regulator/consumer.h>
41#include <linux/platform_device.h> 43#include <linux/platform_device.h>
42#include <linux/slab.h> 44#include <linux/slab.h>
43#include <sound/core.h> 45#include <sound/core.h>
@@ -47,16 +49,25 @@
47#include <sound/soc-dapm.h> 49#include <sound/soc-dapm.h>
48#include <sound/initval.h> 50#include <sound/initval.h>
49#include <sound/tlv.h> 51#include <sound/tlv.h>
52#include <sound/tlv320aic3x.h>
50 53
51#include "tlv320aic3x.h" 54#include "tlv320aic3x.h"
52 55
53#define AIC3X_VERSION "0.2" 56#define AIC3X_NUM_SUPPLIES 4
57static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
58 "IOVDD", /* I/O Voltage */
59 "DVDD", /* Digital Core Voltage */
60 "AVDD", /* Analog DAC Voltage */
61 "DRVDD", /* ADC Analog and Output Driver Voltage */
62};
54 63
55/* codec private data */ 64/* codec private data */
56struct aic3x_priv { 65struct aic3x_priv {
57 struct snd_soc_codec codec; 66 struct snd_soc_codec codec;
67 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
58 unsigned int sysclk; 68 unsigned int sysclk;
59 int master; 69 int master;
70 int gpio_reset;
60}; 71};
61 72
62/* 73/*
@@ -764,7 +775,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
764 struct snd_soc_pcm_runtime *rtd = substream->private_data; 775 struct snd_soc_pcm_runtime *rtd = substream->private_data;
765 struct snd_soc_device *socdev = rtd->socdev; 776 struct snd_soc_device *socdev = rtd->socdev;
766 struct snd_soc_codec *codec = socdev->card->codec; 777 struct snd_soc_codec *codec = socdev->card->codec;
767 struct aic3x_priv *aic3x = codec->private_data; 778 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
768 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 779 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
769 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 780 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
770 u16 d, pll_d = 1; 781 u16 d, pll_d = 1;
@@ -931,7 +942,7 @@ static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
931 int clk_id, unsigned int freq, int dir) 942 int clk_id, unsigned int freq, int dir)
932{ 943{
933 struct snd_soc_codec *codec = codec_dai->codec; 944 struct snd_soc_codec *codec = codec_dai->codec;
934 struct aic3x_priv *aic3x = codec->private_data; 945 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
935 946
936 aic3x->sysclk = freq; 947 aic3x->sysclk = freq;
937 return 0; 948 return 0;
@@ -941,7 +952,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
941 unsigned int fmt) 952 unsigned int fmt)
942{ 953{
943 struct snd_soc_codec *codec = codec_dai->codec; 954 struct snd_soc_codec *codec = codec_dai->codec;
944 struct aic3x_priv *aic3x = codec->private_data; 955 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
945 u8 iface_areg, iface_breg; 956 u8 iface_areg, iface_breg;
946 int delay = 0; 957 int delay = 0;
947 958
@@ -995,12 +1006,13 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
995static int aic3x_set_bias_level(struct snd_soc_codec *codec, 1006static int aic3x_set_bias_level(struct snd_soc_codec *codec,
996 enum snd_soc_bias_level level) 1007 enum snd_soc_bias_level level)
997{ 1008{
998 struct aic3x_priv *aic3x = codec->private_data; 1009 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
999 u8 reg; 1010 u8 reg;
1000 1011
1001 switch (level) { 1012 switch (level) {
1002 case SND_SOC_BIAS_ON: 1013 case SND_SOC_BIAS_ON:
1003 /* all power is driven by DAPM system */ 1014 break;
1015 case SND_SOC_BIAS_PREPARE:
1004 if (aic3x->master) { 1016 if (aic3x->master) {
1005 /* enable pll */ 1017 /* enable pll */
1006 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 1018 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
@@ -1008,48 +1020,9 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1008 reg | PLL_ENABLE); 1020 reg | PLL_ENABLE);
1009 } 1021 }
1010 break; 1022 break;
1011 case SND_SOC_BIAS_PREPARE:
1012 break;
1013 case SND_SOC_BIAS_STANDBY: 1023 case SND_SOC_BIAS_STANDBY:
1014 /* 1024 /* fall through and disable pll */
1015 * all power is driven by DAPM system,
1016 * so output power is safe if bypass was set
1017 */
1018 if (aic3x->master) {
1019 /* disable pll */
1020 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
1021 aic3x_write(codec, AIC3X_PLL_PROGA_REG,
1022 reg & ~PLL_ENABLE);
1023 }
1024 break;
1025 case SND_SOC_BIAS_OFF: 1025 case SND_SOC_BIAS_OFF:
1026 /* force all power off */
1027 reg = aic3x_read_reg_cache(codec, LINE1L_2_LADC_CTRL);
1028 aic3x_write(codec, LINE1L_2_LADC_CTRL, reg & ~LADC_PWR_ON);
1029 reg = aic3x_read_reg_cache(codec, LINE1R_2_RADC_CTRL);
1030 aic3x_write(codec, LINE1R_2_RADC_CTRL, reg & ~RADC_PWR_ON);
1031
1032 reg = aic3x_read_reg_cache(codec, DAC_PWR);
1033 aic3x_write(codec, DAC_PWR, reg & ~(LDAC_PWR_ON | RDAC_PWR_ON));
1034
1035 reg = aic3x_read_reg_cache(codec, HPLOUT_CTRL);
1036 aic3x_write(codec, HPLOUT_CTRL, reg & ~HPLOUT_PWR_ON);
1037 reg = aic3x_read_reg_cache(codec, HPROUT_CTRL);
1038 aic3x_write(codec, HPROUT_CTRL, reg & ~HPROUT_PWR_ON);
1039
1040 reg = aic3x_read_reg_cache(codec, HPLCOM_CTRL);
1041 aic3x_write(codec, HPLCOM_CTRL, reg & ~HPLCOM_PWR_ON);
1042 reg = aic3x_read_reg_cache(codec, HPRCOM_CTRL);
1043 aic3x_write(codec, HPRCOM_CTRL, reg & ~HPRCOM_PWR_ON);
1044
1045 reg = aic3x_read_reg_cache(codec, MONOLOPM_CTRL);
1046 aic3x_write(codec, MONOLOPM_CTRL, reg & ~MONOLOPM_PWR_ON);
1047
1048 reg = aic3x_read_reg_cache(codec, LLOPM_CTRL);
1049 aic3x_write(codec, LLOPM_CTRL, reg & ~LLOPM_PWR_ON);
1050 reg = aic3x_read_reg_cache(codec, RLOPM_CTRL);
1051 aic3x_write(codec, RLOPM_CTRL, reg & ~RLOPM_PWR_ON);
1052
1053 if (aic3x->master) { 1026 if (aic3x->master) {
1054 /* disable pll */ 1027 /* disable pll */
1055 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 1028 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
@@ -1171,7 +1144,7 @@ static int aic3x_resume(struct platform_device *pdev)
1171 codec->hw_write(codec->control_data, data, 2); 1144 codec->hw_write(codec->control_data, data, 2);
1172 } 1145 }
1173 1146
1174 aic3x_set_bias_level(codec, codec->suspend_bias_level); 1147 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1175 1148
1176 return 0; 1149 return 0;
1177} 1150}
@@ -1309,6 +1282,13 @@ static int aic3x_unregister(struct aic3x_priv *aic3x)
1309 snd_soc_unregister_dai(&aic3x_dai); 1282 snd_soc_unregister_dai(&aic3x_dai);
1310 snd_soc_unregister_codec(&aic3x->codec); 1283 snd_soc_unregister_codec(&aic3x->codec);
1311 1284
1285 if (aic3x->gpio_reset >= 0) {
1286 gpio_set_value(aic3x->gpio_reset, 0);
1287 gpio_free(aic3x->gpio_reset);
1288 }
1289 regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1290 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1291
1312 kfree(aic3x); 1292 kfree(aic3x);
1313 aic3x_codec = NULL; 1293 aic3x_codec = NULL;
1314 1294
@@ -1330,6 +1310,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1330{ 1310{
1331 struct snd_soc_codec *codec; 1311 struct snd_soc_codec *codec;
1332 struct aic3x_priv *aic3x; 1312 struct aic3x_priv *aic3x;
1313 struct aic3x_pdata *pdata = i2c->dev.platform_data;
1314 int ret, i;
1333 1315
1334 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); 1316 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
1335 if (aic3x == NULL) { 1317 if (aic3x == NULL) {
@@ -1339,13 +1321,53 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1339 1321
1340 codec = &aic3x->codec; 1322 codec = &aic3x->codec;
1341 codec->dev = &i2c->dev; 1323 codec->dev = &i2c->dev;
1342 codec->private_data = aic3x; 1324 snd_soc_codec_set_drvdata(codec, aic3x);
1343 codec->control_data = i2c; 1325 codec->control_data = i2c;
1344 codec->hw_write = (hw_write_t) i2c_master_send; 1326 codec->hw_write = (hw_write_t) i2c_master_send;
1345 1327
1346 i2c_set_clientdata(i2c, aic3x); 1328 i2c_set_clientdata(i2c, aic3x);
1347 1329
1330 aic3x->gpio_reset = -1;
1331 if (pdata && pdata->gpio_reset >= 0) {
1332 ret = gpio_request(pdata->gpio_reset, "tlv320aic3x reset");
1333 if (ret != 0)
1334 goto err_gpio;
1335 aic3x->gpio_reset = pdata->gpio_reset;
1336 gpio_direction_output(aic3x->gpio_reset, 0);
1337 }
1338
1339 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1340 aic3x->supplies[i].supply = aic3x_supply_names[i];
1341
1342 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies),
1343 aic3x->supplies);
1344 if (ret != 0) {
1345 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1346 goto err_get;
1347 }
1348
1349 ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies),
1350 aic3x->supplies);
1351 if (ret != 0) {
1352 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1353 goto err_enable;
1354 }
1355
1356 if (aic3x->gpio_reset >= 0) {
1357 udelay(1);
1358 gpio_set_value(aic3x->gpio_reset, 1);
1359 }
1360
1348 return aic3x_register(codec); 1361 return aic3x_register(codec);
1362
1363err_enable:
1364 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1365err_get:
1366 if (aic3x->gpio_reset >= 0)
1367 gpio_free(aic3x->gpio_reset);
1368err_gpio:
1369 kfree(aic3x);
1370 return ret;
1349} 1371}
1350 1372
1351static int aic3x_i2c_remove(struct i2c_client *client) 1373static int aic3x_i2c_remove(struct i2c_client *client)
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index d1e0e81ef30c..65adc77eada1 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -51,6 +51,20 @@
51 51
52#define LATENCY_TIME_MS 20 52#define LATENCY_TIME_MS 20
53 53
54#define MODE7_LTHR 10
55#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10)
56
57#define BURST_BASEFREQ_HZ 49152000
58
59#define SAMPLES_TO_US(rate, samples) \
60 (1000000000 / ((rate * 1000) / samples))
61
62#define US_TO_SAMPLES(rate, us) \
63 (rate / (1000000 / us))
64
65static void dac33_calculate_times(struct snd_pcm_substream *substream);
66static int dac33_prepare_chip(struct snd_pcm_substream *substream);
67
54static struct snd_soc_codec *tlv320dac33_codec; 68static struct snd_soc_codec *tlv320dac33_codec;
55 69
56enum dac33_state { 70enum dac33_state {
@@ -80,6 +94,7 @@ struct tlv320dac33_priv {
80 struct work_struct work; 94 struct work_struct work;
81 struct snd_soc_codec codec; 95 struct snd_soc_codec codec;
82 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES]; 96 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
97 struct snd_pcm_substream *substream;
83 int power_gpio; 98 int power_gpio;
84 int chip_power; 99 int chip_power;
85 int irq; 100 int irq;
@@ -93,6 +108,17 @@ struct tlv320dac33_priv {
93 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ 108 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
94 unsigned int nsample; /* burst read amount from host */ 109 unsigned int nsample; /* burst read amount from host */
95 u8 burst_bclkdiv; /* BCLK divider value in burst mode */ 110 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
111 unsigned int burst_rate; /* Interface speed in Burst modes */
112
113 int keep_bclk; /* Keep the BCLK continuously running
114 * in FIFO modes */
115 spinlock_t lock;
116 unsigned long long t_stamp1; /* Time stamp for FIFO modes to */
117 unsigned long long t_stamp2; /* calculate the FIFO caused delay */
118
119 unsigned int mode1_us_burst; /* Time to burst read n number of
120 * samples */
121 unsigned int mode7_us_to_lthr; /* Time to reach lthr from uthr */
96 122
97 enum dac33_state state; 123 enum dac33_state state;
98}; 124};
@@ -166,7 +192,7 @@ static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
166static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, 192static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
167 u8 *value) 193 u8 *value)
168{ 194{
169 struct tlv320dac33_priv *dac33 = codec->private_data; 195 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
170 int val; 196 int val;
171 197
172 *value = reg & 0xff; 198 *value = reg & 0xff;
@@ -191,7 +217,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
191static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, 217static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
192 unsigned int value) 218 unsigned int value)
193{ 219{
194 struct tlv320dac33_priv *dac33 = codec->private_data; 220 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
195 u8 data[2]; 221 u8 data[2];
196 int ret = 0; 222 int ret = 0;
197 223
@@ -218,7 +244,7 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
218static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg, 244static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
219 unsigned int value) 245 unsigned int value)
220{ 246{
221 struct tlv320dac33_priv *dac33 = codec->private_data; 247 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
222 int ret; 248 int ret;
223 249
224 mutex_lock(&dac33->mutex); 250 mutex_lock(&dac33->mutex);
@@ -232,7 +258,7 @@ static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
232static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg, 258static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
233 unsigned int value) 259 unsigned int value)
234{ 260{
235 struct tlv320dac33_priv *dac33 = codec->private_data; 261 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
236 u8 data[3]; 262 u8 data[3];
237 int ret = 0; 263 int ret = 0;
238 264
@@ -262,45 +288,47 @@ static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
262 return ret; 288 return ret;
263} 289}
264 290
265static void dac33_restore_regs(struct snd_soc_codec *codec) 291static void dac33_init_chip(struct snd_soc_codec *codec)
266{ 292{
267 struct tlv320dac33_priv *dac33 = codec->private_data; 293 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
268 u8 *cache = codec->reg_cache;
269 u8 data[2];
270 int i, ret;
271 294
272 if (!dac33->chip_power) 295 if (unlikely(!dac33->chip_power))
273 return; 296 return;
274 297
275 for (i = DAC33_PWR_CTRL; i <= DAC33_INTP_CTRL_B; i++) { 298 /* 44-46: DAC Control Registers */
276 data[0] = i; 299 /* A : DAC sample rate Fsref/1.5 */
277 data[1] = cache[i]; 300 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
278 /* Skip the read only registers */ 301 /* B : DAC src=normal, not muted */
279 if ((i >= DAC33_INT_OSC_STATUS && 302 dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
280 i <= DAC33_INT_OSC_FREQ_RAT_READ_B) || 303 DAC33_DACSRCL_LEFT);
281 (i >= DAC33_FIFO_WPTR_MSB && i <= DAC33_FIFO_IRQ_FLAG) || 304 /* C : (defaults) */
282 i == DAC33_DAC_STATUS_FLAGS || 305 dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
283 i == DAC33_SRC_EST_REF_CLK_RATIO_A || 306
284 i == DAC33_SRC_EST_REF_CLK_RATIO_B) 307 /* 73 : volume soft stepping control,
285 continue; 308 clock source = internal osc (?) */
286 ret = codec->hw_write(codec->control_data, data, 2); 309 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
287 if (ret != 2) 310
288 dev_err(codec->dev, "Write failed (%d)\n", ret); 311 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
289 } 312
290 for (i = DAC33_LDAC_PWR_CTRL; i <= DAC33_LINEL_TO_LLO_VOL; i++) { 313 /* Restore only selected registers (gains mostly) */
291 data[0] = i; 314 dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
292 data[1] = cache[i]; 315 dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL));
293 ret = codec->hw_write(codec->control_data, data, 2); 316 dac33_write(codec, DAC33_RDAC_DIG_VOL_CTRL,
294 if (ret != 2) 317 dac33_read_reg_cache(codec, DAC33_RDAC_DIG_VOL_CTRL));
295 dev_err(codec->dev, "Write failed (%d)\n", ret); 318
296 } 319 dac33_write(codec, DAC33_LINEL_TO_LLO_VOL,
297 for (i = DAC33_LINER_TO_RLO_VOL; i <= DAC33_OSC_TRIM; i++) { 320 dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL));
298 data[0] = i; 321 dac33_write(codec, DAC33_LINER_TO_RLO_VOL,
299 data[1] = cache[i]; 322 dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL));
300 ret = codec->hw_write(codec->control_data, data, 2); 323}
301 if (ret != 2) 324
302 dev_err(codec->dev, "Write failed (%d)\n", ret); 325static inline void dac33_read_id(struct snd_soc_codec *codec)
303 } 326{
327 u8 reg;
328
329 dac33_read(codec, DAC33_DEVICE_ID_MSB, &reg);
330 dac33_read(codec, DAC33_DEVICE_ID_LSB, &reg);
331 dac33_read(codec, DAC33_DEVICE_REV_ID, &reg);
304} 332}
305 333
306static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) 334static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
@@ -311,16 +339,25 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
311 if (power) 339 if (power)
312 reg |= DAC33_PDNALLB; 340 reg |= DAC33_PDNALLB;
313 else 341 else
314 reg &= ~DAC33_PDNALLB; 342 reg &= ~(DAC33_PDNALLB | DAC33_OSCPDNB |
343 DAC33_DACRPDNB | DAC33_DACLPDNB);
315 dac33_write(codec, DAC33_PWR_CTRL, reg); 344 dac33_write(codec, DAC33_PWR_CTRL, reg);
316} 345}
317 346
318static int dac33_hard_power(struct snd_soc_codec *codec, int power) 347static int dac33_hard_power(struct snd_soc_codec *codec, int power)
319{ 348{
320 struct tlv320dac33_priv *dac33 = codec->private_data; 349 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
321 int ret; 350 int ret = 0;
322 351
323 mutex_lock(&dac33->mutex); 352 mutex_lock(&dac33->mutex);
353
354 /* Safety check */
355 if (unlikely(power == dac33->chip_power)) {
356 dev_dbg(codec->dev, "Trying to set the same power state: %s\n",
357 power ? "ON" : "OFF");
358 goto exit;
359 }
360
324 if (power) { 361 if (power) {
325 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies), 362 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
326 dac33->supplies); 363 dac33->supplies);
@@ -334,11 +371,6 @@ static int dac33_hard_power(struct snd_soc_codec *codec, int power)
334 gpio_set_value(dac33->power_gpio, 1); 371 gpio_set_value(dac33->power_gpio, 1);
335 372
336 dac33->chip_power = 1; 373 dac33->chip_power = 1;
337
338 /* Restore registers */
339 dac33_restore_regs(codec);
340
341 dac33_soft_power(codec, 1);
342 } else { 374 } else {
343 dac33_soft_power(codec, 0); 375 dac33_soft_power(codec, 0);
344 if (dac33->power_gpio >= 0) 376 if (dac33->power_gpio >= 0)
@@ -360,11 +392,27 @@ exit:
360 return ret; 392 return ret;
361} 393}
362 394
395static int playback_event(struct snd_soc_dapm_widget *w,
396 struct snd_kcontrol *kcontrol, int event)
397{
398 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
399
400 switch (event) {
401 case SND_SOC_DAPM_PRE_PMU:
402 if (likely(dac33->substream)) {
403 dac33_calculate_times(dac33->substream);
404 dac33_prepare_chip(dac33->substream);
405 }
406 break;
407 }
408 return 0;
409}
410
363static int dac33_get_nsample(struct snd_kcontrol *kcontrol, 411static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
364 struct snd_ctl_elem_value *ucontrol) 412 struct snd_ctl_elem_value *ucontrol)
365{ 413{
366 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 414 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
367 struct tlv320dac33_priv *dac33 = codec->private_data; 415 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
368 416
369 ucontrol->value.integer.value[0] = dac33->nsample; 417 ucontrol->value.integer.value[0] = dac33->nsample;
370 418
@@ -375,17 +423,21 @@ static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
375 struct snd_ctl_elem_value *ucontrol) 423 struct snd_ctl_elem_value *ucontrol)
376{ 424{
377 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 425 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
378 struct tlv320dac33_priv *dac33 = codec->private_data; 426 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
379 int ret = 0; 427 int ret = 0;
380 428
381 if (dac33->nsample == ucontrol->value.integer.value[0]) 429 if (dac33->nsample == ucontrol->value.integer.value[0])
382 return 0; 430 return 0;
383 431
384 if (ucontrol->value.integer.value[0] < dac33->nsample_min || 432 if (ucontrol->value.integer.value[0] < dac33->nsample_min ||
385 ucontrol->value.integer.value[0] > dac33->nsample_max) 433 ucontrol->value.integer.value[0] > dac33->nsample_max) {
386 ret = -EINVAL; 434 ret = -EINVAL;
387 else 435 } else {
388 dac33->nsample = ucontrol->value.integer.value[0]; 436 dac33->nsample = ucontrol->value.integer.value[0];
437 /* Re calculate the burst time */
438 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
439 dac33->nsample);
440 }
389 441
390 return ret; 442 return ret;
391} 443}
@@ -394,7 +446,7 @@ static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
394 struct snd_ctl_elem_value *ucontrol) 446 struct snd_ctl_elem_value *ucontrol)
395{ 447{
396 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 448 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
397 struct tlv320dac33_priv *dac33 = codec->private_data; 449 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
398 450
399 ucontrol->value.integer.value[0] = dac33->fifo_mode; 451 ucontrol->value.integer.value[0] = dac33->fifo_mode;
400 452
@@ -405,7 +457,7 @@ static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
405 struct snd_ctl_elem_value *ucontrol) 457 struct snd_ctl_elem_value *ucontrol)
406{ 458{
407 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 459 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
408 struct tlv320dac33_priv *dac33 = codec->private_data; 460 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
409 int ret = 0; 461 int ret = 0;
410 462
411 if (dac33->fifo_mode == ucontrol->value.integer.value[0]) 463 if (dac33->fifo_mode == ucontrol->value.integer.value[0])
@@ -485,6 +537,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
485 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0), 537 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
486 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power", 538 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power",
487 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0), 539 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
540
541 SND_SOC_DAPM_PRE("Prepare Playback", playback_event),
488}; 542};
489 543
490static const struct snd_soc_dapm_route audio_map[] = { 544static const struct snd_soc_dapm_route audio_map[] = {
@@ -527,18 +581,21 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
527 break; 581 break;
528 case SND_SOC_BIAS_STANDBY: 582 case SND_SOC_BIAS_STANDBY:
529 if (codec->bias_level == SND_SOC_BIAS_OFF) { 583 if (codec->bias_level == SND_SOC_BIAS_OFF) {
584 /* Coming from OFF, switch on the codec */
530 ret = dac33_hard_power(codec, 1); 585 ret = dac33_hard_power(codec, 1);
531 if (ret != 0) 586 if (ret != 0)
532 return ret; 587 return ret;
533 }
534 588
535 dac33_soft_power(codec, 0); 589 dac33_init_chip(codec);
590 }
536 break; 591 break;
537 case SND_SOC_BIAS_OFF: 592 case SND_SOC_BIAS_OFF:
593 /* Do not power off, when the codec is already off */
594 if (codec->bias_level == SND_SOC_BIAS_OFF)
595 return 0;
538 ret = dac33_hard_power(codec, 0); 596 ret = dac33_hard_power(codec, 0);
539 if (ret != 0) 597 if (ret != 0)
540 return ret; 598 return ret;
541
542 break; 599 break;
543 } 600 }
544 codec->bias_level = level; 601 codec->bias_level = level;
@@ -555,13 +612,34 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
555 switch (dac33->fifo_mode) { 612 switch (dac33->fifo_mode) {
556 case DAC33_FIFO_MODE1: 613 case DAC33_FIFO_MODE1:
557 dac33_write16(codec, DAC33_NSAMPLE_MSB, 614 dac33_write16(codec, DAC33_NSAMPLE_MSB,
558 DAC33_THRREG(dac33->nsample)); 615 DAC33_THRREG(dac33->nsample + dac33->alarm_threshold));
616
617 /* Take the timestamps */
618 spin_lock_irq(&dac33->lock);
619 dac33->t_stamp2 = ktime_to_us(ktime_get());
620 dac33->t_stamp1 = dac33->t_stamp2;
621 spin_unlock_irq(&dac33->lock);
622
559 dac33_write16(codec, DAC33_PREFILL_MSB, 623 dac33_write16(codec, DAC33_PREFILL_MSB,
560 DAC33_THRREG(dac33->alarm_threshold)); 624 DAC33_THRREG(dac33->alarm_threshold));
625 /* Enable Alarm Threshold IRQ with a delay */
626 udelay(SAMPLES_TO_US(dac33->burst_rate,
627 dac33->alarm_threshold));
628 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
561 break; 629 break;
562 case DAC33_FIFO_MODE7: 630 case DAC33_FIFO_MODE7:
631 /* Take the timestamp */
632 spin_lock_irq(&dac33->lock);
633 dac33->t_stamp1 = ktime_to_us(ktime_get());
634 /* Move back the timestamp with drain time */
635 dac33->t_stamp1 -= dac33->mode7_us_to_lthr;
636 spin_unlock_irq(&dac33->lock);
637
563 dac33_write16(codec, DAC33_PREFILL_MSB, 638 dac33_write16(codec, DAC33_PREFILL_MSB,
564 DAC33_THRREG(10)); 639 DAC33_THRREG(MODE7_LTHR));
640
641 /* Enable Upper Threshold IRQ */
642 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
565 break; 643 break;
566 default: 644 default:
567 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n", 645 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
@@ -578,6 +656,11 @@ static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
578 656
579 switch (dac33->fifo_mode) { 657 switch (dac33->fifo_mode) {
580 case DAC33_FIFO_MODE1: 658 case DAC33_FIFO_MODE1:
659 /* Take the timestamp */
660 spin_lock_irq(&dac33->lock);
661 dac33->t_stamp2 = ktime_to_us(ktime_get());
662 spin_unlock_irq(&dac33->lock);
663
581 dac33_write16(codec, DAC33_NSAMPLE_MSB, 664 dac33_write16(codec, DAC33_NSAMPLE_MSB,
582 DAC33_THRREG(dac33->nsample)); 665 DAC33_THRREG(dac33->nsample));
583 break; 666 break;
@@ -628,31 +711,17 @@ static void dac33_work(struct work_struct *work)
628static irqreturn_t dac33_interrupt_handler(int irq, void *dev) 711static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
629{ 712{
630 struct snd_soc_codec *codec = dev; 713 struct snd_soc_codec *codec = dev;
631 struct tlv320dac33_priv *dac33 = codec->private_data; 714 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
632
633 queue_work(dac33->dac33_wq, &dac33->work);
634 715
635 return IRQ_HANDLED; 716 spin_lock(&dac33->lock);
636} 717 dac33->t_stamp1 = ktime_to_us(ktime_get());
718 spin_unlock(&dac33->lock);
637 719
638static void dac33_shutdown(struct snd_pcm_substream *substream, 720 /* Do not schedule the workqueue in Mode7 */
639 struct snd_soc_dai *dai) 721 if (dac33->fifo_mode != DAC33_FIFO_MODE7)
640{ 722 queue_work(dac33->dac33_wq, &dac33->work);
641 struct snd_soc_pcm_runtime *rtd = substream->private_data;
642 struct snd_soc_device *socdev = rtd->socdev;
643 struct snd_soc_codec *codec = socdev->card->codec;
644 struct tlv320dac33_priv *dac33 = codec->private_data;
645 unsigned int pwr_ctrl;
646 723
647 /* Stop pending workqueue */ 724 return IRQ_HANDLED;
648 if (dac33->fifo_mode)
649 cancel_work_sync(&dac33->work);
650
651 mutex_lock(&dac33->mutex);
652 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
653 pwr_ctrl &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
654 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
655 mutex_unlock(&dac33->mutex);
656} 725}
657 726
658static void dac33_oscwait(struct snd_soc_codec *codec) 727static void dac33_oscwait(struct snd_soc_codec *codec)
@@ -669,6 +738,31 @@ static void dac33_oscwait(struct snd_soc_codec *codec)
669 "internal oscillator calibration failed\n"); 738 "internal oscillator calibration failed\n");
670} 739}
671 740
741static int dac33_startup(struct snd_pcm_substream *substream,
742 struct snd_soc_dai *dai)
743{
744 struct snd_soc_pcm_runtime *rtd = substream->private_data;
745 struct snd_soc_device *socdev = rtd->socdev;
746 struct snd_soc_codec *codec = socdev->card->codec;
747 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
748
749 /* Stream started, save the substream pointer */
750 dac33->substream = substream;
751
752 return 0;
753}
754
755static void dac33_shutdown(struct snd_pcm_substream *substream,
756 struct snd_soc_dai *dai)
757{
758 struct snd_soc_pcm_runtime *rtd = substream->private_data;
759 struct snd_soc_device *socdev = rtd->socdev;
760 struct snd_soc_codec *codec = socdev->card->codec;
761 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
762
763 dac33->substream = NULL;
764}
765
672static int dac33_hw_params(struct snd_pcm_substream *substream, 766static int dac33_hw_params(struct snd_pcm_substream *substream,
673 struct snd_pcm_hw_params *params, 767 struct snd_pcm_hw_params *params,
674 struct snd_soc_dai *dai) 768 struct snd_soc_dai *dai)
@@ -715,7 +809,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
715 struct snd_soc_pcm_runtime *rtd = substream->private_data; 809 struct snd_soc_pcm_runtime *rtd = substream->private_data;
716 struct snd_soc_device *socdev = rtd->socdev; 810 struct snd_soc_device *socdev = rtd->socdev;
717 struct snd_soc_codec *codec = socdev->card->codec; 811 struct snd_soc_codec *codec = socdev->card->codec;
718 struct tlv320dac33_priv *dac33 = codec->private_data; 812 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
719 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp; 813 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
720 u8 aictrl_a, aictrl_b, fifoctrl_a; 814 u8 aictrl_a, aictrl_b, fifoctrl_a;
721 815
@@ -752,6 +846,17 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
752 } 846 }
753 847
754 mutex_lock(&dac33->mutex); 848 mutex_lock(&dac33->mutex);
849
850 if (!dac33->chip_power) {
851 /*
852 * Chip is not powered yet.
853 * Do the init in the dac33_set_bias_level later.
854 */
855 mutex_unlock(&dac33->mutex);
856 return 0;
857 }
858
859 dac33_soft_power(codec, 0);
755 dac33_soft_power(codec, 1); 860 dac33_soft_power(codec, 1);
756 861
757 reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL); 862 reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
@@ -799,11 +904,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
799 case DAC33_FIFO_MODE1: 904 case DAC33_FIFO_MODE1:
800 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B, 905 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
801 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL)); 906 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
802 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
803 break; 907 break;
804 case DAC33_FIFO_MODE7: 908 case DAC33_FIFO_MODE7:
805 /* Disable all interrupts */ 909 dac33_write(codec, DAC33_FIFO_IRQ_MODE_A,
806 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0); 910 DAC33_UTM(DAC33_FIFO_IRQ_MODE_LEVEL));
807 break; 911 break;
808 default: 912 default:
809 /* in FIFO bypass mode, the interrupts are not used */ 913 /* in FIFO bypass mode, the interrupts are not used */
@@ -822,7 +926,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
822 */ 926 */
823 fifoctrl_a &= ~DAC33_FBYPAS; 927 fifoctrl_a &= ~DAC33_FBYPAS;
824 fifoctrl_a &= ~DAC33_FAUTO; 928 fifoctrl_a &= ~DAC33_FAUTO;
825 aictrl_b &= ~DAC33_BCLKON; 929 if (dac33->keep_bclk)
930 aictrl_b |= DAC33_BCLKON;
931 else
932 aictrl_b &= ~DAC33_BCLKON;
826 break; 933 break;
827 case DAC33_FIFO_MODE7: 934 case DAC33_FIFO_MODE7:
828 /* 935 /*
@@ -833,7 +940,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
833 */ 940 */
834 fifoctrl_a &= ~DAC33_FBYPAS; 941 fifoctrl_a &= ~DAC33_FBYPAS;
835 fifoctrl_a |= DAC33_FAUTO; 942 fifoctrl_a |= DAC33_FAUTO;
836 aictrl_b &= ~DAC33_BCLKON; 943 if (dac33->keep_bclk)
944 aictrl_b |= DAC33_BCLKON;
945 else
946 aictrl_b &= ~DAC33_BCLKON;
837 break; 947 break;
838 default: 948 default:
839 /* 949 /*
@@ -875,10 +985,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
875 * Configure the threshold levels, and leave 10 sample space 985 * Configure the threshold levels, and leave 10 sample space
876 * at the bottom, and also at the top of the FIFO 986 * at the bottom, and also at the top of the FIFO
877 */ 987 */
878 dac33_write16(codec, DAC33_UTHR_MSB, 988 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(MODE7_UTHR));
879 DAC33_THRREG(DAC33_BUFFER_SIZE_SAMPLES - 10)); 989 dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR));
880 dac33_write16(codec, DAC33_LTHR_MSB,
881 DAC33_THRREG(10));
882 break; 990 break;
883 default: 991 default:
884 break; 992 break;
@@ -894,9 +1002,13 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
894 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1002 struct snd_soc_pcm_runtime *rtd = substream->private_data;
895 struct snd_soc_device *socdev = rtd->socdev; 1003 struct snd_soc_device *socdev = rtd->socdev;
896 struct snd_soc_codec *codec = socdev->card->codec; 1004 struct snd_soc_codec *codec = socdev->card->codec;
897 struct tlv320dac33_priv *dac33 = codec->private_data; 1005 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
898 unsigned int nsample_limit; 1006 unsigned int nsample_limit;
899 1007
1008 /* In bypass mode we don't need to calculate */
1009 if (!dac33->fifo_mode)
1010 return;
1011
900 /* Number of samples (16bit, stereo) in one period */ 1012 /* Number of samples (16bit, stereo) in one period */
901 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4; 1013 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
902 1014
@@ -930,15 +1042,24 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
930 1042
931 if (dac33->nsample > dac33->nsample_max) 1043 if (dac33->nsample > dac33->nsample_max)
932 dac33->nsample = dac33->nsample_max; 1044 dac33->nsample = dac33->nsample_max;
933}
934 1045
935static int dac33_pcm_prepare(struct snd_pcm_substream *substream, 1046 switch (dac33->fifo_mode) {
936 struct snd_soc_dai *dai) 1047 case DAC33_FIFO_MODE1:
937{ 1048 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
938 dac33_calculate_times(substream); 1049 dac33->nsample);
939 dac33_prepare_chip(substream); 1050 dac33->t_stamp1 = 0;
1051 dac33->t_stamp2 = 0;
1052 break;
1053 case DAC33_FIFO_MODE7:
1054 dac33->mode7_us_to_lthr =
1055 SAMPLES_TO_US(substream->runtime->rate,
1056 MODE7_UTHR - MODE7_LTHR + 1);
1057 dac33->t_stamp1 = 0;
1058 break;
1059 default:
1060 break;
1061 }
940 1062
941 return 0;
942} 1063}
943 1064
944static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd, 1065static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -947,7 +1068,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
947 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1068 struct snd_soc_pcm_runtime *rtd = substream->private_data;
948 struct snd_soc_device *socdev = rtd->socdev; 1069 struct snd_soc_device *socdev = rtd->socdev;
949 struct snd_soc_codec *codec = socdev->card->codec; 1070 struct snd_soc_codec *codec = socdev->card->codec;
950 struct tlv320dac33_priv *dac33 = codec->private_data; 1071 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
951 int ret = 0; 1072 int ret = 0;
952 1073
953 switch (cmd) { 1074 switch (cmd) {
@@ -974,11 +1095,156 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
974 return ret; 1095 return ret;
975} 1096}
976 1097
1098static snd_pcm_sframes_t dac33_dai_delay(
1099 struct snd_pcm_substream *substream,
1100 struct snd_soc_dai *dai)
1101{
1102 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1103 struct snd_soc_device *socdev = rtd->socdev;
1104 struct snd_soc_codec *codec = socdev->card->codec;
1105 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1106 unsigned long long t0, t1, t_now;
1107 unsigned int time_delta;
1108 int samples_out, samples_in, samples;
1109 snd_pcm_sframes_t delay = 0;
1110
1111 switch (dac33->fifo_mode) {
1112 case DAC33_FIFO_BYPASS:
1113 break;
1114 case DAC33_FIFO_MODE1:
1115 spin_lock(&dac33->lock);
1116 t0 = dac33->t_stamp1;
1117 t1 = dac33->t_stamp2;
1118 spin_unlock(&dac33->lock);
1119 t_now = ktime_to_us(ktime_get());
1120
1121 /* We have not started to fill the FIFO yet, delay is 0 */
1122 if (!t1)
1123 goto out;
1124
1125 if (t0 > t1) {
1126 /*
1127 * Phase 1:
1128 * After Alarm threshold, and before nSample write
1129 */
1130 time_delta = t_now - t0;
1131 samples_out = time_delta ? US_TO_SAMPLES(
1132 substream->runtime->rate,
1133 time_delta) : 0;
1134
1135 if (likely(dac33->alarm_threshold > samples_out))
1136 delay = dac33->alarm_threshold - samples_out;
1137 else
1138 delay = 0;
1139 } else if ((t_now - t1) <= dac33->mode1_us_burst) {
1140 /*
1141 * Phase 2:
1142 * After nSample write (during burst operation)
1143 */
1144 time_delta = t_now - t0;
1145 samples_out = time_delta ? US_TO_SAMPLES(
1146 substream->runtime->rate,
1147 time_delta) : 0;
1148
1149 time_delta = t_now - t1;
1150 samples_in = time_delta ? US_TO_SAMPLES(
1151 dac33->burst_rate,
1152 time_delta) : 0;
1153
1154 samples = dac33->alarm_threshold;
1155 samples += (samples_in - samples_out);
1156
1157 if (likely(samples > 0))
1158 delay = samples;
1159 else
1160 delay = 0;
1161 } else {
1162 /*
1163 * Phase 3:
1164 * After burst operation, before next alarm threshold
1165 */
1166 time_delta = t_now - t0;
1167 samples_out = time_delta ? US_TO_SAMPLES(
1168 substream->runtime->rate,
1169 time_delta) : 0;
1170
1171 samples_in = dac33->nsample;
1172 samples = dac33->alarm_threshold;
1173 samples += (samples_in - samples_out);
1174
1175 if (likely(samples > 0))
1176 delay = samples > DAC33_BUFFER_SIZE_SAMPLES ?
1177 DAC33_BUFFER_SIZE_SAMPLES : samples;
1178 else
1179 delay = 0;
1180 }
1181 break;
1182 case DAC33_FIFO_MODE7:
1183 spin_lock(&dac33->lock);
1184 t0 = dac33->t_stamp1;
1185 spin_unlock(&dac33->lock);
1186 t_now = ktime_to_us(ktime_get());
1187
1188 /* We have not started to fill the FIFO yet, delay is 0 */
1189 if (!t0)
1190 goto out;
1191
1192 if (t_now <= t0) {
1193 /*
1194 * Either the timestamps are messed or equal. Report
1195 * maximum delay
1196 */
1197 delay = MODE7_UTHR;
1198 goto out;
1199 }
1200
1201 time_delta = t_now - t0;
1202 if (time_delta <= dac33->mode7_us_to_lthr) {
1203 /*
1204 * Phase 1:
1205 * After burst (draining phase)
1206 */
1207 samples_out = US_TO_SAMPLES(
1208 substream->runtime->rate,
1209 time_delta);
1210
1211 if (likely(MODE7_UTHR > samples_out))
1212 delay = MODE7_UTHR - samples_out;
1213 else
1214 delay = 0;
1215 } else {
1216 /*
1217 * Phase 2:
1218 * During burst operation
1219 */
1220 time_delta = time_delta - dac33->mode7_us_to_lthr;
1221
1222 samples_out = US_TO_SAMPLES(
1223 substream->runtime->rate,
1224 time_delta);
1225 samples_in = US_TO_SAMPLES(
1226 dac33->burst_rate,
1227 time_delta);
1228 delay = MODE7_LTHR + samples_in - samples_out;
1229
1230 if (unlikely(delay > MODE7_UTHR))
1231 delay = MODE7_UTHR;
1232 }
1233 break;
1234 default:
1235 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
1236 dac33->fifo_mode);
1237 break;
1238 }
1239out:
1240 return delay;
1241}
1242
977static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai, 1243static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
978 int clk_id, unsigned int freq, int dir) 1244 int clk_id, unsigned int freq, int dir)
979{ 1245{
980 struct snd_soc_codec *codec = codec_dai->codec; 1246 struct snd_soc_codec *codec = codec_dai->codec;
981 struct tlv320dac33_priv *dac33 = codec->private_data; 1247 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
982 u8 ioc_reg, asrcb_reg; 1248 u8 ioc_reg, asrcb_reg;
983 1249
984 ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL); 1250 ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
@@ -1008,7 +1274,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
1008 unsigned int fmt) 1274 unsigned int fmt)
1009{ 1275{
1010 struct snd_soc_codec *codec = codec_dai->codec; 1276 struct snd_soc_codec *codec = codec_dai->codec;
1011 struct tlv320dac33_priv *dac33 = codec->private_data; 1277 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1012 u8 aictrl_a, aictrl_b; 1278 u8 aictrl_a, aictrl_b;
1013 1279
1014 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A); 1280 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
@@ -1059,35 +1325,6 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
1059 return 0; 1325 return 0;
1060} 1326}
1061 1327
1062static void dac33_init_chip(struct snd_soc_codec *codec)
1063{
1064 /* 44-46: DAC Control Registers */
1065 /* A : DAC sample rate Fsref/1.5 */
1066 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
1067 /* B : DAC src=normal, not muted */
1068 dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
1069 DAC33_DACSRCL_LEFT);
1070 /* C : (defaults) */
1071 dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
1072
1073 /* 64-65 : L&R DAC power control
1074 Line In -> OUT 1V/V Gain, DAC -> OUT 4V/V Gain*/
1075 dac33_write(codec, DAC33_LDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
1076 dac33_write(codec, DAC33_RDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
1077
1078 /* 73 : volume soft stepping control,
1079 clock source = internal osc (?) */
1080 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
1081
1082 /* 66 : LOP/LOM Modes */
1083 dac33_write(codec, DAC33_OUT_AMP_CM_CTRL, 0xff);
1084
1085 /* 68 : LOM inverted from LOP */
1086 dac33_write(codec, DAC33_OUT_AMP_CTRL, (3<<2));
1087
1088 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
1089}
1090
1091static int dac33_soc_probe(struct platform_device *pdev) 1328static int dac33_soc_probe(struct platform_device *pdev)
1092{ 1329{
1093 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1330 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -1099,12 +1336,7 @@ static int dac33_soc_probe(struct platform_device *pdev)
1099 1336
1100 codec = tlv320dac33_codec; 1337 codec = tlv320dac33_codec;
1101 socdev->card->codec = codec; 1338 socdev->card->codec = codec;
1102 dac33 = codec->private_data; 1339 dac33 = snd_soc_codec_get_drvdata(codec);
1103
1104 /* Power up the codec */
1105 dac33_hard_power(codec, 1);
1106 /* Set default configuration */
1107 dac33_init_chip(codec);
1108 1340
1109 /* register pcms */ 1341 /* register pcms */
1110 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1342 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -1122,12 +1354,6 @@ static int dac33_soc_probe(struct platform_device *pdev)
1122 1354
1123 dac33_add_widgets(codec); 1355 dac33_add_widgets(codec);
1124 1356
1125 /* power on device */
1126 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1127
1128 /* Bias level configuration has enabled regulator an extra time */
1129 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1130
1131 return 0; 1357 return 0;
1132 1358
1133pcm_err: 1359pcm_err:
@@ -1164,7 +1390,6 @@ static int dac33_soc_resume(struct platform_device *pdev)
1164 struct snd_soc_codec *codec = socdev->card->codec; 1390 struct snd_soc_codec *codec = socdev->card->codec;
1165 1391
1166 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1392 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1167 dac33_set_bias_level(codec, codec->suspend_bias_level);
1168 1393
1169 return 0; 1394 return 0;
1170} 1395}
@@ -1182,10 +1407,11 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320dac33);
1182#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE 1407#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE
1183 1408
1184static struct snd_soc_dai_ops dac33_dai_ops = { 1409static struct snd_soc_dai_ops dac33_dai_ops = {
1410 .startup = dac33_startup,
1185 .shutdown = dac33_shutdown, 1411 .shutdown = dac33_shutdown,
1186 .hw_params = dac33_hw_params, 1412 .hw_params = dac33_hw_params,
1187 .prepare = dac33_pcm_prepare,
1188 .trigger = dac33_pcm_trigger, 1413 .trigger = dac33_pcm_trigger,
1414 .delay = dac33_dai_delay,
1189 .set_sysclk = dac33_set_dai_sysclk, 1415 .set_sysclk = dac33_set_dai_sysclk,
1190 .set_fmt = dac33_set_dai_fmt, 1416 .set_fmt = dac33_set_dai_fmt,
1191}; 1417};
@@ -1221,11 +1447,12 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1221 return -ENOMEM; 1447 return -ENOMEM;
1222 1448
1223 codec = &dac33->codec; 1449 codec = &dac33->codec;
1224 codec->private_data = dac33; 1450 snd_soc_codec_set_drvdata(codec, dac33);
1225 codec->control_data = client; 1451 codec->control_data = client;
1226 1452
1227 mutex_init(&codec->mutex); 1453 mutex_init(&codec->mutex);
1228 mutex_init(&dac33->mutex); 1454 mutex_init(&dac33->mutex);
1455 spin_lock_init(&dac33->lock);
1229 INIT_LIST_HEAD(&codec->dapm_widgets); 1456 INIT_LIST_HEAD(&codec->dapm_widgets);
1230 INIT_LIST_HEAD(&codec->dapm_paths); 1457 INIT_LIST_HEAD(&codec->dapm_paths);
1231 1458
@@ -1236,6 +1463,7 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1236 codec->hw_write = (hw_write_t) i2c_master_send; 1463 codec->hw_write = (hw_write_t) i2c_master_send;
1237 codec->bias_level = SND_SOC_BIAS_OFF; 1464 codec->bias_level = SND_SOC_BIAS_OFF;
1238 codec->set_bias_level = dac33_set_bias_level; 1465 codec->set_bias_level = dac33_set_bias_level;
1466 codec->idle_bias_off = 1;
1239 codec->dai = &dac33_dai; 1467 codec->dai = &dac33_dai;
1240 codec->num_dai = 1; 1468 codec->num_dai = 1;
1241 codec->reg_cache_size = ARRAY_SIZE(dac33_reg); 1469 codec->reg_cache_size = ARRAY_SIZE(dac33_reg);
@@ -1250,8 +1478,12 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1250 1478
1251 dac33->power_gpio = pdata->power_gpio; 1479 dac33->power_gpio = pdata->power_gpio;
1252 dac33->burst_bclkdiv = pdata->burst_bclkdiv; 1480 dac33->burst_bclkdiv = pdata->burst_bclkdiv;
1481 /* Pre calculate the burst rate */
1482 dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
1483 dac33->keep_bclk = pdata->keep_bclk;
1253 dac33->irq = client->irq; 1484 dac33->irq = client->irq;
1254 dac33->nsample = NSAMPLE_MAX; 1485 dac33->nsample = NSAMPLE_MAX;
1486 dac33->nsample_max = NSAMPLE_MAX;
1255 /* Disable FIFO use by default */ 1487 /* Disable FIFO use by default */
1256 dac33->fifo_mode = DAC33_FIFO_BYPASS; 1488 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1257 1489
@@ -1272,8 +1504,6 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1272 goto error_gpio; 1504 goto error_gpio;
1273 } 1505 }
1274 gpio_direction_output(dac33->power_gpio, 0); 1506 gpio_direction_output(dac33->power_gpio, 0);
1275 } else {
1276 dac33->chip_power = 1;
1277 } 1507 }
1278 1508
1279 /* Check if the IRQ number is valid and request it */ 1509 /* Check if the IRQ number is valid and request it */
@@ -1311,12 +1541,14 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1311 goto err_get; 1541 goto err_get;
1312 } 1542 }
1313 1543
1314 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies), 1544 /* Read the tlv320dac33 ID registers */
1315 dac33->supplies); 1545 ret = dac33_hard_power(codec, 1);
1316 if (ret != 0) { 1546 if (ret != 0) {
1317 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 1547 dev_err(codec->dev, "Failed to power up codec: %d\n", ret);
1318 goto err_enable; 1548 goto error_codec;
1319 } 1549 }
1550 dac33_read_id(codec);
1551 dac33_hard_power(codec, 0);
1320 1552
1321 ret = snd_soc_register_codec(codec); 1553 ret = snd_soc_register_codec(codec);
1322 if (ret != 0) { 1554 if (ret != 0) {
@@ -1331,14 +1563,9 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1331 goto error_codec; 1563 goto error_codec;
1332 } 1564 }
1333 1565
1334 /* Shut down the codec for now */
1335 dac33_hard_power(codec, 0);
1336
1337 return ret; 1566 return ret;
1338 1567
1339error_codec: 1568error_codec:
1340 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1341err_enable:
1342 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies); 1569 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1343err_get: 1570err_get:
1344 if (dac33->irq >= 0) { 1571 if (dac33->irq >= 0) {
@@ -1362,7 +1589,9 @@ static int __devexit dac33_i2c_remove(struct i2c_client *client)
1362 struct tlv320dac33_priv *dac33; 1589 struct tlv320dac33_priv *dac33;
1363 1590
1364 dac33 = i2c_get_clientdata(client); 1591 dac33 = i2c_get_clientdata(client);
1365 dac33_hard_power(&dac33->codec, 0); 1592
1593 if (unlikely(dac33->chip_power))
1594 dac33_hard_power(&dac33->codec, 0);
1366 1595
1367 if (dac33->power_gpio >= 0) 1596 if (dac33->power_gpio >= 0)
1368 gpio_free(dac33->power_gpio); 1597 gpio_free(dac33->power_gpio);
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 569ad8758a84..99b70e5978a2 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -36,24 +36,14 @@
36 36
37static struct i2c_client *tpa6130a2_client; 37static struct i2c_client *tpa6130a2_client;
38 38
39#define TPA6130A2_NUM_SUPPLIES 2
40static const char *tpa6130a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
41 "CPVSS",
42 "Vdd",
43};
44
45static const char *tpa6140a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
46 "HPVdd",
47 "AVdd",
48};
49
50/* This struct is used to save the context */ 39/* This struct is used to save the context */
51struct tpa6130a2_data { 40struct tpa6130a2_data {
52 struct mutex mutex; 41 struct mutex mutex;
53 unsigned char regs[TPA6130A2_CACHEREGNUM]; 42 unsigned char regs[TPA6130A2_CACHEREGNUM];
54 struct regulator_bulk_data supplies[TPA6130A2_NUM_SUPPLIES]; 43 struct regulator *supply;
55 int power_gpio; 44 int power_gpio;
56 unsigned char power_state; 45 unsigned char power_state;
46 enum tpa_model id;
57}; 47};
58 48
59static int tpa6130a2_i2c_read(int reg) 49static int tpa6130a2_i2c_read(int reg)
@@ -135,11 +125,10 @@ static int tpa6130a2_power(int power)
135 if (data->power_gpio >= 0) 125 if (data->power_gpio >= 0)
136 gpio_set_value(data->power_gpio, 1); 126 gpio_set_value(data->power_gpio, 1);
137 127
138 ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies), 128 ret = regulator_enable(data->supply);
139 data->supplies);
140 if (ret != 0) { 129 if (ret != 0) {
141 dev_err(&tpa6130a2_client->dev, 130 dev_err(&tpa6130a2_client->dev,
142 "Failed to enable supplies: %d\n", ret); 131 "Failed to enable supply: %d\n", ret);
143 goto exit; 132 goto exit;
144 } 133 }
145 134
@@ -160,11 +149,10 @@ static int tpa6130a2_power(int power)
160 if (data->power_gpio >= 0) 149 if (data->power_gpio >= 0)
161 gpio_set_value(data->power_gpio, 0); 150 gpio_set_value(data->power_gpio, 0);
162 151
163 ret = regulator_bulk_disable(ARRAY_SIZE(data->supplies), 152 ret = regulator_disable(data->supply);
164 data->supplies);
165 if (ret != 0) { 153 if (ret != 0) {
166 dev_err(&tpa6130a2_client->dev, 154 dev_err(&tpa6130a2_client->dev,
167 "Failed to disable supplies: %d\n", ret); 155 "Failed to disable supply: %d\n", ret);
168 goto exit; 156 goto exit;
169 } 157 }
170 158
@@ -176,7 +164,7 @@ exit:
176 return ret; 164 return ret;
177} 165}
178 166
179static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol, 167static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol) 168 struct snd_ctl_elem_value *ucontrol)
181{ 169{
182 struct soc_mixer_control *mc = 170 struct soc_mixer_control *mc =
@@ -184,7 +172,8 @@ static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
184 struct tpa6130a2_data *data; 172 struct tpa6130a2_data *data;
185 unsigned int reg = mc->reg; 173 unsigned int reg = mc->reg;
186 unsigned int shift = mc->shift; 174 unsigned int shift = mc->shift;
187 unsigned int mask = mc->max; 175 int max = mc->max;
176 unsigned int mask = (1 << fls(max)) - 1;
188 unsigned int invert = mc->invert; 177 unsigned int invert = mc->invert;
189 178
190 BUG_ON(tpa6130a2_client == NULL); 179 BUG_ON(tpa6130a2_client == NULL);
@@ -197,13 +186,13 @@ static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
197 186
198 if (invert) 187 if (invert)
199 ucontrol->value.integer.value[0] = 188 ucontrol->value.integer.value[0] =
200 mask - ucontrol->value.integer.value[0]; 189 max - ucontrol->value.integer.value[0];
201 190
202 mutex_unlock(&data->mutex); 191 mutex_unlock(&data->mutex);
203 return 0; 192 return 0;
204} 193}
205 194
206static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol, 195static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol) 196 struct snd_ctl_elem_value *ucontrol)
208{ 197{
209 struct soc_mixer_control *mc = 198 struct soc_mixer_control *mc =
@@ -211,7 +200,8 @@ static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol,
211 struct tpa6130a2_data *data; 200 struct tpa6130a2_data *data;
212 unsigned int reg = mc->reg; 201 unsigned int reg = mc->reg;
213 unsigned int shift = mc->shift; 202 unsigned int shift = mc->shift;
214 unsigned int mask = mc->max; 203 int max = mc->max;
204 unsigned int mask = (1 << fls(max)) - 1;
215 unsigned int invert = mc->invert; 205 unsigned int invert = mc->invert;
216 unsigned int val = (ucontrol->value.integer.value[0] & mask); 206 unsigned int val = (ucontrol->value.integer.value[0] & mask);
217 unsigned int val_reg; 207 unsigned int val_reg;
@@ -220,7 +210,7 @@ static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol,
220 data = i2c_get_clientdata(tpa6130a2_client); 210 data = i2c_get_clientdata(tpa6130a2_client);
221 211
222 if (invert) 212 if (invert)
223 val = mask - val; 213 val = max - val;
224 214
225 mutex_lock(&data->mutex); 215 mutex_lock(&data->mutex);
226 216
@@ -260,10 +250,24 @@ static const unsigned int tpa6130_tlv[] = {
260static const struct snd_kcontrol_new tpa6130a2_controls[] = { 250static const struct snd_kcontrol_new tpa6130a2_controls[] = {
261 SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume", 251 SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume",
262 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0, 252 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
263 tpa6130a2_get_reg, tpa6130a2_set_reg, 253 tpa6130a2_get_volsw, tpa6130a2_put_volsw,
264 tpa6130_tlv), 254 tpa6130_tlv),
265}; 255};
266 256
257static const unsigned int tpa6140_tlv[] = {
258 TLV_DB_RANGE_HEAD(3),
259 0, 8, TLV_DB_SCALE_ITEM(-5900, 400, 0),
260 9, 16, TLV_DB_SCALE_ITEM(-2500, 200, 0),
261 17, 31, TLV_DB_SCALE_ITEM(-1000, 100, 0),
262};
263
264static const struct snd_kcontrol_new tpa6140a2_controls[] = {
265 SOC_SINGLE_EXT_TLV("TPA6140A2 Headphone Playback Volume",
266 TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
267 tpa6130a2_get_volsw, tpa6130a2_put_volsw,
268 tpa6140_tlv),
269};
270
267/* 271/*
268 * Enable or disable channel (left or right) 272 * Enable or disable channel (left or right)
269 * The bit number for mute and amplifier are the same per channel: 273 * The bit number for mute and amplifier are the same per channel:
@@ -355,8 +359,8 @@ static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
355 0, 0, tpa6130a2_supply_event, 359 0, 0, tpa6130a2_supply_event,
356 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 360 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
357 /* Outputs */ 361 /* Outputs */
358 SND_SOC_DAPM_HP("TPA6130A2 Headphone Left", NULL), 362 SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Left"),
359 SND_SOC_DAPM_HP("TPA6130A2 Headphone Right", NULL), 363 SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Right"),
360}; 364};
361 365
362static const struct snd_soc_dapm_route audio_map[] = { 366static const struct snd_soc_dapm_route audio_map[] = {
@@ -369,13 +373,22 @@ static const struct snd_soc_dapm_route audio_map[] = {
369 373
370int tpa6130a2_add_controls(struct snd_soc_codec *codec) 374int tpa6130a2_add_controls(struct snd_soc_codec *codec)
371{ 375{
376 struct tpa6130a2_data *data;
377
378 BUG_ON(tpa6130a2_client == NULL);
379 data = i2c_get_clientdata(tpa6130a2_client);
380
372 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets, 381 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
373 ARRAY_SIZE(tpa6130a2_dapm_widgets)); 382 ARRAY_SIZE(tpa6130a2_dapm_widgets));
374 383
375 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 384 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
376 385
377 return snd_soc_add_controls(codec, tpa6130a2_controls, 386 if (data->id == TPA6140A2)
378 ARRAY_SIZE(tpa6130a2_controls)); 387 return snd_soc_add_controls(codec, tpa6140a2_controls,
388 ARRAY_SIZE(tpa6140a2_controls));
389 else
390 return snd_soc_add_controls(codec, tpa6130a2_controls,
391 ARRAY_SIZE(tpa6130a2_controls));
379 392
380} 393}
381EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); 394EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
@@ -386,7 +399,8 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
386 struct device *dev; 399 struct device *dev;
387 struct tpa6130a2_data *data; 400 struct tpa6130a2_data *data;
388 struct tpa6130a2_platform_data *pdata; 401 struct tpa6130a2_platform_data *pdata;
389 int i, ret; 402 const char *regulator;
403 int ret;
390 404
391 dev = &client->dev; 405 dev = &client->dev;
392 406
@@ -408,6 +422,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
408 422
409 pdata = client->dev.platform_data; 423 pdata = client->dev.platform_data;
410 data->power_gpio = pdata->power_gpio; 424 data->power_gpio = pdata->power_gpio;
425 data->id = pdata->id;
411 426
412 mutex_init(&data->mutex); 427 mutex_init(&data->mutex);
413 428
@@ -426,26 +441,22 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
426 gpio_direction_output(data->power_gpio, 0); 441 gpio_direction_output(data->power_gpio, 0);
427 } 442 }
428 443
429 switch (pdata->id) { 444 switch (data->id) {
445 default:
446 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
447 pdata->id);
430 case TPA6130A2: 448 case TPA6130A2:
431 for (i = 0; i < ARRAY_SIZE(data->supplies); i++) 449 regulator = "Vdd";
432 data->supplies[i].supply = tpa6130a2_supply_names[i];
433 break; 450 break;
434 case TPA6140A2: 451 case TPA6140A2:
435 for (i = 0; i < ARRAY_SIZE(data->supplies); i++) 452 regulator = "AVdd";
436 data->supplies[i].supply = tpa6140a2_supply_names[i];;
437 break; 453 break;
438 default:
439 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
440 pdata->id);
441 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
442 data->supplies[i].supply = tpa6130a2_supply_names[i];
443 } 454 }
444 455
445 ret = regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), 456 data->supply = regulator_get(dev, regulator);
446 data->supplies); 457 if (IS_ERR(data->supply)) {
447 if (ret != 0) { 458 ret = PTR_ERR(data->supply);
448 dev_err(dev, "Failed to request supplies: %d\n", ret); 459 dev_err(dev, "Failed to request supply: %d\n", ret);
449 goto err_regulator; 460 goto err_regulator;
450 } 461 }
451 462
@@ -468,7 +479,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
468 return 0; 479 return 0;
469 480
470err_power: 481err_power:
471 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies); 482 regulator_put(data->supply);
472err_regulator: 483err_regulator:
473 if (data->power_gpio >= 0) 484 if (data->power_gpio >= 0)
474 gpio_free(data->power_gpio); 485 gpio_free(data->power_gpio);
@@ -489,7 +500,7 @@ static int __devexit tpa6130a2_remove(struct i2c_client *client)
489 if (data->power_gpio >= 0) 500 if (data->power_gpio >= 0)
490 gpio_free(data->power_gpio); 501 gpio_free(data->power_gpio);
491 502
492 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies); 503 regulator_put(data->supply);
493 504
494 kfree(data); 505 kfree(data);
495 tpa6130a2_client = NULL; 506 tpa6130a2_client = NULL;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 520ffd6536c3..b4fcdb01fc49 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -124,6 +124,8 @@ struct twl4030_priv {
124 struct snd_soc_codec codec; 124 struct snd_soc_codec codec;
125 125
126 unsigned int codec_powered; 126 unsigned int codec_powered;
127
128 /* reference counts of AIF/APLL users */
127 unsigned int apll_enabled; 129 unsigned int apll_enabled;
128 130
129 struct snd_pcm_substream *master_substream; 131 struct snd_pcm_substream *master_substream;
@@ -136,9 +138,11 @@ struct twl4030_priv {
136 138
137 unsigned int sysclk; 139 unsigned int sysclk;
138 140
139 /* Headset output state handling */ 141 /* Output (with associated amp) states */
140 unsigned int hsl_enabled; 142 u8 hsl_enabled, hsr_enabled;
141 unsigned int hsr_enabled; 143 u8 earpiece_enabled;
144 u8 predrivel_enabled, predriver_enabled;
145 u8 carkitl_enabled, carkitr_enabled;
142}; 146};
143 147
144/* 148/*
@@ -174,17 +178,52 @@ static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
174static int twl4030_write(struct snd_soc_codec *codec, 178static int twl4030_write(struct snd_soc_codec *codec,
175 unsigned int reg, unsigned int value) 179 unsigned int reg, unsigned int value)
176{ 180{
181 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
182 int write_to_reg = 0;
183
177 twl4030_write_reg_cache(codec, reg, value); 184 twl4030_write_reg_cache(codec, reg, value);
178 if (likely(reg < TWL4030_REG_SW_SHADOW)) 185 if (likely(reg < TWL4030_REG_SW_SHADOW)) {
179 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, 186 /* Decide if the given register can be written */
180 reg); 187 switch (reg) {
181 else 188 case TWL4030_REG_EAR_CTL:
182 return 0; 189 if (twl4030->earpiece_enabled)
190 write_to_reg = 1;
191 break;
192 case TWL4030_REG_PREDL_CTL:
193 if (twl4030->predrivel_enabled)
194 write_to_reg = 1;
195 break;
196 case TWL4030_REG_PREDR_CTL:
197 if (twl4030->predriver_enabled)
198 write_to_reg = 1;
199 break;
200 case TWL4030_REG_PRECKL_CTL:
201 if (twl4030->carkitl_enabled)
202 write_to_reg = 1;
203 break;
204 case TWL4030_REG_PRECKR_CTL:
205 if (twl4030->carkitr_enabled)
206 write_to_reg = 1;
207 break;
208 case TWL4030_REG_HS_GAIN_SET:
209 if (twl4030->hsl_enabled || twl4030->hsr_enabled)
210 write_to_reg = 1;
211 break;
212 default:
213 /* All other register can be written */
214 write_to_reg = 1;
215 break;
216 }
217 if (write_to_reg)
218 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
219 value, reg);
220 }
221 return 0;
183} 222}
184 223
185static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) 224static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
186{ 225{
187 struct twl4030_priv *twl4030 = codec->private_data; 226 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
188 int mode; 227 int mode;
189 228
190 if (enable == twl4030->codec_powered) 229 if (enable == twl4030->codec_powered)
@@ -222,28 +261,28 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
222 261
223static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable) 262static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
224{ 263{
225 struct twl4030_priv *twl4030 = codec->private_data; 264 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
226 int status; 265 int status = -1;
227 266
228 if (enable == twl4030->apll_enabled) 267 if (enable) {
229 return; 268 twl4030->apll_enabled++;
230 269 if (twl4030->apll_enabled == 1)
231 if (enable) 270 status = twl4030_codec_enable_resource(
232 /* Enable PLL */ 271 TWL4030_CODEC_RES_APLL);
233 status = twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL); 272 } else {
234 else 273 twl4030->apll_enabled--;
235 /* Disable PLL */ 274 if (!twl4030->apll_enabled)
236 status = twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); 275 status = twl4030_codec_disable_resource(
276 TWL4030_CODEC_RES_APLL);
277 }
237 278
238 if (status >= 0) 279 if (status >= 0)
239 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status); 280 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
240
241 twl4030->apll_enabled = enable;
242} 281}
243 282
244static void twl4030_power_up(struct snd_soc_codec *codec) 283static void twl4030_power_up(struct snd_soc_codec *codec)
245{ 284{
246 struct twl4030_priv *twl4030 = codec->private_data; 285 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
247 u8 anamicl, regmisc1, byte; 286 u8 anamicl, regmisc1, byte;
248 int i = 0; 287 int i = 0;
249 288
@@ -526,26 +565,26 @@ static int micpath_event(struct snd_soc_dapm_widget *w,
526 * Output PGA builder: 565 * Output PGA builder:
527 * Handle the muting and unmuting of the given output (turning off the 566 * Handle the muting and unmuting of the given output (turning off the
528 * amplifier associated with the output pin) 567 * amplifier associated with the output pin)
529 * On mute bypass the reg_cache and mute the volume 568 * On mute bypass the reg_cache and write 0 to the register
530 * On unmute: restore the register content 569 * On unmute: restore the register content from the reg_cache
531 * Outputs handled in this way: Earpiece, PreDrivL/R, CarkitL/R 570 * Outputs handled in this way: Earpiece, PreDrivL/R, CarkitL/R
532 */ 571 */
533#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \ 572#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \
534static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \ 573static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
535 struct snd_kcontrol *kcontrol, int event) \ 574 struct snd_kcontrol *kcontrol, int event) \
536{ \ 575{ \
537 u8 reg_val; \ 576 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \
538 \ 577 \
539 switch (event) { \ 578 switch (event) { \
540 case SND_SOC_DAPM_POST_PMU: \ 579 case SND_SOC_DAPM_POST_PMU: \
580 twl4030->pin_name##_enabled = 1; \
541 twl4030_write(w->codec, reg, \ 581 twl4030_write(w->codec, reg, \
542 twl4030_read_reg_cache(w->codec, reg)); \ 582 twl4030_read_reg_cache(w->codec, reg)); \
543 break; \ 583 break; \
544 case SND_SOC_DAPM_POST_PMD: \ 584 case SND_SOC_DAPM_POST_PMD: \
545 reg_val = twl4030_read_reg_cache(w->codec, reg); \ 585 twl4030->pin_name##_enabled = 0; \
546 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \ 586 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \
547 reg_val & (~mask), \ 587 0, reg); \
548 reg); \
549 break; \ 588 break; \
550 } \ 589 } \
551 return 0; \ 590 return 0; \
@@ -636,13 +675,38 @@ static int apll_event(struct snd_soc_dapm_widget *w,
636 return 0; 675 return 0;
637} 676}
638 677
678static int aif_event(struct snd_soc_dapm_widget *w,
679 struct snd_kcontrol *kcontrol, int event)
680{
681 u8 audio_if;
682
683 audio_if = twl4030_read_reg_cache(w->codec, TWL4030_REG_AUDIO_IF);
684 switch (event) {
685 case SND_SOC_DAPM_PRE_PMU:
686 /* Enable AIF */
687 /* enable the PLL before we use it to clock the DAI */
688 twl4030_apll_enable(w->codec, 1);
689
690 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
691 audio_if | TWL4030_AIF_EN);
692 break;
693 case SND_SOC_DAPM_POST_PMD:
694 /* disable the DAI before we stop it's source PLL */
695 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
696 audio_if & ~TWL4030_AIF_EN);
697 twl4030_apll_enable(w->codec, 0);
698 break;
699 }
700 return 0;
701}
702
639static void headset_ramp(struct snd_soc_codec *codec, int ramp) 703static void headset_ramp(struct snd_soc_codec *codec, int ramp)
640{ 704{
641 struct snd_soc_device *socdev = codec->socdev; 705 struct snd_soc_device *socdev = codec->socdev;
642 struct twl4030_setup_data *setup = socdev->codec_data; 706 struct twl4030_setup_data *setup = socdev->codec_data;
643 707
644 unsigned char hs_gain, hs_pop; 708 unsigned char hs_gain, hs_pop;
645 struct twl4030_priv *twl4030 = codec->private_data; 709 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
646 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 710 /* Base values for ramp delay calculation: 2^19 - 2^26 */
647 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, 711 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
648 8388608, 16777216, 33554432, 67108864}; 712 8388608, 16777216, 33554432, 67108864};
@@ -665,7 +729,10 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
665 /* Headset ramp-up according to the TRM */ 729 /* Headset ramp-up according to the TRM */
666 hs_pop |= TWL4030_VMID_EN; 730 hs_pop |= TWL4030_VMID_EN;
667 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 731 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
668 twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain); 732 /* Actually write to the register */
733 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
734 hs_gain,
735 TWL4030_REG_HS_GAIN_SET);
669 hs_pop |= TWL4030_RAMP_EN; 736 hs_pop |= TWL4030_RAMP_EN;
670 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 737 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
671 /* Wait ramp delay time + 1, so the VMID can settle */ 738 /* Wait ramp delay time + 1, so the VMID can settle */
@@ -702,7 +769,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
702static int headsetlpga_event(struct snd_soc_dapm_widget *w, 769static int headsetlpga_event(struct snd_soc_dapm_widget *w,
703 struct snd_kcontrol *kcontrol, int event) 770 struct snd_kcontrol *kcontrol, int event)
704{ 771{
705 struct twl4030_priv *twl4030 = w->codec->private_data; 772 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
706 773
707 switch (event) { 774 switch (event) {
708 case SND_SOC_DAPM_POST_PMU: 775 case SND_SOC_DAPM_POST_PMU:
@@ -726,7 +793,7 @@ static int headsetlpga_event(struct snd_soc_dapm_widget *w,
726static int headsetrpga_event(struct snd_soc_dapm_widget *w, 793static int headsetrpga_event(struct snd_soc_dapm_widget *w,
727 struct snd_kcontrol *kcontrol, int event) 794 struct snd_kcontrol *kcontrol, int event)
728{ 795{
729 struct twl4030_priv *twl4030 = w->codec->private_data; 796 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
730 797
731 switch (event) { 798 switch (event) {
732 case SND_SOC_DAPM_POST_PMU: 799 case SND_SOC_DAPM_POST_PMU:
@@ -918,7 +985,7 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
918 struct snd_ctl_elem_value *ucontrol) 985 struct snd_ctl_elem_value *ucontrol)
919{ 986{
920 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 987 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
921 struct twl4030_priv *twl4030 = codec->private_data; 988 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
922 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 989 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
923 unsigned short val; 990 unsigned short val;
924 unsigned short mask, bitmask; 991 unsigned short mask, bitmask;
@@ -1036,6 +1103,16 @@ static const struct soc_enum twl4030_vibradir_enum =
1036 ARRAY_SIZE(twl4030_vibradir_texts), 1103 ARRAY_SIZE(twl4030_vibradir_texts),
1037 twl4030_vibradir_texts); 1104 twl4030_vibradir_texts);
1038 1105
1106/* Digimic Left and right swapping */
1107static const char *twl4030_digimicswap_texts[] = {
1108 "Not swapped", "Swapped",
1109};
1110
1111static const struct soc_enum twl4030_digimicswap_enum =
1112 SOC_ENUM_SINGLE(TWL4030_REG_MISC_SET_1, 0,
1113 ARRAY_SIZE(twl4030_digimicswap_texts),
1114 twl4030_digimicswap_texts);
1115
1039static const struct snd_kcontrol_new twl4030_snd_controls[] = { 1116static const struct snd_kcontrol_new twl4030_snd_controls[] = {
1040 /* Codec operation mode control */ 1117 /* Codec operation mode control */
1041 SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum, 1118 SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum,
@@ -1112,6 +1189,8 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
1112 1189
1113 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum), 1190 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum),
1114 SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum), 1191 SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum),
1192
1193 SOC_ENUM("Digimic LR Swap", twl4030_digimicswap_enum),
1115}; 1194};
1116 1195
1117static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { 1196static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
@@ -1128,8 +1207,6 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1128 SND_SOC_DAPM_INPUT("DIGIMIC1"), 1207 SND_SOC_DAPM_INPUT("DIGIMIC1"),
1129 1208
1130 /* Outputs */ 1209 /* Outputs */
1131 SND_SOC_DAPM_OUTPUT("OUTL"),
1132 SND_SOC_DAPM_OUTPUT("OUTR"),
1133 SND_SOC_DAPM_OUTPUT("EARPIECE"), 1210 SND_SOC_DAPM_OUTPUT("EARPIECE"),
1134 SND_SOC_DAPM_OUTPUT("PREDRIVEL"), 1211 SND_SOC_DAPM_OUTPUT("PREDRIVEL"),
1135 SND_SOC_DAPM_OUTPUT("PREDRIVER"), 1212 SND_SOC_DAPM_OUTPUT("PREDRIVER"),
@@ -1141,6 +1218,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1141 SND_SOC_DAPM_OUTPUT("HFR"), 1218 SND_SOC_DAPM_OUTPUT("HFR"),
1142 SND_SOC_DAPM_OUTPUT("VIBRA"), 1219 SND_SOC_DAPM_OUTPUT("VIBRA"),
1143 1220
1221 /* AIF and APLL clocks for running DAIs (including loopback) */
1222 SND_SOC_DAPM_OUTPUT("Virtual HiFi OUT"),
1223 SND_SOC_DAPM_INPUT("Virtual HiFi IN"),
1224 SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"),
1225
1144 /* DACs */ 1226 /* DACs */
1145 SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback", 1227 SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback",
1146 SND_SOC_NOPM, 0, 0), 1228 SND_SOC_NOPM, 0, 0),
@@ -1204,7 +1286,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1204 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event, 1286 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1205 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), 1287 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1206 1288
1207 SND_SOC_DAPM_SUPPLY("AIF Enable", TWL4030_REG_AUDIO_IF, 0, 0, NULL, 0), 1289 SND_SOC_DAPM_SUPPLY("AIF Enable", SND_SOC_NOPM, 0, 0, aif_event,
1290 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1208 1291
1209 /* Output MIXER controls */ 1292 /* Output MIXER controls */
1210 /* Earpiece */ 1293 /* Earpiece */
@@ -1334,10 +1417,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1334 {"Digital Voice Playback Mixer", NULL, "DAC Voice"}, 1417 {"Digital Voice Playback Mixer", NULL, "DAC Voice"},
1335 1418
1336 /* Supply for the digital part (APLL) */ 1419 /* Supply for the digital part (APLL) */
1337 {"Digital R1 Playback Mixer", NULL, "APLL Enable"},
1338 {"Digital L1 Playback Mixer", NULL, "APLL Enable"},
1339 {"Digital R2 Playback Mixer", NULL, "APLL Enable"},
1340 {"Digital L2 Playback Mixer", NULL, "APLL Enable"},
1341 {"Digital Voice Playback Mixer", NULL, "APLL Enable"}, 1420 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1342 1421
1343 {"Digital R1 Playback Mixer", NULL, "AIF Enable"}, 1422 {"Digital R1 Playback Mixer", NULL, "AIF Enable"},
@@ -1411,8 +1490,14 @@ static const struct snd_soc_dapm_route intercon[] = {
1411 {"Vibra Mux", "AudioR2", "DAC Right2"}, 1490 {"Vibra Mux", "AudioR2", "DAC Right2"},
1412 1491
1413 /* outputs */ 1492 /* outputs */
1414 {"OUTL", NULL, "Analog L2 Playback Mixer"}, 1493 /* Must be always connected (for AIF and APLL) */
1415 {"OUTR", NULL, "Analog R2 Playback Mixer"}, 1494 {"Virtual HiFi OUT", NULL, "Digital L1 Playback Mixer"},
1495 {"Virtual HiFi OUT", NULL, "Digital R1 Playback Mixer"},
1496 {"Virtual HiFi OUT", NULL, "Digital L2 Playback Mixer"},
1497 {"Virtual HiFi OUT", NULL, "Digital R2 Playback Mixer"},
1498 /* Must be always connected (for APLL) */
1499 {"Virtual Voice OUT", NULL, "Digital Voice Playback Mixer"},
1500 /* Physical outputs */
1416 {"EARPIECE", NULL, "Earpiece PGA"}, 1501 {"EARPIECE", NULL, "Earpiece PGA"},
1417 {"PREDRIVEL", NULL, "PredriveL PGA"}, 1502 {"PREDRIVEL", NULL, "PredriveL PGA"},
1418 {"PREDRIVER", NULL, "PredriveR PGA"}, 1503 {"PREDRIVER", NULL, "PredriveR PGA"},
@@ -1426,6 +1511,12 @@ static const struct snd_soc_dapm_route intercon[] = {
1426 {"VIBRA", NULL, "Vibra Route"}, 1511 {"VIBRA", NULL, "Vibra Route"},
1427 1512
1428 /* Capture path */ 1513 /* Capture path */
1514 /* Must be always connected (for AIF and APLL) */
1515 {"ADC Virtual Left1", NULL, "Virtual HiFi IN"},
1516 {"ADC Virtual Right1", NULL, "Virtual HiFi IN"},
1517 {"ADC Virtual Left2", NULL, "Virtual HiFi IN"},
1518 {"ADC Virtual Right2", NULL, "Virtual HiFi IN"},
1519 /* Physical inputs */
1429 {"Analog Left", "Main Mic Capture Switch", "MAINMIC"}, 1520 {"Analog Left", "Main Mic Capture Switch", "MAINMIC"},
1430 {"Analog Left", "Headset Mic Capture Switch", "HSMIC"}, 1521 {"Analog Left", "Headset Mic Capture Switch", "HSMIC"},
1431 {"Analog Left", "AUXL Capture Switch", "AUXL"}, 1522 {"Analog Left", "AUXL Capture Switch", "AUXL"},
@@ -1458,11 +1549,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1458 {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, 1549 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
1459 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1550 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1460 1551
1461 {"ADC Virtual Left1", NULL, "APLL Enable"},
1462 {"ADC Virtual Right1", NULL, "APLL Enable"},
1463 {"ADC Virtual Left2", NULL, "APLL Enable"},
1464 {"ADC Virtual Right2", NULL, "APLL Enable"},
1465
1466 {"ADC Virtual Left1", NULL, "AIF Enable"}, 1552 {"ADC Virtual Left1", NULL, "AIF Enable"},
1467 {"ADC Virtual Right1", NULL, "AIF Enable"}, 1553 {"ADC Virtual Right1", NULL, "AIF Enable"},
1468 {"ADC Virtual Left2", NULL, "AIF Enable"}, 1554 {"ADC Virtual Left2", NULL, "AIF Enable"},
@@ -1588,7 +1674,7 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
1588 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1674 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1589 struct snd_soc_device *socdev = rtd->socdev; 1675 struct snd_soc_device *socdev = rtd->socdev;
1590 struct snd_soc_codec *codec = socdev->card->codec; 1676 struct snd_soc_codec *codec = socdev->card->codec;
1591 struct twl4030_priv *twl4030 = codec->private_data; 1677 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1592 1678
1593 if (twl4030->master_substream) { 1679 if (twl4030->master_substream) {
1594 twl4030->slave_substream = substream; 1680 twl4030->slave_substream = substream;
@@ -1619,7 +1705,7 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream,
1619 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1705 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1620 struct snd_soc_device *socdev = rtd->socdev; 1706 struct snd_soc_device *socdev = rtd->socdev;
1621 struct snd_soc_codec *codec = socdev->card->codec; 1707 struct snd_soc_codec *codec = socdev->card->codec;
1622 struct twl4030_priv *twl4030 = codec->private_data; 1708 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1623 1709
1624 if (twl4030->master_substream == substream) 1710 if (twl4030->master_substream == substream)
1625 twl4030->master_substream = twl4030->slave_substream; 1711 twl4030->master_substream = twl4030->slave_substream;
@@ -1645,7 +1731,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1645 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1731 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1646 struct snd_soc_device *socdev = rtd->socdev; 1732 struct snd_soc_device *socdev = rtd->socdev;
1647 struct snd_soc_codec *codec = socdev->card->codec; 1733 struct snd_soc_codec *codec = socdev->card->codec;
1648 struct twl4030_priv *twl4030 = codec->private_data; 1734 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1649 u8 mode, old_mode, format, old_format; 1735 u8 mode, old_mode, format, old_format;
1650 1736
1651 /* If the substream has 4 channel, do the necessary setup */ 1737 /* If the substream has 4 channel, do the necessary setup */
@@ -1765,7 +1851,7 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1765 int clk_id, unsigned int freq, int dir) 1851 int clk_id, unsigned int freq, int dir)
1766{ 1852{
1767 struct snd_soc_codec *codec = codec_dai->codec; 1853 struct snd_soc_codec *codec = codec_dai->codec;
1768 struct twl4030_priv *twl4030 = codec->private_data; 1854 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1769 1855
1770 switch (freq) { 1856 switch (freq) {
1771 case 19200000: 1857 case 19200000:
@@ -1880,7 +1966,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1880 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1966 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1881 struct snd_soc_device *socdev = rtd->socdev; 1967 struct snd_soc_device *socdev = rtd->socdev;
1882 struct snd_soc_codec *codec = socdev->card->codec; 1968 struct snd_soc_codec *codec = socdev->card->codec;
1883 struct twl4030_priv *twl4030 = codec->private_data; 1969 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1884 u8 mode; 1970 u8 mode;
1885 1971
1886 /* If the system master clock is not 26MHz, the voice PCM interface is 1972 /* If the system master clock is not 26MHz, the voice PCM interface is
@@ -1962,7 +2048,7 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1962 int clk_id, unsigned int freq, int dir) 2048 int clk_id, unsigned int freq, int dir)
1963{ 2049{
1964 struct snd_soc_codec *codec = codec_dai->codec; 2050 struct snd_soc_codec *codec = codec_dai->codec;
1965 struct twl4030_priv *twl4030 = codec->private_data; 2051 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1966 2052
1967 if (freq != 26000000) { 2053 if (freq != 26000000) {
1968 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice" 2054 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice"
@@ -2108,7 +2194,6 @@ static int twl4030_soc_resume(struct platform_device *pdev)
2108 struct snd_soc_codec *codec = socdev->card->codec; 2194 struct snd_soc_codec *codec = socdev->card->codec;
2109 2195
2110 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2196 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2111 twl4030_set_bias_level(codec, codec->suspend_bias_level);
2112 return 0; 2197 return 0;
2113} 2198}
2114 2199
@@ -2125,7 +2210,7 @@ static int twl4030_soc_probe(struct platform_device *pdev)
2125 BUG_ON(!twl4030_codec); 2210 BUG_ON(!twl4030_codec);
2126 2211
2127 codec = twl4030_codec; 2212 codec = twl4030_codec;
2128 twl4030 = codec->private_data; 2213 twl4030 = snd_soc_codec_get_drvdata(codec);
2129 socdev->card->codec = codec; 2214 socdev->card->codec = codec;
2130 2215
2131 /* Configuration for headset ramp delay from setup data */ 2216 /* Configuration for headset ramp delay from setup data */
@@ -2188,7 +2273,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2188 } 2273 }
2189 2274
2190 codec = &twl4030->codec; 2275 codec = &twl4030->codec;
2191 codec->private_data = twl4030; 2276 snd_soc_codec_set_drvdata(codec, twl4030);
2192 codec->dev = &pdev->dev; 2277 codec->dev = &pdev->dev;
2193 twl4030_dai[0].dev = &pdev->dev; 2278 twl4030_dai[0].dev = &pdev->dev;
2194 twl4030_dai[1].dev = &pdev->dev; 2279 twl4030_dai[1].dev = &pdev->dev;
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
new file mode 100644
index 000000000000..af36346ff336
--- /dev/null
+++ b/sound/soc/codecs/twl6040.c
@@ -0,0 +1,1246 @@
1/*
2 * ALSA SoC TWL6040 codec driver
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/pm.h>
27#include <linux/i2c.h>
28#include <linux/gpio.h>
29#include <linux/platform_device.h>
30#include <linux/slab.h>
31#include <linux/i2c/twl.h>
32
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/soc.h>
37#include <sound/soc-dapm.h>
38#include <sound/initval.h>
39#include <sound/tlv.h>
40
41#include "twl6040.h"
42
43#define TWL6040_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
44#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
45
46/* codec private data */
47struct twl6040_data {
48 struct snd_soc_codec codec;
49 int audpwron;
50 int naudint;
51 int codec_powered;
52 int pll;
53 int non_lp;
54 unsigned int sysclk;
55 struct snd_pcm_hw_constraint_list *sysclk_constraints;
56 struct completion ready;
57};
58
59/*
60 * twl6040 register cache & default register settings
61 */
62static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = {
63 0x00, /* not used 0x00 */
64 0x4B, /* TWL6040_ASICID (ro) 0x01 */
65 0x00, /* TWL6040_ASICREV (ro) 0x02 */
66 0x00, /* TWL6040_INTID 0x03 */
67 0x00, /* TWL6040_INTMR 0x04 */
68 0x00, /* TWL6040_NCPCTRL 0x05 */
69 0x00, /* TWL6040_LDOCTL 0x06 */
70 0x60, /* TWL6040_HPPLLCTL 0x07 */
71 0x00, /* TWL6040_LPPLLCTL 0x08 */
72 0x4A, /* TWL6040_LPPLLDIV 0x09 */
73 0x00, /* TWL6040_AMICBCTL 0x0A */
74 0x00, /* TWL6040_DMICBCTL 0x0B */
75 0x18, /* TWL6040_MICLCTL 0x0C - No input selected on Left Mic */
76 0x18, /* TWL6040_MICRCTL 0x0D - No input selected on Right Mic */
77 0x00, /* TWL6040_MICGAIN 0x0E */
78 0x1B, /* TWL6040_LINEGAIN 0x0F */
79 0x00, /* TWL6040_HSLCTL 0x10 */
80 0x00, /* TWL6040_HSRCTL 0x11 */
81 0x00, /* TWL6040_HSGAIN 0x12 */
82 0x00, /* TWL6040_EARCTL 0x13 */
83 0x00, /* TWL6040_HFLCTL 0x14 */
84 0x00, /* TWL6040_HFLGAIN 0x15 */
85 0x00, /* TWL6040_HFRCTL 0x16 */
86 0x00, /* TWL6040_HFRGAIN 0x17 */
87 0x00, /* TWL6040_VIBCTLL 0x18 */
88 0x00, /* TWL6040_VIBDATL 0x19 */
89 0x00, /* TWL6040_VIBCTLR 0x1A */
90 0x00, /* TWL6040_VIBDATR 0x1B */
91 0x00, /* TWL6040_HKCTL1 0x1C */
92 0x00, /* TWL6040_HKCTL2 0x1D */
93 0x00, /* TWL6040_GPOCTL 0x1E */
94 0x00, /* TWL6040_ALB 0x1F */
95 0x00, /* TWL6040_DLB 0x20 */
96 0x00, /* not used 0x21 */
97 0x00, /* not used 0x22 */
98 0x00, /* not used 0x23 */
99 0x00, /* not used 0x24 */
100 0x00, /* not used 0x25 */
101 0x00, /* not used 0x26 */
102 0x00, /* not used 0x27 */
103 0x00, /* TWL6040_TRIM1 0x28 */
104 0x00, /* TWL6040_TRIM2 0x29 */
105 0x00, /* TWL6040_TRIM3 0x2A */
106 0x00, /* TWL6040_HSOTRIM 0x2B */
107 0x00, /* TWL6040_HFOTRIM 0x2C */
108 0x09, /* TWL6040_ACCCTL 0x2D */
109 0x00, /* TWL6040_STATUS (ro) 0x2E */
110};
111
112/*
113 * twl6040 vio/gnd registers:
114 * registers under vio/gnd supply can be accessed
115 * before the power-up sequence, after NRESPWRON goes high
116 */
117static const int twl6040_vio_reg[TWL6040_VIOREGNUM] = {
118 TWL6040_REG_ASICID,
119 TWL6040_REG_ASICREV,
120 TWL6040_REG_INTID,
121 TWL6040_REG_INTMR,
122 TWL6040_REG_NCPCTL,
123 TWL6040_REG_LDOCTL,
124 TWL6040_REG_AMICBCTL,
125 TWL6040_REG_DMICBCTL,
126 TWL6040_REG_HKCTL1,
127 TWL6040_REG_HKCTL2,
128 TWL6040_REG_GPOCTL,
129 TWL6040_REG_TRIM1,
130 TWL6040_REG_TRIM2,
131 TWL6040_REG_TRIM3,
132 TWL6040_REG_HSOTRIM,
133 TWL6040_REG_HFOTRIM,
134 TWL6040_REG_ACCCTL,
135 TWL6040_REG_STATUS,
136};
137
138/*
139 * twl6040 vdd/vss registers:
140 * registers under vdd/vss supplies can only be accessed
141 * after the power-up sequence
142 */
143static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
144 TWL6040_REG_HPPLLCTL,
145 TWL6040_REG_LPPLLCTL,
146 TWL6040_REG_LPPLLDIV,
147 TWL6040_REG_MICLCTL,
148 TWL6040_REG_MICRCTL,
149 TWL6040_REG_MICGAIN,
150 TWL6040_REG_LINEGAIN,
151 TWL6040_REG_HSLCTL,
152 TWL6040_REG_HSRCTL,
153 TWL6040_REG_HSGAIN,
154 TWL6040_REG_EARCTL,
155 TWL6040_REG_HFLCTL,
156 TWL6040_REG_HFLGAIN,
157 TWL6040_REG_HFRCTL,
158 TWL6040_REG_HFRGAIN,
159 TWL6040_REG_VIBCTLL,
160 TWL6040_REG_VIBDATL,
161 TWL6040_REG_VIBCTLR,
162 TWL6040_REG_VIBDATR,
163 TWL6040_REG_ALB,
164 TWL6040_REG_DLB,
165};
166
167/*
168 * read twl6040 register cache
169 */
170static inline unsigned int twl6040_read_reg_cache(struct snd_soc_codec *codec,
171 unsigned int reg)
172{
173 u8 *cache = codec->reg_cache;
174
175 if (reg >= TWL6040_CACHEREGNUM)
176 return -EIO;
177
178 return cache[reg];
179}
180
181/*
182 * write twl6040 register cache
183 */
184static inline void twl6040_write_reg_cache(struct snd_soc_codec *codec,
185 u8 reg, u8 value)
186{
187 u8 *cache = codec->reg_cache;
188
189 if (reg >= TWL6040_CACHEREGNUM)
190 return;
191 cache[reg] = value;
192}
193
194/*
195 * read from twl6040 hardware register
196 */
197static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
198 unsigned int reg)
199{
200 u8 value;
201
202 if (reg >= TWL6040_CACHEREGNUM)
203 return -EIO;
204
205 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &value, reg);
206 twl6040_write_reg_cache(codec, reg, value);
207
208 return value;
209}
210
211/*
212 * write to the twl6040 register space
213 */
214static int twl6040_write(struct snd_soc_codec *codec,
215 unsigned int reg, unsigned int value)
216{
217 if (reg >= TWL6040_CACHEREGNUM)
218 return -EIO;
219
220 twl6040_write_reg_cache(codec, reg, value);
221 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
222}
223
224static void twl6040_init_vio_regs(struct snd_soc_codec *codec)
225{
226 u8 *cache = codec->reg_cache;
227 int reg, i;
228
229 /* allow registers to be accessed by i2c */
230 twl6040_write(codec, TWL6040_REG_ACCCTL, cache[TWL6040_REG_ACCCTL]);
231
232 for (i = 0; i < TWL6040_VIOREGNUM; i++) {
233 reg = twl6040_vio_reg[i];
234 /* skip read-only registers (ASICID, ASICREV, STATUS) */
235 switch (reg) {
236 case TWL6040_REG_ASICID:
237 case TWL6040_REG_ASICREV:
238 case TWL6040_REG_STATUS:
239 continue;
240 default:
241 break;
242 }
243 twl6040_write(codec, reg, cache[reg]);
244 }
245}
246
247static void twl6040_init_vdd_regs(struct snd_soc_codec *codec)
248{
249 u8 *cache = codec->reg_cache;
250 int reg, i;
251
252 for (i = 0; i < TWL6040_VDDREGNUM; i++) {
253 reg = twl6040_vdd_reg[i];
254 twl6040_write(codec, reg, cache[reg]);
255 }
256}
257
258/* twl6040 codec manual power-up sequence */
259static void twl6040_power_up(struct snd_soc_codec *codec)
260{
261 u8 ncpctl, ldoctl, lppllctl, accctl;
262
263 ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
264 ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
265 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
266 accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
267
268 /* enable reference system */
269 ldoctl |= TWL6040_REFENA;
270 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
271 msleep(10);
272 /* enable internal oscillator */
273 ldoctl |= TWL6040_OSCENA;
274 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
275 udelay(10);
276 /* enable high-side ldo */
277 ldoctl |= TWL6040_HSLDOENA;
278 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
279 udelay(244);
280 /* enable negative charge pump */
281 ncpctl |= TWL6040_NCPENA | TWL6040_NCPOPEN;
282 twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
283 udelay(488);
284 /* enable low-side ldo */
285 ldoctl |= TWL6040_LSLDOENA;
286 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
287 udelay(244);
288 /* enable low-power pll */
289 lppllctl |= TWL6040_LPLLENA;
290 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
291 /* reset state machine */
292 accctl |= TWL6040_RESETSPLIT;
293 twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
294 mdelay(5);
295 accctl &= ~TWL6040_RESETSPLIT;
296 twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
297 /* disable internal oscillator */
298 ldoctl &= ~TWL6040_OSCENA;
299 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
300}
301
302/* twl6040 codec manual power-down sequence */
303static void twl6040_power_down(struct snd_soc_codec *codec)
304{
305 u8 ncpctl, ldoctl, lppllctl, accctl;
306
307 ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
308 ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
309 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
310 accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
311
312 /* enable internal oscillator */
313 ldoctl |= TWL6040_OSCENA;
314 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
315 udelay(10);
316 /* disable low-power pll */
317 lppllctl &= ~TWL6040_LPLLENA;
318 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
319 /* disable low-side ldo */
320 ldoctl &= ~TWL6040_LSLDOENA;
321 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
322 udelay(244);
323 /* disable negative charge pump */
324 ncpctl &= ~(TWL6040_NCPENA | TWL6040_NCPOPEN);
325 twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
326 udelay(488);
327 /* disable high-side ldo */
328 ldoctl &= ~TWL6040_HSLDOENA;
329 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
330 udelay(244);
331 /* disable internal oscillator */
332 ldoctl &= ~TWL6040_OSCENA;
333 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
334 /* disable reference system */
335 ldoctl &= ~TWL6040_REFENA;
336 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
337 msleep(10);
338}
339
340/* set headset dac and driver power mode */
341static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
342{
343 int hslctl, hsrctl;
344 int mask = TWL6040_HSDRVMODEL | TWL6040_HSDACMODEL;
345
346 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
347 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
348
349 if (high_perf) {
350 hslctl &= ~mask;
351 hsrctl &= ~mask;
352 } else {
353 hslctl |= mask;
354 hsrctl |= mask;
355 }
356
357 twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
358 twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
359
360 return 0;
361}
362
363static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
364 struct snd_kcontrol *kcontrol, int event)
365{
366 struct snd_soc_codec *codec = w->codec;
367 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
368
369 if (SND_SOC_DAPM_EVENT_ON(event))
370 priv->non_lp++;
371 else
372 priv->non_lp--;
373
374 return 0;
375}
376
377/* audio interrupt handler */
378static irqreturn_t twl6040_naudint_handler(int irq, void *data)
379{
380 struct snd_soc_codec *codec = data;
381 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
382 u8 intid;
383
384 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID);
385
386 switch (intid) {
387 case TWL6040_THINT:
388 dev_alert(codec->dev, "die temp over-limit detection\n");
389 break;
390 case TWL6040_PLUGINT:
391 case TWL6040_UNPLUGINT:
392 case TWL6040_HOOKINT:
393 break;
394 case TWL6040_HFINT:
395 dev_alert(codec->dev, "hf drivers over current detection\n");
396 break;
397 case TWL6040_VIBINT:
398 dev_alert(codec->dev, "vib drivers over current detection\n");
399 break;
400 case TWL6040_READYINT:
401 complete(&priv->ready);
402 break;
403 default:
404 dev_err(codec->dev, "unknown audio interrupt %d\n", intid);
405 break;
406 }
407
408 return IRQ_HANDLED;
409}
410
411/*
412 * MICATT volume control:
413 * from -6 to 0 dB in 6 dB steps
414 */
415static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0);
416
417/*
418 * MICGAIN volume control:
419 * from 6 to 30 dB in 6 dB steps
420 */
421static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0);
422
423/*
424 * HSGAIN volume control:
425 * from -30 to 0 dB in 2 dB steps
426 */
427static DECLARE_TLV_DB_SCALE(hs_tlv, -3000, 200, 0);
428
429/*
430 * HFGAIN volume control:
431 * from -52 to 6 dB in 2 dB steps
432 */
433static DECLARE_TLV_DB_SCALE(hf_tlv, -5200, 200, 0);
434
435/*
436 * EPGAIN volume control:
437 * from -24 to 6 dB in 2 dB steps
438 */
439static DECLARE_TLV_DB_SCALE(ep_tlv, -2400, 200, 0);
440
441/* Left analog microphone selection */
442static const char *twl6040_amicl_texts[] =
443 {"Headset Mic", "Main Mic", "Aux/FM Left", "Off"};
444
445/* Right analog microphone selection */
446static const char *twl6040_amicr_texts[] =
447 {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"};
448
449static const struct soc_enum twl6040_enum[] = {
450 SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 3, twl6040_amicl_texts),
451 SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 3, twl6040_amicr_texts),
452};
453
454static const struct snd_kcontrol_new amicl_control =
455 SOC_DAPM_ENUM("Route", twl6040_enum[0]);
456
457static const struct snd_kcontrol_new amicr_control =
458 SOC_DAPM_ENUM("Route", twl6040_enum[1]);
459
460/* Headset DAC playback switches */
461static const struct snd_kcontrol_new hsdacl_switch_controls =
462 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 5, 1, 0);
463
464static const struct snd_kcontrol_new hsdacr_switch_controls =
465 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 5, 1, 0);
466
467/* Handsfree DAC playback switches */
468static const struct snd_kcontrol_new hfdacl_switch_controls =
469 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 2, 1, 0);
470
471static const struct snd_kcontrol_new hfdacr_switch_controls =
472 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0);
473
474/* Headset driver switches */
475static const struct snd_kcontrol_new hsl_driver_switch_controls =
476 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 2, 1, 0);
477
478static const struct snd_kcontrol_new hsr_driver_switch_controls =
479 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 2, 1, 0);
480
481/* Handsfree driver switches */
482static const struct snd_kcontrol_new hfl_driver_switch_controls =
483 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 4, 1, 0);
484
485static const struct snd_kcontrol_new hfr_driver_switch_controls =
486 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 4, 1, 0);
487
488static const struct snd_kcontrol_new ep_driver_switch_controls =
489 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
490
491static const struct snd_kcontrol_new twl6040_snd_controls[] = {
492 /* Capture gains */
493 SOC_DOUBLE_TLV("Capture Preamplifier Volume",
494 TWL6040_REG_MICGAIN, 6, 7, 1, 1, mic_preamp_tlv),
495 SOC_DOUBLE_TLV("Capture Volume",
496 TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv),
497
498 /* Playback gains */
499 SOC_DOUBLE_TLV("Headset Playback Volume",
500 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv),
501 SOC_DOUBLE_R_TLV("Handsfree Playback Volume",
502 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
503 SOC_SINGLE_TLV("Earphone Playback Volume",
504 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
505};
506
507static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
508 /* Inputs */
509 SND_SOC_DAPM_INPUT("MAINMIC"),
510 SND_SOC_DAPM_INPUT("HSMIC"),
511 SND_SOC_DAPM_INPUT("SUBMIC"),
512 SND_SOC_DAPM_INPUT("AFML"),
513 SND_SOC_DAPM_INPUT("AFMR"),
514
515 /* Outputs */
516 SND_SOC_DAPM_OUTPUT("HSOL"),
517 SND_SOC_DAPM_OUTPUT("HSOR"),
518 SND_SOC_DAPM_OUTPUT("HFL"),
519 SND_SOC_DAPM_OUTPUT("HFR"),
520 SND_SOC_DAPM_OUTPUT("EP"),
521
522 /* Analog input muxes for the capture amplifiers */
523 SND_SOC_DAPM_MUX("Analog Left Capture Route",
524 SND_SOC_NOPM, 0, 0, &amicl_control),
525 SND_SOC_DAPM_MUX("Analog Right Capture Route",
526 SND_SOC_NOPM, 0, 0, &amicr_control),
527
528 /* Analog capture PGAs */
529 SND_SOC_DAPM_PGA("MicAmpL",
530 TWL6040_REG_MICLCTL, 0, 0, NULL, 0),
531 SND_SOC_DAPM_PGA("MicAmpR",
532 TWL6040_REG_MICRCTL, 0, 0, NULL, 0),
533
534 /* ADCs */
535 SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture",
536 TWL6040_REG_MICLCTL, 2, 0),
537 SND_SOC_DAPM_ADC("ADC Right", "Right Front Capture",
538 TWL6040_REG_MICRCTL, 2, 0),
539
540 /* Microphone bias */
541 SND_SOC_DAPM_MICBIAS("Headset Mic Bias",
542 TWL6040_REG_AMICBCTL, 0, 0),
543 SND_SOC_DAPM_MICBIAS("Main Mic Bias",
544 TWL6040_REG_AMICBCTL, 4, 0),
545 SND_SOC_DAPM_MICBIAS("Digital Mic1 Bias",
546 TWL6040_REG_DMICBCTL, 0, 0),
547 SND_SOC_DAPM_MICBIAS("Digital Mic2 Bias",
548 TWL6040_REG_DMICBCTL, 4, 0),
549
550 /* DACs */
551 SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback",
552 TWL6040_REG_HSLCTL, 0, 0),
553 SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback",
554 TWL6040_REG_HSRCTL, 0, 0),
555 SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback",
556 TWL6040_REG_HFLCTL, 0, 0,
557 twl6040_power_mode_event,
558 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
559 SND_SOC_DAPM_DAC_E("HFDAC Right", "Handsfree Playback",
560 TWL6040_REG_HFRCTL, 0, 0,
561 twl6040_power_mode_event,
562 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
563
564 /* Analog playback switches */
565 SND_SOC_DAPM_SWITCH("HSDAC Left Playback",
566 SND_SOC_NOPM, 0, 0, &hsdacl_switch_controls),
567 SND_SOC_DAPM_SWITCH("HSDAC Right Playback",
568 SND_SOC_NOPM, 0, 0, &hsdacr_switch_controls),
569 SND_SOC_DAPM_SWITCH("HFDAC Left Playback",
570 SND_SOC_NOPM, 0, 0, &hfdacl_switch_controls),
571 SND_SOC_DAPM_SWITCH("HFDAC Right Playback",
572 SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls),
573
574 SND_SOC_DAPM_SWITCH("Headset Left Driver",
575 SND_SOC_NOPM, 0, 0, &hsl_driver_switch_controls),
576 SND_SOC_DAPM_SWITCH("Headset Right Driver",
577 SND_SOC_NOPM, 0, 0, &hsr_driver_switch_controls),
578 SND_SOC_DAPM_SWITCH_E("Handsfree Left Driver",
579 SND_SOC_NOPM, 0, 0, &hfl_driver_switch_controls,
580 twl6040_power_mode_event,
581 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
582 SND_SOC_DAPM_SWITCH_E("Handsfree Right Driver",
583 SND_SOC_NOPM, 0, 0, &hfr_driver_switch_controls,
584 twl6040_power_mode_event,
585 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
586 SND_SOC_DAPM_SWITCH_E("Earphone Driver",
587 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls,
588 twl6040_power_mode_event,
589 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
590
591 /* Analog playback PGAs */
592 SND_SOC_DAPM_PGA("HFDAC Left PGA",
593 TWL6040_REG_HFLCTL, 1, 0, NULL, 0),
594 SND_SOC_DAPM_PGA("HFDAC Right PGA",
595 TWL6040_REG_HFRCTL, 1, 0, NULL, 0),
596
597};
598
599static const struct snd_soc_dapm_route intercon[] = {
600 /* Capture path */
601 {"Analog Left Capture Route", "Headset Mic", "HSMIC"},
602 {"Analog Left Capture Route", "Main Mic", "MAINMIC"},
603 {"Analog Left Capture Route", "Aux/FM Left", "AFML"},
604
605 {"Analog Right Capture Route", "Headset Mic", "HSMIC"},
606 {"Analog Right Capture Route", "Sub Mic", "SUBMIC"},
607 {"Analog Right Capture Route", "Aux/FM Right", "AFMR"},
608
609 {"MicAmpL", NULL, "Analog Left Capture Route"},
610 {"MicAmpR", NULL, "Analog Right Capture Route"},
611
612 {"ADC Left", NULL, "MicAmpL"},
613 {"ADC Right", NULL, "MicAmpR"},
614
615 /* Headset playback path */
616 {"HSDAC Left Playback", "Switch", "HSDAC Left"},
617 {"HSDAC Right Playback", "Switch", "HSDAC Right"},
618
619 {"Headset Left Driver", "Switch", "HSDAC Left Playback"},
620 {"Headset Right Driver", "Switch", "HSDAC Right Playback"},
621
622 {"HSOL", NULL, "Headset Left Driver"},
623 {"HSOR", NULL, "Headset Right Driver"},
624
625 /* Earphone playback path */
626 {"Earphone Driver", "Switch", "HSDAC Left"},
627 {"EP", NULL, "Earphone Driver"},
628
629 /* Handsfree playback path */
630 {"HFDAC Left Playback", "Switch", "HFDAC Left"},
631 {"HFDAC Right Playback", "Switch", "HFDAC Right"},
632
633 {"HFDAC Left PGA", NULL, "HFDAC Left Playback"},
634 {"HFDAC Right PGA", NULL, "HFDAC Right Playback"},
635
636 {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"},
637 {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"},
638
639 {"HFL", NULL, "Handsfree Left Driver"},
640 {"HFR", NULL, "Handsfree Right Driver"},
641};
642
643static int twl6040_add_widgets(struct snd_soc_codec *codec)
644{
645 snd_soc_dapm_new_controls(codec, twl6040_dapm_widgets,
646 ARRAY_SIZE(twl6040_dapm_widgets));
647
648 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
649
650 snd_soc_dapm_new_widgets(codec);
651
652 return 0;
653}
654
655static int twl6040_power_up_completion(struct snd_soc_codec *codec,
656 int naudint)
657{
658 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
659 int time_left;
660 u8 intid;
661
662 time_left = wait_for_completion_timeout(&priv->ready,
663 msecs_to_jiffies(48));
664
665 if (!time_left) {
666 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid,
667 TWL6040_REG_INTID);
668 if (!(intid & TWL6040_READYINT)) {
669 dev_err(codec->dev, "timeout waiting for READYINT\n");
670 return -ETIMEDOUT;
671 }
672 }
673
674 priv->codec_powered = 1;
675
676 return 0;
677}
678
679static int twl6040_set_bias_level(struct snd_soc_codec *codec,
680 enum snd_soc_bias_level level)
681{
682 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
683 int audpwron = priv->audpwron;
684 int naudint = priv->naudint;
685 int ret;
686
687 switch (level) {
688 case SND_SOC_BIAS_ON:
689 break;
690 case SND_SOC_BIAS_PREPARE:
691 break;
692 case SND_SOC_BIAS_STANDBY:
693 if (priv->codec_powered)
694 break;
695
696 if (gpio_is_valid(audpwron)) {
697 /* use AUDPWRON line */
698 gpio_set_value(audpwron, 1);
699
700 /* wait for power-up completion */
701 ret = twl6040_power_up_completion(codec, naudint);
702 if (ret)
703 return ret;
704
705 /* sync registers updated during power-up sequence */
706 twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
707 twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
708 twl6040_read_reg_volatile(codec, TWL6040_REG_LPPLLCTL);
709 } else {
710 /* use manual power-up sequence */
711 twl6040_power_up(codec);
712 priv->codec_powered = 1;
713 }
714
715 /* initialize vdd/vss registers with reg_cache */
716 twl6040_init_vdd_regs(codec);
717 break;
718 case SND_SOC_BIAS_OFF:
719 if (!priv->codec_powered)
720 break;
721
722 if (gpio_is_valid(audpwron)) {
723 /* use AUDPWRON line */
724 gpio_set_value(audpwron, 0);
725
726 /* power-down sequence latency */
727 udelay(500);
728
729 /* sync registers updated during power-down sequence */
730 twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
731 twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
732 twl6040_write_reg_cache(codec, TWL6040_REG_LPPLLCTL,
733 0x00);
734 } else {
735 /* use manual power-down sequence */
736 twl6040_power_down(codec);
737 }
738
739 priv->codec_powered = 0;
740 break;
741 }
742
743 codec->bias_level = level;
744
745 return 0;
746}
747
748/* set of rates for each pll: low-power and high-performance */
749
750static unsigned int lp_rates[] = {
751 88200,
752 96000,
753};
754
755static struct snd_pcm_hw_constraint_list lp_constraints = {
756 .count = ARRAY_SIZE(lp_rates),
757 .list = lp_rates,
758};
759
760static unsigned int hp_rates[] = {
761 96000,
762};
763
764static struct snd_pcm_hw_constraint_list hp_constraints = {
765 .count = ARRAY_SIZE(hp_rates),
766 .list = hp_rates,
767};
768
769static int twl6040_startup(struct snd_pcm_substream *substream,
770 struct snd_soc_dai *dai)
771{
772 struct snd_soc_pcm_runtime *rtd = substream->private_data;
773 struct snd_soc_device *socdev = rtd->socdev;
774 struct snd_soc_codec *codec = socdev->card->codec;
775 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
776
777 if (!priv->sysclk) {
778 dev_err(codec->dev,
779 "no mclk configured, call set_sysclk() on init\n");
780 return -EINVAL;
781 }
782
783 /*
784 * capture is not supported at 17.64 MHz,
785 * it's reserved for headset low-power playback scenario
786 */
787 if ((priv->sysclk == 17640000) && substream->stream) {
788 dev_err(codec->dev,
789 "capture mode is not supported at %dHz\n",
790 priv->sysclk);
791 return -EINVAL;
792 }
793
794 snd_pcm_hw_constraint_list(substream->runtime, 0,
795 SNDRV_PCM_HW_PARAM_RATE,
796 priv->sysclk_constraints);
797
798 return 0;
799}
800
801static int twl6040_hw_params(struct snd_pcm_substream *substream,
802 struct snd_pcm_hw_params *params,
803 struct snd_soc_dai *dai)
804{
805 struct snd_soc_pcm_runtime *rtd = substream->private_data;
806 struct snd_soc_device *socdev = rtd->socdev;
807 struct snd_soc_codec *codec = socdev->card->codec;
808 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
809 u8 lppllctl;
810 int rate;
811
812 /* nothing to do for high-perf pll, it supports only 48 kHz */
813 if (priv->pll == TWL6040_HPPLL_ID)
814 return 0;
815
816 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
817
818 rate = params_rate(params);
819 switch (rate) {
820 case 88200:
821 lppllctl |= TWL6040_LPLLFIN;
822 priv->sysclk = 17640000;
823 break;
824 case 96000:
825 lppllctl &= ~TWL6040_LPLLFIN;
826 priv->sysclk = 19200000;
827 break;
828 default:
829 dev_err(codec->dev, "unsupported rate %d\n", rate);
830 return -EINVAL;
831 }
832
833 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
834
835 return 0;
836}
837
838static int twl6040_trigger(struct snd_pcm_substream *substream,
839 int cmd, struct snd_soc_dai *dai)
840{
841 struct snd_soc_pcm_runtime *rtd = substream->private_data;
842 struct snd_soc_device *socdev = rtd->socdev;
843 struct snd_soc_codec *codec = socdev->card->codec;
844 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
845
846 switch (cmd) {
847 case SNDRV_PCM_TRIGGER_START:
848 case SNDRV_PCM_TRIGGER_RESUME:
849 /*
850 * low-power playback mode is restricted
851 * for headset path only
852 */
853 if ((priv->sysclk == 17640000) && priv->non_lp) {
854 dev_err(codec->dev,
855 "some enabled paths aren't supported at %dHz\n",
856 priv->sysclk);
857 return -EPERM;
858 }
859 break;
860 default:
861 break;
862 }
863
864 return 0;
865}
866
867static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
868 int clk_id, unsigned int freq, int dir)
869{
870 struct snd_soc_codec *codec = codec_dai->codec;
871 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
872 u8 hppllctl, lppllctl;
873
874 hppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_HPPLLCTL);
875 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
876
877 switch (clk_id) {
878 case TWL6040_SYSCLK_SEL_LPPLL:
879 switch (freq) {
880 case 32768:
881 /* headset dac and driver must be in low-power mode */
882 headset_power_mode(codec, 0);
883
884 /* clk32k input requires low-power pll */
885 lppllctl |= TWL6040_LPLLENA;
886 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
887 mdelay(5);
888 lppllctl &= ~TWL6040_HPLLSEL;
889 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
890 hppllctl &= ~TWL6040_HPLLENA;
891 twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
892 break;
893 default:
894 dev_err(codec->dev, "unknown mclk freq %d\n", freq);
895 return -EINVAL;
896 }
897
898 /* lppll divider */
899 switch (priv->sysclk) {
900 case 17640000:
901 lppllctl |= TWL6040_LPLLFIN;
902 break;
903 case 19200000:
904 lppllctl &= ~TWL6040_LPLLFIN;
905 break;
906 default:
907 /* sysclk not yet configured */
908 lppllctl &= ~TWL6040_LPLLFIN;
909 priv->sysclk = 19200000;
910 break;
911 }
912
913 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
914
915 priv->pll = TWL6040_LPPLL_ID;
916 priv->sysclk_constraints = &lp_constraints;
917 break;
918 case TWL6040_SYSCLK_SEL_HPPLL:
919 hppllctl &= ~TWL6040_MCLK_MSK;
920
921 switch (freq) {
922 case 12000000:
923 /* mclk input, pll enabled */
924 hppllctl |= TWL6040_MCLK_12000KHZ |
925 TWL6040_HPLLSQRBP |
926 TWL6040_HPLLENA;
927 break;
928 case 19200000:
929 /* mclk input, pll disabled */
930 hppllctl |= TWL6040_MCLK_19200KHZ |
931 TWL6040_HPLLSQRBP |
932 TWL6040_HPLLBP;
933 break;
934 case 26000000:
935 /* mclk input, pll enabled */
936 hppllctl |= TWL6040_MCLK_26000KHZ |
937 TWL6040_HPLLSQRBP |
938 TWL6040_HPLLENA;
939 break;
940 case 38400000:
941 /* clk slicer, pll disabled */
942 hppllctl |= TWL6040_MCLK_38400KHZ |
943 TWL6040_HPLLSQRENA |
944 TWL6040_HPLLBP;
945 break;
946 default:
947 dev_err(codec->dev, "unknown mclk freq %d\n", freq);
948 return -EINVAL;
949 }
950
951 /* headset dac and driver must be in high-performance mode */
952 headset_power_mode(codec, 1);
953
954 twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
955 udelay(500);
956 lppllctl |= TWL6040_HPLLSEL;
957 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
958 lppllctl &= ~TWL6040_LPLLENA;
959 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
960
961 /* high-performance pll can provide only 19.2 MHz */
962 priv->pll = TWL6040_HPPLL_ID;
963 priv->sysclk = 19200000;
964 priv->sysclk_constraints = &hp_constraints;
965 break;
966 default:
967 dev_err(codec->dev, "unknown clk_id %d\n", clk_id);
968 return -EINVAL;
969 }
970
971 return 0;
972}
973
974static struct snd_soc_dai_ops twl6040_dai_ops = {
975 .startup = twl6040_startup,
976 .hw_params = twl6040_hw_params,
977 .trigger = twl6040_trigger,
978 .set_sysclk = twl6040_set_dai_sysclk,
979};
980
981struct snd_soc_dai twl6040_dai = {
982 .name = "twl6040",
983 .playback = {
984 .stream_name = "Playback",
985 .channels_min = 1,
986 .channels_max = 4,
987 .rates = TWL6040_RATES,
988 .formats = TWL6040_FORMATS,
989 },
990 .capture = {
991 .stream_name = "Capture",
992 .channels_min = 1,
993 .channels_max = 2,
994 .rates = TWL6040_RATES,
995 .formats = TWL6040_FORMATS,
996 },
997 .ops = &twl6040_dai_ops,
998};
999EXPORT_SYMBOL_GPL(twl6040_dai);
1000
1001#ifdef CONFIG_PM
1002static int twl6040_suspend(struct platform_device *pdev, pm_message_t state)
1003{
1004 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1005 struct snd_soc_codec *codec = socdev->card->codec;
1006
1007 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1008
1009 return 0;
1010}
1011
1012static int twl6040_resume(struct platform_device *pdev)
1013{
1014 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1015 struct snd_soc_codec *codec = socdev->card->codec;
1016
1017 twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1018
1019 return 0;
1020}
1021#else
1022#define twl6040_suspend NULL
1023#define twl6040_resume NULL
1024#endif
1025
1026static struct snd_soc_codec *twl6040_codec;
1027
1028static int twl6040_probe(struct platform_device *pdev)
1029{
1030 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1031 struct snd_soc_codec *codec;
1032 int ret = 0;
1033
1034 BUG_ON(!twl6040_codec);
1035
1036 codec = twl6040_codec;
1037 socdev->card->codec = codec;
1038
1039 /* register pcms */
1040 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1041 if (ret < 0) {
1042 dev_err(&pdev->dev, "failed to create pcms\n");
1043 return ret;
1044 }
1045
1046 snd_soc_add_controls(codec, twl6040_snd_controls,
1047 ARRAY_SIZE(twl6040_snd_controls));
1048 twl6040_add_widgets(codec);
1049
1050 if (ret < 0) {
1051 dev_err(&pdev->dev, "failed to register card\n");
1052 goto card_err;
1053 }
1054
1055 return ret;
1056
1057card_err:
1058 snd_soc_free_pcms(socdev);
1059 snd_soc_dapm_free(socdev);
1060 return ret;
1061}
1062
1063static int twl6040_remove(struct platform_device *pdev)
1064{
1065 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1066 struct snd_soc_codec *codec = socdev->card->codec;
1067
1068 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1069 snd_soc_free_pcms(socdev);
1070 snd_soc_dapm_free(socdev);
1071 kfree(codec);
1072
1073 return 0;
1074}
1075
1076struct snd_soc_codec_device soc_codec_dev_twl6040 = {
1077 .probe = twl6040_probe,
1078 .remove = twl6040_remove,
1079 .suspend = twl6040_suspend,
1080 .resume = twl6040_resume,
1081};
1082EXPORT_SYMBOL_GPL(soc_codec_dev_twl6040);
1083
1084static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1085{
1086 struct twl4030_codec_data *twl_codec = pdev->dev.platform_data;
1087 struct snd_soc_codec *codec;
1088 struct twl6040_data *priv;
1089 int audpwron, naudint;
1090 int ret = 0;
1091
1092 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
1093 if (priv == NULL)
1094 return -ENOMEM;
1095
1096 if (twl_codec) {
1097 audpwron = twl_codec->audpwron_gpio;
1098 naudint = twl_codec->naudint_irq;
1099 } else {
1100 audpwron = -EINVAL;
1101 naudint = 0;
1102 }
1103
1104 priv->audpwron = audpwron;
1105 priv->naudint = naudint;
1106
1107 codec = &priv->codec;
1108 codec->dev = &pdev->dev;
1109 twl6040_dai.dev = &pdev->dev;
1110
1111 codec->name = "twl6040";
1112 codec->owner = THIS_MODULE;
1113 codec->read = twl6040_read_reg_cache;
1114 codec->write = twl6040_write;
1115 codec->set_bias_level = twl6040_set_bias_level;
1116 snd_soc_codec_set_drvdata(codec, priv);
1117 codec->dai = &twl6040_dai;
1118 codec->num_dai = 1;
1119 codec->reg_cache_size = ARRAY_SIZE(twl6040_reg);
1120 codec->reg_cache = kmemdup(twl6040_reg, sizeof(twl6040_reg),
1121 GFP_KERNEL);
1122 if (codec->reg_cache == NULL) {
1123 ret = -ENOMEM;
1124 goto cache_err;
1125 }
1126
1127 mutex_init(&codec->mutex);
1128 INIT_LIST_HEAD(&codec->dapm_widgets);
1129 INIT_LIST_HEAD(&codec->dapm_paths);
1130 init_completion(&priv->ready);
1131
1132 if (gpio_is_valid(audpwron)) {
1133 ret = gpio_request(audpwron, "audpwron");
1134 if (ret)
1135 goto gpio1_err;
1136
1137 ret = gpio_direction_output(audpwron, 0);
1138 if (ret)
1139 goto gpio2_err;
1140
1141 priv->codec_powered = 0;
1142 }
1143
1144 if (naudint) {
1145 /* audio interrupt */
1146 ret = request_threaded_irq(naudint, NULL,
1147 twl6040_naudint_handler,
1148 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1149 "twl6040_codec", codec);
1150 if (ret)
1151 goto gpio2_err;
1152 } else {
1153 if (gpio_is_valid(audpwron)) {
1154 /* enable only codec ready interrupt */
1155 twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
1156 ~TWL6040_READYMSK & TWL6040_ALLINT_MSK);
1157 } else {
1158 /* no interrupts at all */
1159 twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
1160 TWL6040_ALLINT_MSK);
1161 }
1162 }
1163
1164 /* init vio registers */
1165 twl6040_init_vio_regs(codec);
1166
1167 /* power on device */
1168 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1169 if (ret)
1170 goto irq_err;
1171
1172 ret = snd_soc_register_codec(codec);
1173 if (ret)
1174 goto reg_err;
1175
1176 twl6040_codec = codec;
1177
1178 ret = snd_soc_register_dai(&twl6040_dai);
1179 if (ret)
1180 goto dai_err;
1181
1182 return 0;
1183
1184dai_err:
1185 snd_soc_unregister_codec(codec);
1186 twl6040_codec = NULL;
1187reg_err:
1188 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1189irq_err:
1190 if (naudint)
1191 free_irq(naudint, codec);
1192gpio2_err:
1193 if (gpio_is_valid(audpwron))
1194 gpio_free(audpwron);
1195gpio1_err:
1196 kfree(codec->reg_cache);
1197cache_err:
1198 kfree(priv);
1199 return ret;
1200}
1201
1202static int __devexit twl6040_codec_remove(struct platform_device *pdev)
1203{
1204 struct twl6040_data *priv = snd_soc_codec_get_drvdata(twl6040_codec);
1205 int audpwron = priv->audpwron;
1206 int naudint = priv->naudint;
1207
1208 if (gpio_is_valid(audpwron))
1209 gpio_free(audpwron);
1210
1211 if (naudint)
1212 free_irq(naudint, twl6040_codec);
1213
1214 snd_soc_unregister_dai(&twl6040_dai);
1215 snd_soc_unregister_codec(twl6040_codec);
1216
1217 kfree(twl6040_codec);
1218 twl6040_codec = NULL;
1219
1220 return 0;
1221}
1222
1223static struct platform_driver twl6040_codec_driver = {
1224 .driver = {
1225 .name = "twl6040_codec",
1226 .owner = THIS_MODULE,
1227 },
1228 .probe = twl6040_codec_probe,
1229 .remove = __devexit_p(twl6040_codec_remove),
1230};
1231
1232static int __init twl6040_codec_init(void)
1233{
1234 return platform_driver_register(&twl6040_codec_driver);
1235}
1236module_init(twl6040_codec_init);
1237
1238static void __exit twl6040_codec_exit(void)
1239{
1240 platform_driver_unregister(&twl6040_codec_driver);
1241}
1242module_exit(twl6040_codec_exit);
1243
1244MODULE_DESCRIPTION("ASoC TWL6040 codec driver");
1245MODULE_AUTHOR("Misael Lopez Cruz");
1246MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
new file mode 100644
index 000000000000..c472070a1da2
--- /dev/null
+++ b/sound/soc/codecs/twl6040.h
@@ -0,0 +1,141 @@
1/*
2 * ALSA SoC TWL6040 codec driver
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __TWL6040_H__
23#define __TWL6040_H__
24
25#define TWL6040_REG_ASICID 0x01
26#define TWL6040_REG_ASICREV 0x02
27#define TWL6040_REG_INTID 0x03
28#define TWL6040_REG_INTMR 0x04
29#define TWL6040_REG_NCPCTL 0x05
30#define TWL6040_REG_LDOCTL 0x06
31#define TWL6040_REG_HPPLLCTL 0x07
32#define TWL6040_REG_LPPLLCTL 0x08
33#define TWL6040_REG_LPPLLDIV 0x09
34#define TWL6040_REG_AMICBCTL 0x0A
35#define TWL6040_REG_DMICBCTL 0x0B
36#define TWL6040_REG_MICLCTL 0x0C
37#define TWL6040_REG_MICRCTL 0x0D
38#define TWL6040_REG_MICGAIN 0x0E
39#define TWL6040_REG_LINEGAIN 0x0F
40#define TWL6040_REG_HSLCTL 0x10
41#define TWL6040_REG_HSRCTL 0x11
42#define TWL6040_REG_HSGAIN 0x12
43#define TWL6040_REG_EARCTL 0x13
44#define TWL6040_REG_HFLCTL 0x14
45#define TWL6040_REG_HFLGAIN 0x15
46#define TWL6040_REG_HFRCTL 0x16
47#define TWL6040_REG_HFRGAIN 0x17
48#define TWL6040_REG_VIBCTLL 0x18
49#define TWL6040_REG_VIBDATL 0x19
50#define TWL6040_REG_VIBCTLR 0x1A
51#define TWL6040_REG_VIBDATR 0x1B
52#define TWL6040_REG_HKCTL1 0x1C
53#define TWL6040_REG_HKCTL2 0x1D
54#define TWL6040_REG_GPOCTL 0x1E
55#define TWL6040_REG_ALB 0x1F
56#define TWL6040_REG_DLB 0x20
57#define TWL6040_REG_TRIM1 0x28
58#define TWL6040_REG_TRIM2 0x29
59#define TWL6040_REG_TRIM3 0x2A
60#define TWL6040_REG_HSOTRIM 0x2B
61#define TWL6040_REG_HFOTRIM 0x2C
62#define TWL6040_REG_ACCCTL 0x2D
63#define TWL6040_REG_STATUS 0x2E
64
65#define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1)
66
67#define TWL6040_VIOREGNUM 18
68#define TWL6040_VDDREGNUM 21
69
70/* INTID (0x03) fields */
71
72#define TWL6040_THINT 0x01
73#define TWL6040_PLUGINT 0x02
74#define TWL6040_UNPLUGINT 0x04
75#define TWL6040_HOOKINT 0x08
76#define TWL6040_HFINT 0x10
77#define TWL6040_VIBINT 0x20
78#define TWL6040_READYINT 0x40
79
80/* INTMR (0x04) fields */
81
82#define TWL6040_READYMSK 0x40
83#define TWL6040_ALLINT_MSK 0x7B
84
85/* NCPCTL (0x05) fields */
86
87#define TWL6040_NCPENA 0x01
88#define TWL6040_NCPOPEN 0x40
89
90/* LDOCTL (0x06) fields */
91
92#define TWL6040_LSLDOENA 0x01
93#define TWL6040_HSLDOENA 0x04
94#define TWL6040_REFENA 0x40
95#define TWL6040_OSCENA 0x80
96
97/* HPPLLCTL (0x07) fields */
98
99#define TWL6040_HPLLENA 0x01
100#define TWL6040_HPLLRST 0x02
101#define TWL6040_HPLLBP 0x04
102#define TWL6040_HPLLSQRENA 0x08
103#define TWL6040_HPLLSQRBP 0x10
104#define TWL6040_MCLK_12000KHZ (0 << 5)
105#define TWL6040_MCLK_19200KHZ (1 << 5)
106#define TWL6040_MCLK_26000KHZ (2 << 5)
107#define TWL6040_MCLK_38400KHZ (3 << 5)
108#define TWL6040_MCLK_MSK 0x60
109
110/* LPPLLCTL (0x08) fields */
111
112#define TWL6040_LPLLENA 0x01
113#define TWL6040_LPLLRST 0x02
114#define TWL6040_LPLLSEL 0x04
115#define TWL6040_LPLLFIN 0x08
116#define TWL6040_HPLLSEL 0x10
117
118/* HSLCTL (0x10) fields */
119
120#define TWL6040_HSDACMODEL 0x02
121#define TWL6040_HSDRVMODEL 0x08
122
123/* HSRCTL (0x11) fields */
124
125#define TWL6040_HSDACMODER 0x02
126#define TWL6040_HSDRVMODER 0x08
127
128/* ACCCTL (0x2D) fields */
129
130#define TWL6040_RESETSPLIT 0x04
131
132#define TWL6040_SYSCLK_SEL_LPPLL 1
133#define TWL6040_SYSCLK_SEL_HPPLL 2
134
135#define TWL6040_HPPLL_ID 1
136#define TWL6040_LPPLL_ID 2
137
138extern struct snd_soc_dai twl6040_dai;
139extern struct snd_soc_codec_device soc_codec_dev_twl6040;
140
141#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index a8dcd5a5bbcb..28aac53c97bb 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -175,7 +175,7 @@ static int uda134x_startup(struct snd_pcm_substream *substream,
175 struct snd_soc_pcm_runtime *rtd = substream->private_data; 175 struct snd_soc_pcm_runtime *rtd = substream->private_data;
176 struct snd_soc_device *socdev = rtd->socdev; 176 struct snd_soc_device *socdev = rtd->socdev;
177 struct snd_soc_codec *codec = socdev->card->codec; 177 struct snd_soc_codec *codec = socdev->card->codec;
178 struct uda134x_priv *uda134x = codec->private_data; 178 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
179 struct snd_pcm_runtime *master_runtime; 179 struct snd_pcm_runtime *master_runtime;
180 180
181 if (uda134x->master_substream) { 181 if (uda134x->master_substream) {
@@ -208,7 +208,7 @@ static void uda134x_shutdown(struct snd_pcm_substream *substream,
208 struct snd_soc_pcm_runtime *rtd = substream->private_data; 208 struct snd_soc_pcm_runtime *rtd = substream->private_data;
209 struct snd_soc_device *socdev = rtd->socdev; 209 struct snd_soc_device *socdev = rtd->socdev;
210 struct snd_soc_codec *codec = socdev->card->codec; 210 struct snd_soc_codec *codec = socdev->card->codec;
211 struct uda134x_priv *uda134x = codec->private_data; 211 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
212 212
213 if (uda134x->master_substream == substream) 213 if (uda134x->master_substream == substream)
214 uda134x->master_substream = uda134x->slave_substream; 214 uda134x->master_substream = uda134x->slave_substream;
@@ -223,7 +223,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream,
223 struct snd_soc_pcm_runtime *rtd = substream->private_data; 223 struct snd_soc_pcm_runtime *rtd = substream->private_data;
224 struct snd_soc_device *socdev = rtd->socdev; 224 struct snd_soc_device *socdev = rtd->socdev;
225 struct snd_soc_codec *codec = socdev->card->codec; 225 struct snd_soc_codec *codec = socdev->card->codec;
226 struct uda134x_priv *uda134x = codec->private_data; 226 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
227 u8 hw_params; 227 u8 hw_params;
228 228
229 if (substream == uda134x->slave_substream) { 229 if (substream == uda134x->slave_substream) {
@@ -295,7 +295,7 @@ static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
295 int clk_id, unsigned int freq, int dir) 295 int clk_id, unsigned int freq, int dir)
296{ 296{
297 struct snd_soc_codec *codec = codec_dai->codec; 297 struct snd_soc_codec *codec = codec_dai->codec;
298 struct uda134x_priv *uda134x = codec->private_data; 298 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
299 299
300 pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__, 300 pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__,
301 clk_id, freq, dir); 301 clk_id, freq, dir);
@@ -317,7 +317,7 @@ static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
317 unsigned int fmt) 317 unsigned int fmt)
318{ 318{
319 struct snd_soc_codec *codec = codec_dai->codec; 319 struct snd_soc_codec *codec = codec_dai->codec;
320 struct uda134x_priv *uda134x = codec->private_data; 320 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
321 321
322 pr_debug("%s fmt: %08X\n", __func__, fmt); 322 pr_debug("%s fmt: %08X\n", __func__, fmt);
323 323
@@ -432,6 +432,14 @@ SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
432SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), 432SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
433}; 433};
434 434
435static const struct snd_kcontrol_new uda1345_snd_controls[] = {
436SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
437
438SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
439
440SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
441};
442
435static struct snd_soc_dai_ops uda134x_dai_ops = { 443static struct snd_soc_dai_ops uda134x_dai_ops = {
436 .startup = uda134x_startup, 444 .startup = uda134x_startup,
437 .shutdown = uda134x_shutdown, 445 .shutdown = uda134x_shutdown,
@@ -487,6 +495,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
487 case UDA134X_UDA1340: 495 case UDA134X_UDA1340:
488 case UDA134X_UDA1341: 496 case UDA134X_UDA1341:
489 case UDA134X_UDA1344: 497 case UDA134X_UDA1344:
498 case UDA134X_UDA1345:
490 break; 499 break;
491 default: 500 default:
492 printk(KERN_ERR "UDA134X SoC codec: " 501 printk(KERN_ERR "UDA134X SoC codec: "
@@ -504,7 +513,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
504 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); 513 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
505 if (uda134x == NULL) 514 if (uda134x == NULL)
506 goto priv_err; 515 goto priv_err;
507 codec->private_data = uda134x; 516 snd_soc_codec_set_drvdata(codec, uda134x);
508 517
509 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg), 518 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg),
510 GFP_KERNEL); 519 GFP_KERNEL);
@@ -552,6 +561,10 @@ static int uda134x_soc_probe(struct platform_device *pdev)
552 ret = snd_soc_add_controls(codec, uda1341_snd_controls, 561 ret = snd_soc_add_controls(codec, uda1341_snd_controls,
553 ARRAY_SIZE(uda1341_snd_controls)); 562 ARRAY_SIZE(uda1341_snd_controls));
554 break; 563 break;
564 case UDA134X_UDA1345:
565 ret = snd_soc_add_controls(codec, uda1345_snd_controls,
566 ARRAY_SIZE(uda1345_snd_controls));
567 break;
555 default: 568 default:
556 printk(KERN_ERR "%s unknown codec type: %d", 569 printk(KERN_ERR "%s unknown codec type: %d",
557 __func__, pd->model); 570 __func__, pd->model);
@@ -568,7 +581,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
568pcm_err: 581pcm_err:
569 kfree(codec->reg_cache); 582 kfree(codec->reg_cache);
570reg_err: 583reg_err:
571 kfree(codec->private_data); 584 kfree(snd_soc_codec_get_drvdata(codec));
572priv_err: 585priv_err:
573 kfree(codec); 586 kfree(codec);
574 return ret; 587 return ret;
@@ -586,7 +599,7 @@ static int uda134x_soc_remove(struct platform_device *pdev)
586 snd_soc_free_pcms(socdev); 599 snd_soc_free_pcms(socdev);
587 snd_soc_dapm_free(socdev); 600 snd_soc_dapm_free(socdev);
588 601
589 kfree(codec->private_data); 602 kfree(snd_soc_codec_get_drvdata(codec));
590 kfree(codec->reg_cache); 603 kfree(codec->reg_cache);
591 kfree(codec); 604 kfree(codec);
592 605
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 9cd0a66b7663..2f925a27dcde 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -476,7 +476,7 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
476 struct snd_soc_pcm_runtime *rtd = substream->private_data; 476 struct snd_soc_pcm_runtime *rtd = substream->private_data;
477 struct snd_soc_device *socdev = rtd->socdev; 477 struct snd_soc_device *socdev = rtd->socdev;
478 struct snd_soc_codec *codec = socdev->card->codec; 478 struct snd_soc_codec *codec = socdev->card->codec;
479 struct uda1380_priv *uda1380 = codec->private_data; 479 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
480 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); 480 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
481 481
482 switch (cmd) { 482 switch (cmd) {
@@ -670,7 +670,6 @@ static int uda1380_resume(struct platform_device *pdev)
670 codec->hw_write(codec->control_data, data, 2); 670 codec->hw_write(codec->control_data, data, 2);
671 } 671 }
672 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 672 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
673 uda1380_set_bias_level(codec, codec->suspend_bias_level);
674 return 0; 673 return 0;
675} 674}
676 675
@@ -774,7 +773,7 @@ static int uda1380_register(struct uda1380_priv *uda1380)
774 INIT_LIST_HEAD(&codec->dapm_widgets); 773 INIT_LIST_HEAD(&codec->dapm_widgets);
775 INIT_LIST_HEAD(&codec->dapm_paths); 774 INIT_LIST_HEAD(&codec->dapm_paths);
776 775
777 codec->private_data = uda1380; 776 snd_soc_codec_set_drvdata(codec, uda1380);
778 codec->name = "UDA1380"; 777 codec->name = "UDA1380";
779 codec->owner = THIS_MODULE; 778 codec->owner = THIS_MODULE;
780 codec->read = uda1380_read_reg_cache; 779 codec->read = uda1380_read_reg_cache;
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 2e0772f9c456..8ae20208e7be 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -55,6 +55,7 @@ struct wm8350_output {
55struct wm8350_jack_data { 55struct wm8350_jack_data {
56 struct snd_soc_jack *jack; 56 struct snd_soc_jack *jack;
57 int report; 57 int report;
58 int short_report;
58}; 59};
59 60
60struct wm8350_data { 61struct wm8350_data {
@@ -63,6 +64,7 @@ struct wm8350_data {
63 struct wm8350_output out2; 64 struct wm8350_output out2;
64 struct wm8350_jack_data hpl; 65 struct wm8350_jack_data hpl;
65 struct wm8350_jack_data hpr; 66 struct wm8350_jack_data hpr;
67 struct wm8350_jack_data mic;
66 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; 68 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
67 int fll_freq_out; 69 int fll_freq_out;
68 int fll_freq_in; 70 int fll_freq_in;
@@ -94,7 +96,7 @@ static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg,
94 */ 96 */
95static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec) 97static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
96{ 98{
97 struct wm8350_data *wm8350_data = codec->private_data; 99 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
98 struct wm8350_output *out1 = &wm8350_data->out1; 100 struct wm8350_output *out1 = &wm8350_data->out1;
99 struct wm8350 *wm8350 = codec->control_data; 101 struct wm8350 *wm8350 = codec->control_data;
100 int left_complete = 0, right_complete = 0; 102 int left_complete = 0, right_complete = 0;
@@ -160,7 +162,7 @@ static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
160 */ 162 */
161static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec) 163static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
162{ 164{
163 struct wm8350_data *wm8350_data = codec->private_data; 165 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
164 struct wm8350_output *out2 = &wm8350_data->out2; 166 struct wm8350_output *out2 = &wm8350_data->out2;
165 struct wm8350 *wm8350 = codec->control_data; 167 struct wm8350 *wm8350 = codec->control_data;
166 int left_complete = 0, right_complete = 0; 168 int left_complete = 0, right_complete = 0;
@@ -230,7 +232,7 @@ static void wm8350_pga_work(struct work_struct *work)
230{ 232{
231 struct snd_soc_codec *codec = 233 struct snd_soc_codec *codec =
232 container_of(work, struct snd_soc_codec, delayed_work.work); 234 container_of(work, struct snd_soc_codec, delayed_work.work);
233 struct wm8350_data *wm8350_data = codec->private_data; 235 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
234 struct wm8350_output *out1 = &wm8350_data->out1, 236 struct wm8350_output *out1 = &wm8350_data->out1,
235 *out2 = &wm8350_data->out2; 237 *out2 = &wm8350_data->out2;
236 int i, out1_complete, out2_complete; 238 int i, out1_complete, out2_complete;
@@ -277,7 +279,7 @@ static int pga_event(struct snd_soc_dapm_widget *w,
277 struct snd_kcontrol *kcontrol, int event) 279 struct snd_kcontrol *kcontrol, int event)
278{ 280{
279 struct snd_soc_codec *codec = w->codec; 281 struct snd_soc_codec *codec = w->codec;
280 struct wm8350_data *wm8350_data = codec->private_data; 282 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
281 struct wm8350_output *out; 283 struct wm8350_output *out;
282 284
283 switch (w->shift) { 285 switch (w->shift) {
@@ -322,7 +324,7 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
322 struct snd_ctl_elem_value *ucontrol) 324 struct snd_ctl_elem_value *ucontrol)
323{ 325{
324 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 326 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
325 struct wm8350_data *wm8350_priv = codec->private_data; 327 struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
326 struct wm8350_output *out = NULL; 328 struct wm8350_output *out = NULL;
327 struct soc_mixer_control *mc = 329 struct soc_mixer_control *mc =
328 (struct soc_mixer_control *)kcontrol->private_value; 330 (struct soc_mixer_control *)kcontrol->private_value;
@@ -365,7 +367,7 @@ static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
365 struct snd_ctl_elem_value *ucontrol) 367 struct snd_ctl_elem_value *ucontrol)
366{ 368{
367 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 369 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
368 struct wm8350_data *wm8350_priv = codec->private_data; 370 struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
369 struct wm8350_output *out1 = &wm8350_priv->out1; 371 struct wm8350_output *out1 = &wm8350_priv->out1;
370 struct wm8350_output *out2 = &wm8350_priv->out2; 372 struct wm8350_output *out2 = &wm8350_priv->out2;
371 struct soc_mixer_control *mc = 373 struct soc_mixer_control *mc =
@@ -1107,7 +1109,7 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1107{ 1109{
1108 struct snd_soc_codec *codec = codec_dai->codec; 1110 struct snd_soc_codec *codec = codec_dai->codec;
1109 struct wm8350 *wm8350 = codec->control_data; 1111 struct wm8350 *wm8350 = codec->control_data;
1110 struct wm8350_data *priv = codec->private_data; 1112 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1111 struct _fll_div fll_div; 1113 struct _fll_div fll_div;
1112 int ret = 0; 1114 int ret = 0;
1113 u16 fll_1, fll_4; 1115 u16 fll_1, fll_4;
@@ -1159,7 +1161,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1159 enum snd_soc_bias_level level) 1161 enum snd_soc_bias_level level)
1160{ 1162{
1161 struct wm8350 *wm8350 = codec->control_data; 1163 struct wm8350 *wm8350 = codec->control_data;
1162 struct wm8350_data *priv = codec->private_data; 1164 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1163 struct wm8350_audio_platform_data *platform = 1165 struct wm8350_audio_platform_data *platform =
1164 wm8350->codec.platform_data; 1166 wm8350->codec.platform_data;
1165 u16 pm1; 1167 u16 pm1;
@@ -1335,9 +1337,6 @@ static int wm8350_resume(struct platform_device *pdev)
1335 1337
1336 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1338 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1337 1339
1338 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
1339 wm8350_set_bias_level(codec, SND_SOC_BIAS_ON);
1340
1341 return 0; 1340 return 0;
1342} 1341}
1343 1342
@@ -1392,12 +1391,13 @@ static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
1392 * @jack: jack to report detection events on 1391 * @jack: jack to report detection events on
1393 * @report: value to report 1392 * @report: value to report
1394 * 1393 *
1395 * Enables the headphone jack detection of the WM8350. 1394 * Enables the headphone jack detection of the WM8350. If no report
1395 * is specified then detection is disabled.
1396 */ 1396 */
1397int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, 1397int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1398 struct snd_soc_jack *jack, int report) 1398 struct snd_soc_jack *jack, int report)
1399{ 1399{
1400 struct wm8350_data *priv = codec->private_data; 1400 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1401 struct wm8350 *wm8350 = codec->control_data; 1401 struct wm8350 *wm8350 = codec->control_data;
1402 int irq; 1402 int irq;
1403 int ena; 1403 int ena;
@@ -1421,8 +1421,12 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1421 return -EINVAL; 1421 return -EINVAL;
1422 } 1422 }
1423 1423
1424 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); 1424 if (report) {
1425 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); 1425 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1426 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena);
1427 } else {
1428 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, ena);
1429 }
1426 1430
1427 /* Sync status */ 1431 /* Sync status */
1428 wm8350_hp_jack_handler(irq + wm8350->irq_base, priv); 1432 wm8350_hp_jack_handler(irq + wm8350->irq_base, priv);
@@ -1431,6 +1435,60 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1431} 1435}
1432EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); 1436EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect);
1433 1437
1438static irqreturn_t wm8350_mic_handler(int irq, void *data)
1439{
1440 struct wm8350_data *priv = data;
1441 struct wm8350 *wm8350 = priv->codec.control_data;
1442 u16 reg;
1443 int report = 0;
1444
1445 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1446 if (reg & WM8350_JACK_MICSCD_LVL)
1447 report |= priv->mic.short_report;
1448 if (reg & WM8350_JACK_MICSD_LVL)
1449 report |= priv->mic.report;
1450
1451 snd_soc_jack_report(priv->mic.jack, report,
1452 priv->mic.report | priv->mic.short_report);
1453
1454 return IRQ_HANDLED;
1455}
1456
1457/**
1458 * wm8350_mic_jack_detect - Enable microphone jack detection.
1459 *
1460 * @codec: WM8350 codec
1461 * @jack: jack to report detection events on
1462 * @detect_report: value to report when presence detected
1463 * @short_report: value to report when microphone short detected
1464 *
1465 * Enables the microphone jack detection of the WM8350. If both reports
1466 * are specified as zero then detection is disabled.
1467 */
1468int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
1469 struct snd_soc_jack *jack,
1470 int detect_report, int short_report)
1471{
1472 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1473 struct wm8350 *wm8350 = codec->control_data;
1474
1475 priv->mic.jack = jack;
1476 priv->mic.report = detect_report;
1477 priv->mic.short_report = short_report;
1478
1479 if (detect_report || short_report) {
1480 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1481 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_1,
1482 WM8350_MIC_DET_ENA);
1483 } else {
1484 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_1,
1485 WM8350_MIC_DET_ENA);
1486 }
1487
1488 return 0;
1489}
1490EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect);
1491
1434static struct snd_soc_codec *wm8350_codec; 1492static struct snd_soc_codec *wm8350_codec;
1435 1493
1436static int wm8350_probe(struct platform_device *pdev) 1494static int wm8350_probe(struct platform_device *pdev)
@@ -1448,7 +1506,7 @@ static int wm8350_probe(struct platform_device *pdev)
1448 socdev->card->codec = wm8350_codec; 1506 socdev->card->codec = wm8350_codec;
1449 codec = socdev->card->codec; 1507 codec = socdev->card->codec;
1450 wm8350 = codec->control_data; 1508 wm8350 = codec->control_data;
1451 priv = codec->private_data; 1509 priv = snd_soc_codec_get_drvdata(codec);
1452 1510
1453 /* Enable the codec */ 1511 /* Enable the codec */
1454 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1512 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1494,6 +1552,10 @@ static int wm8350_probe(struct platform_device *pdev)
1494 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, 1552 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R,
1495 wm8350_hp_jack_handler, 0, "Right jack detect", 1553 wm8350_hp_jack_handler, 0, "Right jack detect",
1496 priv); 1554 priv);
1555 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICSCD,
1556 wm8350_mic_handler, 0, "Microphone short", priv);
1557 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD,
1558 wm8350_mic_handler, 0, "Microphone detect", priv);
1497 1559
1498 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1560 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1499 if (ret < 0) { 1561 if (ret < 0) {
@@ -1515,18 +1577,21 @@ static int wm8350_remove(struct platform_device *pdev)
1515 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1577 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1516 struct snd_soc_codec *codec = socdev->card->codec; 1578 struct snd_soc_codec *codec = socdev->card->codec;
1517 struct wm8350 *wm8350 = codec->control_data; 1579 struct wm8350 *wm8350 = codec->control_data;
1518 struct wm8350_data *priv = codec->private_data; 1580 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1519 int ret; 1581 int ret;
1520 1582
1521 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, 1583 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
1522 WM8350_JDL_ENA | WM8350_JDR_ENA); 1584 WM8350_JDL_ENA | WM8350_JDR_ENA);
1523 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); 1585 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1524 1586
1587 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICD, priv);
1588 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, priv);
1525 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv); 1589 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv);
1526 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv); 1590 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv);
1527 1591
1528 priv->hpl.jack = NULL; 1592 priv->hpl.jack = NULL;
1529 priv->hpr.jack = NULL; 1593 priv->hpr.jack = NULL;
1594 priv->mic.jack = NULL;
1530 1595
1531 /* cancel any work waiting to be queued. */ 1596 /* cancel any work waiting to be queued. */
1532 ret = cancel_delayed_work(&codec->delayed_work); 1597 ret = cancel_delayed_work(&codec->delayed_work);
@@ -1631,7 +1696,7 @@ static __devinit int wm8350_codec_probe(struct platform_device *pdev)
1631 codec->dai = &wm8350_dai; 1696 codec->dai = &wm8350_dai;
1632 codec->num_dai = 1; 1697 codec->num_dai = 1;
1633 codec->reg_cache_size = WM8350_MAX_REGISTER; 1698 codec->reg_cache_size = WM8350_MAX_REGISTER;
1634 codec->private_data = priv; 1699 snd_soc_codec_set_drvdata(codec, priv);
1635 codec->control_data = wm8350; 1700 codec->control_data = wm8350;
1636 1701
1637 /* Put the codec into reset if it wasn't already */ 1702 /* Put the codec into reset if it wasn't already */
@@ -1663,7 +1728,7 @@ static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1663{ 1728{
1664 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 1729 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
1665 struct snd_soc_codec *codec = wm8350->codec.codec; 1730 struct snd_soc_codec *codec = wm8350->codec.codec;
1666 struct wm8350_data *priv = codec->private_data; 1731 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1667 1732
1668 snd_soc_unregister_dai(&wm8350_dai); 1733 snd_soc_unregister_dai(&wm8350_dai);
1669 snd_soc_unregister_codec(codec); 1734 snd_soc_unregister_codec(codec);
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
index d088eb4b88bb..9ed0467c71db 100644
--- a/sound/soc/codecs/wm8350.h
+++ b/sound/soc/codecs/wm8350.h
@@ -25,5 +25,8 @@ enum wm8350_jack {
25 25
26int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, 26int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
27 struct snd_soc_jack *jack, int report); 27 struct snd_soc_jack *jack, int report);
28int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
29 struct snd_soc_jack *jack,
30 int detect_report, int short_report);
28 31
29#endif 32#endif
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 6acc885cf9b7..7f5d080536a0 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -77,7 +77,7 @@ struct wm8400_priv {
77static inline unsigned int wm8400_read(struct snd_soc_codec *codec, 77static inline unsigned int wm8400_read(struct snd_soc_codec *codec,
78 unsigned int reg) 78 unsigned int reg)
79{ 79{
80 struct wm8400_priv *wm8400 = codec->private_data; 80 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
81 81
82 if (reg == WM8400_INTDRIVBITS) 82 if (reg == WM8400_INTDRIVBITS)
83 return wm8400->fake_register; 83 return wm8400->fake_register;
@@ -91,7 +91,7 @@ static inline unsigned int wm8400_read(struct snd_soc_codec *codec,
91static int wm8400_write(struct snd_soc_codec *codec, unsigned int reg, 91static int wm8400_write(struct snd_soc_codec *codec, unsigned int reg,
92 unsigned int value) 92 unsigned int value)
93{ 93{
94 struct wm8400_priv *wm8400 = codec->private_data; 94 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
95 95
96 if (reg == WM8400_INTDRIVBITS) { 96 if (reg == WM8400_INTDRIVBITS) {
97 wm8400->fake_register = value; 97 wm8400->fake_register = value;
@@ -102,7 +102,7 @@ static int wm8400_write(struct snd_soc_codec *codec, unsigned int reg,
102 102
103static void wm8400_codec_reset(struct snd_soc_codec *codec) 103static void wm8400_codec_reset(struct snd_soc_codec *codec)
104{ 104{
105 struct wm8400_priv *wm8400 = codec->private_data; 105 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
106 106
107 wm8400_reset_codec_reg_cache(wm8400->wm8400); 107 wm8400_reset_codec_reg_cache(wm8400->wm8400);
108} 108}
@@ -926,7 +926,7 @@ static int wm8400_set_dai_sysclk(struct snd_soc_dai *codec_dai,
926 int clk_id, unsigned int freq, int dir) 926 int clk_id, unsigned int freq, int dir)
927{ 927{
928 struct snd_soc_codec *codec = codec_dai->codec; 928 struct snd_soc_codec *codec = codec_dai->codec;
929 struct wm8400_priv *wm8400 = codec->private_data; 929 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
930 930
931 wm8400->sysclk = freq; 931 wm8400->sysclk = freq;
932 return 0; 932 return 0;
@@ -1015,7 +1015,7 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1015 unsigned int freq_out) 1015 unsigned int freq_out)
1016{ 1016{
1017 struct snd_soc_codec *codec = codec_dai->codec; 1017 struct snd_soc_codec *codec = codec_dai->codec;
1018 struct wm8400_priv *wm8400 = codec->private_data; 1018 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
1019 struct fll_factors factors; 1019 struct fll_factors factors;
1020 int ret; 1020 int ret;
1021 u16 reg; 1021 u16 reg;
@@ -1204,7 +1204,7 @@ static int wm8400_mute(struct snd_soc_dai *dai, int mute)
1204static int wm8400_set_bias_level(struct snd_soc_codec *codec, 1204static int wm8400_set_bias_level(struct snd_soc_codec *codec,
1205 enum snd_soc_bias_level level) 1205 enum snd_soc_bias_level level)
1206{ 1206{
1207 struct wm8400_priv *wm8400 = codec->private_data; 1207 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
1208 u16 val; 1208 u16 val;
1209 int ret; 1209 int ret;
1210 1210
@@ -1467,7 +1467,7 @@ static int wm8400_codec_probe(struct platform_device *dev)
1467 return -ENOMEM; 1467 return -ENOMEM;
1468 1468
1469 codec = &priv->codec; 1469 codec = &priv->codec;
1470 codec->private_data = priv; 1470 snd_soc_codec_set_drvdata(codec, priv);
1471 codec->control_data = dev_get_drvdata(&dev->dev); 1471 codec->control_data = dev_get_drvdata(&dev->dev);
1472 priv->wm8400 = dev_get_drvdata(&dev->dev); 1472 priv->wm8400 = dev_get_drvdata(&dev->dev);
1473 1473
@@ -1530,7 +1530,7 @@ err:
1530 1530
1531static int __exit wm8400_codec_remove(struct platform_device *dev) 1531static int __exit wm8400_codec_remove(struct platform_device *dev)
1532{ 1532{
1533 struct wm8400_priv *priv = wm8400_codec->private_data; 1533 struct wm8400_priv *priv = snd_soc_codec_get_drvdata(wm8400_codec);
1534 u16 reg; 1534 u16 reg;
1535 1535
1536 snd_soc_unregister_dai(&wm8400_dai); 1536 snd_soc_unregister_dai(&wm8400_dai);
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 9000b1d19afb..0f7bcb61071a 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -557,7 +557,7 @@ static int wm8510_resume(struct platform_device *pdev)
557 codec->hw_write(codec->control_data, data, 2); 557 codec->hw_write(codec->control_data, data, 2);
558 } 558 }
559 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 559 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
560 wm8510_set_bias_level(codec, codec->suspend_bias_level); 560
561 return 0; 561 return 0;
562} 562}
563 563
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 19cd47293424..37242a7d3077 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -138,7 +138,7 @@ static int wm8523_startup(struct snd_pcm_substream *substream,
138 struct snd_soc_dai *dai) 138 struct snd_soc_dai *dai)
139{ 139{
140 struct snd_soc_codec *codec = dai->codec; 140 struct snd_soc_codec *codec = dai->codec;
141 struct wm8523_priv *wm8523 = codec->private_data; 141 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
142 142
143 /* The set of sample rates that can be supported depends on the 143 /* The set of sample rates that can be supported depends on the
144 * MCLK supplied to the CODEC - enforce this. 144 * MCLK supplied to the CODEC - enforce this.
@@ -164,7 +164,7 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
164 struct snd_soc_pcm_runtime *rtd = substream->private_data; 164 struct snd_soc_pcm_runtime *rtd = substream->private_data;
165 struct snd_soc_device *socdev = rtd->socdev; 165 struct snd_soc_device *socdev = rtd->socdev;
166 struct snd_soc_codec *codec = socdev->card->codec; 166 struct snd_soc_codec *codec = socdev->card->codec;
167 struct wm8523_priv *wm8523 = codec->private_data; 167 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
168 int i; 168 int i;
169 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1); 169 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
170 u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2); 170 u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2);
@@ -211,7 +211,7 @@ static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
211 int clk_id, unsigned int freq, int dir) 211 int clk_id, unsigned int freq, int dir)
212{ 212{
213 struct snd_soc_codec *codec = codec_dai->codec; 213 struct snd_soc_codec *codec = codec_dai->codec;
214 struct wm8523_priv *wm8523 = codec->private_data; 214 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
215 unsigned int val; 215 unsigned int val;
216 int i; 216 int i;
217 217
@@ -318,7 +318,7 @@ static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
318static int wm8523_set_bias_level(struct snd_soc_codec *codec, 318static int wm8523_set_bias_level(struct snd_soc_codec *codec,
319 enum snd_soc_bias_level level) 319 enum snd_soc_bias_level level)
320{ 320{
321 struct wm8523_priv *wm8523 = codec->private_data; 321 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
322 int ret, i; 322 int ret, i;
323 323
324 switch (level) { 324 switch (level) {
@@ -489,7 +489,7 @@ static int wm8523_register(struct wm8523_priv *wm8523,
489 INIT_LIST_HEAD(&codec->dapm_widgets); 489 INIT_LIST_HEAD(&codec->dapm_widgets);
490 INIT_LIST_HEAD(&codec->dapm_paths); 490 INIT_LIST_HEAD(&codec->dapm_paths);
491 491
492 codec->private_data = wm8523; 492 snd_soc_codec_set_drvdata(codec, wm8523);
493 codec->name = "WM8523"; 493 codec->name = "WM8523";
494 codec->owner = THIS_MODULE; 494 codec->owner = THIS_MODULE;
495 codec->bias_level = SND_SOC_BIAS_OFF; 495 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 8cc9042965eb..c3571ee5c11b 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -412,7 +412,7 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
412{ 412{
413 int offset; 413 int offset;
414 struct snd_soc_codec *codec = codec_dai->codec; 414 struct snd_soc_codec *codec = codec_dai->codec;
415 struct wm8580_priv *wm8580 = codec->private_data; 415 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
416 struct pll_state *state; 416 struct pll_state *state;
417 struct _pll_div pll_div; 417 struct _pll_div pll_div;
418 unsigned int reg; 418 unsigned int reg;
@@ -840,7 +840,7 @@ static int wm8580_register(struct wm8580_priv *wm8580,
840 INIT_LIST_HEAD(&codec->dapm_widgets); 840 INIT_LIST_HEAD(&codec->dapm_widgets);
841 INIT_LIST_HEAD(&codec->dapm_paths); 841 INIT_LIST_HEAD(&codec->dapm_paths);
842 842
843 codec->private_data = wm8580; 843 snd_soc_codec_set_drvdata(codec, wm8580);
844 codec->name = "WM8580"; 844 codec->name = "WM8580";
845 codec->owner = THIS_MODULE; 845 codec->owner = THIS_MODULE;
846 codec->bias_level = SND_SOC_BIAS_OFF; 846 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 8ca3812f2f2f..effb14eee7d4 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -163,7 +163,7 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
163 struct snd_soc_dai *dai) 163 struct snd_soc_dai *dai)
164{ 164{
165 struct snd_soc_codec *codec = dai->codec; 165 struct snd_soc_codec *codec = dai->codec;
166 struct wm8711_priv *wm8711 = codec->private_data; 166 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
167 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc; 167 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
168 int i = get_coeff(wm8711->sysclk, params_rate(params)); 168 int i = get_coeff(wm8711->sysclk, params_rate(params));
169 u16 srate = (coeff_div[i].sr << 2) | 169 u16 srate = (coeff_div[i].sr << 2) |
@@ -227,7 +227,7 @@ static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
227 int clk_id, unsigned int freq, int dir) 227 int clk_id, unsigned int freq, int dir)
228{ 228{
229 struct snd_soc_codec *codec = codec_dai->codec; 229 struct snd_soc_codec *codec = codec_dai->codec;
230 struct wm8711_priv *wm8711 = codec->private_data; 230 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
231 231
232 switch (freq) { 232 switch (freq) {
233 case 11289600: 233 case 11289600:
@@ -376,7 +376,7 @@ static int wm8711_resume(struct platform_device *pdev)
376 codec->hw_write(codec->control_data, data, 2); 376 codec->hw_write(codec->control_data, data, 2);
377 } 377 }
378 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 378 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
379 wm8711_set_bias_level(codec, codec->suspend_bias_level); 379
380 return 0; 380 return 0;
381} 381}
382 382
@@ -446,7 +446,7 @@ static int wm8711_register(struct wm8711_priv *wm8711,
446 INIT_LIST_HEAD(&codec->dapm_widgets); 446 INIT_LIST_HEAD(&codec->dapm_widgets);
447 INIT_LIST_HEAD(&codec->dapm_paths); 447 INIT_LIST_HEAD(&codec->dapm_paths);
448 448
449 codec->private_data = wm8711; 449 snd_soc_codec_set_drvdata(codec, wm8711);
450 codec->name = "WM8711"; 450 codec->name = "WM8711";
451 codec->owner = THIS_MODULE; 451 codec->owner = THIS_MODULE;
452 codec->bias_level = SND_SOC_BIAS_OFF; 452 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 07adc375a706..34be2d2b69ef 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -238,7 +238,7 @@ static int wm8728_resume(struct platform_device *pdev)
238 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 238 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
239 struct snd_soc_codec *codec = socdev->card->codec; 239 struct snd_soc_codec *codec = socdev->card->codec;
240 240
241 wm8728_set_bias_level(codec, codec->suspend_bias_level); 241 wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
242 242
243 return 0; 243 return 0;
244} 244}
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index e7c6bf163185..0ab9b6355297 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -225,7 +225,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
225 struct snd_soc_pcm_runtime *rtd = substream->private_data; 225 struct snd_soc_pcm_runtime *rtd = substream->private_data;
226 struct snd_soc_device *socdev = rtd->socdev; 226 struct snd_soc_device *socdev = rtd->socdev;
227 struct snd_soc_codec *codec = socdev->card->codec; 227 struct snd_soc_codec *codec = socdev->card->codec;
228 struct wm8731_priv *wm8731 = codec->private_data; 228 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
229 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; 229 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
230 int i = get_coeff(wm8731->sysclk, params_rate(params)); 230 int i = get_coeff(wm8731->sysclk, params_rate(params));
231 u16 srate = (coeff_div[i].sr << 2) | 231 u16 srate = (coeff_div[i].sr << 2) |
@@ -292,7 +292,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
292 int clk_id, unsigned int freq, int dir) 292 int clk_id, unsigned int freq, int dir)
293{ 293{
294 struct snd_soc_codec *codec = codec_dai->codec; 294 struct snd_soc_codec *codec = codec_dai->codec;
295 struct wm8731_priv *wm8731 = codec->private_data; 295 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
296 296
297 switch (freq) { 297 switch (freq) {
298 case 11289600: 298 case 11289600:
@@ -369,6 +369,10 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
369static int wm8731_set_bias_level(struct snd_soc_codec *codec, 369static int wm8731_set_bias_level(struct snd_soc_codec *codec,
370 enum snd_soc_bias_level level) 370 enum snd_soc_bias_level level)
371{ 371{
372 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
373 int i, ret;
374 u8 data[2];
375 u16 *cache = codec->reg_cache;
372 u16 reg; 376 u16 reg;
373 377
374 switch (level) { 378 switch (level) {
@@ -377,6 +381,24 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
377 case SND_SOC_BIAS_PREPARE: 381 case SND_SOC_BIAS_PREPARE:
378 break; 382 break;
379 case SND_SOC_BIAS_STANDBY: 383 case SND_SOC_BIAS_STANDBY:
384 if (codec->bias_level == SND_SOC_BIAS_OFF) {
385 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
386 wm8731->supplies);
387 if (ret != 0)
388 return ret;
389
390 /* Sync reg_cache with the hardware */
391 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
392 if (cache[i] == wm8731_reg[i])
393 continue;
394
395 data[0] = (i << 1) | ((cache[i] >> 8)
396 & 0x0001);
397 data[1] = cache[i] & 0x00ff;
398 codec->hw_write(codec->control_data, data, 2);
399 }
400 }
401
380 /* Clear PWROFF, gate CLKOUT, everything else as-is */ 402 /* Clear PWROFF, gate CLKOUT, everything else as-is */
381 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f; 403 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f;
382 snd_soc_write(codec, WM8731_PWR, reg | 0x0040); 404 snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
@@ -384,17 +406,15 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
384 case SND_SOC_BIAS_OFF: 406 case SND_SOC_BIAS_OFF:
385 snd_soc_write(codec, WM8731_ACTIVE, 0x0); 407 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
386 snd_soc_write(codec, WM8731_PWR, 0xffff); 408 snd_soc_write(codec, WM8731_PWR, 0xffff);
409 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
410 wm8731->supplies);
387 break; 411 break;
388 } 412 }
389 codec->bias_level = level; 413 codec->bias_level = level;
390 return 0; 414 return 0;
391} 415}
392 416
393#define WM8731_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 417#define WM8731_RATES SNDRV_PCM_RATE_8000_96000
394 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
395 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
396 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
397 SNDRV_PCM_RATE_96000)
398 418
399#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 419#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
400 SNDRV_PCM_FMTBIT_S24_LE) 420 SNDRV_PCM_FMTBIT_S24_LE)
@@ -432,12 +452,9 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
432{ 452{
433 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 453 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
434 struct snd_soc_codec *codec = socdev->card->codec; 454 struct snd_soc_codec *codec = socdev->card->codec;
435 struct wm8731_priv *wm8731 = codec->private_data;
436 455
437 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
438 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 456 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
439 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), 457
440 wm8731->supplies);
441 return 0; 458 return 0;
442} 459}
443 460
@@ -445,27 +462,8 @@ static int wm8731_resume(struct platform_device *pdev)
445{ 462{
446 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
447 struct snd_soc_codec *codec = socdev->card->codec; 464 struct snd_soc_codec *codec = socdev->card->codec;
448 struct wm8731_priv *wm8731 = codec->private_data;
449 int i, ret;
450 u8 data[2];
451 u16 *cache = codec->reg_cache;
452 465
453 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
454 wm8731->supplies);
455 if (ret != 0)
456 return ret;
457
458 /* Sync reg_cache with the hardware */
459 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
460 if (cache[i] == wm8731_reg[i])
461 continue;
462
463 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
464 data[1] = cache[i] & 0x00ff;
465 codec->hw_write(codec->control_data, data, 2);
466 }
467 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 466 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
468 wm8731_set_bias_level(codec, codec->suspend_bias_level);
469 467
470 return 0; 468 return 0;
471} 469}
@@ -540,7 +538,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
540 INIT_LIST_HEAD(&codec->dapm_widgets); 538 INIT_LIST_HEAD(&codec->dapm_widgets);
541 INIT_LIST_HEAD(&codec->dapm_paths); 539 INIT_LIST_HEAD(&codec->dapm_paths);
542 540
543 codec->private_data = wm8731; 541 snd_soc_codec_set_drvdata(codec, wm8731);
544 codec->name = "WM8731"; 542 codec->name = "WM8731";
545 codec->owner = THIS_MODULE; 543 codec->owner = THIS_MODULE;
546 codec->bias_level = SND_SOC_BIAS_OFF; 544 codec->bias_level = SND_SOC_BIAS_OFF;
@@ -609,6 +607,9 @@ static int wm8731_register(struct wm8731_priv *wm8731,
609 goto err_codec; 607 goto err_codec;
610 } 608 }
611 609
610 /* Regulators will have been enabled by bias management */
611 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
612
612 return 0; 613 return 0;
613 614
614err_codec: 615err_codec:
@@ -627,7 +628,6 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
627 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 628 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
628 snd_soc_unregister_dai(&wm8731_dai); 629 snd_soc_unregister_dai(&wm8731_dai);
629 snd_soc_unregister_codec(&wm8731->codec); 630 snd_soc_unregister_codec(&wm8731->codec);
630 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
632 kfree(wm8731); 632 kfree(wm8731);
633 wm8731_codec = NULL; 633 wm8731_codec = NULL;
@@ -708,7 +708,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
708 708
709static struct i2c_driver wm8731_i2c_driver = { 709static struct i2c_driver wm8731_i2c_driver = {
710 .driver = { 710 .driver = {
711 .name = "WM8731 I2C Codec", 711 .name = "wm8731",
712 .owner = THIS_MODULE, 712 .owner = THIS_MODULE,
713 }, 713 },
714 .probe = wm8731_i2c_probe, 714 .probe = wm8731_i2c_probe,
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 2916ed4d3844..9407e193fcc3 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -30,13 +30,6 @@
30 30
31#include "wm8750.h" 31#include "wm8750.h"
32 32
33#define WM8750_VERSION "0.12"
34
35/* codec private data */
36struct wm8750_priv {
37 unsigned int sysclk;
38};
39
40/* 33/*
41 * wm8750 register cache 34 * wm8750 register cache
42 * We can't read the WM8750 register space when we 35 * We can't read the WM8750 register space when we
@@ -56,6 +49,13 @@ static const u16 wm8750_reg[] = {
56 0x0079, 0x0079, 0x0079, /* 40 */ 49 0x0079, 0x0079, 0x0079, /* 40 */
57}; 50};
58 51
52/* codec private data */
53struct wm8750_priv {
54 unsigned int sysclk;
55 struct snd_soc_codec codec;
56 u16 reg_cache[ARRAY_SIZE(wm8750_reg)];
57};
58
59#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) 59#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
60 60
61/* 61/*
@@ -483,7 +483,7 @@ static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
483 int clk_id, unsigned int freq, int dir) 483 int clk_id, unsigned int freq, int dir)
484{ 484{
485 struct snd_soc_codec *codec = codec_dai->codec; 485 struct snd_soc_codec *codec = codec_dai->codec;
486 struct wm8750_priv *wm8750 = codec->private_data; 486 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
487 487
488 switch (freq) { 488 switch (freq) {
489 case 11289600: 489 case 11289600:
@@ -562,7 +562,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
562 struct snd_soc_pcm_runtime *rtd = substream->private_data; 562 struct snd_soc_pcm_runtime *rtd = substream->private_data;
563 struct snd_soc_device *socdev = rtd->socdev; 563 struct snd_soc_device *socdev = rtd->socdev;
564 struct snd_soc_codec *codec = socdev->card->codec; 564 struct snd_soc_codec *codec = socdev->card->codec;
565 struct wm8750_priv *wm8750 = codec->private_data; 565 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
566 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3; 566 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
567 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0; 567 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
568 int coeff = get_coeff(wm8750->sysclk, params_rate(params)); 568 int coeff = get_coeff(wm8750->sysclk, params_rate(params));
@@ -614,10 +614,16 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
614 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 614 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
615 break; 615 break;
616 case SND_SOC_BIAS_PREPARE: 616 case SND_SOC_BIAS_PREPARE:
617 /* set vmid to 5k for quick power up */
618 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
619 break; 617 break;
620 case SND_SOC_BIAS_STANDBY: 618 case SND_SOC_BIAS_STANDBY:
619 if (codec->bias_level == SND_SOC_BIAS_OFF) {
620 /* Set VMID to 5k */
621 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
622
623 /* ...and ramp */
624 msleep(1000);
625 }
626
621 /* mute dac and set vmid to 500k, enable VREF */ 627 /* mute dac and set vmid to 500k, enable VREF */
622 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 628 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
623 break; 629 break;
@@ -661,13 +667,6 @@ struct snd_soc_dai wm8750_dai = {
661}; 667};
662EXPORT_SYMBOL_GPL(wm8750_dai); 668EXPORT_SYMBOL_GPL(wm8750_dai);
663 669
664static void wm8750_work(struct work_struct *work)
665{
666 struct snd_soc_codec *codec =
667 container_of(work, struct snd_soc_codec, delayed_work.work);
668 wm8750_set_bias_level(codec, codec->bias_level);
669}
670
671static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 670static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
672{ 671{
673 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 672 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -696,36 +695,92 @@ static int wm8750_resume(struct platform_device *pdev)
696 695
697 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 696 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
698 697
699 /* charge wm8750 caps */ 698 return 0;
700 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 699}
701 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 700
702 codec->bias_level = SND_SOC_BIAS_ON; 701static struct snd_soc_codec *wm8750_codec;
703 schedule_delayed_work(&codec->delayed_work, 702
704 msecs_to_jiffies(1000)); 703static int wm8750_probe(struct platform_device *pdev)
704{
705 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
706 struct snd_soc_codec *codec;
707 int ret = 0;
708
709 if (!wm8750_codec) {
710 dev_err(&pdev->dev, "WM8750 codec not yet registered\n");
711 return -EINVAL;
712 }
713
714 socdev->card->codec = wm8750_codec;
715 codec = wm8750_codec;
716
717 /* register pcms */
718 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
719 if (ret < 0) {
720 printk(KERN_ERR "wm8750: failed to create pcms\n");
721 goto err;
705 } 722 }
706 723
724 snd_soc_add_controls(codec, wm8750_snd_controls,
725 ARRAY_SIZE(wm8750_snd_controls));
726 wm8750_add_widgets(codec);
727
728 return 0;
729
730err:
731 return ret;
732}
733
734/* power down chip */
735static int wm8750_remove(struct platform_device *pdev)
736{
737 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
738
739 snd_soc_free_pcms(socdev);
740 snd_soc_dapm_free(socdev);
741
707 return 0; 742 return 0;
708} 743}
709 744
745struct snd_soc_codec_device soc_codec_dev_wm8750 = {
746 .probe = wm8750_probe,
747 .remove = wm8750_remove,
748 .suspend = wm8750_suspend,
749 .resume = wm8750_resume,
750};
751EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
752
710/* 753/*
711 * initialise the WM8750 driver 754 * initialise the WM8750 driver
712 * register the mixer and dsp interfaces with the kernel 755 * register the mixer and dsp interfaces with the kernel
713 */ 756 */
714static int wm8750_init(struct snd_soc_device *socdev, 757static int wm8750_register(struct wm8750_priv *wm8750,
715 enum snd_soc_control_type control) 758 enum snd_soc_control_type control)
716{ 759{
717 struct snd_soc_codec *codec = socdev->card->codec; 760 struct snd_soc_codec *codec = &wm8750->codec;
718 int reg, ret = 0; 761 int reg, ret = 0;
719 762
763 if (wm8750_codec) {
764 dev_err(codec->dev, "Multiple WM8750 devices not supported\n");
765 ret = -EINVAL;
766 goto err;
767 }
768
769 mutex_init(&codec->mutex);
770 INIT_LIST_HEAD(&codec->dapm_widgets);
771 INIT_LIST_HEAD(&codec->dapm_paths);
772
720 codec->name = "WM8750"; 773 codec->name = "WM8750";
721 codec->owner = THIS_MODULE; 774 codec->owner = THIS_MODULE;
775 codec->bias_level = SND_SOC_BIAS_STANDBY;
722 codec->set_bias_level = wm8750_set_bias_level; 776 codec->set_bias_level = wm8750_set_bias_level;
723 codec->dai = &wm8750_dai; 777 codec->dai = &wm8750_dai;
724 codec->num_dai = 1; 778 codec->num_dai = 1;
725 codec->reg_cache_size = ARRAY_SIZE(wm8750_reg); 779 codec->reg_cache_size = ARRAY_SIZE(wm8750->reg_cache) + 1;
726 codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL); 780 codec->reg_cache = &wm8750->reg_cache;
727 if (codec->reg_cache == NULL) 781 snd_soc_codec_set_drvdata(codec, wm8750);
728 return -ENOMEM; 782
783 memcpy(codec->reg_cache, wm8750_reg, sizeof(wm8750->reg_cache));
729 784
730 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 785 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
731 if (ret < 0) { 786 if (ret < 0) {
@@ -739,17 +794,8 @@ static int wm8750_init(struct snd_soc_device *socdev,
739 goto err; 794 goto err;
740 } 795 }
741 796
742 /* register pcms */
743 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
744 if (ret < 0) {
745 printk(KERN_ERR "wm8750: failed to create pcms\n");
746 goto err;
747 }
748
749 /* charge output caps */ 797 /* charge output caps */
750 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 798 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
751 codec->bias_level = SND_SOC_BIAS_STANDBY;
752 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));
753 799
754 /* set the update bits */ 800 /* set the update bits */
755 reg = snd_soc_read(codec, WM8750_LDAC); 801 reg = snd_soc_read(codec, WM8750_LDAC);
@@ -769,19 +815,37 @@ static int wm8750_init(struct snd_soc_device *socdev,
769 reg = snd_soc_read(codec, WM8750_RINVOL); 815 reg = snd_soc_read(codec, WM8750_RINVOL);
770 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100); 816 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
771 817
772 snd_soc_add_controls(codec, wm8750_snd_controls, 818 wm8750_codec = codec;
773 ARRAY_SIZE(wm8750_snd_controls));
774 wm8750_add_widgets(codec);
775 return ret;
776 819
820 ret = snd_soc_register_codec(codec);
821 if (ret != 0) {
822 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
823 goto err;
824 }
825
826 ret = snd_soc_register_dais(&wm8750_dai, 1);
827 if (ret != 0) {
828 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
829 goto err_codec;
830 }
831
832 return 0;
833
834err_codec:
835 snd_soc_unregister_codec(codec);
777err: 836err:
778 kfree(codec->reg_cache); 837 kfree(wm8750);
779 return ret; 838 return ret;
780} 839}
781 840
782/* If the i2c layer weren't so broken, we could pass this kind of data 841static void wm8750_unregister(struct wm8750_priv *wm8750)
783 around */ 842{
784static struct snd_soc_device *wm8750_socdev; 843 wm8750_set_bias_level(&wm8750->codec, SND_SOC_BIAS_OFF);
844 snd_soc_unregister_dais(&wm8750_dai, 1);
845 snd_soc_unregister_codec(&wm8750->codec);
846 kfree(wm8750);
847 wm8750_codec = NULL;
848}
785 849
786#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 850#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
787 851
@@ -795,24 +859,26 @@ static struct snd_soc_device *wm8750_socdev;
795static int wm8750_i2c_probe(struct i2c_client *i2c, 859static int wm8750_i2c_probe(struct i2c_client *i2c,
796 const struct i2c_device_id *id) 860 const struct i2c_device_id *id)
797{ 861{
798 struct snd_soc_device *socdev = wm8750_socdev; 862 struct snd_soc_codec *codec;
799 struct snd_soc_codec *codec = socdev->card->codec; 863 struct wm8750_priv *wm8750;
800 int ret; 864
865 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
866 if (wm8750 == NULL)
867 return -ENOMEM;
801 868
802 i2c_set_clientdata(i2c, codec); 869 codec = &wm8750->codec;
803 codec->control_data = i2c; 870 codec->control_data = i2c;
871 i2c_set_clientdata(i2c, wm8750);
804 872
805 ret = wm8750_init(socdev, SND_SOC_I2C); 873 codec->dev = &i2c->dev;
806 if (ret < 0)
807 pr_err("failed to initialise WM8750\n");
808 874
809 return ret; 875 return wm8750_register(wm8750, SND_SOC_I2C);
810} 876}
811 877
812static int wm8750_i2c_remove(struct i2c_client *client) 878static int wm8750_i2c_remove(struct i2c_client *client)
813{ 879{
814 struct snd_soc_codec *codec = i2c_get_clientdata(client); 880 struct wm8750_priv *wm8750 = i2c_get_clientdata(client);
815 kfree(codec->reg_cache); 881 wm8750_unregister(wm8750);
816 return 0; 882 return 0;
817} 883}
818 884
@@ -831,66 +897,31 @@ static struct i2c_driver wm8750_i2c_driver = {
831 .remove = wm8750_i2c_remove, 897 .remove = wm8750_i2c_remove,
832 .id_table = wm8750_i2c_id, 898 .id_table = wm8750_i2c_id,
833}; 899};
834
835static int wm8750_add_i2c_device(struct platform_device *pdev,
836 const struct wm8750_setup_data *setup)
837{
838 struct i2c_board_info info;
839 struct i2c_adapter *adapter;
840 struct i2c_client *client;
841 int ret;
842
843 ret = i2c_add_driver(&wm8750_i2c_driver);
844 if (ret != 0) {
845 dev_err(&pdev->dev, "can't add i2c driver\n");
846 return ret;
847 }
848
849 memset(&info, 0, sizeof(struct i2c_board_info));
850 info.addr = setup->i2c_address;
851 strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
852
853 adapter = i2c_get_adapter(setup->i2c_bus);
854 if (!adapter) {
855 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
856 setup->i2c_bus);
857 goto err_driver;
858 }
859
860 client = i2c_new_device(adapter, &info);
861 i2c_put_adapter(adapter);
862 if (!client) {
863 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
864 (unsigned int)info.addr);
865 goto err_driver;
866 }
867
868 return 0;
869
870err_driver:
871 i2c_del_driver(&wm8750_i2c_driver);
872 return -ENODEV;
873}
874#endif 900#endif
875 901
876#if defined(CONFIG_SPI_MASTER) 902#if defined(CONFIG_SPI_MASTER)
877static int __devinit wm8750_spi_probe(struct spi_device *spi) 903static int __devinit wm8750_spi_probe(struct spi_device *spi)
878{ 904{
879 struct snd_soc_device *socdev = wm8750_socdev; 905 struct snd_soc_codec *codec;
880 struct snd_soc_codec *codec = socdev->card->codec; 906 struct wm8750_priv *wm8750;
881 int ret; 907
908 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
909 if (wm8750 == NULL)
910 return -ENOMEM;
882 911
912 codec = &wm8750->codec;
883 codec->control_data = spi; 913 codec->control_data = spi;
914 codec->dev = &spi->dev;
884 915
885 ret = wm8750_init(socdev, SND_SOC_SPI); 916 dev_set_drvdata(&spi->dev, wm8750);
886 if (ret < 0)
887 dev_err(&spi->dev, "failed to initialise WM8750\n");
888 917
889 return ret; 918 return wm8750_register(wm8750, SND_SOC_SPI);
890} 919}
891 920
892static int __devexit wm8750_spi_remove(struct spi_device *spi) 921static int __devexit wm8750_spi_remove(struct spi_device *spi)
893{ 922{
923 struct wm8750_priv *wm8750 = dev_get_drvdata(&spi->dev);
924 wm8750_unregister(wm8750);
894 return 0; 925 return 0;
895} 926}
896 927
@@ -905,115 +936,31 @@ static struct spi_driver wm8750_spi_driver = {
905}; 936};
906#endif 937#endif
907 938
908static int wm8750_probe(struct platform_device *pdev) 939static int __init wm8750_modinit(void)
909{ 940{
910 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
911 struct wm8750_setup_data *setup = socdev->codec_data;
912 struct snd_soc_codec *codec;
913 struct wm8750_priv *wm8750;
914 int ret; 941 int ret;
915
916 pr_info("WM8750 Audio Codec %s", WM8750_VERSION);
917 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
918 if (codec == NULL)
919 return -ENOMEM;
920
921 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
922 if (wm8750 == NULL) {
923 kfree(codec);
924 return -ENOMEM;
925 }
926
927 codec->private_data = wm8750;
928 socdev->card->codec = codec;
929 mutex_init(&codec->mutex);
930 INIT_LIST_HEAD(&codec->dapm_widgets);
931 INIT_LIST_HEAD(&codec->dapm_paths);
932 wm8750_socdev = socdev;
933 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work);
934
935 ret = -ENODEV;
936
937#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 942#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
938 if (setup->i2c_address) { 943 ret = i2c_add_driver(&wm8750_i2c_driver);
939 ret = wm8750_add_i2c_device(pdev, setup); 944 if (ret != 0)
940 } 945 pr_err("Failed to register WM8750 I2C driver: %d\n", ret);
941#endif 946#endif
942#if defined(CONFIG_SPI_MASTER) 947#if defined(CONFIG_SPI_MASTER)
943 if (setup->spi) { 948 ret = spi_register_driver(&wm8750_spi_driver);
944 ret = spi_register_driver(&wm8750_spi_driver); 949 if (ret != 0)
945 if (ret != 0) 950 pr_err("Failed to register WM8750 SPI driver: %d\n", ret);
946 printk(KERN_ERR "can't add spi driver");
947 }
948#endif 951#endif
949 952 return 0;
950 if (ret != 0) {
951 kfree(codec->private_data);
952 kfree(codec);
953 }
954 return ret;
955}
956
957/*
958 * This function forces any delayed work to be queued and run.
959 */
960static int run_delayed_work(struct delayed_work *dwork)
961{
962 int ret;
963
964 /* cancel any work waiting to be queued. */
965 ret = cancel_delayed_work(dwork);
966
967 /* if there was any work waiting then we run it now and
968 * wait for it's completion */
969 if (ret) {
970 schedule_delayed_work(dwork, 0);
971 flush_scheduled_work();
972 }
973 return ret;
974} 953}
954module_init(wm8750_modinit);
975 955
976/* power down chip */ 956static void __exit wm8750_exit(void)
977static int wm8750_remove(struct platform_device *pdev)
978{ 957{
979 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
980 struct snd_soc_codec *codec = socdev->card->codec;
981
982 if (codec->control_data)
983 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
984 run_delayed_work(&codec->delayed_work);
985 snd_soc_free_pcms(socdev);
986 snd_soc_dapm_free(socdev);
987#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 958#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
988 i2c_unregister_device(codec->control_data);
989 i2c_del_driver(&wm8750_i2c_driver); 959 i2c_del_driver(&wm8750_i2c_driver);
990#endif 960#endif
991#if defined(CONFIG_SPI_MASTER) 961#if defined(CONFIG_SPI_MASTER)
992 spi_unregister_driver(&wm8750_spi_driver); 962 spi_unregister_driver(&wm8750_spi_driver);
993#endif 963#endif
994 kfree(codec->private_data);
995 kfree(codec);
996
997 return 0;
998}
999
1000struct snd_soc_codec_device soc_codec_dev_wm8750 = {
1001 .probe = wm8750_probe,
1002 .remove = wm8750_remove,
1003 .suspend = wm8750_suspend,
1004 .resume = wm8750_resume,
1005};
1006EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
1007
1008static int __init wm8750_modinit(void)
1009{
1010 return snd_soc_register_dai(&wm8750_dai);
1011}
1012module_init(wm8750_modinit);
1013
1014static void __exit wm8750_exit(void)
1015{
1016 snd_soc_unregister_dai(&wm8750_dai);
1017} 964}
1018module_exit(wm8750_exit); 965module_exit(wm8750_exit);
1019 966
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 613199a0f799..b59f349c5218 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -851,7 +851,7 @@ static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
851 int clk_id, unsigned int freq, int dir) 851 int clk_id, unsigned int freq, int dir)
852{ 852{
853 struct snd_soc_codec *codec = codec_dai->codec; 853 struct snd_soc_codec *codec = codec_dai->codec;
854 struct wm8753_priv *wm8753 = codec->private_data; 854 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
855 855
856 switch (freq) { 856 switch (freq) {
857 case 11289600: 857 case 11289600:
@@ -914,7 +914,7 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
914 struct snd_soc_pcm_runtime *rtd = substream->private_data; 914 struct snd_soc_pcm_runtime *rtd = substream->private_data;
915 struct snd_soc_device *socdev = rtd->socdev; 915 struct snd_soc_device *socdev = rtd->socdev;
916 struct snd_soc_codec *codec = socdev->card->codec; 916 struct snd_soc_codec *codec = socdev->card->codec;
917 struct wm8753_priv *wm8753 = codec->private_data; 917 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
918 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; 918 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
919 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; 919 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
920 920
@@ -1148,7 +1148,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1148 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1149 struct snd_soc_device *socdev = rtd->socdev; 1149 struct snd_soc_device *socdev = rtd->socdev;
1150 struct snd_soc_codec *codec = socdev->card->codec; 1150 struct snd_soc_codec *codec = socdev->card->codec;
1151 struct wm8753_priv *wm8753 = codec->private_data; 1151 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1152 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; 1152 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
1153 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; 1153 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
1154 int coeff; 1154 int coeff;
@@ -1646,7 +1646,7 @@ static int wm8753_register(struct wm8753_priv *wm8753)
1646 codec->num_dai = 2; 1646 codec->num_dai = 2;
1647 codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache) + 1; 1647 codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache) + 1;
1648 codec->reg_cache = &wm8753->reg_cache; 1648 codec->reg_cache = &wm8753->reg_cache;
1649 codec->private_data = wm8753; 1649 snd_soc_codec_set_drvdata(codec, wm8753);
1650 1650
1651 memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache)); 1651 memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache));
1652 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); 1652 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 60b1b3e1094b..7e4a627b4c7e 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -227,7 +227,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
227 struct snd_soc_dai *dai) 227 struct snd_soc_dai *dai)
228{ 228{
229 struct snd_soc_codec *codec = dai->codec; 229 struct snd_soc_codec *codec = dai->codec;
230 struct wm8776_priv *wm8776 = codec->private_data; 230 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
231 int iface_reg, iface; 231 int iface_reg, iface;
232 int ratio_shift, master; 232 int ratio_shift, master;
233 int i; 233 int i;
@@ -304,7 +304,7 @@ static int wm8776_set_sysclk(struct snd_soc_dai *dai,
304 int clk_id, unsigned int freq, int dir) 304 int clk_id, unsigned int freq, int dir)
305{ 305{
306 struct snd_soc_codec *codec = dai->codec; 306 struct snd_soc_codec *codec = dai->codec;
307 struct wm8776_priv *wm8776 = codec->private_data; 307 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
308 308
309 BUG_ON(dai->id >= ARRAY_SIZE(wm8776->sysclk)); 309 BUG_ON(dai->id >= ARRAY_SIZE(wm8776->sysclk));
310 310
@@ -491,7 +491,7 @@ static int wm8776_register(struct wm8776_priv *wm8776,
491 INIT_LIST_HEAD(&codec->dapm_widgets); 491 INIT_LIST_HEAD(&codec->dapm_widgets);
492 INIT_LIST_HEAD(&codec->dapm_paths); 492 INIT_LIST_HEAD(&codec->dapm_paths);
493 493
494 codec->private_data = wm8776; 494 snd_soc_codec_set_drvdata(codec, wm8776);
495 codec->name = "WM8776"; 495 codec->name = "WM8776";
496 codec->owner = THIS_MODULE; 496 codec->owner = THIS_MODULE;
497 codec->bias_level = SND_SOC_BIAS_OFF; 497 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index b7fd96adac64..5da17a704e5a 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -745,7 +745,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
745static int wm8900_set_fll(struct snd_soc_codec *codec, 745static int wm8900_set_fll(struct snd_soc_codec *codec,
746 int fll_id, unsigned int freq_in, unsigned int freq_out) 746 int fll_id, unsigned int freq_in, unsigned int freq_out)
747{ 747{
748 struct wm8900_priv *wm8900 = codec->private_data; 748 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
749 struct _fll_div fll_div; 749 struct _fll_div fll_div;
750 unsigned int reg; 750 unsigned int reg;
751 751
@@ -1132,7 +1132,7 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1132{ 1132{
1133 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1133 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1134 struct snd_soc_codec *codec = socdev->card->codec; 1134 struct snd_soc_codec *codec = socdev->card->codec;
1135 struct wm8900_priv *wm8900 = codec->private_data; 1135 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1136 int fll_out = wm8900->fll_out; 1136 int fll_out = wm8900->fll_out;
1137 int fll_in = wm8900->fll_in; 1137 int fll_in = wm8900->fll_in;
1138 int ret; 1138 int ret;
@@ -1156,7 +1156,7 @@ static int wm8900_resume(struct platform_device *pdev)
1156{ 1156{
1157 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1157 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1158 struct snd_soc_codec *codec = socdev->card->codec; 1158 struct snd_soc_codec *codec = socdev->card->codec;
1159 struct wm8900_priv *wm8900 = codec->private_data; 1159 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1160 u16 *cache; 1160 u16 *cache;
1161 int i, ret; 1161 int i, ret;
1162 1162
@@ -1206,7 +1206,7 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1206 return -ENOMEM; 1206 return -ENOMEM;
1207 1207
1208 codec = &wm8900->codec; 1208 codec = &wm8900->codec;
1209 codec->private_data = wm8900; 1209 snd_soc_codec_set_drvdata(codec, wm8900);
1210 codec->reg_cache = &wm8900->reg_cache[0]; 1210 codec->reg_cache = &wm8900->reg_cache[0];
1211 codec->reg_cache_size = WM8900_MAXREG; 1211 codec->reg_cache_size = WM8900_MAXREG;
1212 1212
@@ -1305,7 +1305,7 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1305 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF); 1305 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF);
1306 1306
1307 wm8900_dai.dev = NULL; 1307 wm8900_dai.dev = NULL;
1308 kfree(wm8900_codec->private_data); 1308 kfree(snd_soc_codec_get_drvdata(wm8900_codec));
1309 wm8900_codec = NULL; 1309 wm8900_codec = NULL;
1310 1310
1311 return 0; 1311 return 0;
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index fa5f99fde68b..bf08282d5ee5 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -11,26 +11,27 @@
11 * 11 *
12 * TODO: 12 * TODO:
13 * - TDM mode configuration. 13 * - TDM mode configuration.
14 * - Mic detect.
15 * - Digital microphone support. 14 * - Digital microphone support.
16 * - Interrupt support (mic detect and sequencer).
17 */ 15 */
18 16
19#include <linux/module.h> 17#include <linux/module.h>
20#include <linux/moduleparam.h> 18#include <linux/moduleparam.h>
21#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/completion.h>
22#include <linux/delay.h> 21#include <linux/delay.h>
23#include <linux/pm.h> 22#include <linux/pm.h>
24#include <linux/i2c.h> 23#include <linux/i2c.h>
25#include <linux/platform_device.h> 24#include <linux/platform_device.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/jack.h>
28#include <sound/pcm.h> 28#include <sound/pcm.h>
29#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
30#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/soc-dapm.h> 32#include <sound/soc-dapm.h>
33#include <sound/initval.h> 33#include <sound/initval.h>
34#include <sound/wm8903.h>
34 35
35#include "wm8903.h" 36#include "wm8903.h"
36 37
@@ -222,6 +223,14 @@ struct wm8903_priv {
222 int playback_active; 223 int playback_active;
223 int capture_active; 224 int capture_active;
224 225
226 struct completion wseq;
227
228 struct snd_soc_jack *mic_jack;
229 int mic_det;
230 int mic_short;
231 int mic_last_report;
232 int mic_delay;
233
225 struct snd_pcm_substream *master_substream; 234 struct snd_pcm_substream *master_substream;
226 struct snd_pcm_substream *slave_substream; 235 struct snd_pcm_substream *slave_substream;
227}; 236};
@@ -244,13 +253,14 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
244{ 253{
245 u16 reg[5]; 254 u16 reg[5];
246 struct i2c_client *i2c = codec->control_data; 255 struct i2c_client *i2c = codec->control_data;
256 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
247 257
248 BUG_ON(start > 48); 258 BUG_ON(start > 48);
249 259
250 /* Enable the sequencer */ 260 /* Enable the sequencer if it's not already on */
251 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0); 261 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0);
252 reg[0] |= WM8903_WSEQ_ENA; 262 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
253 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]); 263 reg[0] | WM8903_WSEQ_ENA);
254 264
255 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start); 265 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);
256 266
@@ -258,20 +268,19 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
258 start | WM8903_WSEQ_START); 268 start | WM8903_WSEQ_START);
259 269
260 /* Wait for it to complete. If we have the interrupt wired up then 270 /* Wait for it to complete. If we have the interrupt wired up then
261 * we could block waiting for an interrupt, though polling may still 271 * that will break us out of the poll early.
262 * be desirable for diagnostic purposes.
263 */ 272 */
264 do { 273 do {
265 msleep(10); 274 wait_for_completion_timeout(&wm8903->wseq,
275 msecs_to_jiffies(10));
266 276
267 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4); 277 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
268 } while (reg[4] & WM8903_WSEQ_BUSY); 278 } while (reg[4] & WM8903_WSEQ_BUSY);
269 279
270 dev_dbg(&i2c->dev, "Sequence complete\n"); 280 dev_dbg(&i2c->dev, "Sequence complete\n");
271 281
272 /* Disable the sequencer again */ 282 /* Disable the sequencer again if we enabled it */
273 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 283 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
274 reg[0] & ~WM8903_WSEQ_ENA);
275 284
276 return 0; 285 return 0;
277} 286}
@@ -412,7 +421,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
412{ 421{
413 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 422 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
414 struct snd_soc_codec *codec = widget->codec; 423 struct snd_soc_codec *codec = widget->codec;
415 struct wm8903_priv *wm8903 = codec->private_data; 424 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
416 struct i2c_client *i2c = codec->control_data; 425 struct i2c_client *i2c = codec->control_data;
417 u16 reg; 426 u16 reg;
418 int ret; 427 int ret;
@@ -993,7 +1002,7 @@ static int wm8903_set_dai_sysclk(struct snd_soc_dai *codec_dai,
993 int clk_id, unsigned int freq, int dir) 1002 int clk_id, unsigned int freq, int dir)
994{ 1003{
995 struct snd_soc_codec *codec = codec_dai->codec; 1004 struct snd_soc_codec *codec = codec_dai->codec;
996 struct wm8903_priv *wm8903 = codec->private_data; 1005 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
997 1006
998 wm8903->sysclk = freq; 1007 wm8903->sysclk = freq;
999 1008
@@ -1221,7 +1230,7 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
1221 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1230 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1222 struct snd_soc_device *socdev = rtd->socdev; 1231 struct snd_soc_device *socdev = rtd->socdev;
1223 struct snd_soc_codec *codec = socdev->card->codec; 1232 struct snd_soc_codec *codec = socdev->card->codec;
1224 struct wm8903_priv *wm8903 = codec->private_data; 1233 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1225 struct i2c_client *i2c = codec->control_data; 1234 struct i2c_client *i2c = codec->control_data;
1226 struct snd_pcm_runtime *master_runtime; 1235 struct snd_pcm_runtime *master_runtime;
1227 1236
@@ -1257,7 +1266,7 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream,
1257 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1266 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1258 struct snd_soc_device *socdev = rtd->socdev; 1267 struct snd_soc_device *socdev = rtd->socdev;
1259 struct snd_soc_codec *codec = socdev->card->codec; 1268 struct snd_soc_codec *codec = socdev->card->codec;
1260 struct wm8903_priv *wm8903 = codec->private_data; 1269 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1261 1270
1262 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1271 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1263 wm8903->playback_active--; 1272 wm8903->playback_active--;
@@ -1277,7 +1286,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1277 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1286 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1278 struct snd_soc_device *socdev = rtd->socdev; 1287 struct snd_soc_device *socdev = rtd->socdev;
1279 struct snd_soc_codec *codec = socdev->card->codec; 1288 struct snd_soc_codec *codec = socdev->card->codec;
1280 struct wm8903_priv *wm8903 = codec->private_data; 1289 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1281 struct i2c_client *i2c = codec->control_data; 1290 struct i2c_client *i2c = codec->control_data;
1282 int fs = params_rate(params); 1291 int fs = params_rate(params);
1283 int bclk; 1292 int bclk;
@@ -1436,6 +1445,116 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1436 return 0; 1445 return 0;
1437} 1446}
1438 1447
1448/**
1449 * wm8903_mic_detect - Enable microphone detection via the WM8903 IRQ
1450 *
1451 * @codec: WM8903 codec
1452 * @jack: jack to report detection events on
1453 * @det: value to report for presence detection
1454 * @shrt: value to report for short detection
1455 *
1456 * Enable microphone detection via IRQ on the WM8903. If GPIOs are
1457 * being used to bring out signals to the processor then only platform
1458 * data configuration is needed for WM8903 and processor GPIOs should
1459 * be configured using snd_soc_jack_add_gpios() instead.
1460 *
1461 * The current threasholds for detection should be configured using
1462 * micdet_cfg in the platform data. Using this function will force on
1463 * the microphone bias for the device.
1464 */
1465int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
1466 int det, int shrt)
1467{
1468 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1469 int irq_mask = WM8903_MICDET_EINT | WM8903_MICSHRT_EINT;
1470
1471 dev_dbg(codec->dev, "Enabling microphone detection: %x %x\n",
1472 det, shrt);
1473
1474 /* Store the configuration */
1475 wm8903->mic_jack = jack;
1476 wm8903->mic_det = det;
1477 wm8903->mic_short = shrt;
1478
1479 /* Enable interrupts we've got a report configured for */
1480 if (det)
1481 irq_mask &= ~WM8903_MICDET_EINT;
1482 if (shrt)
1483 irq_mask &= ~WM8903_MICSHRT_EINT;
1484
1485 snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
1486 WM8903_MICDET_EINT | WM8903_MICSHRT_EINT,
1487 irq_mask);
1488
1489 if (det && shrt) {
1490 /* Enable mic detection, this may not have been set through
1491 * platform data (eg, if the defaults are OK). */
1492 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1493 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1494 snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0,
1495 WM8903_MICDET_ENA, WM8903_MICDET_ENA);
1496 } else {
1497 snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0,
1498 WM8903_MICDET_ENA, 0);
1499 }
1500
1501 return 0;
1502}
1503EXPORT_SYMBOL_GPL(wm8903_mic_detect);
1504
1505static irqreturn_t wm8903_irq(int irq, void *data)
1506{
1507 struct wm8903_priv *wm8903 = data;
1508 struct snd_soc_codec *codec = &wm8903->codec;
1509 int mic_report;
1510 int int_pol;
1511 int int_val = 0;
1512 int mask = ~snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1_MASK);
1513
1514 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask;
1515
1516 if (int_val & WM8903_WSEQ_BUSY_EINT) {
1517 dev_dbg(codec->dev, "Write sequencer done\n");
1518 complete(&wm8903->wseq);
1519 }
1520
1521 /*
1522 * The rest is microphone jack detection. We need to manually
1523 * invert the polarity of the interrupt after each event - to
1524 * simplify the code keep track of the last state we reported
1525 * and just invert the relevant bits in both the report and
1526 * the polarity register.
1527 */
1528 mic_report = wm8903->mic_last_report;
1529 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1);
1530
1531 if (int_val & WM8903_MICSHRT_EINT) {
1532 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol);
1533
1534 mic_report ^= wm8903->mic_short;
1535 int_pol ^= WM8903_MICSHRT_INV;
1536 }
1537
1538 if (int_val & WM8903_MICDET_EINT) {
1539 dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol);
1540
1541 mic_report ^= wm8903->mic_det;
1542 int_pol ^= WM8903_MICDET_INV;
1543
1544 msleep(wm8903->mic_delay);
1545 }
1546
1547 snd_soc_update_bits(codec, WM8903_INTERRUPT_POLARITY_1,
1548 WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol);
1549
1550 snd_soc_jack_report(wm8903->mic_jack, mic_report,
1551 wm8903->mic_short | wm8903->mic_det);
1552
1553 wm8903->mic_last_report = mic_report;
1554
1555 return IRQ_HANDLED;
1556}
1557
1439#define WM8903_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\ 1558#define WM8903_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
1440 SNDRV_PCM_RATE_11025 | \ 1559 SNDRV_PCM_RATE_11025 | \
1441 SNDRV_PCM_RATE_16000 | \ 1560 SNDRV_PCM_RATE_16000 | \
@@ -1510,7 +1629,6 @@ static int wm8903_resume(struct platform_device *pdev)
1510 1629
1511 /* Bring the codec back up to standby first to minimise pop/clicks */ 1630 /* Bring the codec back up to standby first to minimise pop/clicks */
1512 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1631 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1513 wm8903_set_bias_level(codec, codec->suspend_bias_level);
1514 1632
1515 /* Sync back everything else */ 1633 /* Sync back everything else */
1516 if (tmp_cache) { 1634 if (tmp_cache) {
@@ -1530,9 +1648,11 @@ static struct snd_soc_codec *wm8903_codec;
1530static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, 1648static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1531 const struct i2c_device_id *id) 1649 const struct i2c_device_id *id)
1532{ 1650{
1651 struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev);
1533 struct wm8903_priv *wm8903; 1652 struct wm8903_priv *wm8903;
1534 struct snd_soc_codec *codec; 1653 struct snd_soc_codec *codec;
1535 int ret; 1654 int ret, i;
1655 int trigger, irq_pol;
1536 u16 val; 1656 u16 val;
1537 1657
1538 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); 1658 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
@@ -1554,8 +1674,9 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1554 codec->num_dai = 1; 1674 codec->num_dai = 1;
1555 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache); 1675 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
1556 codec->reg_cache = &wm8903->reg_cache[0]; 1676 codec->reg_cache = &wm8903->reg_cache[0];
1557 codec->private_data = wm8903; 1677 snd_soc_codec_set_drvdata(codec, wm8903);
1558 codec->volatile_register = wm8903_volatile_register; 1678 codec->volatile_register = wm8903_volatile_register;
1679 init_completion(&wm8903->wseq);
1559 1680
1560 i2c_set_clientdata(i2c, codec); 1681 i2c_set_clientdata(i2c, codec);
1561 codec->control_data = i2c; 1682 codec->control_data = i2c;
@@ -1579,6 +1700,53 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1579 1700
1580 wm8903_reset(codec); 1701 wm8903_reset(codec);
1581 1702
1703 /* Set up GPIOs and microphone detection */
1704 if (pdata) {
1705 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
1706 if (!pdata->gpio_cfg[i])
1707 continue;
1708
1709 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
1710 pdata->gpio_cfg[i] & 0xffff);
1711 }
1712
1713 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
1714 pdata->micdet_cfg);
1715
1716 /* Microphone detection needs the WSEQ clock */
1717 if (pdata->micdet_cfg)
1718 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1719 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1720
1721 wm8903->mic_delay = pdata->micdet_delay;
1722 }
1723
1724 if (i2c->irq) {
1725 if (pdata && pdata->irq_active_low) {
1726 trigger = IRQF_TRIGGER_LOW;
1727 irq_pol = WM8903_IRQ_POL;
1728 } else {
1729 trigger = IRQF_TRIGGER_HIGH;
1730 irq_pol = 0;
1731 }
1732
1733 snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL,
1734 WM8903_IRQ_POL, irq_pol);
1735
1736 ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq,
1737 trigger | IRQF_ONESHOT,
1738 "wm8903", wm8903);
1739 if (ret != 0) {
1740 dev_err(&i2c->dev, "Failed to request IRQ: %d\n",
1741 ret);
1742 goto err;
1743 }
1744
1745 /* Enable write sequencer interrupts */
1746 snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
1747 WM8903_IM_WSEQ_BUSY_EINT, 0);
1748 }
1749
1582 /* power on device */ 1750 /* power on device */
1583 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1751 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1584 1752
@@ -1619,7 +1787,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1619 ret = snd_soc_register_codec(codec); 1787 ret = snd_soc_register_codec(codec);
1620 if (ret != 0) { 1788 if (ret != 0) {
1621 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); 1789 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1622 goto err; 1790 goto err_irq;
1623 } 1791 }
1624 1792
1625 ret = snd_soc_register_dai(&wm8903_dai); 1793 ret = snd_soc_register_dai(&wm8903_dai);
@@ -1632,6 +1800,9 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1632 1800
1633err_codec: 1801err_codec:
1634 snd_soc_unregister_codec(codec); 1802 snd_soc_unregister_codec(codec);
1803err_irq:
1804 if (i2c->irq)
1805 free_irq(i2c->irq, wm8903);
1635err: 1806err:
1636 wm8903_codec = NULL; 1807 wm8903_codec = NULL;
1637 kfree(wm8903); 1808 kfree(wm8903);
@@ -1641,13 +1812,17 @@ err:
1641static __devexit int wm8903_i2c_remove(struct i2c_client *client) 1812static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1642{ 1813{
1643 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1814 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1815 struct wm8903_priv *priv = snd_soc_codec_get_drvdata(codec);
1644 1816
1645 snd_soc_unregister_dai(&wm8903_dai); 1817 snd_soc_unregister_dai(&wm8903_dai);
1646 snd_soc_unregister_codec(codec); 1818 snd_soc_unregister_codec(codec);
1647 1819
1648 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1820 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1649 1821
1650 kfree(codec->private_data); 1822 if (client->irq)
1823 free_irq(client->irq, priv);
1824
1825 kfree(priv);
1651 1826
1652 wm8903_codec = NULL; 1827 wm8903_codec = NULL;
1653 wm8903_dai.dev = NULL; 1828 wm8903_dai.dev = NULL;
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index 0ea27e2b9963..ce384a2ad820 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -18,6 +18,10 @@
18extern struct snd_soc_dai wm8903_dai; 18extern struct snd_soc_dai wm8903_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8903; 19extern struct snd_soc_codec_device soc_codec_dev_wm8903;
20 20
21extern int wm8903_mic_detect(struct snd_soc_codec *codec,
22 struct snd_soc_jack *jack,
23 int det, int shrt);
24
21#define WM8903_MCLK_DIV_2 1 25#define WM8903_MCLK_DIV_2 1
22#define WM8903_CLK_SYS 2 26#define WM8903_CLK_SYS 2
23#define WM8903_BCLK 3 27#define WM8903_BCLK 3
@@ -173,28 +177,6 @@ extern struct snd_soc_codec_device soc_codec_dev_wm8903;
173#define WM8903_VMID_RES_5K 4 177#define WM8903_VMID_RES_5K 4
174 178
175/* 179/*
176 * R6 (0x06) - Mic Bias Control 0
177 */
178#define WM8903_MICDET_HYST_ENA 0x0080 /* MICDET_HYST_ENA */
179#define WM8903_MICDET_HYST_ENA_MASK 0x0080 /* MICDET_HYST_ENA */
180#define WM8903_MICDET_HYST_ENA_SHIFT 7 /* MICDET_HYST_ENA */
181#define WM8903_MICDET_HYST_ENA_WIDTH 1 /* MICDET_HYST_ENA */
182#define WM8903_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
183#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
184#define WM8903_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
185#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
186#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
187#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
188#define WM8903_MICDET_ENA 0x0002 /* MICDET_ENA */
189#define WM8903_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
190#define WM8903_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
191#define WM8903_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
192#define WM8903_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
193#define WM8903_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
194#define WM8903_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
195#define WM8903_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
196
197/*
198 * R8 (0x08) - Analogue DAC 0 180 * R8 (0x08) - Analogue DAC 0
199 */ 181 */
200#define WM8903_DACBIAS_SEL_MASK 0x0018 /* DACBIAS_SEL - [4:3] */ 182#define WM8903_DACBIAS_SEL_MASK 0x0018 /* DACBIAS_SEL - [4:3] */
@@ -1135,201 +1117,6 @@ extern struct snd_soc_codec_device soc_codec_dev_wm8903;
1135#define WM8903_MASK_WRITE_ENA_WIDTH 1 /* MASK_WRITE_ENA */ 1117#define WM8903_MASK_WRITE_ENA_WIDTH 1 /* MASK_WRITE_ENA */
1136 1118
1137/* 1119/*
1138 * R116 (0x74) - GPIO Control 1
1139 */
1140#define WM8903_GP1_FN_MASK 0x1F00 /* GP1_FN - [12:8] */
1141#define WM8903_GP1_FN_SHIFT 8 /* GP1_FN - [12:8] */
1142#define WM8903_GP1_FN_WIDTH 5 /* GP1_FN - [12:8] */
1143#define WM8903_GP1_DIR 0x0080 /* GP1_DIR */
1144#define WM8903_GP1_DIR_MASK 0x0080 /* GP1_DIR */
1145#define WM8903_GP1_DIR_SHIFT 7 /* GP1_DIR */
1146#define WM8903_GP1_DIR_WIDTH 1 /* GP1_DIR */
1147#define WM8903_GP1_OP_CFG 0x0040 /* GP1_OP_CFG */
1148#define WM8903_GP1_OP_CFG_MASK 0x0040 /* GP1_OP_CFG */
1149#define WM8903_GP1_OP_CFG_SHIFT 6 /* GP1_OP_CFG */
1150#define WM8903_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
1151#define WM8903_GP1_IP_CFG 0x0020 /* GP1_IP_CFG */
1152#define WM8903_GP1_IP_CFG_MASK 0x0020 /* GP1_IP_CFG */
1153#define WM8903_GP1_IP_CFG_SHIFT 5 /* GP1_IP_CFG */
1154#define WM8903_GP1_IP_CFG_WIDTH 1 /* GP1_IP_CFG */
1155#define WM8903_GP1_LVL 0x0010 /* GP1_LVL */
1156#define WM8903_GP1_LVL_MASK 0x0010 /* GP1_LVL */
1157#define WM8903_GP1_LVL_SHIFT 4 /* GP1_LVL */
1158#define WM8903_GP1_LVL_WIDTH 1 /* GP1_LVL */
1159#define WM8903_GP1_PD 0x0008 /* GP1_PD */
1160#define WM8903_GP1_PD_MASK 0x0008 /* GP1_PD */
1161#define WM8903_GP1_PD_SHIFT 3 /* GP1_PD */
1162#define WM8903_GP1_PD_WIDTH 1 /* GP1_PD */
1163#define WM8903_GP1_PU 0x0004 /* GP1_PU */
1164#define WM8903_GP1_PU_MASK 0x0004 /* GP1_PU */
1165#define WM8903_GP1_PU_SHIFT 2 /* GP1_PU */
1166#define WM8903_GP1_PU_WIDTH 1 /* GP1_PU */
1167#define WM8903_GP1_INTMODE 0x0002 /* GP1_INTMODE */
1168#define WM8903_GP1_INTMODE_MASK 0x0002 /* GP1_INTMODE */
1169#define WM8903_GP1_INTMODE_SHIFT 1 /* GP1_INTMODE */
1170#define WM8903_GP1_INTMODE_WIDTH 1 /* GP1_INTMODE */
1171#define WM8903_GP1_DB 0x0001 /* GP1_DB */
1172#define WM8903_GP1_DB_MASK 0x0001 /* GP1_DB */
1173#define WM8903_GP1_DB_SHIFT 0 /* GP1_DB */
1174#define WM8903_GP1_DB_WIDTH 1 /* GP1_DB */
1175
1176/*
1177 * R117 (0x75) - GPIO Control 2
1178 */
1179#define WM8903_GP2_FN_MASK 0x1F00 /* GP2_FN - [12:8] */
1180#define WM8903_GP2_FN_SHIFT 8 /* GP2_FN - [12:8] */
1181#define WM8903_GP2_FN_WIDTH 5 /* GP2_FN - [12:8] */
1182#define WM8903_GP2_DIR 0x0080 /* GP2_DIR */
1183#define WM8903_GP2_DIR_MASK 0x0080 /* GP2_DIR */
1184#define WM8903_GP2_DIR_SHIFT 7 /* GP2_DIR */
1185#define WM8903_GP2_DIR_WIDTH 1 /* GP2_DIR */
1186#define WM8903_GP2_OP_CFG 0x0040 /* GP2_OP_CFG */
1187#define WM8903_GP2_OP_CFG_MASK 0x0040 /* GP2_OP_CFG */
1188#define WM8903_GP2_OP_CFG_SHIFT 6 /* GP2_OP_CFG */
1189#define WM8903_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
1190#define WM8903_GP2_IP_CFG 0x0020 /* GP2_IP_CFG */
1191#define WM8903_GP2_IP_CFG_MASK 0x0020 /* GP2_IP_CFG */
1192#define WM8903_GP2_IP_CFG_SHIFT 5 /* GP2_IP_CFG */
1193#define WM8903_GP2_IP_CFG_WIDTH 1 /* GP2_IP_CFG */
1194#define WM8903_GP2_LVL 0x0010 /* GP2_LVL */
1195#define WM8903_GP2_LVL_MASK 0x0010 /* GP2_LVL */
1196#define WM8903_GP2_LVL_SHIFT 4 /* GP2_LVL */
1197#define WM8903_GP2_LVL_WIDTH 1 /* GP2_LVL */
1198#define WM8903_GP2_PD 0x0008 /* GP2_PD */
1199#define WM8903_GP2_PD_MASK 0x0008 /* GP2_PD */
1200#define WM8903_GP2_PD_SHIFT 3 /* GP2_PD */
1201#define WM8903_GP2_PD_WIDTH 1 /* GP2_PD */
1202#define WM8903_GP2_PU 0x0004 /* GP2_PU */
1203#define WM8903_GP2_PU_MASK 0x0004 /* GP2_PU */
1204#define WM8903_GP2_PU_SHIFT 2 /* GP2_PU */
1205#define WM8903_GP2_PU_WIDTH 1 /* GP2_PU */
1206#define WM8903_GP2_INTMODE 0x0002 /* GP2_INTMODE */
1207#define WM8903_GP2_INTMODE_MASK 0x0002 /* GP2_INTMODE */
1208#define WM8903_GP2_INTMODE_SHIFT 1 /* GP2_INTMODE */
1209#define WM8903_GP2_INTMODE_WIDTH 1 /* GP2_INTMODE */
1210#define WM8903_GP2_DB 0x0001 /* GP2_DB */
1211#define WM8903_GP2_DB_MASK 0x0001 /* GP2_DB */
1212#define WM8903_GP2_DB_SHIFT 0 /* GP2_DB */
1213#define WM8903_GP2_DB_WIDTH 1 /* GP2_DB */
1214
1215/*
1216 * R118 (0x76) - GPIO Control 3
1217 */
1218#define WM8903_GP3_FN_MASK 0x1F00 /* GP3_FN - [12:8] */
1219#define WM8903_GP3_FN_SHIFT 8 /* GP3_FN - [12:8] */
1220#define WM8903_GP3_FN_WIDTH 5 /* GP3_FN - [12:8] */
1221#define WM8903_GP3_DIR 0x0080 /* GP3_DIR */
1222#define WM8903_GP3_DIR_MASK 0x0080 /* GP3_DIR */
1223#define WM8903_GP3_DIR_SHIFT 7 /* GP3_DIR */
1224#define WM8903_GP3_DIR_WIDTH 1 /* GP3_DIR */
1225#define WM8903_GP3_OP_CFG 0x0040 /* GP3_OP_CFG */
1226#define WM8903_GP3_OP_CFG_MASK 0x0040 /* GP3_OP_CFG */
1227#define WM8903_GP3_OP_CFG_SHIFT 6 /* GP3_OP_CFG */
1228#define WM8903_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
1229#define WM8903_GP3_IP_CFG 0x0020 /* GP3_IP_CFG */
1230#define WM8903_GP3_IP_CFG_MASK 0x0020 /* GP3_IP_CFG */
1231#define WM8903_GP3_IP_CFG_SHIFT 5 /* GP3_IP_CFG */
1232#define WM8903_GP3_IP_CFG_WIDTH 1 /* GP3_IP_CFG */
1233#define WM8903_GP3_LVL 0x0010 /* GP3_LVL */
1234#define WM8903_GP3_LVL_MASK 0x0010 /* GP3_LVL */
1235#define WM8903_GP3_LVL_SHIFT 4 /* GP3_LVL */
1236#define WM8903_GP3_LVL_WIDTH 1 /* GP3_LVL */
1237#define WM8903_GP3_PD 0x0008 /* GP3_PD */
1238#define WM8903_GP3_PD_MASK 0x0008 /* GP3_PD */
1239#define WM8903_GP3_PD_SHIFT 3 /* GP3_PD */
1240#define WM8903_GP3_PD_WIDTH 1 /* GP3_PD */
1241#define WM8903_GP3_PU 0x0004 /* GP3_PU */
1242#define WM8903_GP3_PU_MASK 0x0004 /* GP3_PU */
1243#define WM8903_GP3_PU_SHIFT 2 /* GP3_PU */
1244#define WM8903_GP3_PU_WIDTH 1 /* GP3_PU */
1245#define WM8903_GP3_INTMODE 0x0002 /* GP3_INTMODE */
1246#define WM8903_GP3_INTMODE_MASK 0x0002 /* GP3_INTMODE */
1247#define WM8903_GP3_INTMODE_SHIFT 1 /* GP3_INTMODE */
1248#define WM8903_GP3_INTMODE_WIDTH 1 /* GP3_INTMODE */
1249#define WM8903_GP3_DB 0x0001 /* GP3_DB */
1250#define WM8903_GP3_DB_MASK 0x0001 /* GP3_DB */
1251#define WM8903_GP3_DB_SHIFT 0 /* GP3_DB */
1252#define WM8903_GP3_DB_WIDTH 1 /* GP3_DB */
1253
1254/*
1255 * R119 (0x77) - GPIO Control 4
1256 */
1257#define WM8903_GP4_FN_MASK 0x1F00 /* GP4_FN - [12:8] */
1258#define WM8903_GP4_FN_SHIFT 8 /* GP4_FN - [12:8] */
1259#define WM8903_GP4_FN_WIDTH 5 /* GP4_FN - [12:8] */
1260#define WM8903_GP4_DIR 0x0080 /* GP4_DIR */
1261#define WM8903_GP4_DIR_MASK 0x0080 /* GP4_DIR */
1262#define WM8903_GP4_DIR_SHIFT 7 /* GP4_DIR */
1263#define WM8903_GP4_DIR_WIDTH 1 /* GP4_DIR */
1264#define WM8903_GP4_OP_CFG 0x0040 /* GP4_OP_CFG */
1265#define WM8903_GP4_OP_CFG_MASK 0x0040 /* GP4_OP_CFG */
1266#define WM8903_GP4_OP_CFG_SHIFT 6 /* GP4_OP_CFG */
1267#define WM8903_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
1268#define WM8903_GP4_IP_CFG 0x0020 /* GP4_IP_CFG */
1269#define WM8903_GP4_IP_CFG_MASK 0x0020 /* GP4_IP_CFG */
1270#define WM8903_GP4_IP_CFG_SHIFT 5 /* GP4_IP_CFG */
1271#define WM8903_GP4_IP_CFG_WIDTH 1 /* GP4_IP_CFG */
1272#define WM8903_GP4_LVL 0x0010 /* GP4_LVL */
1273#define WM8903_GP4_LVL_MASK 0x0010 /* GP4_LVL */
1274#define WM8903_GP4_LVL_SHIFT 4 /* GP4_LVL */
1275#define WM8903_GP4_LVL_WIDTH 1 /* GP4_LVL */
1276#define WM8903_GP4_PD 0x0008 /* GP4_PD */
1277#define WM8903_GP4_PD_MASK 0x0008 /* GP4_PD */
1278#define WM8903_GP4_PD_SHIFT 3 /* GP4_PD */
1279#define WM8903_GP4_PD_WIDTH 1 /* GP4_PD */
1280#define WM8903_GP4_PU 0x0004 /* GP4_PU */
1281#define WM8903_GP4_PU_MASK 0x0004 /* GP4_PU */
1282#define WM8903_GP4_PU_SHIFT 2 /* GP4_PU */
1283#define WM8903_GP4_PU_WIDTH 1 /* GP4_PU */
1284#define WM8903_GP4_INTMODE 0x0002 /* GP4_INTMODE */
1285#define WM8903_GP4_INTMODE_MASK 0x0002 /* GP4_INTMODE */
1286#define WM8903_GP4_INTMODE_SHIFT 1 /* GP4_INTMODE */
1287#define WM8903_GP4_INTMODE_WIDTH 1 /* GP4_INTMODE */
1288#define WM8903_GP4_DB 0x0001 /* GP4_DB */
1289#define WM8903_GP4_DB_MASK 0x0001 /* GP4_DB */
1290#define WM8903_GP4_DB_SHIFT 0 /* GP4_DB */
1291#define WM8903_GP4_DB_WIDTH 1 /* GP4_DB */
1292
1293/*
1294 * R120 (0x78) - GPIO Control 5
1295 */
1296#define WM8903_GP5_FN_MASK 0x1F00 /* GP5_FN - [12:8] */
1297#define WM8903_GP5_FN_SHIFT 8 /* GP5_FN - [12:8] */
1298#define WM8903_GP5_FN_WIDTH 5 /* GP5_FN - [12:8] */
1299#define WM8903_GP5_DIR 0x0080 /* GP5_DIR */
1300#define WM8903_GP5_DIR_MASK 0x0080 /* GP5_DIR */
1301#define WM8903_GP5_DIR_SHIFT 7 /* GP5_DIR */
1302#define WM8903_GP5_DIR_WIDTH 1 /* GP5_DIR */
1303#define WM8903_GP5_OP_CFG 0x0040 /* GP5_OP_CFG */
1304#define WM8903_GP5_OP_CFG_MASK 0x0040 /* GP5_OP_CFG */
1305#define WM8903_GP5_OP_CFG_SHIFT 6 /* GP5_OP_CFG */
1306#define WM8903_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
1307#define WM8903_GP5_IP_CFG 0x0020 /* GP5_IP_CFG */
1308#define WM8903_GP5_IP_CFG_MASK 0x0020 /* GP5_IP_CFG */
1309#define WM8903_GP5_IP_CFG_SHIFT 5 /* GP5_IP_CFG */
1310#define WM8903_GP5_IP_CFG_WIDTH 1 /* GP5_IP_CFG */
1311#define WM8903_GP5_LVL 0x0010 /* GP5_LVL */
1312#define WM8903_GP5_LVL_MASK 0x0010 /* GP5_LVL */
1313#define WM8903_GP5_LVL_SHIFT 4 /* GP5_LVL */
1314#define WM8903_GP5_LVL_WIDTH 1 /* GP5_LVL */
1315#define WM8903_GP5_PD 0x0008 /* GP5_PD */
1316#define WM8903_GP5_PD_MASK 0x0008 /* GP5_PD */
1317#define WM8903_GP5_PD_SHIFT 3 /* GP5_PD */
1318#define WM8903_GP5_PD_WIDTH 1 /* GP5_PD */
1319#define WM8903_GP5_PU 0x0004 /* GP5_PU */
1320#define WM8903_GP5_PU_MASK 0x0004 /* GP5_PU */
1321#define WM8903_GP5_PU_SHIFT 2 /* GP5_PU */
1322#define WM8903_GP5_PU_WIDTH 1 /* GP5_PU */
1323#define WM8903_GP5_INTMODE 0x0002 /* GP5_INTMODE */
1324#define WM8903_GP5_INTMODE_MASK 0x0002 /* GP5_INTMODE */
1325#define WM8903_GP5_INTMODE_SHIFT 1 /* GP5_INTMODE */
1326#define WM8903_GP5_INTMODE_WIDTH 1 /* GP5_INTMODE */
1327#define WM8903_GP5_DB 0x0001 /* GP5_DB */
1328#define WM8903_GP5_DB_MASK 0x0001 /* GP5_DB */
1329#define WM8903_GP5_DB_SHIFT 0 /* GP5_DB */
1330#define WM8903_GP5_DB_WIDTH 1 /* GP5_DB */
1331
1332/*
1333 * R121 (0x79) - Interrupt Status 1 1120 * R121 (0x79) - Interrupt Status 1
1334 */ 1121 */
1335#define WM8903_MICSHRT_EINT 0x8000 /* MICSHRT_EINT */ 1122#define WM8903_MICSHRT_EINT 0x8000 /* MICSHRT_EINT */
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index c6f0abcc5711..87f14f8675fa 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -613,7 +613,7 @@ static int wm8904_reset(struct snd_soc_codec *codec)
613 613
614static int wm8904_configure_clocking(struct snd_soc_codec *codec) 614static int wm8904_configure_clocking(struct snd_soc_codec *codec)
615{ 615{
616 struct wm8904_priv *wm8904 = codec->private_data; 616 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
617 unsigned int clock0, clock2, rate; 617 unsigned int clock0, clock2, rate;
618 618
619 /* Gate the clock while we're updating to avoid misclocking */ 619 /* Gate the clock while we're updating to avoid misclocking */
@@ -669,7 +669,7 @@ static int wm8904_configure_clocking(struct snd_soc_codec *codec)
669 669
670static void wm8904_set_drc(struct snd_soc_codec *codec) 670static void wm8904_set_drc(struct snd_soc_codec *codec)
671{ 671{
672 struct wm8904_priv *wm8904 = codec->private_data; 672 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
673 struct wm8904_pdata *pdata = wm8904->pdata; 673 struct wm8904_pdata *pdata = wm8904->pdata;
674 int save, i; 674 int save, i;
675 675
@@ -689,7 +689,7 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
689 struct snd_ctl_elem_value *ucontrol) 689 struct snd_ctl_elem_value *ucontrol)
690{ 690{
691 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 691 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
692 struct wm8904_priv *wm8904 = codec->private_data; 692 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
693 struct wm8904_pdata *pdata = wm8904->pdata; 693 struct wm8904_pdata *pdata = wm8904->pdata;
694 int value = ucontrol->value.integer.value[0]; 694 int value = ucontrol->value.integer.value[0];
695 695
@@ -707,7 +707,7 @@ static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
707 struct snd_ctl_elem_value *ucontrol) 707 struct snd_ctl_elem_value *ucontrol)
708{ 708{
709 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 709 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
710 struct wm8904_priv *wm8904 = codec->private_data; 710 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
711 711
712 ucontrol->value.enumerated.item[0] = wm8904->drc_cfg; 712 ucontrol->value.enumerated.item[0] = wm8904->drc_cfg;
713 713
@@ -716,7 +716,7 @@ static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
716 716
717static void wm8904_set_retune_mobile(struct snd_soc_codec *codec) 717static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
718{ 718{
719 struct wm8904_priv *wm8904 = codec->private_data; 719 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
720 struct wm8904_pdata *pdata = wm8904->pdata; 720 struct wm8904_pdata *pdata = wm8904->pdata;
721 int best, best_val, save, i, cfg; 721 int best, best_val, save, i, cfg;
722 722
@@ -760,7 +760,7 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
760 struct snd_ctl_elem_value *ucontrol) 760 struct snd_ctl_elem_value *ucontrol)
761{ 761{
762 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 762 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
763 struct wm8904_priv *wm8904 = codec->private_data; 763 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
764 struct wm8904_pdata *pdata = wm8904->pdata; 764 struct wm8904_pdata *pdata = wm8904->pdata;
765 int value = ucontrol->value.integer.value[0]; 765 int value = ucontrol->value.integer.value[0];
766 766
@@ -778,7 +778,7 @@ static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
778 struct snd_ctl_elem_value *ucontrol) 778 struct snd_ctl_elem_value *ucontrol)
779{ 779{
780 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 780 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
781 struct wm8904_priv *wm8904 = codec->private_data; 781 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
782 782
783 ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg; 783 ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg;
784 784
@@ -789,7 +789,7 @@ static int deemph_settings[] = { 0, 32000, 44100, 48000 };
789 789
790static int wm8904_set_deemph(struct snd_soc_codec *codec) 790static int wm8904_set_deemph(struct snd_soc_codec *codec)
791{ 791{
792 struct wm8904_priv *wm8904 = codec->private_data; 792 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
793 int val, i, best; 793 int val, i, best;
794 794
795 /* If we're using deemphasis select the nearest available sample 795 /* If we're using deemphasis select the nearest available sample
@@ -818,7 +818,7 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
818 struct snd_ctl_elem_value *ucontrol) 818 struct snd_ctl_elem_value *ucontrol)
819{ 819{
820 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 820 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
821 struct wm8904_priv *wm8904 = codec->private_data; 821 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
822 822
823 return wm8904->deemph; 823 return wm8904->deemph;
824} 824}
@@ -827,7 +827,7 @@ static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
827 struct snd_ctl_elem_value *ucontrol) 827 struct snd_ctl_elem_value *ucontrol)
828{ 828{
829 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 829 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
830 struct wm8904_priv *wm8904 = codec->private_data; 830 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
831 int deemph = ucontrol->value.enumerated.item[0]; 831 int deemph = ucontrol->value.enumerated.item[0];
832 832
833 if (deemph > 1) 833 if (deemph > 1)
@@ -943,7 +943,7 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
943 struct snd_kcontrol *kcontrol, int event) 943 struct snd_kcontrol *kcontrol, int event)
944{ 944{
945 struct snd_soc_codec *codec = w->codec; 945 struct snd_soc_codec *codec = w->codec;
946 struct wm8904_priv *wm8904 = codec->private_data; 946 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
947 947
948 switch (event) { 948 switch (event) {
949 case SND_SOC_DAPM_PRE_PMU: 949 case SND_SOC_DAPM_PRE_PMU:
@@ -981,7 +981,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
981 struct snd_kcontrol *kcontrol, int event) 981 struct snd_kcontrol *kcontrol, int event)
982{ 982{
983 struct snd_soc_codec *codec = w->codec; 983 struct snd_soc_codec *codec = w->codec;
984 struct wm8904_priv *wm8904 = codec->private_data; 984 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
985 int reg, val; 985 int reg, val;
986 int dcs_mask; 986 int dcs_mask;
987 int dcs_l, dcs_r; 987 int dcs_l, dcs_r;
@@ -1429,7 +1429,7 @@ static const struct snd_soc_dapm_route wm8912_intercon[] = {
1429 1429
1430static int wm8904_add_widgets(struct snd_soc_codec *codec) 1430static int wm8904_add_widgets(struct snd_soc_codec *codec)
1431{ 1431{
1432 struct wm8904_priv *wm8904 = codec->private_data; 1432 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
1433 1433
1434 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets, 1434 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets,
1435 ARRAY_SIZE(wm8904_core_dapm_widgets)); 1435 ARRAY_SIZE(wm8904_core_dapm_widgets));
@@ -1543,7 +1543,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
1543 struct snd_soc_dai *dai) 1543 struct snd_soc_dai *dai)
1544{ 1544{
1545 struct snd_soc_codec *codec = dai->codec; 1545 struct snd_soc_codec *codec = dai->codec;
1546 struct wm8904_priv *wm8904 = codec->private_data; 1546 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
1547 int ret, i, best, best_val, cur_val; 1547 int ret, i, best, best_val, cur_val;
1548 unsigned int aif1 = 0; 1548 unsigned int aif1 = 0;
1549 unsigned int aif2 = 0; 1549 unsigned int aif2 = 0;
@@ -1670,7 +1670,7 @@ static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1670 unsigned int freq, int dir) 1670 unsigned int freq, int dir)
1671{ 1671{
1672 struct snd_soc_codec *codec = dai->codec; 1672 struct snd_soc_codec *codec = dai->codec;
1673 struct wm8904_priv *priv = codec->private_data; 1673 struct wm8904_priv *priv = snd_soc_codec_get_drvdata(codec);
1674 1674
1675 switch (clk_id) { 1675 switch (clk_id) {
1676 case WM8904_CLK_MCLK: 1676 case WM8904_CLK_MCLK:
@@ -1786,7 +1786,7 @@ static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1786 unsigned int rx_mask, int slots, int slot_width) 1786 unsigned int rx_mask, int slots, int slot_width)
1787{ 1787{
1788 struct snd_soc_codec *codec = dai->codec; 1788 struct snd_soc_codec *codec = dai->codec;
1789 struct wm8904_priv *wm8904 = codec->private_data; 1789 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
1790 int aif1 = 0; 1790 int aif1 = 0;
1791 1791
1792 /* Don't need to validate anything if we're turning off TDM */ 1792 /* Don't need to validate anything if we're turning off TDM */
@@ -1943,7 +1943,7 @@ static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
1943 unsigned int Fref, unsigned int Fout) 1943 unsigned int Fref, unsigned int Fout)
1944{ 1944{
1945 struct snd_soc_codec *codec = dai->codec; 1945 struct snd_soc_codec *codec = dai->codec;
1946 struct wm8904_priv *wm8904 = codec->private_data; 1946 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
1947 struct _fll_div fll_div; 1947 struct _fll_div fll_div;
1948 int ret, val; 1948 int ret, val;
1949 int clock2, fll1; 1949 int clock2, fll1;
@@ -2095,7 +2095,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2095 2095
2096static void wm8904_sync_cache(struct snd_soc_codec *codec) 2096static void wm8904_sync_cache(struct snd_soc_codec *codec)
2097{ 2097{
2098 struct wm8904_priv *wm8904 = codec->private_data; 2098 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2099 int i; 2099 int i;
2100 2100
2101 if (!codec->cache_sync) 2101 if (!codec->cache_sync)
@@ -2122,7 +2122,7 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec)
2122static int wm8904_set_bias_level(struct snd_soc_codec *codec, 2122static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2123 enum snd_soc_bias_level level) 2123 enum snd_soc_bias_level level)
2124{ 2124{
2125 struct wm8904_priv *wm8904 = codec->private_data; 2125 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2126 int ret; 2126 int ret;
2127 2127
2128 switch (level) { 2128 switch (level) {
@@ -2395,7 +2395,7 @@ static int wm8904_probe(struct platform_device *pdev)
2395 goto pcm_err; 2395 goto pcm_err;
2396 } 2396 }
2397 2397
2398 wm8904_handle_pdata(codec->private_data); 2398 wm8904_handle_pdata(snd_soc_codec_get_drvdata(codec));
2399 2399
2400 wm8904_add_widgets(codec); 2400 wm8904_add_widgets(codec);
2401 2401
@@ -2426,6 +2426,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
2426static int wm8904_register(struct wm8904_priv *wm8904, 2426static int wm8904_register(struct wm8904_priv *wm8904,
2427 enum snd_soc_control_type control) 2427 enum snd_soc_control_type control)
2428{ 2428{
2429 struct wm8904_pdata *pdata = wm8904->pdata;
2429 int ret; 2430 int ret;
2430 struct snd_soc_codec *codec = &wm8904->codec; 2431 struct snd_soc_codec *codec = &wm8904->codec;
2431 int i; 2432 int i;
@@ -2439,7 +2440,7 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2439 INIT_LIST_HEAD(&codec->dapm_widgets); 2440 INIT_LIST_HEAD(&codec->dapm_widgets);
2440 INIT_LIST_HEAD(&codec->dapm_paths); 2441 INIT_LIST_HEAD(&codec->dapm_paths);
2441 2442
2442 codec->private_data = wm8904; 2443 snd_soc_codec_set_drvdata(codec, wm8904);
2443 codec->name = "WM8904"; 2444 codec->name = "WM8904";
2444 codec->owner = THIS_MODULE; 2445 codec->owner = THIS_MODULE;
2445 codec->bias_level = SND_SOC_BIAS_OFF; 2446 codec->bias_level = SND_SOC_BIAS_OFF;
@@ -2531,6 +2532,22 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2531 WM8904_LINEOUTRZC; 2532 WM8904_LINEOUTRZC;
2532 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; 2533 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
2533 2534
2535 /* Apply configuration from the platform data. */
2536 if (wm8904->pdata) {
2537 for (i = 0; i < WM8904_GPIO_REGS; i++) {
2538 if (!pdata->gpio_cfg[i])
2539 continue;
2540
2541 wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i]
2542 = pdata->gpio_cfg[i] & 0xffff;
2543 }
2544
2545 /* Zero is the default value for these anyway */
2546 for (i = 0; i < WM8904_MIC_REGS; i++)
2547 wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
2548 = pdata->mic_cfg[i];
2549 }
2550
2534 /* Set Class W by default - this will be managed by the Class 2551 /* Set Class W by default - this will be managed by the Class
2535 * G widget at runtime where bypass paths are available. 2552 * G widget at runtime where bypass paths are available.
2536 */ 2553 */
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h
index b68886df34e4..abe5059b3004 100644
--- a/sound/soc/codecs/wm8904.h
+++ b/sound/soc/codecs/wm8904.h
@@ -186,39 +186,6 @@ extern struct snd_soc_codec_device soc_codec_dev_wm8904;
186#define WM8904_VMID_ENA_WIDTH 1 /* VMID_ENA */ 186#define WM8904_VMID_ENA_WIDTH 1 /* VMID_ENA */
187 187
188/* 188/*
189 * R6 (0x06) - Mic Bias Control 0
190 */
191#define WM8904_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
192#define WM8904_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
193#define WM8904_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
194#define WM8904_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
195#define WM8904_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
196#define WM8904_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
197#define WM8904_MICDET_ENA 0x0002 /* MICDET_ENA */
198#define WM8904_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
199#define WM8904_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
200#define WM8904_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
201#define WM8904_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
202#define WM8904_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
203#define WM8904_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
204#define WM8904_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
205
206/*
207 * R7 (0x07) - Mic Bias Control 1
208 */
209#define WM8904_MIC_DET_FILTER_ENA 0x8000 /* MIC_DET_FILTER_ENA */
210#define WM8904_MIC_DET_FILTER_ENA_MASK 0x8000 /* MIC_DET_FILTER_ENA */
211#define WM8904_MIC_DET_FILTER_ENA_SHIFT 15 /* MIC_DET_FILTER_ENA */
212#define WM8904_MIC_DET_FILTER_ENA_WIDTH 1 /* MIC_DET_FILTER_ENA */
213#define WM8904_MIC_SHORT_FILTER_ENA 0x4000 /* MIC_SHORT_FILTER_ENA */
214#define WM8904_MIC_SHORT_FILTER_ENA_MASK 0x4000 /* MIC_SHORT_FILTER_ENA */
215#define WM8904_MIC_SHORT_FILTER_ENA_SHIFT 14 /* MIC_SHORT_FILTER_ENA */
216#define WM8904_MIC_SHORT_FILTER_ENA_WIDTH 1 /* MIC_SHORT_FILTER_ENA */
217#define WM8904_MICBIAS_SEL_MASK 0x0007 /* MICBIAS_SEL - [2:0] */
218#define WM8904_MICBIAS_SEL_SHIFT 0 /* MICBIAS_SEL - [2:0] */
219#define WM8904_MICBIAS_SEL_WIDTH 3 /* MICBIAS_SEL - [2:0] */
220
221/*
222 * R8 (0x08) - Analogue DAC 0 189 * R8 (0x08) - Analogue DAC 0
223 */ 190 */
224#define WM8904_DAC_BIAS_SEL_MASK 0x0018 /* DAC_BIAS_SEL - [4:3] */ 191#define WM8904_DAC_BIAS_SEL_MASK 0x0018 /* DAC_BIAS_SEL - [4:3] */
@@ -1200,70 +1167,6 @@ extern struct snd_soc_codec_device soc_codec_dev_wm8904;
1200#define WM8904_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */ 1167#define WM8904_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */
1201 1168
1202/* 1169/*
1203 * R121 (0x79) - GPIO Control 1
1204 */
1205#define WM8904_GPIO1_PU 0x0020 /* GPIO1_PU */
1206#define WM8904_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */
1207#define WM8904_GPIO1_PU_SHIFT 5 /* GPIO1_PU */
1208#define WM8904_GPIO1_PU_WIDTH 1 /* GPIO1_PU */
1209#define WM8904_GPIO1_PD 0x0010 /* GPIO1_PD */
1210#define WM8904_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */
1211#define WM8904_GPIO1_PD_SHIFT 4 /* GPIO1_PD */
1212#define WM8904_GPIO1_PD_WIDTH 1 /* GPIO1_PD */
1213#define WM8904_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
1214#define WM8904_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */
1215#define WM8904_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */
1216
1217/*
1218 * R122 (0x7A) - GPIO Control 2
1219 */
1220#define WM8904_GPIO2_PU 0x0020 /* GPIO2_PU */
1221#define WM8904_GPIO2_PU_MASK 0x0020 /* GPIO2_PU */
1222#define WM8904_GPIO2_PU_SHIFT 5 /* GPIO2_PU */
1223#define WM8904_GPIO2_PU_WIDTH 1 /* GPIO2_PU */
1224#define WM8904_GPIO2_PD 0x0010 /* GPIO2_PD */
1225#define WM8904_GPIO2_PD_MASK 0x0010 /* GPIO2_PD */
1226#define WM8904_GPIO2_PD_SHIFT 4 /* GPIO2_PD */
1227#define WM8904_GPIO2_PD_WIDTH 1 /* GPIO2_PD */
1228#define WM8904_GPIO2_SEL_MASK 0x000F /* GPIO2_SEL - [3:0] */
1229#define WM8904_GPIO2_SEL_SHIFT 0 /* GPIO2_SEL - [3:0] */
1230#define WM8904_GPIO2_SEL_WIDTH 4 /* GPIO2_SEL - [3:0] */
1231
1232/*
1233 * R123 (0x7B) - GPIO Control 3
1234 */
1235#define WM8904_GPIO3_PU 0x0020 /* GPIO3_PU */
1236#define WM8904_GPIO3_PU_MASK 0x0020 /* GPIO3_PU */
1237#define WM8904_GPIO3_PU_SHIFT 5 /* GPIO3_PU */
1238#define WM8904_GPIO3_PU_WIDTH 1 /* GPIO3_PU */
1239#define WM8904_GPIO3_PD 0x0010 /* GPIO3_PD */
1240#define WM8904_GPIO3_PD_MASK 0x0010 /* GPIO3_PD */
1241#define WM8904_GPIO3_PD_SHIFT 4 /* GPIO3_PD */
1242#define WM8904_GPIO3_PD_WIDTH 1 /* GPIO3_PD */
1243#define WM8904_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
1244#define WM8904_GPIO3_SEL_SHIFT 0 /* GPIO3_SEL - [3:0] */
1245#define WM8904_GPIO3_SEL_WIDTH 4 /* GPIO3_SEL - [3:0] */
1246
1247/*
1248 * R124 (0x7C) - GPIO Control 4
1249 */
1250#define WM8904_GPI7_ENA 0x0200 /* GPI7_ENA */
1251#define WM8904_GPI7_ENA_MASK 0x0200 /* GPI7_ENA */
1252#define WM8904_GPI7_ENA_SHIFT 9 /* GPI7_ENA */
1253#define WM8904_GPI7_ENA_WIDTH 1 /* GPI7_ENA */
1254#define WM8904_GPI8_ENA 0x0100 /* GPI8_ENA */
1255#define WM8904_GPI8_ENA_MASK 0x0100 /* GPI8_ENA */
1256#define WM8904_GPI8_ENA_SHIFT 8 /* GPI8_ENA */
1257#define WM8904_GPI8_ENA_WIDTH 1 /* GPI8_ENA */
1258#define WM8904_GPIO_BCLK_MODE_ENA 0x0080 /* GPIO_BCLK_MODE_ENA */
1259#define WM8904_GPIO_BCLK_MODE_ENA_MASK 0x0080 /* GPIO_BCLK_MODE_ENA */
1260#define WM8904_GPIO_BCLK_MODE_ENA_SHIFT 7 /* GPIO_BCLK_MODE_ENA */
1261#define WM8904_GPIO_BCLK_MODE_ENA_WIDTH 1 /* GPIO_BCLK_MODE_ENA */
1262#define WM8904_GPIO_BCLK_SEL_MASK 0x000F /* GPIO_BCLK_SEL - [3:0] */
1263#define WM8904_GPIO_BCLK_SEL_SHIFT 0 /* GPIO_BCLK_SEL - [3:0] */
1264#define WM8904_GPIO_BCLK_SEL_WIDTH 4 /* GPIO_BCLK_SEL - [3:0] */
1265
1266/*
1267 * R126 (0x7E) - Digital Pulls 1170 * R126 (0x7E) - Digital Pulls
1268 */ 1171 */
1269#define WM8904_MCLK_PU 0x0080 /* MCLK_PU */ 1172#define WM8904_MCLK_PU 0x0080 /* MCLK_PU */
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 0c04b476487f..e3c4bbfaae27 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -581,7 +581,7 @@ static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai,
581 int clk_id, unsigned int freq, int dir) 581 int clk_id, unsigned int freq, int dir)
582{ 582{
583 struct snd_soc_codec *codec = codec_dai->codec; 583 struct snd_soc_codec *codec = codec_dai->codec;
584 struct wm8940_priv *wm8940 = codec->private_data; 584 struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
585 585
586 switch (freq) { 586 switch (freq) {
587 case 11289600: 587 case 11289600:
@@ -692,7 +692,6 @@ static int wm8940_resume(struct platform_device *pdev)
692 ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 692 ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
693 if (ret) 693 if (ret)
694 goto error_ret; 694 goto error_ret;
695 ret = wm8940_set_bias_level(codec, codec->suspend_bias_level);
696 695
697error_ret: 696error_ret:
698 return ret; 697 return ret;
@@ -773,7 +772,7 @@ static int wm8940_register(struct wm8940_priv *wm8940,
773 INIT_LIST_HEAD(&codec->dapm_widgets); 772 INIT_LIST_HEAD(&codec->dapm_widgets);
774 INIT_LIST_HEAD(&codec->dapm_paths); 773 INIT_LIST_HEAD(&codec->dapm_paths);
775 774
776 codec->private_data = wm8940; 775 snd_soc_codec_set_drvdata(codec, wm8940);
777 codec->name = "WM8940"; 776 codec->name = "WM8940";
778 codec->owner = THIS_MODULE; 777 codec->owner = THIS_MODULE;
779 codec->bias_level = SND_SOC_BIAS_OFF; 778 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index c8d7a809af4d..fedb76452f1b 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -235,7 +235,7 @@ static struct {
235 235
236static int wm8955_configure_clocking(struct snd_soc_codec *codec) 236static int wm8955_configure_clocking(struct snd_soc_codec *codec)
237{ 237{
238 struct wm8955_priv *wm8955 = codec->private_data; 238 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
239 int i, ret, val; 239 int i, ret, val;
240 int clocking = 0; 240 int clocking = 0;
241 int srate = 0; 241 int srate = 0;
@@ -353,7 +353,7 @@ static int deemph_settings[] = { 0, 32000, 44100, 48000 };
353 353
354static int wm8955_set_deemph(struct snd_soc_codec *codec) 354static int wm8955_set_deemph(struct snd_soc_codec *codec)
355{ 355{
356 struct wm8955_priv *wm8955 = codec->private_data; 356 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
357 int val, i, best; 357 int val, i, best;
358 358
359 /* If we're using deemphasis select the nearest available sample 359 /* If we're using deemphasis select the nearest available sample
@@ -382,7 +382,7 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
382 struct snd_ctl_elem_value *ucontrol) 382 struct snd_ctl_elem_value *ucontrol)
383{ 383{
384 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 384 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
385 struct wm8955_priv *wm8955 = codec->private_data; 385 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
386 386
387 return wm8955->deemph; 387 return wm8955->deemph;
388} 388}
@@ -391,7 +391,7 @@ static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
391 struct snd_ctl_elem_value *ucontrol) 391 struct snd_ctl_elem_value *ucontrol)
392{ 392{
393 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 393 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
394 struct wm8955_priv *wm8955 = codec->private_data; 394 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
395 int deemph = ucontrol->value.enumerated.item[0]; 395 int deemph = ucontrol->value.enumerated.item[0];
396 396
397 if (deemph > 1) 397 if (deemph > 1)
@@ -598,7 +598,7 @@ static int wm8955_hw_params(struct snd_pcm_substream *substream,
598 struct snd_soc_dai *dai) 598 struct snd_soc_dai *dai)
599{ 599{
600 struct snd_soc_codec *codec = dai->codec; 600 struct snd_soc_codec *codec = dai->codec;
601 struct wm8955_priv *wm8955 = codec->private_data; 601 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
602 int ret; 602 int ret;
603 int wl; 603 int wl;
604 604
@@ -647,7 +647,7 @@ static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id,
647 unsigned int freq, int dir) 647 unsigned int freq, int dir)
648{ 648{
649 struct snd_soc_codec *codec = dai->codec; 649 struct snd_soc_codec *codec = dai->codec;
650 struct wm8955_priv *priv = codec->private_data; 650 struct wm8955_priv *priv = snd_soc_codec_get_drvdata(codec);
651 int div; 651 int div;
652 652
653 switch (clk_id) { 653 switch (clk_id) {
@@ -770,7 +770,7 @@ static int wm8955_digital_mute(struct snd_soc_dai *codec_dai, int mute)
770static int wm8955_set_bias_level(struct snd_soc_codec *codec, 770static int wm8955_set_bias_level(struct snd_soc_codec *codec,
771 enum snd_soc_bias_level level) 771 enum snd_soc_bias_level level)
772{ 772{
773 struct wm8955_priv *wm8955 = codec->private_data; 773 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
774 int ret, i; 774 int ret, i;
775 775
776 switch (level) { 776 switch (level) {
@@ -971,7 +971,7 @@ static int wm8955_register(struct wm8955_priv *wm8955,
971 INIT_LIST_HEAD(&codec->dapm_widgets); 971 INIT_LIST_HEAD(&codec->dapm_widgets);
972 INIT_LIST_HEAD(&codec->dapm_paths); 972 INIT_LIST_HEAD(&codec->dapm_paths);
973 973
974 codec->private_data = wm8955; 974 snd_soc_codec_set_drvdata(codec, wm8955);
975 codec->name = "WM8955"; 975 codec->name = "WM8955";
976 codec->owner = THIS_MODULE; 976 codec->owner = THIS_MODULE;
977 codec->bias_level = SND_SOC_BIAS_OFF; 977 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index f1e63e01b04d..7233cc68435a 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -23,6 +23,7 @@
23#include <sound/soc-dapm.h> 23#include <sound/soc-dapm.h>
24#include <sound/initval.h> 24#include <sound/initval.h>
25#include <sound/tlv.h> 25#include <sound/tlv.h>
26#include <sound/wm8960.h>
26 27
27#include "wm8960.h" 28#include "wm8960.h"
28 29
@@ -31,8 +32,14 @@
31struct snd_soc_codec_device soc_codec_dev_wm8960; 32struct snd_soc_codec_device soc_codec_dev_wm8960;
32 33
33/* R25 - Power 1 */ 34/* R25 - Power 1 */
35#define WM8960_VMID_MASK 0x180
34#define WM8960_VREF 0x40 36#define WM8960_VREF 0x40
35 37
38/* R26 - Power 2 */
39#define WM8960_PWR2_LOUT1 0x40
40#define WM8960_PWR2_ROUT1 0x20
41#define WM8960_PWR2_OUT3 0x02
42
36/* R28 - Anti-pop 1 */ 43/* R28 - Anti-pop 1 */
37#define WM8960_POBCTRL 0x80 44#define WM8960_POBCTRL 0x80
38#define WM8960_BUFDCOPEN 0x10 45#define WM8960_BUFDCOPEN 0x10
@@ -42,6 +49,7 @@ struct snd_soc_codec_device soc_codec_dev_wm8960;
42 49
43/* R29 - Anti-pop 2 */ 50/* R29 - Anti-pop 2 */
44#define WM8960_DISOP 0x40 51#define WM8960_DISOP 0x40
52#define WM8960_DRES_MASK 0x30
45 53
46/* 54/*
47 * wm8960 register cache 55 * wm8960 register cache
@@ -68,6 +76,9 @@ static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
68struct wm8960_priv { 76struct wm8960_priv {
69 u16 reg_cache[WM8960_CACHEREGNUM]; 77 u16 reg_cache[WM8960_CACHEREGNUM];
70 struct snd_soc_codec codec; 78 struct snd_soc_codec codec;
79 struct snd_soc_dapm_widget *lout1;
80 struct snd_soc_dapm_widget *rout1;
81 struct snd_soc_dapm_widget *out3;
71}; 82};
72 83
73#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0) 84#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0)
@@ -226,10 +237,6 @@ SND_SOC_DAPM_MIXER("Right Output Mixer", WM8960_POWER3, 2, 0,
226 &wm8960_routput_mixer[0], 237 &wm8960_routput_mixer[0],
227 ARRAY_SIZE(wm8960_routput_mixer)), 238 ARRAY_SIZE(wm8960_routput_mixer)),
228 239
229SND_SOC_DAPM_MIXER("Mono Output Mixer", WM8960_POWER2, 1, 0,
230 &wm8960_mono_out[0],
231 ARRAY_SIZE(wm8960_mono_out)),
232
233SND_SOC_DAPM_PGA("LOUT1 PGA", WM8960_POWER2, 6, 0, NULL, 0), 240SND_SOC_DAPM_PGA("LOUT1 PGA", WM8960_POWER2, 6, 0, NULL, 0),
234SND_SOC_DAPM_PGA("ROUT1 PGA", WM8960_POWER2, 5, 0, NULL, 0), 241SND_SOC_DAPM_PGA("ROUT1 PGA", WM8960_POWER2, 5, 0, NULL, 0),
235 242
@@ -248,6 +255,17 @@ SND_SOC_DAPM_OUTPUT("SPK_RN"),
248SND_SOC_DAPM_OUTPUT("OUT3"), 255SND_SOC_DAPM_OUTPUT("OUT3"),
249}; 256};
250 257
258static const struct snd_soc_dapm_widget wm8960_dapm_widgets_out3[] = {
259SND_SOC_DAPM_MIXER("Mono Output Mixer", WM8960_POWER2, 1, 0,
260 &wm8960_mono_out[0],
261 ARRAY_SIZE(wm8960_mono_out)),
262};
263
264/* Represent OUT3 as a PGA so that it gets turned on with LOUT1/ROUT1 */
265static const struct snd_soc_dapm_widget wm8960_dapm_widgets_capless[] = {
266SND_SOC_DAPM_PGA("OUT3 VMID", WM8960_POWER2, 1, 0, NULL, 0),
267};
268
251static const struct snd_soc_dapm_route audio_paths[] = { 269static const struct snd_soc_dapm_route audio_paths[] = {
252 { "Left Boost Mixer", "LINPUT1 Switch", "LINPUT1" }, 270 { "Left Boost Mixer", "LINPUT1 Switch", "LINPUT1" },
253 { "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" }, 271 { "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" },
@@ -278,9 +296,6 @@ static const struct snd_soc_dapm_route audio_paths[] = {
278 { "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" } , 296 { "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" } ,
279 { "Right Output Mixer", "PCM Playback Switch", "Right DAC" }, 297 { "Right Output Mixer", "PCM Playback Switch", "Right DAC" },
280 298
281 { "Mono Output Mixer", "Left Switch", "Left Output Mixer" },
282 { "Mono Output Mixer", "Right Switch", "Right Output Mixer" },
283
284 { "LOUT1 PGA", NULL, "Left Output Mixer" }, 299 { "LOUT1 PGA", NULL, "Left Output Mixer" },
285 { "ROUT1 PGA", NULL, "Right Output Mixer" }, 300 { "ROUT1 PGA", NULL, "Right Output Mixer" },
286 301
@@ -297,17 +312,65 @@ static const struct snd_soc_dapm_route audio_paths[] = {
297 { "SPK_LP", NULL, "Left Speaker Output" }, 312 { "SPK_LP", NULL, "Left Speaker Output" },
298 { "SPK_RN", NULL, "Right Speaker Output" }, 313 { "SPK_RN", NULL, "Right Speaker Output" },
299 { "SPK_RP", NULL, "Right Speaker Output" }, 314 { "SPK_RP", NULL, "Right Speaker Output" },
315};
316
317static const struct snd_soc_dapm_route audio_paths_out3[] = {
318 { "Mono Output Mixer", "Left Switch", "Left Output Mixer" },
319 { "Mono Output Mixer", "Right Switch", "Right Output Mixer" },
300 320
301 { "OUT3", NULL, "Mono Output Mixer", } 321 { "OUT3", NULL, "Mono Output Mixer", }
302}; 322};
303 323
324static const struct snd_soc_dapm_route audio_paths_capless[] = {
325 { "HP_L", NULL, "OUT3 VMID" },
326 { "HP_R", NULL, "OUT3 VMID" },
327
328 { "OUT3 VMID", NULL, "Left Output Mixer" },
329 { "OUT3 VMID", NULL, "Right Output Mixer" },
330};
331
304static int wm8960_add_widgets(struct snd_soc_codec *codec) 332static int wm8960_add_widgets(struct snd_soc_codec *codec)
305{ 333{
334 struct wm8960_data *pdata = codec->dev->platform_data;
335 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
336 struct snd_soc_dapm_widget *w;
337
306 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets, 338 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets,
307 ARRAY_SIZE(wm8960_dapm_widgets)); 339 ARRAY_SIZE(wm8960_dapm_widgets));
308 340
309 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 341 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
310 342
343 /* In capless mode OUT3 is used to provide VMID for the
344 * headphone outputs, otherwise it is used as a mono mixer.
345 */
346 if (pdata && pdata->capless) {
347 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_capless,
348 ARRAY_SIZE(wm8960_dapm_widgets_capless));
349
350 snd_soc_dapm_add_routes(codec, audio_paths_capless,
351 ARRAY_SIZE(audio_paths_capless));
352 } else {
353 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_out3,
354 ARRAY_SIZE(wm8960_dapm_widgets_out3));
355
356 snd_soc_dapm_add_routes(codec, audio_paths_out3,
357 ARRAY_SIZE(audio_paths_out3));
358 }
359
360 /* We need to power up the headphone output stage out of
361 * sequence for capless mode. To save scanning the widget
362 * list each time to find the desired power state do so now
363 * and save the result.
364 */
365 list_for_each_entry(w, &codec->dapm_widgets, list) {
366 if (strcmp(w->name, "LOUT1 PGA") == 0)
367 wm8960->lout1 = w;
368 if (strcmp(w->name, "ROUT1 PGA") == 0)
369 wm8960->rout1 = w;
370 if (strcmp(w->name, "OUT3 VMID") == 0)
371 wm8960->out3 = w;
372 }
373
311 return 0; 374 return 0;
312} 375}
313 376
@@ -408,10 +471,9 @@ static int wm8960_mute(struct snd_soc_dai *dai, int mute)
408 return 0; 471 return 0;
409} 472}
410 473
411static int wm8960_set_bias_level(struct snd_soc_codec *codec, 474static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
412 enum snd_soc_bias_level level) 475 enum snd_soc_bias_level level)
413{ 476{
414 struct wm8960_data *pdata = codec->dev->platform_data;
415 u16 reg; 477 u16 reg;
416 478
417 switch (level) { 479 switch (level) {
@@ -430,18 +492,8 @@ static int wm8960_set_bias_level(struct snd_soc_codec *codec,
430 if (codec->bias_level == SND_SOC_BIAS_OFF) { 492 if (codec->bias_level == SND_SOC_BIAS_OFF) {
431 /* Enable anti-pop features */ 493 /* Enable anti-pop features */
432 snd_soc_write(codec, WM8960_APOP1, 494 snd_soc_write(codec, WM8960_APOP1,
433 WM8960_POBCTRL | WM8960_SOFT_ST | 495 WM8960_POBCTRL | WM8960_SOFT_ST |
434 WM8960_BUFDCOPEN | WM8960_BUFIOEN); 496 WM8960_BUFDCOPEN | WM8960_BUFIOEN);
435
436 /* Discharge HP output */
437 reg = WM8960_DISOP;
438 if (pdata)
439 reg |= pdata->dres << 4;
440 snd_soc_write(codec, WM8960_APOP2, reg);
441
442 msleep(400);
443
444 snd_soc_write(codec, WM8960_APOP2, 0);
445 497
446 /* Enable & ramp VMID at 2x50k */ 498 /* Enable & ramp VMID at 2x50k */
447 reg = snd_soc_read(codec, WM8960_POWER1); 499 reg = snd_soc_read(codec, WM8960_POWER1);
@@ -472,8 +524,101 @@ static int wm8960_set_bias_level(struct snd_soc_codec *codec,
472 /* Disable VMID and VREF, let them discharge */ 524 /* Disable VMID and VREF, let them discharge */
473 snd_soc_write(codec, WM8960_POWER1, 0); 525 snd_soc_write(codec, WM8960_POWER1, 0);
474 msleep(600); 526 msleep(600);
527 break;
528 }
529
530 codec->bias_level = level;
531
532 return 0;
533}
534
535static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
536 enum snd_soc_bias_level level)
537{
538 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
539 int reg;
540
541 switch (level) {
542 case SND_SOC_BIAS_ON:
543 break;
544
545 case SND_SOC_BIAS_PREPARE:
546 switch (codec->bias_level) {
547 case SND_SOC_BIAS_STANDBY:
548 /* Enable anti pop mode */
549 snd_soc_update_bits(codec, WM8960_APOP1,
550 WM8960_POBCTRL | WM8960_SOFT_ST |
551 WM8960_BUFDCOPEN,
552 WM8960_POBCTRL | WM8960_SOFT_ST |
553 WM8960_BUFDCOPEN);
554
555 /* Enable LOUT1, ROUT1 and OUT3 if they're enabled */
556 reg = 0;
557 if (wm8960->lout1 && wm8960->lout1->power)
558 reg |= WM8960_PWR2_LOUT1;
559 if (wm8960->rout1 && wm8960->rout1->power)
560 reg |= WM8960_PWR2_ROUT1;
561 if (wm8960->out3 && wm8960->out3->power)
562 reg |= WM8960_PWR2_OUT3;
563 snd_soc_update_bits(codec, WM8960_POWER2,
564 WM8960_PWR2_LOUT1 |
565 WM8960_PWR2_ROUT1 |
566 WM8960_PWR2_OUT3, reg);
567
568 /* Enable VMID at 2*50k */
569 snd_soc_update_bits(codec, WM8960_POWER1,
570 WM8960_VMID_MASK, 0x80);
571
572 /* Ramp */
573 msleep(100);
574
575 /* Enable VREF */
576 snd_soc_update_bits(codec, WM8960_POWER1,
577 WM8960_VREF, WM8960_VREF);
578
579 msleep(100);
580 break;
581
582 case SND_SOC_BIAS_ON:
583 /* Enable anti-pop mode */
584 snd_soc_update_bits(codec, WM8960_APOP1,
585 WM8960_POBCTRL | WM8960_SOFT_ST |
586 WM8960_BUFDCOPEN,
587 WM8960_POBCTRL | WM8960_SOFT_ST |
588 WM8960_BUFDCOPEN);
589
590 /* Disable VMID and VREF */
591 snd_soc_update_bits(codec, WM8960_POWER1,
592 WM8960_VREF | WM8960_VMID_MASK, 0);
593 break;
594
595 default:
596 break;
597 }
598 break;
475 599
476 snd_soc_write(codec, WM8960_APOP1, 0); 600 case SND_SOC_BIAS_STANDBY:
601 switch (codec->bias_level) {
602 case SND_SOC_BIAS_PREPARE:
603 /* Disable HP discharge */
604 snd_soc_update_bits(codec, WM8960_APOP2,
605 WM8960_DISOP | WM8960_DRES_MASK,
606 0);
607
608 /* Disable anti-pop features */
609 snd_soc_update_bits(codec, WM8960_APOP1,
610 WM8960_POBCTRL | WM8960_SOFT_ST |
611 WM8960_BUFDCOPEN,
612 WM8960_POBCTRL | WM8960_SOFT_ST |
613 WM8960_BUFDCOPEN);
614 break;
615
616 default:
617 break;
618 }
619 break;
620
621 case SND_SOC_BIAS_OFF:
477 break; 622 break;
478 } 623 }
479 624
@@ -594,10 +739,6 @@ static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
594 u16 reg; 739 u16 reg;
595 740
596 switch (div_id) { 741 switch (div_id) {
597 case WM8960_SYSCLKSEL:
598 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1fe;
599 snd_soc_write(codec, WM8960_CLOCK1, reg | div);
600 break;
601 case WM8960_SYSCLKDIV: 742 case WM8960_SYSCLKDIV:
602 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1f9; 743 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1f9;
603 snd_soc_write(codec, WM8960_CLOCK1, reg | div); 744 snd_soc_write(codec, WM8960_CLOCK1, reg | div);
@@ -663,7 +804,7 @@ static int wm8960_suspend(struct platform_device *pdev, pm_message_t state)
663 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 804 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
664 struct snd_soc_codec *codec = socdev->card->codec; 805 struct snd_soc_codec *codec = socdev->card->codec;
665 806
666 wm8960_set_bias_level(codec, SND_SOC_BIAS_OFF); 807 codec->set_bias_level(codec, SND_SOC_BIAS_OFF);
667 return 0; 808 return 0;
668} 809}
669 810
@@ -682,8 +823,8 @@ static int wm8960_resume(struct platform_device *pdev)
682 codec->hw_write(codec->control_data, data, 2); 823 codec->hw_write(codec->control_data, data, 2);
683 } 824 }
684 825
685 wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 826 codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
686 wm8960_set_bias_level(codec, codec->suspend_bias_level); 827
687 return 0; 828 return 0;
688} 829}
689 830
@@ -753,6 +894,8 @@ static int wm8960_register(struct wm8960_priv *wm8960,
753 goto err; 894 goto err;
754 } 895 }
755 896
897 codec->set_bias_level = wm8960_set_bias_level_out3;
898
756 if (!pdata) { 899 if (!pdata) {
757 dev_warn(codec->dev, "No platform data supplied\n"); 900 dev_warn(codec->dev, "No platform data supplied\n");
758 } else { 901 } else {
@@ -760,17 +903,19 @@ static int wm8960_register(struct wm8960_priv *wm8960,
760 dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres); 903 dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres);
761 pdata->dres = 0; 904 pdata->dres = 0;
762 } 905 }
906
907 if (pdata->capless)
908 codec->set_bias_level = wm8960_set_bias_level_capless;
763 } 909 }
764 910
765 mutex_init(&codec->mutex); 911 mutex_init(&codec->mutex);
766 INIT_LIST_HEAD(&codec->dapm_widgets); 912 INIT_LIST_HEAD(&codec->dapm_widgets);
767 INIT_LIST_HEAD(&codec->dapm_paths); 913 INIT_LIST_HEAD(&codec->dapm_paths);
768 914
769 codec->private_data = wm8960; 915 snd_soc_codec_set_drvdata(codec, wm8960);
770 codec->name = "WM8960"; 916 codec->name = "WM8960";
771 codec->owner = THIS_MODULE; 917 codec->owner = THIS_MODULE;
772 codec->bias_level = SND_SOC_BIAS_OFF; 918 codec->bias_level = SND_SOC_BIAS_OFF;
773 codec->set_bias_level = wm8960_set_bias_level;
774 codec->dai = &wm8960_dai; 919 codec->dai = &wm8960_dai;
775 codec->num_dai = 1; 920 codec->num_dai = 1;
776 codec->reg_cache_size = WM8960_CACHEREGNUM; 921 codec->reg_cache_size = WM8960_CACHEREGNUM;
@@ -792,7 +937,7 @@ static int wm8960_register(struct wm8960_priv *wm8960,
792 937
793 wm8960_dai.dev = codec->dev; 938 wm8960_dai.dev = codec->dev;
794 939
795 wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 940 codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
796 941
797 /* Latch the update bits */ 942 /* Latch the update bits */
798 reg = snd_soc_read(codec, WM8960_LINVOL); 943 reg = snd_soc_read(codec, WM8960_LINVOL);
@@ -841,7 +986,7 @@ err:
841 986
842static void wm8960_unregister(struct wm8960_priv *wm8960) 987static void wm8960_unregister(struct wm8960_priv *wm8960)
843{ 988{
844 wm8960_set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF); 989 wm8960->codec.set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF);
845 snd_soc_unregister_dai(&wm8960_dai); 990 snd_soc_unregister_dai(&wm8960_dai);
846 snd_soc_unregister_codec(&wm8960->codec); 991 snd_soc_unregister_codec(&wm8960->codec);
847 kfree(wm8960); 992 kfree(wm8960);
@@ -883,7 +1028,7 @@ MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id);
883 1028
884static struct i2c_driver wm8960_i2c_driver = { 1029static struct i2c_driver wm8960_i2c_driver = {
885 .driver = { 1030 .driver = {
886 .name = "WM8960 I2C Codec", 1031 .name = "wm8960",
887 .owner = THIS_MODULE, 1032 .owner = THIS_MODULE,
888 }, 1033 },
889 .probe = wm8960_i2c_probe, 1034 .probe = wm8960_i2c_probe,
diff --git a/sound/soc/codecs/wm8960.h b/sound/soc/codecs/wm8960.h
index c9af56c9d9d4..a5ef65481b86 100644
--- a/sound/soc/codecs/wm8960.h
+++ b/sound/soc/codecs/wm8960.h
@@ -76,7 +76,6 @@
76#define WM8960_OPCLKDIV 2 76#define WM8960_OPCLKDIV 2
77#define WM8960_DCLKDIV 3 77#define WM8960_DCLKDIV 3
78#define WM8960_TOCLKSEL 4 78#define WM8960_TOCLKSEL 4
79#define WM8960_SYSCLKSEL 5
80 79
81#define WM8960_SYSCLK_DIV_1 (0 << 1) 80#define WM8960_SYSCLK_DIV_1 (0 << 1)
82#define WM8960_SYSCLK_DIV_2 (2 << 1) 81#define WM8960_SYSCLK_DIV_2 (2 << 1)
@@ -114,14 +113,4 @@
114extern struct snd_soc_dai wm8960_dai; 113extern struct snd_soc_dai wm8960_dai;
115extern struct snd_soc_codec_device soc_codec_dev_wm8960; 114extern struct snd_soc_codec_device soc_codec_dev_wm8960;
116 115
117#define WM8960_DRES_400R 0
118#define WM8960_DRES_200R 1
119#define WM8960_DRES_600R 2
120#define WM8960_DRES_150R 3
121#define WM8960_DRES_MAX 3
122
123struct wm8960_data {
124 int dres;
125};
126
127#endif 116#endif
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 50634ab76a5c..5b9a756242f1 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -631,7 +631,7 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream,
631 struct snd_soc_dai *dai) 631 struct snd_soc_dai *dai)
632{ 632{
633 struct snd_soc_codec *codec = dai->codec; 633 struct snd_soc_codec *codec = dai->codec;
634 struct wm8961_priv *wm8961 = codec->private_data; 634 struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
635 int i, best, target, fs; 635 int i, best, target, fs;
636 u16 reg; 636 u16 reg;
637 637
@@ -722,7 +722,7 @@ static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id,
722 int dir) 722 int dir)
723{ 723{
724 struct snd_soc_codec *codec = dai->codec; 724 struct snd_soc_codec *codec = dai->codec;
725 struct wm8961_priv *wm8961 = codec->private_data; 725 struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
726 u16 reg = snd_soc_read(codec, WM8961_CLOCKING1); 726 u16 reg = snd_soc_read(codec, WM8961_CLOCKING1);
727 727
728 if (freq > 33000000) { 728 if (freq > 33000000) {
@@ -1065,7 +1065,7 @@ static int wm8961_register(struct wm8961_priv *wm8961)
1065 INIT_LIST_HEAD(&codec->dapm_widgets); 1065 INIT_LIST_HEAD(&codec->dapm_widgets);
1066 INIT_LIST_HEAD(&codec->dapm_paths); 1066 INIT_LIST_HEAD(&codec->dapm_paths);
1067 1067
1068 codec->private_data = wm8961; 1068 snd_soc_codec_set_drvdata(codec, wm8961);
1069 codec->name = "WM8961"; 1069 codec->name = "WM8961";
1070 codec->owner = THIS_MODULE; 1070 codec->owner = THIS_MODULE;
1071 codec->dai = &wm8961_dai; 1071 codec->dai = &wm8961_dai;
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index a65b781af512..a99620f335d2 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -415,7 +415,7 @@ static int wm8971_set_dai_sysclk(struct snd_soc_dai *codec_dai,
415 int clk_id, unsigned int freq, int dir) 415 int clk_id, unsigned int freq, int dir)
416{ 416{
417 struct snd_soc_codec *codec = codec_dai->codec; 417 struct snd_soc_codec *codec = codec_dai->codec;
418 struct wm8971_priv *wm8971 = codec->private_data; 418 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
419 419
420 switch (freq) { 420 switch (freq) {
421 case 11289600: 421 case 11289600:
@@ -494,7 +494,7 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
494 struct snd_soc_pcm_runtime *rtd = substream->private_data; 494 struct snd_soc_pcm_runtime *rtd = substream->private_data;
495 struct snd_soc_device *socdev = rtd->socdev; 495 struct snd_soc_device *socdev = rtd->socdev;
496 struct snd_soc_codec *codec = socdev->card->codec; 496 struct snd_soc_codec *codec = socdev->card->codec;
497 struct wm8971_priv *wm8971 = codec->private_data; 497 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
498 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3; 498 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
499 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0; 499 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
500 int coeff = get_coeff(wm8971->sysclk, params_rate(params)); 500 int coeff = get_coeff(wm8971->sysclk, params_rate(params));
@@ -820,7 +820,7 @@ static int wm8971_probe(struct platform_device *pdev)
820 return -ENOMEM; 820 return -ENOMEM;
821 } 821 }
822 822
823 codec->private_data = wm8971; 823 snd_soc_codec_set_drvdata(codec, wm8971);
824 socdev->card->codec = codec; 824 socdev->card->codec = codec;
825 mutex_init(&codec->mutex); 825 mutex_init(&codec->mutex);
826 INIT_LIST_HEAD(&codec->dapm_widgets); 826 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -830,7 +830,7 @@ static int wm8971_probe(struct platform_device *pdev)
830 INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work); 830 INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
831 wm8971_workq = create_workqueue("wm8971"); 831 wm8971_workq = create_workqueue("wm8971");
832 if (wm8971_workq == NULL) { 832 if (wm8971_workq == NULL) {
833 kfree(codec->private_data); 833 kfree(snd_soc_codec_get_drvdata(codec));
834 kfree(codec); 834 kfree(codec);
835 return -ENOMEM; 835 return -ENOMEM;
836 } 836 }
@@ -844,7 +844,7 @@ static int wm8971_probe(struct platform_device *pdev)
844 844
845 if (ret != 0) { 845 if (ret != 0) {
846 destroy_workqueue(wm8971_workq); 846 destroy_workqueue(wm8971_workq);
847 kfree(codec->private_data); 847 kfree(snd_soc_codec_get_drvdata(codec));
848 kfree(codec); 848 kfree(codec);
849 } 849 }
850 850
@@ -867,7 +867,7 @@ static int wm8971_remove(struct platform_device *pdev)
867 i2c_unregister_device(codec->control_data); 867 i2c_unregister_device(codec->control_data);
868 i2c_del_driver(&wm8971_i2c_driver); 868 i2c_del_driver(&wm8971_i2c_driver);
869#endif 869#endif
870 kfree(codec->private_data); 870 kfree(snd_soc_codec_get_drvdata(codec));
871 kfree(codec); 871 kfree(codec);
872 872
873 return 0; 873 return 0;
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 69708c4cc004..a2c4b2f37cca 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -181,7 +181,7 @@ SOC_SINGLE("ADC 128x Oversampling Switch", WM8974_ADC, 8, 1, 0),
181static const struct snd_kcontrol_new wm8974_speaker_mixer_controls[] = { 181static const struct snd_kcontrol_new wm8974_speaker_mixer_controls[] = {
182SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_SPKMIX, 1, 1, 0), 182SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_SPKMIX, 1, 1, 0),
183SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_SPKMIX, 5, 1, 0), 183SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_SPKMIX, 5, 1, 0),
184SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_SPKMIX, 0, 1, 1), 184SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_SPKMIX, 0, 1, 0),
185}; 185};
186 186
187/* Mono Output Mixer */ 187/* Mono Output Mixer */
@@ -609,7 +609,7 @@ static int wm8974_resume(struct platform_device *pdev)
609 codec->hw_write(codec->control_data, data, 2); 609 codec->hw_write(codec->control_data, data, 2);
610 } 610 }
611 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 611 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
612 wm8974_set_bias_level(codec, codec->suspend_bias_level); 612
613 return 0; 613 return 0;
614} 614}
615 615
@@ -677,7 +677,7 @@ static __devinit int wm8974_register(struct wm8974_priv *wm8974)
677 INIT_LIST_HEAD(&codec->dapm_widgets); 677 INIT_LIST_HEAD(&codec->dapm_widgets);
678 INIT_LIST_HEAD(&codec->dapm_paths); 678 INIT_LIST_HEAD(&codec->dapm_paths);
679 679
680 codec->private_data = wm8974; 680 snd_soc_codec_set_drvdata(codec, wm8974);
681 codec->name = "WM8974"; 681 codec->name = "WM8974";
682 codec->owner = THIS_MODULE; 682 codec->owner = THIS_MODULE;
683 codec->bias_level = SND_SOC_BIAS_OFF; 683 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 526f56b09066..51d5f433215c 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -439,7 +439,7 @@ static int wm8978_enum_mclk(unsigned int f_out, unsigned int f_mclk,
439 */ 439 */
440static int wm8978_configure_pll(struct snd_soc_codec *codec) 440static int wm8978_configure_pll(struct snd_soc_codec *codec)
441{ 441{
442 struct wm8978_priv *wm8978 = codec->private_data; 442 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
443 struct wm8978_pll_div pll_div; 443 struct wm8978_pll_div pll_div;
444 unsigned int f_opclk = wm8978->f_opclk, f_mclk = wm8978->f_mclk, 444 unsigned int f_opclk = wm8978->f_opclk, f_mclk = wm8978->f_mclk,
445 f_256fs = wm8978->f_256fs; 445 f_256fs = wm8978->f_256fs;
@@ -535,7 +535,7 @@ static int wm8978_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
535 int div_id, int div) 535 int div_id, int div)
536{ 536{
537 struct snd_soc_codec *codec = codec_dai->codec; 537 struct snd_soc_codec *codec = codec_dai->codec;
538 struct wm8978_priv *wm8978 = codec->private_data; 538 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
539 int ret = 0; 539 int ret = 0;
540 540
541 switch (div_id) { 541 switch (div_id) {
@@ -580,7 +580,7 @@ static int wm8978_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
580 unsigned int freq, int dir) 580 unsigned int freq, int dir)
581{ 581{
582 struct snd_soc_codec *codec = codec_dai->codec; 582 struct snd_soc_codec *codec = codec_dai->codec;
583 struct wm8978_priv *wm8978 = codec->private_data; 583 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
584 int ret = 0; 584 int ret = 0;
585 585
586 dev_dbg(codec->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq); 586 dev_dbg(codec->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq);
@@ -692,7 +692,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
692 struct snd_soc_pcm_runtime *rtd = substream->private_data; 692 struct snd_soc_pcm_runtime *rtd = substream->private_data;
693 struct snd_soc_device *socdev = rtd->socdev; 693 struct snd_soc_device *socdev = rtd->socdev;
694 struct snd_soc_codec *codec = socdev->card->codec; 694 struct snd_soc_codec *codec = socdev->card->codec;
695 struct wm8978_priv *wm8978 = codec->private_data; 695 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
696 /* Word length mask = 0x60 */ 696 /* Word length mask = 0x60 */
697 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60; 697 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
698 /* Sampling rate mask = 0xe (for filters) */ 698 /* Sampling rate mask = 0xe (for filters) */
@@ -912,7 +912,7 @@ static int wm8978_resume(struct platform_device *pdev)
912{ 912{
913 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 913 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
914 struct snd_soc_codec *codec = socdev->card->codec; 914 struct snd_soc_codec *codec = socdev->card->codec;
915 struct wm8978_priv *wm8978 = codec->private_data; 915 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
916 int i; 916 int i;
917 u16 *cache = codec->reg_cache; 917 u16 *cache = codec->reg_cache;
918 918
@@ -1020,7 +1020,7 @@ static __devinit int wm8978_register(struct wm8978_priv *wm8978)
1020 INIT_LIST_HEAD(&codec->dapm_widgets); 1020 INIT_LIST_HEAD(&codec->dapm_widgets);
1021 INIT_LIST_HEAD(&codec->dapm_paths); 1021 INIT_LIST_HEAD(&codec->dapm_paths);
1022 1022
1023 codec->private_data = wm8978; 1023 snd_soc_codec_set_drvdata(codec, wm8978);
1024 codec->name = "WM8978"; 1024 codec->name = "WM8978";
1025 codec->owner = THIS_MODULE; 1025 codec->owner = THIS_MODULE;
1026 codec->bias_level = SND_SOC_BIAS_OFF; 1026 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index bb18c3ecfeb9..0417dae32e6f 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -495,7 +495,7 @@ static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai,
495 int clk_id, unsigned int freq, int dir) 495 int clk_id, unsigned int freq, int dir)
496{ 496{
497 struct snd_soc_codec *codec = codec_dai->codec; 497 struct snd_soc_codec *codec = codec_dai->codec;
498 struct wm8988_priv *wm8988 = codec->private_data; 498 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
499 499
500 switch (freq) { 500 switch (freq) {
501 case 11289600: 501 case 11289600:
@@ -585,7 +585,7 @@ static int wm8988_pcm_startup(struct snd_pcm_substream *substream,
585 struct snd_soc_dai *dai) 585 struct snd_soc_dai *dai)
586{ 586{
587 struct snd_soc_codec *codec = dai->codec; 587 struct snd_soc_codec *codec = dai->codec;
588 struct wm8988_priv *wm8988 = codec->private_data; 588 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
589 589
590 /* The set of sample rates that can be supported depends on the 590 /* The set of sample rates that can be supported depends on the
591 * MCLK supplied to the CODEC - enforce this. 591 * MCLK supplied to the CODEC - enforce this.
@@ -610,7 +610,7 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
610 struct snd_soc_pcm_runtime *rtd = substream->private_data; 610 struct snd_soc_pcm_runtime *rtd = substream->private_data;
611 struct snd_soc_device *socdev = rtd->socdev; 611 struct snd_soc_device *socdev = rtd->socdev;
612 struct snd_soc_codec *codec = socdev->card->codec; 612 struct snd_soc_codec *codec = socdev->card->codec;
613 struct wm8988_priv *wm8988 = codec->private_data; 613 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
614 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3; 614 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3;
615 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180; 615 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180;
616 int coeff; 616 int coeff;
@@ -833,7 +833,7 @@ static int wm8988_register(struct wm8988_priv *wm8988,
833 INIT_LIST_HEAD(&codec->dapm_widgets); 833 INIT_LIST_HEAD(&codec->dapm_widgets);
834 INIT_LIST_HEAD(&codec->dapm_paths); 834 INIT_LIST_HEAD(&codec->dapm_paths);
835 835
836 codec->private_data = wm8988; 836 snd_soc_codec_set_drvdata(codec, wm8988);
837 codec->name = "WM8988"; 837 codec->name = "WM8988";
838 codec->owner = THIS_MODULE; 838 codec->owner = THIS_MODULE;
839 codec->dai = &wm8988_dai; 839 codec->dai = &wm8988_dai;
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 831f4730bfd5..7b536d923ea9 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1012,7 +1012,7 @@ static int wm8990_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1012 int clk_id, unsigned int freq, int dir) 1012 int clk_id, unsigned int freq, int dir)
1013{ 1013{
1014 struct snd_soc_codec *codec = codec_dai->codec; 1014 struct snd_soc_codec *codec = codec_dai->codec;
1015 struct wm8990_priv *wm8990 = codec->private_data; 1015 struct wm8990_priv *wm8990 = snd_soc_codec_get_drvdata(codec);
1016 1016
1017 wm8990->sysclk = freq; 1017 wm8990->sysclk = freq;
1018 return 0; 1018 return 0;
@@ -1524,7 +1524,7 @@ static int wm8990_probe(struct platform_device *pdev)
1524 return -ENOMEM; 1524 return -ENOMEM;
1525 } 1525 }
1526 1526
1527 codec->private_data = wm8990; 1527 snd_soc_codec_set_drvdata(codec, wm8990);
1528 socdev->card->codec = codec; 1528 socdev->card->codec = codec;
1529 mutex_init(&codec->mutex); 1529 mutex_init(&codec->mutex);
1530 INIT_LIST_HEAD(&codec->dapm_widgets); 1530 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -1541,7 +1541,7 @@ static int wm8990_probe(struct platform_device *pdev)
1541#endif 1541#endif
1542 1542
1543 if (ret != 0) { 1543 if (ret != 0) {
1544 kfree(codec->private_data); 1544 kfree(snd_soc_codec_get_drvdata(codec));
1545 kfree(codec); 1545 kfree(codec);
1546 } 1546 }
1547 return ret; 1547 return ret;
@@ -1561,7 +1561,7 @@ static int wm8990_remove(struct platform_device *pdev)
1561 i2c_unregister_device(codec->control_data); 1561 i2c_unregister_device(codec->control_data);
1562 i2c_del_driver(&wm8990_i2c_driver); 1562 i2c_del_driver(&wm8990_i2c_driver);
1563#endif 1563#endif
1564 kfree(codec->private_data); 1564 kfree(snd_soc_codec_get_drvdata(codec));
1565 kfree(codec); 1565 kfree(codec);
1566 1566
1567 return 0; 1567 return 0;
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 03e8b1a6a56c..d8d300c6175f 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -371,7 +371,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
371 unsigned int Fref, unsigned int Fout) 371 unsigned int Fref, unsigned int Fout)
372{ 372{
373 struct snd_soc_codec *codec = dai->codec; 373 struct snd_soc_codec *codec = dai->codec;
374 struct wm8993_priv *wm8993 = codec->private_data; 374 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
375 u16 reg1, reg4, reg5; 375 u16 reg1, reg4, reg5;
376 struct _fll_div fll_div; 376 struct _fll_div fll_div;
377 int ret; 377 int ret;
@@ -458,7 +458,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
458 458
459static int configure_clock(struct snd_soc_codec *codec) 459static int configure_clock(struct snd_soc_codec *codec)
460{ 460{
461 struct wm8993_priv *wm8993 = codec->private_data; 461 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
462 unsigned int reg; 462 unsigned int reg;
463 463
464 /* This should be done on init() for bypass paths */ 464 /* This should be done on init() for bypass paths */
@@ -717,7 +717,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol,
717{ 717{
718 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 718 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
719 struct snd_soc_codec *codec = widget->codec; 719 struct snd_soc_codec *codec = widget->codec;
720 struct wm8993_priv *wm8993 = codec->private_data; 720 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
721 int ret; 721 int ret;
722 722
723 /* Turn it off if we're using the main output mixer */ 723 /* Turn it off if we're using the main output mixer */
@@ -949,7 +949,7 @@ static void wm8993_cache_restore(struct snd_soc_codec *codec)
949static int wm8993_set_bias_level(struct snd_soc_codec *codec, 949static int wm8993_set_bias_level(struct snd_soc_codec *codec,
950 enum snd_soc_bias_level level) 950 enum snd_soc_bias_level level)
951{ 951{
952 struct wm8993_priv *wm8993 = codec->private_data; 952 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
953 int ret; 953 int ret;
954 954
955 switch (level) { 955 switch (level) {
@@ -1047,7 +1047,7 @@ static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai,
1047 int clk_id, unsigned int freq, int dir) 1047 int clk_id, unsigned int freq, int dir)
1048{ 1048{
1049 struct snd_soc_codec *codec = codec_dai->codec; 1049 struct snd_soc_codec *codec = codec_dai->codec;
1050 struct wm8993_priv *wm8993 = codec->private_data; 1050 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1051 1051
1052 switch (clk_id) { 1052 switch (clk_id) {
1053 case WM8993_SYSCLK_MCLK: 1053 case WM8993_SYSCLK_MCLK:
@@ -1067,7 +1067,7 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1067 unsigned int fmt) 1067 unsigned int fmt)
1068{ 1068{
1069 struct snd_soc_codec *codec = dai->codec; 1069 struct snd_soc_codec *codec = dai->codec;
1070 struct wm8993_priv *wm8993 = codec->private_data; 1070 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1071 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1); 1071 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1072 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4); 1072 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1073 1073
@@ -1163,7 +1163,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1163 struct snd_soc_dai *dai) 1163 struct snd_soc_dai *dai)
1164{ 1164{
1165 struct snd_soc_codec *codec = dai->codec; 1165 struct snd_soc_codec *codec = dai->codec;
1166 struct wm8993_priv *wm8993 = codec->private_data; 1166 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1167 int ret, i, best, best_val, cur_val; 1167 int ret, i, best, best_val, cur_val;
1168 unsigned int clocking1, clocking3, aif1, aif4; 1168 unsigned int clocking1, clocking3, aif1, aif4;
1169 1169
@@ -1328,7 +1328,7 @@ static int wm8993_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1328 unsigned int rx_mask, int slots, int slot_width) 1328 unsigned int rx_mask, int slots, int slot_width)
1329{ 1329{
1330 struct snd_soc_codec *codec = dai->codec; 1330 struct snd_soc_codec *codec = dai->codec;
1331 struct wm8993_priv *wm8993 = codec->private_data; 1331 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1332 int aif1 = 0; 1332 int aif1 = 0;
1333 int aif2 = 0; 1333 int aif2 = 0;
1334 1334
@@ -1431,7 +1431,7 @@ static int wm8993_probe(struct platform_device *pdev)
1431 1431
1432 socdev->card->codec = wm8993_codec; 1432 socdev->card->codec = wm8993_codec;
1433 codec = wm8993_codec; 1433 codec = wm8993_codec;
1434 wm8993 = codec->private_data; 1434 wm8993 = snd_soc_codec_get_drvdata(codec);
1435 1435
1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1437 if (ret < 0) { 1437 if (ret < 0) {
@@ -1478,7 +1478,7 @@ static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1478{ 1478{
1479 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1479 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1480 struct snd_soc_codec *codec = socdev->card->codec; 1480 struct snd_soc_codec *codec = socdev->card->codec;
1481 struct wm8993_priv *wm8993 = codec->private_data; 1481 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1482 int fll_fout = wm8993->fll_fout; 1482 int fll_fout = wm8993->fll_fout;
1483 int fll_fref = wm8993->fll_fref; 1483 int fll_fref = wm8993->fll_fref;
1484 int ret; 1484 int ret;
@@ -1502,7 +1502,7 @@ static int wm8993_resume(struct platform_device *pdev)
1502{ 1502{
1503 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1503 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1504 struct snd_soc_codec *codec = socdev->card->codec; 1504 struct snd_soc_codec *codec = socdev->card->codec;
1505 struct wm8993_priv *wm8993 = codec->private_data; 1505 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1506 int ret; 1506 int ret;
1507 1507
1508 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1508 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1571,7 +1571,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1571 codec->set_bias_level = wm8993_set_bias_level; 1571 codec->set_bias_level = wm8993_set_bias_level;
1572 codec->dai = &wm8993_dai; 1572 codec->dai = &wm8993_dai;
1573 codec->num_dai = 1; 1573 codec->num_dai = 1;
1574 codec->private_data = wm8993; 1574 snd_soc_codec_set_drvdata(codec, wm8993);
1575 1575
1576 wm8993->hubs_data.hp_startup_mode = 1; 1576 wm8993->hubs_data.hp_startup_mode = 1;
1577 wm8993->hubs_data.dcs_codes = -2; 1577 wm8993->hubs_data.dcs_codes = -2;
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 9da0724cd47a..e84a1177f350 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -62,6 +62,12 @@ static int wm8994_retune_mobile_base[] = {
62 62
63#define WM8994_REG_CACHE_SIZE 0x621 63#define WM8994_REG_CACHE_SIZE 0x621
64 64
65struct wm8994_micdet {
66 struct snd_soc_jack *jack;
67 int det;
68 int shrt;
69};
70
65/* codec private data */ 71/* codec private data */
66struct wm8994_priv { 72struct wm8994_priv {
67 struct wm_hubs_data hubs; 73 struct wm_hubs_data hubs;
@@ -87,6 +93,8 @@ struct wm8994_priv {
87 int retune_mobile_cfg[WM8994_NUM_EQ]; 93 int retune_mobile_cfg[WM8994_NUM_EQ];
88 struct soc_enum retune_mobile_enum; 94 struct soc_enum retune_mobile_enum;
89 95
96 struct wm8994_micdet micdet[2];
97
90 struct wm8994_pdata *pdata; 98 struct wm8994_pdata *pdata;
91}; 99};
92 100
@@ -1696,13 +1704,15 @@ static int wm8994_volatile(unsigned int reg)
1696static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, 1704static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
1697 unsigned int value) 1705 unsigned int value)
1698{ 1706{
1699 struct wm8994_priv *wm8994 = codec->private_data; 1707 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1700 1708
1701 BUG_ON(reg > WM8994_MAX_REGISTER); 1709 BUG_ON(reg > WM8994_MAX_REGISTER);
1702 1710
1703 if (!wm8994_volatile(reg)) 1711 if (!wm8994_volatile(reg))
1704 wm8994->reg_cache[reg] = value; 1712 wm8994->reg_cache[reg] = value;
1705 1713
1714 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
1715
1706 return wm8994_reg_write(codec->control_data, reg, value); 1716 return wm8994_reg_write(codec->control_data, reg, value);
1707} 1717}
1708 1718
@@ -1721,7 +1731,7 @@ static unsigned int wm8994_read(struct snd_soc_codec *codec,
1721 1731
1722static int configure_aif_clock(struct snd_soc_codec *codec, int aif) 1732static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
1723{ 1733{
1724 struct wm8994_priv *wm8994 = codec->private_data; 1734 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1725 int rate; 1735 int rate;
1726 int reg1 = 0; 1736 int reg1 = 0;
1727 int offset; 1737 int offset;
@@ -1762,6 +1772,11 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
1762 dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n", 1772 dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
1763 aif + 1, rate); 1773 aif + 1, rate);
1764 } 1774 }
1775
1776 if (rate && rate < 3000000)
1777 dev_warn(codec->dev, "AIF%dCLK is %dHz, should be >=3MHz for optimal performance\n",
1778 aif + 1, rate);
1779
1765 wm8994->aifclk[aif] = rate; 1780 wm8994->aifclk[aif] = rate;
1766 1781
1767 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset, 1782 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
@@ -1773,7 +1788,7 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
1773 1788
1774static int configure_clock(struct snd_soc_codec *codec) 1789static int configure_clock(struct snd_soc_codec *codec)
1775{ 1790{
1776 struct wm8994_priv *wm8994 = codec->private_data; 1791 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1777 int old, new; 1792 int old, new;
1778 1793
1779 /* Bring up the AIF clocks first */ 1794 /* Bring up the AIF clocks first */
@@ -1870,7 +1885,7 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
1870 1885
1871static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) 1886static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
1872{ 1887{
1873 struct wm8994_priv *wm8994 = codec->private_data; 1888 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1874 struct wm8994_pdata *pdata = wm8994->pdata; 1889 struct wm8994_pdata *pdata = wm8994->pdata;
1875 int base = wm8994_drc_base[drc]; 1890 int base = wm8994_drc_base[drc];
1876 int cfg = wm8994->drc_cfg[drc]; 1891 int cfg = wm8994->drc_cfg[drc];
@@ -1906,7 +1921,7 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
1906 struct snd_ctl_elem_value *ucontrol) 1921 struct snd_ctl_elem_value *ucontrol)
1907{ 1922{
1908 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1923 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1909 struct wm8994_priv *wm8994 = codec->private_data; 1924 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1910 struct wm8994_pdata *pdata = wm8994->pdata; 1925 struct wm8994_pdata *pdata = wm8994->pdata;
1911 int drc = wm8994_get_drc(kcontrol->id.name); 1926 int drc = wm8994_get_drc(kcontrol->id.name);
1912 int value = ucontrol->value.integer.value[0]; 1927 int value = ucontrol->value.integer.value[0];
@@ -1928,7 +1943,7 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
1928 struct snd_ctl_elem_value *ucontrol) 1943 struct snd_ctl_elem_value *ucontrol)
1929{ 1944{
1930 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1945 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1931 struct wm8994_priv *wm8994 = codec->private_data; 1946 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1932 int drc = wm8994_get_drc(kcontrol->id.name); 1947 int drc = wm8994_get_drc(kcontrol->id.name);
1933 1948
1934 ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc]; 1949 ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];
@@ -1938,7 +1953,7 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
1938 1953
1939static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) 1954static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
1940{ 1955{
1941 struct wm8994_priv *wm8994 = codec->private_data; 1956 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1942 struct wm8994_pdata *pdata = wm8994->pdata; 1957 struct wm8994_pdata *pdata = wm8994->pdata;
1943 int base = wm8994_retune_mobile_base[block]; 1958 int base = wm8994_retune_mobile_base[block];
1944 int iface, best, best_val, save, i, cfg; 1959 int iface, best, best_val, save, i, cfg;
@@ -2009,7 +2024,7 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2009 struct snd_ctl_elem_value *ucontrol) 2024 struct snd_ctl_elem_value *ucontrol)
2010{ 2025{
2011 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2026 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2012 struct wm8994_priv *wm8994 = codec->private_data; 2027 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2013 struct wm8994_pdata *pdata = wm8994->pdata; 2028 struct wm8994_pdata *pdata = wm8994->pdata;
2014 int block = wm8994_get_retune_mobile_block(kcontrol->id.name); 2029 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2015 int value = ucontrol->value.integer.value[0]; 2030 int value = ucontrol->value.integer.value[0];
@@ -2031,7 +2046,7 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2031 struct snd_ctl_elem_value *ucontrol) 2046 struct snd_ctl_elem_value *ucontrol)
2032{ 2047{
2033 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2048 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2034 struct wm8994_priv *wm8994 = codec->private_data; 2049 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2035 int block = wm8994_get_retune_mobile_block(kcontrol->id.name); 2050 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2036 2051
2037 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block]; 2052 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
@@ -2182,13 +2197,13 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
2182 /* Only support direct DAC->headphone paths */ 2197 /* Only support direct DAC->headphone paths */
2183 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1); 2198 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1);
2184 if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) { 2199 if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) {
2185 dev_dbg(codec->dev, "HPL connected to output mixer\n"); 2200 dev_vdbg(codec->dev, "HPL connected to output mixer\n");
2186 enable = 0; 2201 enable = 0;
2187 } 2202 }
2188 2203
2189 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2); 2204 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2);
2190 if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) { 2205 if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) {
2191 dev_dbg(codec->dev, "HPR connected to output mixer\n"); 2206 dev_vdbg(codec->dev, "HPR connected to output mixer\n");
2192 enable = 0; 2207 enable = 0;
2193 } 2208 }
2194 2209
@@ -2196,26 +2211,26 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
2196 reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING); 2211 reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
2197 switch (reg) { 2212 switch (reg) {
2198 case WM8994_AIF2DACL_TO_DAC1L: 2213 case WM8994_AIF2DACL_TO_DAC1L:
2199 dev_dbg(codec->dev, "Class W source AIF2DAC\n"); 2214 dev_vdbg(codec->dev, "Class W source AIF2DAC\n");
2200 source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT; 2215 source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2201 break; 2216 break;
2202 case WM8994_AIF1DAC2L_TO_DAC1L: 2217 case WM8994_AIF1DAC2L_TO_DAC1L:
2203 dev_dbg(codec->dev, "Class W source AIF1DAC2\n"); 2218 dev_vdbg(codec->dev, "Class W source AIF1DAC2\n");
2204 source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT; 2219 source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2205 break; 2220 break;
2206 case WM8994_AIF1DAC1L_TO_DAC1L: 2221 case WM8994_AIF1DAC1L_TO_DAC1L:
2207 dev_dbg(codec->dev, "Class W source AIF1DAC1\n"); 2222 dev_vdbg(codec->dev, "Class W source AIF1DAC1\n");
2208 source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT; 2223 source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2209 break; 2224 break;
2210 default: 2225 default:
2211 dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg); 2226 dev_vdbg(codec->dev, "DAC mixer setting: %x\n", reg);
2212 enable = 0; 2227 enable = 0;
2213 break; 2228 break;
2214 } 2229 }
2215 2230
2216 reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING); 2231 reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
2217 if (reg_r != reg) { 2232 if (reg_r != reg) {
2218 dev_dbg(codec->dev, "Left and right DAC mixers different\n"); 2233 dev_vdbg(codec->dev, "Left and right DAC mixers different\n");
2219 enable = 0; 2234 enable = 0;
2220 } 2235 }
2221 2236
@@ -2777,9 +2792,18 @@ static int wm8994_get_fll_config(struct fll_div *fll,
2777 2792
2778 if (freq_in > 1000000) { 2793 if (freq_in > 1000000) {
2779 fll->fll_fratio = 0; 2794 fll->fll_fratio = 0;
2780 } else { 2795 } else if (freq_in > 256000) {
2796 fll->fll_fratio = 1;
2797 freq_in *= 2;
2798 } else if (freq_in > 128000) {
2799 fll->fll_fratio = 2;
2800 freq_in *= 4;
2801 } else if (freq_in > 64000) {
2781 fll->fll_fratio = 3; 2802 fll->fll_fratio = 3;
2782 freq_in *= 8; 2803 freq_in *= 8;
2804 } else {
2805 fll->fll_fratio = 4;
2806 freq_in *= 16;
2783 } 2807 }
2784 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in); 2808 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
2785 2809
@@ -2812,7 +2836,7 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2812 unsigned int freq_in, unsigned int freq_out) 2836 unsigned int freq_in, unsigned int freq_out)
2813{ 2837{
2814 struct snd_soc_codec *codec = dai->codec; 2838 struct snd_soc_codec *codec = dai->codec;
2815 struct wm8994_priv *wm8994 = codec->private_data; 2839 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2816 int reg_offset, ret; 2840 int reg_offset, ret;
2817 struct fll_div fll; 2841 struct fll_div fll;
2818 u16 reg, aif1, aif2; 2842 u16 reg, aif1, aif2;
@@ -2836,6 +2860,21 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2836 return -EINVAL; 2860 return -EINVAL;
2837 } 2861 }
2838 2862
2863 switch (src) {
2864 case 0:
2865 /* Allow no source specification when stopping */
2866 if (freq_out)
2867 return -EINVAL;
2868 break;
2869 case WM8994_FLL_SRC_MCLK1:
2870 case WM8994_FLL_SRC_MCLK2:
2871 case WM8994_FLL_SRC_LRCLK:
2872 case WM8994_FLL_SRC_BCLK:
2873 break;
2874 default:
2875 return -EINVAL;
2876 }
2877
2839 /* Are we changing anything? */ 2878 /* Are we changing anything? */
2840 if (wm8994->fll[id].src == src && 2879 if (wm8994->fll[id].src == src &&
2841 wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out) 2880 wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out)
@@ -2876,8 +2915,10 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2876 fll.n << WM8994_FLL1_N_SHIFT); 2915 fll.n << WM8994_FLL1_N_SHIFT);
2877 2916
2878 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, 2917 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
2879 WM8994_FLL1_REFCLK_DIV_MASK, 2918 WM8994_FLL1_REFCLK_DIV_MASK |
2880 fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT); 2919 WM8994_FLL1_REFCLK_SRC_MASK,
2920 (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) |
2921 (src - 1));
2881 2922
2882 /* Enable (with fractional mode if required) */ 2923 /* Enable (with fractional mode if required) */
2883 if (freq_out) { 2924 if (freq_out) {
@@ -2892,6 +2933,7 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2892 2933
2893 wm8994->fll[id].in = freq_in; 2934 wm8994->fll[id].in = freq_in;
2894 wm8994->fll[id].out = freq_out; 2935 wm8994->fll[id].out = freq_out;
2936 wm8994->fll[id].src = src;
2895 2937
2896 /* Enable any gated AIF clocks */ 2938 /* Enable any gated AIF clocks */
2897 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, 2939 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
@@ -2908,7 +2950,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2908 int clk_id, unsigned int freq, int dir) 2950 int clk_id, unsigned int freq, int dir)
2909{ 2951{
2910 struct snd_soc_codec *codec = dai->codec; 2952 struct snd_soc_codec *codec = dai->codec;
2911 struct wm8994_priv *wm8994 = codec->private_data; 2953 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2912 2954
2913 switch (dai->id) { 2955 switch (dai->id) {
2914 case 1: 2956 case 1:
@@ -3174,7 +3216,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3174 struct snd_soc_dai *dai) 3216 struct snd_soc_dai *dai)
3175{ 3217{
3176 struct snd_soc_codec *codec = dai->codec; 3218 struct snd_soc_codec *codec = dai->codec;
3177 struct wm8994_priv *wm8994 = codec->private_data; 3219 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3178 int aif1_reg; 3220 int aif1_reg;
3179 int bclk_reg; 3221 int bclk_reg;
3180 int lrclk_reg; 3222 int lrclk_reg;
@@ -3338,6 +3380,36 @@ static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
3338 return 0; 3380 return 0;
3339} 3381}
3340 3382
3383static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
3384{
3385 struct snd_soc_codec *codec = codec_dai->codec;
3386 int reg, val, mask;
3387
3388 switch (codec_dai->id) {
3389 case 1:
3390 reg = WM8994_AIF1_MASTER_SLAVE;
3391 mask = WM8994_AIF1_TRI;
3392 break;
3393 case 2:
3394 reg = WM8994_AIF2_MASTER_SLAVE;
3395 mask = WM8994_AIF2_TRI;
3396 break;
3397 case 3:
3398 reg = WM8994_POWER_MANAGEMENT_6;
3399 mask = WM8994_AIF3_TRI;
3400 break;
3401 default:
3402 return -EINVAL;
3403 }
3404
3405 if (tristate)
3406 val = mask;
3407 else
3408 val = 0;
3409
3410 return snd_soc_update_bits(codec, reg, mask, reg);
3411}
3412
3341#define WM8994_RATES SNDRV_PCM_RATE_8000_96000 3413#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
3342 3414
3343#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 3415#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
@@ -3349,6 +3421,7 @@ static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
3349 .hw_params = wm8994_hw_params, 3421 .hw_params = wm8994_hw_params,
3350 .digital_mute = wm8994_aif_mute, 3422 .digital_mute = wm8994_aif_mute,
3351 .set_pll = wm8994_set_fll, 3423 .set_pll = wm8994_set_fll,
3424 .set_tristate = wm8994_set_tristate,
3352}; 3425};
3353 3426
3354static struct snd_soc_dai_ops wm8994_aif2_dai_ops = { 3427static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
@@ -3357,6 +3430,11 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
3357 .hw_params = wm8994_hw_params, 3430 .hw_params = wm8994_hw_params,
3358 .digital_mute = wm8994_aif_mute, 3431 .digital_mute = wm8994_aif_mute,
3359 .set_pll = wm8994_set_fll, 3432 .set_pll = wm8994_set_fll,
3433 .set_tristate = wm8994_set_tristate,
3434};
3435
3436static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
3437 .set_tristate = wm8994_set_tristate,
3360}; 3438};
3361 3439
3362struct snd_soc_dai wm8994_dai[] = { 3440struct snd_soc_dai wm8994_dai[] = {
@@ -3400,6 +3478,7 @@ struct snd_soc_dai wm8994_dai[] = {
3400 }, 3478 },
3401 { 3479 {
3402 .name = "WM8994 AIF3", 3480 .name = "WM8994 AIF3",
3481 .id = 3,
3403 .playback = { 3482 .playback = {
3404 .stream_name = "AIF3 Playback", 3483 .stream_name = "AIF3 Playback",
3405 .channels_min = 2, 3484 .channels_min = 2,
@@ -3414,6 +3493,7 @@ struct snd_soc_dai wm8994_dai[] = {
3414 .rates = WM8994_RATES, 3493 .rates = WM8994_RATES,
3415 .formats = WM8994_FORMATS, 3494 .formats = WM8994_FORMATS,
3416 }, 3495 },
3496 .ops = &wm8994_aif3_dai_ops,
3417 } 3497 }
3418}; 3498};
3419EXPORT_SYMBOL_GPL(wm8994_dai); 3499EXPORT_SYMBOL_GPL(wm8994_dai);
@@ -3423,7 +3503,7 @@ static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
3423{ 3503{
3424 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 3504 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3425 struct snd_soc_codec *codec = socdev->card->codec; 3505 struct snd_soc_codec *codec = socdev->card->codec;
3426 struct wm8994_priv *wm8994 = codec->private_data; 3506 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3427 int i, ret; 3507 int i, ret;
3428 3508
3429 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 3509 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
@@ -3444,7 +3524,7 @@ static int wm8994_resume(struct platform_device *pdev)
3444{ 3524{
3445 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 3525 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3446 struct snd_soc_codec *codec = socdev->card->codec; 3526 struct snd_soc_codec *codec = socdev->card->codec;
3447 struct wm8994_priv *wm8994 = codec->private_data; 3527 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3448 u16 *reg_cache = codec->reg_cache; 3528 u16 *reg_cache = codec->reg_cache;
3449 int i, ret; 3529 int i, ret;
3450 3530
@@ -3469,6 +3549,9 @@ static int wm8994_resume(struct platform_device *pdev)
3469 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 3549 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3470 3550
3471 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 3551 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3552 if (!wm8994->fll_suspend[i].out)
3553 continue;
3554
3472 ret = wm8994_set_fll(&codec->dai[0], i + 1, 3555 ret = wm8994_set_fll(&codec->dai[0], i + 1,
3473 wm8994->fll_suspend[i].src, 3556 wm8994->fll_suspend[i].src,
3474 wm8994->fll_suspend[i].in, 3557 wm8994->fll_suspend[i].in,
@@ -3639,7 +3722,7 @@ static int wm8994_probe(struct platform_device *pdev)
3639 return ret; 3722 return ret;
3640 } 3723 }
3641 3724
3642 wm8994_handle_pdata(codec->private_data); 3725 wm8994_handle_pdata(snd_soc_codec_get_drvdata(codec));
3643 3726
3644 wm_hubs_add_analogue_controls(codec); 3727 wm_hubs_add_analogue_controls(codec);
3645 snd_soc_add_controls(codec, wm8994_snd_controls, 3728 snd_soc_add_controls(codec, wm8994_snd_controls,
@@ -3670,6 +3753,96 @@ struct snd_soc_codec_device soc_codec_dev_wm8994 = {
3670}; 3753};
3671EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994); 3754EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
3672 3755
3756/**
3757 * wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ
3758 *
3759 * @codec: WM8994 codec
3760 * @jack: jack to report detection events on
3761 * @micbias: microphone bias to detect on
3762 * @det: value to report for presence detection
3763 * @shrt: value to report for short detection
3764 *
3765 * Enable microphone detection via IRQ on the WM8994. If GPIOs are
3766 * being used to bring out signals to the processor then only platform
3767 * data configuration is needed for WM8903 and processor GPIOs should
3768 * be configured using snd_soc_jack_add_gpios() instead.
3769 *
3770 * Configuration of detection levels is available via the micbias1_lvl
3771 * and micbias2_lvl platform data members.
3772 */
3773int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3774 int micbias, int det, int shrt)
3775{
3776 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3777 struct wm8994_micdet *micdet;
3778 int reg;
3779
3780 switch (micbias) {
3781 case 1:
3782 micdet = &wm8994->micdet[0];
3783 break;
3784 case 2:
3785 micdet = &wm8994->micdet[1];
3786 break;
3787 default:
3788 return -EINVAL;
3789 }
3790
3791 dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n",
3792 micbias, det, shrt);
3793
3794 /* Store the configuration */
3795 micdet->jack = jack;
3796 micdet->det = det;
3797 micdet->shrt = shrt;
3798
3799 /* If either of the jacks is set up then enable detection */
3800 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
3801 reg = WM8994_MICD_ENA;
3802 else
3803 reg = 0;
3804
3805 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
3806
3807 return 0;
3808}
3809EXPORT_SYMBOL_GPL(wm8994_mic_detect);
3810
3811static irqreturn_t wm8994_mic_irq(int irq, void *data)
3812{
3813 struct wm8994_priv *priv = data;
3814 struct snd_soc_codec *codec = &priv->codec;
3815 int reg;
3816 int report;
3817
3818 reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2);
3819 if (reg < 0) {
3820 dev_err(codec->dev, "Failed to read microphone status: %d\n",
3821 reg);
3822 return IRQ_HANDLED;
3823 }
3824
3825 dev_dbg(codec->dev, "Microphone status: %x\n", reg);
3826
3827 report = 0;
3828 if (reg & WM8994_MIC1_DET_STS)
3829 report |= priv->micdet[0].det;
3830 if (reg & WM8994_MIC1_SHRT_STS)
3831 report |= priv->micdet[0].shrt;
3832 snd_soc_jack_report(priv->micdet[0].jack, report,
3833 priv->micdet[0].det | priv->micdet[0].shrt);
3834
3835 report = 0;
3836 if (reg & WM8994_MIC2_DET_STS)
3837 report |= priv->micdet[1].det;
3838 if (reg & WM8994_MIC2_SHRT_STS)
3839 report |= priv->micdet[1].shrt;
3840 snd_soc_jack_report(priv->micdet[1].jack, report,
3841 priv->micdet[1].det | priv->micdet[1].shrt);
3842
3843 return IRQ_HANDLED;
3844}
3845
3673static int wm8994_codec_probe(struct platform_device *pdev) 3846static int wm8994_codec_probe(struct platform_device *pdev)
3674{ 3847{
3675 int ret; 3848 int ret;
@@ -3695,7 +3868,7 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3695 INIT_LIST_HEAD(&codec->dapm_widgets); 3868 INIT_LIST_HEAD(&codec->dapm_widgets);
3696 INIT_LIST_HEAD(&codec->dapm_paths); 3869 INIT_LIST_HEAD(&codec->dapm_paths);
3697 3870
3698 codec->private_data = wm8994; 3871 snd_soc_codec_set_drvdata(codec, wm8994);
3699 codec->control_data = dev_get_drvdata(pdev->dev.parent); 3872 codec->control_data = dev_get_drvdata(pdev->dev.parent);
3700 codec->name = "WM8994"; 3873 codec->name = "WM8994";
3701 codec->owner = THIS_MODULE; 3874 codec->owner = THIS_MODULE;
@@ -3743,6 +3916,30 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3743 break; 3916 break;
3744 } 3917 }
3745 3918
3919 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
3920 wm8994_mic_irq, "Mic 1 detect", wm8994);
3921 if (ret != 0)
3922 dev_warn(&pdev->dev,
3923 "Failed to request Mic1 detect IRQ: %d\n", ret);
3924
3925 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
3926 wm8994_mic_irq, "Mic 1 short", wm8994);
3927 if (ret != 0)
3928 dev_warn(&pdev->dev,
3929 "Failed to request Mic1 short IRQ: %d\n", ret);
3930
3931 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
3932 wm8994_mic_irq, "Mic 2 detect", wm8994);
3933 if (ret != 0)
3934 dev_warn(&pdev->dev,
3935 "Failed to request Mic2 detect IRQ: %d\n", ret);
3936
3937 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
3938 wm8994_mic_irq, "Mic 2 short", wm8994);
3939 if (ret != 0)
3940 dev_warn(&pdev->dev,
3941 "Failed to request Mic2 short IRQ: %d\n", ret);
3942
3746 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3943 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3747 * configured on init - if a system wants to do this dynamically 3944 * configured on init - if a system wants to do this dynamically
3748 * at runtime we can deal with that then. 3945 * at runtime we can deal with that then.
@@ -3750,7 +3947,7 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3750 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1); 3947 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1);
3751 if (ret < 0) { 3948 if (ret < 0) {
3752 dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret); 3949 dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret);
3753 goto err; 3950 goto err_irq;
3754 } 3951 }
3755 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { 3952 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3756 wm8994->lrclk_shared[0] = 1; 3953 wm8994->lrclk_shared[0] = 1;
@@ -3762,7 +3959,7 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3762 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6); 3959 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6);
3763 if (ret < 0) { 3960 if (ret < 0) {
3764 dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret); 3961 dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret);
3765 goto err; 3962 goto err_irq;
3766 } 3963 }
3767 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { 3964 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3768 wm8994->lrclk_shared[1] = 1; 3965 wm8994->lrclk_shared[1] = 1;
@@ -3812,7 +4009,7 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3812 ret = snd_soc_register_codec(codec); 4009 ret = snd_soc_register_codec(codec);
3813 if (ret != 0) { 4010 if (ret != 0) {
3814 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 4011 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
3815 goto err; 4012 goto err_irq;
3816 } 4013 }
3817 4014
3818 ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); 4015 ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
@@ -3827,6 +4024,11 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3827 4024
3828err_codec: 4025err_codec:
3829 snd_soc_unregister_codec(codec); 4026 snd_soc_unregister_codec(codec);
4027err_irq:
4028 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
4029 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
4030 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
4031 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
3830err: 4032err:
3831 kfree(wm8994); 4033 kfree(wm8994);
3832 return ret; 4034 return ret;
@@ -3840,6 +4042,10 @@ static int __devexit wm8994_codec_remove(struct platform_device *pdev)
3840 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); 4042 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3841 snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); 4043 snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3842 snd_soc_unregister_codec(&wm8994->codec); 4044 snd_soc_unregister_codec(&wm8994->codec);
4045 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
4046 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
4047 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
4048 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
3843 kfree(wm8994); 4049 kfree(wm8994);
3844 wm8994_codec = NULL; 4050 wm8994_codec = NULL;
3845 4051
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 0a5e1424dea0..7072dc539354 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -23,4 +23,12 @@ extern struct snd_soc_dai wm8994_dai[];
23#define WM8994_FLL1 1 23#define WM8994_FLL1 1
24#define WM8994_FLL2 2 24#define WM8994_FLL2 2
25 25
26#define WM8994_FLL_SRC_MCLK1 1
27#define WM8994_FLL_SRC_MCLK2 2
28#define WM8994_FLL_SRC_LRCLK 3
29#define WM8994_FLL_SRC_BCLK 4
30
31int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
32 int micbias, int det, int shrt);
33
26#endif 34#endif
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 3a184fcb702b..13186fb4dcb4 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -521,7 +521,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
521static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id, 521static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
522 unsigned int Fref, unsigned int Fout) 522 unsigned int Fref, unsigned int Fout)
523{ 523{
524 struct wm9081_priv *wm9081 = codec->private_data; 524 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
525 u16 reg1, reg4, reg5; 525 u16 reg1, reg4, reg5;
526 struct _fll_div fll_div; 526 struct _fll_div fll_div;
527 int ret; 527 int ret;
@@ -607,7 +607,7 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
607 607
608static int configure_clock(struct snd_soc_codec *codec) 608static int configure_clock(struct snd_soc_codec *codec)
609{ 609{
610 struct wm9081_priv *wm9081 = codec->private_data; 610 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
611 int new_sysclk, i, target; 611 int new_sysclk, i, target;
612 unsigned int reg; 612 unsigned int reg;
613 int ret = 0; 613 int ret = 0;
@@ -702,7 +702,7 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
702 struct snd_kcontrol *kcontrol, int event) 702 struct snd_kcontrol *kcontrol, int event)
703{ 703{
704 struct snd_soc_codec *codec = w->codec; 704 struct snd_soc_codec *codec = w->codec;
705 struct wm9081_priv *wm9081 = codec->private_data; 705 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
706 706
707 /* This should be done on init() for bypass paths */ 707 /* This should be done on init() for bypass paths */
708 switch (wm9081->sysclk_source) { 708 switch (wm9081->sysclk_source) {
@@ -873,7 +873,7 @@ static int wm9081_set_dai_fmt(struct snd_soc_dai *dai,
873 unsigned int fmt) 873 unsigned int fmt)
874{ 874{
875 struct snd_soc_codec *codec = dai->codec; 875 struct snd_soc_codec *codec = dai->codec;
876 struct wm9081_priv *wm9081 = codec->private_data; 876 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
877 unsigned int aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2); 877 unsigned int aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2);
878 878
879 aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV | 879 aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV |
@@ -965,7 +965,7 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
965 struct snd_soc_dai *dai) 965 struct snd_soc_dai *dai)
966{ 966{
967 struct snd_soc_codec *codec = dai->codec; 967 struct snd_soc_codec *codec = dai->codec;
968 struct wm9081_priv *wm9081 = codec->private_data; 968 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
969 int ret, i, best, best_val, cur_val; 969 int ret, i, best, best_val, cur_val;
970 unsigned int clk_ctrl2, aif1, aif2, aif3, aif4; 970 unsigned int clk_ctrl2, aif1, aif2, aif3, aif4;
971 971
@@ -1139,7 +1139,7 @@ static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai,
1139 int clk_id, unsigned int freq, int dir) 1139 int clk_id, unsigned int freq, int dir)
1140{ 1140{
1141 struct snd_soc_codec *codec = codec_dai->codec; 1141 struct snd_soc_codec *codec = codec_dai->codec;
1142 struct wm9081_priv *wm9081 = codec->private_data; 1142 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1143 1143
1144 switch (clk_id) { 1144 switch (clk_id) {
1145 case WM9081_SYSCLK_MCLK: 1145 case WM9081_SYSCLK_MCLK:
@@ -1159,7 +1159,7 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1159 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 1159 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
1160{ 1160{
1161 struct snd_soc_codec *codec = dai->codec; 1161 struct snd_soc_codec *codec = dai->codec;
1162 struct wm9081_priv *wm9081 = codec->private_data; 1162 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1163 unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1); 1163 unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1);
1164 1164
1165 aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK); 1165 aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK);
@@ -1242,7 +1242,7 @@ static int wm9081_probe(struct platform_device *pdev)
1242 1242
1243 socdev->card->codec = wm9081_codec; 1243 socdev->card->codec = wm9081_codec;
1244 codec = wm9081_codec; 1244 codec = wm9081_codec;
1245 wm9081 = codec->private_data; 1245 wm9081 = snd_soc_codec_get_drvdata(codec);
1246 1246
1247 /* register pcms */ 1247 /* register pcms */
1248 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1248 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -1339,7 +1339,7 @@ static int wm9081_register(struct wm9081_priv *wm9081,
1339 INIT_LIST_HEAD(&codec->dapm_widgets); 1339 INIT_LIST_HEAD(&codec->dapm_widgets);
1340 INIT_LIST_HEAD(&codec->dapm_paths); 1340 INIT_LIST_HEAD(&codec->dapm_paths);
1341 1341
1342 codec->private_data = wm9081; 1342 snd_soc_codec_set_drvdata(codec, wm9081);
1343 codec->name = "WM9081"; 1343 codec->name = "WM9081";
1344 codec->owner = THIS_MODULE; 1344 codec->owner = THIS_MODULE;
1345 codec->dai = &wm9081_dai; 1345 codec->dai = &wm9081_dai;
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
new file mode 100644
index 000000000000..1592250daec0
--- /dev/null
+++ b/sound/soc/codecs/wm9090.c
@@ -0,0 +1,773 @@
1/*
2 * ALSA SoC WM9090 driver
3 *
4 * Copyright 2009, 2010 Wolfson Microelectronics
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/device.h>
26#include <linux/i2c.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <sound/initval.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/tlv.h>
33#include <sound/wm9090.h>
34
35#include "wm9090.h"
36
37static struct snd_soc_codec *wm9090_codec;
38
39static const u16 wm9090_reg_defaults[] = {
40 0x9093, /* R0 - Software Reset */
41 0x0006, /* R1 - Power Management (1) */
42 0x6000, /* R2 - Power Management (2) */
43 0x0000, /* R3 - Power Management (3) */
44 0x0000, /* R4 */
45 0x0000, /* R5 */
46 0x01C0, /* R6 - Clocking 1 */
47 0x0000, /* R7 */
48 0x0000, /* R8 */
49 0x0000, /* R9 */
50 0x0000, /* R10 */
51 0x0000, /* R11 */
52 0x0000, /* R12 */
53 0x0000, /* R13 */
54 0x0000, /* R14 */
55 0x0000, /* R15 */
56 0x0000, /* R16 */
57 0x0000, /* R17 */
58 0x0000, /* R18 */
59 0x0000, /* R19 */
60 0x0000, /* R20 */
61 0x0000, /* R21 */
62 0x0003, /* R22 - IN1 Line Control */
63 0x0003, /* R23 - IN2 Line Control */
64 0x0083, /* R24 - IN1 Line Input A Volume */
65 0x0083, /* R25 - IN1 Line Input B Volume */
66 0x0083, /* R26 - IN2 Line Input A Volume */
67 0x0083, /* R27 - IN2 Line Input B Volume */
68 0x002D, /* R28 - Left Output Volume */
69 0x002D, /* R29 - Right Output Volume */
70 0x0000, /* R30 */
71 0x0000, /* R31 */
72 0x0000, /* R32 */
73 0x0000, /* R33 */
74 0x0100, /* R34 - SPKMIXL Attenuation */
75 0x0000, /* R35 */
76 0x0010, /* R36 - SPKOUT Mixers */
77 0x0140, /* R37 - ClassD3 */
78 0x0039, /* R38 - Speaker Volume Left */
79 0x0000, /* R39 */
80 0x0000, /* R40 */
81 0x0000, /* R41 */
82 0x0000, /* R42 */
83 0x0000, /* R43 */
84 0x0000, /* R44 */
85 0x0000, /* R45 - Output Mixer1 */
86 0x0000, /* R46 - Output Mixer2 */
87 0x0100, /* R47 - Output Mixer3 */
88 0x0100, /* R48 - Output Mixer4 */
89 0x0000, /* R49 */
90 0x0000, /* R50 */
91 0x0000, /* R51 */
92 0x0000, /* R52 */
93 0x0000, /* R53 */
94 0x0000, /* R54 - Speaker Mixer */
95 0x0000, /* R55 */
96 0x0000, /* R56 */
97 0x000D, /* R57 - AntiPOP2 */
98 0x0000, /* R58 */
99 0x0000, /* R59 */
100 0x0000, /* R60 */
101 0x0000, /* R61 */
102 0x0000, /* R62 */
103 0x0000, /* R63 */
104 0x0000, /* R64 */
105 0x0000, /* R65 */
106 0x0000, /* R66 */
107 0x0000, /* R67 */
108 0x0000, /* R68 */
109 0x0000, /* R69 */
110 0x0000, /* R70 - Write Sequencer 0 */
111 0x0000, /* R71 - Write Sequencer 1 */
112 0x0000, /* R72 - Write Sequencer 2 */
113 0x0000, /* R73 - Write Sequencer 3 */
114 0x0000, /* R74 - Write Sequencer 4 */
115 0x0000, /* R75 - Write Sequencer 5 */
116 0x1F25, /* R76 - Charge Pump 1 */
117 0x0000, /* R77 */
118 0x0000, /* R78 */
119 0x0000, /* R79 */
120 0x0000, /* R80 */
121 0x0000, /* R81 */
122 0x0000, /* R82 */
123 0x0000, /* R83 */
124 0x0000, /* R84 - DC Servo 0 */
125 0x054A, /* R85 - DC Servo 1 */
126 0x0000, /* R86 */
127 0x0000, /* R87 - DC Servo 3 */
128 0x0000, /* R88 - DC Servo Readback 0 */
129 0x0000, /* R89 - DC Servo Readback 1 */
130 0x0000, /* R90 - DC Servo Readback 2 */
131 0x0000, /* R91 */
132 0x0000, /* R92 */
133 0x0000, /* R93 */
134 0x0000, /* R94 */
135 0x0000, /* R95 */
136 0x0100, /* R96 - Analogue HP 0 */
137 0x0000, /* R97 */
138 0x8640, /* R98 - AGC Control 0 */
139 0xC000, /* R99 - AGC Control 1 */
140 0x0200, /* R100 - AGC Control 2 */
141};
142
143/* This struct is used to save the context */
144struct wm9090_priv {
145 /* We're not really registering as a CODEC since ASoC core
146 * does not yet support multiple CODECs but having the CODEC
147 * structure means we can reuse some of the ASoC core
148 * features.
149 */
150 struct snd_soc_codec codec;
151 struct mutex mutex;
152 u16 reg_cache[WM9090_MAX_REGISTER + 1];
153 struct wm9090_platform_data pdata;
154};
155
156static int wm9090_volatile(unsigned int reg)
157{
158 switch (reg) {
159 case WM9090_SOFTWARE_RESET:
160 case WM9090_DC_SERVO_0:
161 case WM9090_DC_SERVO_READBACK_0:
162 case WM9090_DC_SERVO_READBACK_1:
163 case WM9090_DC_SERVO_READBACK_2:
164 return 1;
165
166 default:
167 return 0;
168 }
169}
170
171static void wait_for_dc_servo(struct snd_soc_codec *codec)
172{
173 unsigned int reg;
174 int count = 0;
175
176 dev_dbg(codec->dev, "Waiting for DC servo...\n");
177 do {
178 count++;
179 msleep(1);
180 reg = snd_soc_read(codec, WM9090_DC_SERVO_READBACK_0);
181 dev_dbg(codec->dev, "DC servo status: %x\n", reg);
182 } while ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
183 != WM9090_DCS_CAL_COMPLETE_MASK && count < 1000);
184
185 if ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
186 != WM9090_DCS_CAL_COMPLETE_MASK)
187 dev_err(codec->dev, "Timed out waiting for DC Servo\n");
188}
189
190static const unsigned int in_tlv[] = {
191 TLV_DB_RANGE_HEAD(6),
192 0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0),
193 1, 3, TLV_DB_SCALE_ITEM(-350, 350, 0),
194 4, 6, TLV_DB_SCALE_ITEM(600, 600, 0),
195};
196static const unsigned int mix_tlv[] = {
197 TLV_DB_RANGE_HEAD(4),
198 0, 2, TLV_DB_SCALE_ITEM(-1200, 300, 0),
199 3, 3, TLV_DB_SCALE_ITEM(0, 0, 0),
200};
201static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
202static const unsigned int spkboost_tlv[] = {
203 TLV_DB_RANGE_HEAD(7),
204 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
205 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
206};
207
208static const struct snd_kcontrol_new wm9090_controls[] = {
209SOC_SINGLE_TLV("IN1A Volume", WM9090_IN1_LINE_INPUT_A_VOLUME, 0, 6, 0,
210 in_tlv),
211SOC_SINGLE("IN1A Switch", WM9090_IN1_LINE_INPUT_A_VOLUME, 7, 1, 1),
212SOC_SINGLE("IN1A ZC Switch", WM9090_IN1_LINE_INPUT_A_VOLUME, 6, 1, 0),
213
214SOC_SINGLE_TLV("IN2A Volume", WM9090_IN2_LINE_INPUT_A_VOLUME, 0, 6, 0,
215 in_tlv),
216SOC_SINGLE("IN2A Switch", WM9090_IN2_LINE_INPUT_A_VOLUME, 7, 1, 1),
217SOC_SINGLE("IN2A ZC Switch", WM9090_IN2_LINE_INPUT_A_VOLUME, 6, 1, 0),
218
219SOC_SINGLE("MIXOUTL Switch", WM9090_OUTPUT_MIXER3, 8, 1, 1),
220SOC_SINGLE_TLV("MIXOUTL IN1A Volume", WM9090_OUTPUT_MIXER3, 6, 3, 1,
221 mix_tlv),
222SOC_SINGLE_TLV("MIXOUTL IN2A Volume", WM9090_OUTPUT_MIXER3, 2, 3, 1,
223 mix_tlv),
224
225SOC_SINGLE("MIXOUTR Switch", WM9090_OUTPUT_MIXER4, 8, 1, 1),
226SOC_SINGLE_TLV("MIXOUTR IN1A Volume", WM9090_OUTPUT_MIXER4, 6, 3, 1,
227 mix_tlv),
228SOC_SINGLE_TLV("MIXOUTR IN2A Volume", WM9090_OUTPUT_MIXER4, 2, 3, 1,
229 mix_tlv),
230
231SOC_SINGLE("SPKMIX Switch", WM9090_SPKMIXL_ATTENUATION, 8, 1, 1),
232SOC_SINGLE_TLV("SPKMIX IN1A Volume", WM9090_SPKMIXL_ATTENUATION, 6, 3, 1,
233 mix_tlv),
234SOC_SINGLE_TLV("SPKMIX IN2A Volume", WM9090_SPKMIXL_ATTENUATION, 2, 3, 1,
235 mix_tlv),
236
237SOC_DOUBLE_R_TLV("Headphone Volume", WM9090_LEFT_OUTPUT_VOLUME,
238 WM9090_RIGHT_OUTPUT_VOLUME, 0, 63, 0, out_tlv),
239SOC_DOUBLE_R("Headphone Switch", WM9090_LEFT_OUTPUT_VOLUME,
240 WM9090_RIGHT_OUTPUT_VOLUME, 6, 1, 1),
241SOC_DOUBLE_R("Headphone ZC Switch", WM9090_LEFT_OUTPUT_VOLUME,
242 WM9090_RIGHT_OUTPUT_VOLUME, 7, 1, 0),
243
244SOC_SINGLE_TLV("Speaker Volume", WM9090_SPEAKER_VOLUME_LEFT, 0, 63, 0,
245 out_tlv),
246SOC_SINGLE("Speaker Switch", WM9090_SPEAKER_VOLUME_LEFT, 6, 1, 1),
247SOC_SINGLE("Speaker ZC Switch", WM9090_SPEAKER_VOLUME_LEFT, 7, 1, 0),
248SOC_SINGLE_TLV("Speaker Boost Volume", WM9090_CLASSD3, 3, 7, 0, spkboost_tlv),
249};
250
251static const struct snd_kcontrol_new wm9090_in1_se_controls[] = {
252SOC_SINGLE_TLV("IN1B Volume", WM9090_IN1_LINE_INPUT_B_VOLUME, 0, 6, 0,
253 in_tlv),
254SOC_SINGLE("IN1B Switch", WM9090_IN1_LINE_INPUT_B_VOLUME, 7, 1, 1),
255SOC_SINGLE("IN1B ZC Switch", WM9090_IN1_LINE_INPUT_B_VOLUME, 6, 1, 0),
256
257SOC_SINGLE_TLV("SPKMIX IN1B Volume", WM9090_SPKMIXL_ATTENUATION, 4, 3, 1,
258 mix_tlv),
259SOC_SINGLE_TLV("MIXOUTL IN1B Volume", WM9090_OUTPUT_MIXER3, 4, 3, 1,
260 mix_tlv),
261SOC_SINGLE_TLV("MIXOUTR IN1B Volume", WM9090_OUTPUT_MIXER4, 4, 3, 1,
262 mix_tlv),
263};
264
265static const struct snd_kcontrol_new wm9090_in2_se_controls[] = {
266SOC_SINGLE_TLV("IN2B Volume", WM9090_IN2_LINE_INPUT_B_VOLUME, 0, 6, 0,
267 in_tlv),
268SOC_SINGLE("IN2B Switch", WM9090_IN2_LINE_INPUT_B_VOLUME, 7, 1, 1),
269SOC_SINGLE("IN2B ZC Switch", WM9090_IN2_LINE_INPUT_B_VOLUME, 6, 1, 0),
270
271SOC_SINGLE_TLV("SPKMIX IN2B Volume", WM9090_SPKMIXL_ATTENUATION, 0, 3, 1,
272 mix_tlv),
273SOC_SINGLE_TLV("MIXOUTL IN2B Volume", WM9090_OUTPUT_MIXER3, 0, 3, 1,
274 mix_tlv),
275SOC_SINGLE_TLV("MIXOUTR IN2B Volume", WM9090_OUTPUT_MIXER4, 0, 3, 1,
276 mix_tlv),
277};
278
279static int hp_ev(struct snd_soc_dapm_widget *w,
280 struct snd_kcontrol *kcontrol, int event)
281{
282 struct snd_soc_codec *codec = w->codec;
283 unsigned int reg = snd_soc_read(codec, WM9090_ANALOGUE_HP_0);
284
285 switch (event) {
286 case SND_SOC_DAPM_POST_PMU:
287 snd_soc_update_bits(codec, WM9090_CHARGE_PUMP_1,
288 WM9090_CP_ENA, WM9090_CP_ENA);
289
290 msleep(5);
291
292 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
293 WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
294 WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA);
295
296 reg |= WM9090_HPOUT1L_DLY | WM9090_HPOUT1R_DLY;
297 snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
298
299 /* Start the DC servo. We don't currently use the
300 * ability to save the state since we don't have full
301 * control of the analogue paths and they can change
302 * DC offsets; see the WM8904 driver for an example of
303 * doing so.
304 */
305 snd_soc_write(codec, WM9090_DC_SERVO_0,
306 WM9090_DCS_ENA_CHAN_0 |
307 WM9090_DCS_ENA_CHAN_1 |
308 WM9090_DCS_TRIG_STARTUP_1 |
309 WM9090_DCS_TRIG_STARTUP_0);
310 wait_for_dc_servo(codec);
311
312 reg |= WM9090_HPOUT1R_OUTP | WM9090_HPOUT1R_RMV_SHORT |
313 WM9090_HPOUT1L_OUTP | WM9090_HPOUT1L_RMV_SHORT;
314 snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
315 break;
316
317 case SND_SOC_DAPM_PRE_PMD:
318 reg &= ~(WM9090_HPOUT1L_RMV_SHORT |
319 WM9090_HPOUT1L_DLY |
320 WM9090_HPOUT1L_OUTP |
321 WM9090_HPOUT1R_RMV_SHORT |
322 WM9090_HPOUT1R_DLY |
323 WM9090_HPOUT1R_OUTP);
324
325 snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
326
327 snd_soc_write(codec, WM9090_DC_SERVO_0, 0);
328
329 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
330 WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
331 0);
332
333 snd_soc_update_bits(codec, WM9090_CHARGE_PUMP_1,
334 WM9090_CP_ENA, 0);
335 break;
336 }
337
338 return 0;
339}
340
341static const struct snd_kcontrol_new spkmix[] = {
342SOC_DAPM_SINGLE("IN1A Switch", WM9090_SPEAKER_MIXER, 6, 1, 0),
343SOC_DAPM_SINGLE("IN1B Switch", WM9090_SPEAKER_MIXER, 4, 1, 0),
344SOC_DAPM_SINGLE("IN2A Switch", WM9090_SPEAKER_MIXER, 2, 1, 0),
345SOC_DAPM_SINGLE("IN2B Switch", WM9090_SPEAKER_MIXER, 0, 1, 0),
346};
347
348static const struct snd_kcontrol_new spkout[] = {
349SOC_DAPM_SINGLE("Mixer Switch", WM9090_SPKOUT_MIXERS, 4, 1, 0),
350};
351
352static const struct snd_kcontrol_new mixoutl[] = {
353SOC_DAPM_SINGLE("IN1A Switch", WM9090_OUTPUT_MIXER1, 6, 1, 0),
354SOC_DAPM_SINGLE("IN1B Switch", WM9090_OUTPUT_MIXER1, 4, 1, 0),
355SOC_DAPM_SINGLE("IN2A Switch", WM9090_OUTPUT_MIXER1, 2, 1, 0),
356SOC_DAPM_SINGLE("IN2B Switch", WM9090_OUTPUT_MIXER1, 0, 1, 0),
357};
358
359static const struct snd_kcontrol_new mixoutr[] = {
360SOC_DAPM_SINGLE("IN1A Switch", WM9090_OUTPUT_MIXER2, 6, 1, 0),
361SOC_DAPM_SINGLE("IN1B Switch", WM9090_OUTPUT_MIXER2, 4, 1, 0),
362SOC_DAPM_SINGLE("IN2A Switch", WM9090_OUTPUT_MIXER2, 2, 1, 0),
363SOC_DAPM_SINGLE("IN2B Switch", WM9090_OUTPUT_MIXER2, 0, 1, 0),
364};
365
366static const struct snd_soc_dapm_widget wm9090_dapm_widgets[] = {
367SND_SOC_DAPM_INPUT("IN1+"),
368SND_SOC_DAPM_INPUT("IN1-"),
369SND_SOC_DAPM_INPUT("IN2+"),
370SND_SOC_DAPM_INPUT("IN2-"),
371
372SND_SOC_DAPM_SUPPLY("OSC", WM9090_POWER_MANAGEMENT_1, 3, 0, NULL, 0),
373
374SND_SOC_DAPM_PGA("IN1A PGA", WM9090_POWER_MANAGEMENT_2, 7, 0, NULL, 0),
375SND_SOC_DAPM_PGA("IN1B PGA", WM9090_POWER_MANAGEMENT_2, 6, 0, NULL, 0),
376SND_SOC_DAPM_PGA("IN2A PGA", WM9090_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
377SND_SOC_DAPM_PGA("IN2B PGA", WM9090_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
378
379SND_SOC_DAPM_MIXER("SPKMIX", WM9090_POWER_MANAGEMENT_3, 3, 0,
380 spkmix, ARRAY_SIZE(spkmix)),
381SND_SOC_DAPM_MIXER("MIXOUTL", WM9090_POWER_MANAGEMENT_3, 5, 0,
382 mixoutl, ARRAY_SIZE(mixoutl)),
383SND_SOC_DAPM_MIXER("MIXOUTR", WM9090_POWER_MANAGEMENT_3, 4, 0,
384 mixoutr, ARRAY_SIZE(mixoutr)),
385
386SND_SOC_DAPM_PGA_E("HP PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
387 hp_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
388
389SND_SOC_DAPM_PGA("SPKPGA", WM9090_POWER_MANAGEMENT_3, 8, 0, NULL, 0),
390SND_SOC_DAPM_MIXER("SPKOUT", WM9090_POWER_MANAGEMENT_1, 12, 0,
391 spkout, ARRAY_SIZE(spkout)),
392
393SND_SOC_DAPM_OUTPUT("HPR"),
394SND_SOC_DAPM_OUTPUT("HPL"),
395SND_SOC_DAPM_OUTPUT("Speaker"),
396};
397
398static const struct snd_soc_dapm_route audio_map[] = {
399 { "IN1A PGA", NULL, "IN1+" },
400 { "IN2A PGA", NULL, "IN2+" },
401
402 { "SPKMIX", "IN1A Switch", "IN1A PGA" },
403 { "SPKMIX", "IN2A Switch", "IN2A PGA" },
404
405 { "MIXOUTL", "IN1A Switch", "IN1A PGA" },
406 { "MIXOUTL", "IN2A Switch", "IN2A PGA" },
407
408 { "MIXOUTR", "IN1A Switch", "IN1A PGA" },
409 { "MIXOUTR", "IN2A Switch", "IN2A PGA" },
410
411 { "HP PGA", NULL, "OSC" },
412 { "HP PGA", NULL, "MIXOUTL" },
413 { "HP PGA", NULL, "MIXOUTR" },
414
415 { "HPL", NULL, "HP PGA" },
416 { "HPR", NULL, "HP PGA" },
417
418 { "SPKPGA", NULL, "OSC" },
419 { "SPKPGA", NULL, "SPKMIX" },
420
421 { "SPKOUT", "Mixer Switch", "SPKPGA" },
422
423 { "Speaker", NULL, "SPKOUT" },
424};
425
426static const struct snd_soc_dapm_route audio_map_in1_se[] = {
427 { "IN1B PGA", NULL, "IN1-" },
428
429 { "SPKMIX", "IN1B Switch", "IN1B PGA" },
430 { "MIXOUTL", "IN1B Switch", "IN1B PGA" },
431 { "MIXOUTR", "IN1B Switch", "IN1B PGA" },
432};
433
434static const struct snd_soc_dapm_route audio_map_in1_diff[] = {
435 { "IN1A PGA", NULL, "IN1-" },
436};
437
438static const struct snd_soc_dapm_route audio_map_in2_se[] = {
439 { "IN2B PGA", NULL, "IN2-" },
440
441 { "SPKMIX", "IN2B Switch", "IN2B PGA" },
442 { "MIXOUTL", "IN2B Switch", "IN2B PGA" },
443 { "MIXOUTR", "IN2B Switch", "IN2B PGA" },
444};
445
446static const struct snd_soc_dapm_route audio_map_in2_diff[] = {
447 { "IN2A PGA", NULL, "IN2-" },
448};
449
450static int wm9090_add_controls(struct snd_soc_codec *codec)
451{
452 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
453 int i;
454
455 snd_soc_dapm_new_controls(codec, wm9090_dapm_widgets,
456 ARRAY_SIZE(wm9090_dapm_widgets));
457
458 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
459
460 snd_soc_add_controls(codec, wm9090_controls,
461 ARRAY_SIZE(wm9090_controls));
462
463 if (wm9090->pdata.lin1_diff) {
464 snd_soc_dapm_add_routes(codec, audio_map_in1_diff,
465 ARRAY_SIZE(audio_map_in1_diff));
466 } else {
467 snd_soc_dapm_add_routes(codec, audio_map_in1_se,
468 ARRAY_SIZE(audio_map_in1_se));
469 snd_soc_add_controls(codec, wm9090_in1_se_controls,
470 ARRAY_SIZE(wm9090_in1_se_controls));
471 }
472
473 if (wm9090->pdata.lin2_diff) {
474 snd_soc_dapm_add_routes(codec, audio_map_in2_diff,
475 ARRAY_SIZE(audio_map_in2_diff));
476 } else {
477 snd_soc_dapm_add_routes(codec, audio_map_in2_se,
478 ARRAY_SIZE(audio_map_in2_se));
479 snd_soc_add_controls(codec, wm9090_in2_se_controls,
480 ARRAY_SIZE(wm9090_in2_se_controls));
481 }
482
483 if (wm9090->pdata.agc_ena) {
484 for (i = 0; i < ARRAY_SIZE(wm9090->pdata.agc); i++)
485 snd_soc_write(codec, WM9090_AGC_CONTROL_0 + i,
486 wm9090->pdata.agc[i]);
487 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_3,
488 WM9090_AGC_ENA, WM9090_AGC_ENA);
489 } else {
490 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_3,
491 WM9090_AGC_ENA, 0);
492 }
493
494 return 0;
495
496}
497
498/*
499 * The machine driver should call this from their set_bias_level; if there
500 * isn't one then this can just be set as the set_bias_level function.
501 */
502static int wm9090_set_bias_level(struct snd_soc_codec *codec,
503 enum snd_soc_bias_level level)
504{
505 u16 *reg_cache = codec->reg_cache;
506 int i, ret;
507
508 switch (level) {
509 case SND_SOC_BIAS_ON:
510 break;
511
512 case SND_SOC_BIAS_PREPARE:
513 snd_soc_update_bits(codec, WM9090_ANTIPOP2, WM9090_VMID_ENA,
514 WM9090_VMID_ENA);
515 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
516 WM9090_BIAS_ENA |
517 WM9090_VMID_RES_MASK,
518 WM9090_BIAS_ENA |
519 1 << WM9090_VMID_RES_SHIFT);
520 msleep(1); /* Probably an overestimate */
521 break;
522
523 case SND_SOC_BIAS_STANDBY:
524 if (codec->bias_level == SND_SOC_BIAS_OFF) {
525 /* Restore the register cache */
526 for (i = 1; i < codec->reg_cache_size; i++) {
527 if (reg_cache[i] == wm9090_reg_defaults[i])
528 continue;
529 if (wm9090_volatile(i))
530 continue;
531
532 ret = snd_soc_write(codec, i, reg_cache[i]);
533 if (ret != 0)
534 dev_warn(codec->dev,
535 "Failed to restore register %d: %d\n",
536 i, ret);
537 }
538 }
539
540 /* We keep VMID off during standby since the combination of
541 * ground referenced outputs and class D speaker mean that
542 * latency is not an issue.
543 */
544 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
545 WM9090_BIAS_ENA | WM9090_VMID_RES_MASK, 0);
546 snd_soc_update_bits(codec, WM9090_ANTIPOP2,
547 WM9090_VMID_ENA, 0);
548 break;
549
550 case SND_SOC_BIAS_OFF:
551 break;
552 }
553
554 codec->bias_level = level;
555
556 return 0;
557}
558
559static int wm9090_probe(struct platform_device *pdev)
560{
561 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
562 struct snd_soc_codec *codec;
563 int ret = 0;
564
565 if (wm9090_codec == NULL) {
566 dev_err(&pdev->dev, "Codec device not registered\n");
567 return -ENODEV;
568 }
569
570 socdev->card->codec = wm9090_codec;
571 codec = wm9090_codec;
572
573 /* register pcms */
574 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
575 if (ret < 0) {
576 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
577 goto pcm_err;
578 }
579
580 wm9090_add_controls(codec);
581
582 return 0;
583
584pcm_err:
585 return ret;
586}
587
588#ifdef CONFIG_PM
589static int wm9090_suspend(struct platform_device *pdev, pm_message_t state)
590{
591 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
592 struct snd_soc_codec *codec = socdev->card->codec;
593
594 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
595
596 return 0;
597}
598
599static int wm9090_resume(struct platform_device *pdev)
600{
601 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
602 struct snd_soc_codec *codec = socdev->card->codec;
603
604 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
605
606 return 0;
607}
608#else
609#define wm9090_suspend NULL
610#define wm9090_resume NULL
611#endif
612
613static int wm9090_remove(struct platform_device *pdev)
614{
615 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
616
617 snd_soc_free_pcms(socdev);
618 snd_soc_dapm_free(socdev);
619
620 return 0;
621}
622
623struct snd_soc_codec_device soc_codec_dev_wm9090 = {
624 .probe = wm9090_probe,
625 .remove = wm9090_remove,
626 .suspend = wm9090_suspend,
627 .resume = wm9090_resume,
628};
629EXPORT_SYMBOL_GPL(soc_codec_dev_wm9090);
630
631static int wm9090_i2c_probe(struct i2c_client *i2c,
632 const struct i2c_device_id *id)
633{
634 struct wm9090_priv *wm9090;
635 struct snd_soc_codec *codec;
636 int ret;
637
638 wm9090 = kzalloc(sizeof(*wm9090), GFP_KERNEL);
639 if (wm9090 == NULL) {
640 dev_err(&i2c->dev, "Can not allocate memory\n");
641 return -ENOMEM;
642 }
643 codec = &wm9090->codec;
644
645 if (i2c->dev.platform_data)
646 memcpy(&wm9090->pdata, i2c->dev.platform_data,
647 sizeof(wm9090->pdata));
648
649 wm9090_codec = codec;
650
651 i2c_set_clientdata(i2c, wm9090);
652
653 mutex_init(&codec->mutex);
654 INIT_LIST_HEAD(&codec->dapm_widgets);
655 INIT_LIST_HEAD(&codec->dapm_paths);
656
657 codec->control_data = i2c;
658 snd_soc_codec_set_drvdata(codec, wm9090);
659 codec->dev = &i2c->dev;
660 codec->name = "WM9090";
661 codec->owner = THIS_MODULE;
662 codec->bias_level = SND_SOC_BIAS_OFF;
663 codec->set_bias_level = wm9090_set_bias_level,
664 codec->reg_cache_size = WM9090_MAX_REGISTER + 1;
665 codec->reg_cache = &wm9090->reg_cache;
666 codec->volatile_register = wm9090_volatile;
667
668 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
669 if (ret != 0) {
670 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
671 goto err;
672 }
673
674 memcpy(&wm9090->reg_cache, wm9090_reg_defaults,
675 sizeof(wm9090->reg_cache));
676
677 ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET);
678 if (ret < 0)
679 goto err;
680 if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) {
681 dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", ret);
682 ret = -EINVAL;
683 goto err;
684 }
685
686 ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0);
687 if (ret < 0)
688 goto err;
689
690 /* Configure some defaults; they will be written out when we
691 * bring the bias up.
692 */
693 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
694 | WM9090_IN1A_ZC;
695 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
696 | WM9090_IN1B_ZC;
697 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
698 | WM9090_IN2A_ZC;
699 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
700 | WM9090_IN2B_ZC;
701 wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
702 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
703 wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
704 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
705 wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
706 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
707
708 wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
709
710 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
711
712 ret = snd_soc_register_codec(codec);
713 if (ret != 0) {
714 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
715 goto err_bias;
716 }
717
718 return 0;
719
720err_bias:
721 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
722err:
723 kfree(wm9090);
724 i2c_set_clientdata(i2c, NULL);
725 wm9090_codec = NULL;
726
727 return ret;
728}
729
730static int wm9090_i2c_remove(struct i2c_client *i2c)
731{
732 struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
733 struct snd_soc_codec *codec = &wm9090->codec;
734
735 snd_soc_unregister_codec(codec);
736 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
737 kfree(wm9090);
738 wm9090_codec = NULL;
739
740 return 0;
741}
742
743static const struct i2c_device_id wm9090_id[] = {
744 { "wm9090", 0 },
745 { }
746};
747MODULE_DEVICE_TABLE(i2c, wm9090_id);
748
749static struct i2c_driver wm9090_i2c_driver = {
750 .driver = {
751 .name = "wm9090",
752 .owner = THIS_MODULE,
753 },
754 .probe = wm9090_i2c_probe,
755 .remove = __devexit_p(wm9090_i2c_remove),
756 .id_table = wm9090_id,
757};
758
759static int __init wm9090_init(void)
760{
761 return i2c_add_driver(&wm9090_i2c_driver);
762}
763module_init(wm9090_init);
764
765static void __exit wm9090_exit(void)
766{
767 i2c_del_driver(&wm9090_i2c_driver);
768}
769module_exit(wm9090_exit);
770
771MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
772MODULE_DESCRIPTION("WM9090 ASoC driver");
773MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm9090.h b/sound/soc/codecs/wm9090.h
new file mode 100644
index 000000000000..b08eab932a5b
--- /dev/null
+++ b/sound/soc/codecs/wm9090.h
@@ -0,0 +1,715 @@
1/*
2 * ALSA SoC WM9090 driver
3 *
4 * Copyright 2009 Wolfson Microelectronics
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#ifndef __WM9090_H
24#define __WM9090_H
25
26extern struct snd_soc_codec_device soc_codec_dev_wm9090;
27
28/*
29 * Register values.
30 */
31#define WM9090_SOFTWARE_RESET 0x00
32#define WM9090_POWER_MANAGEMENT_1 0x01
33#define WM9090_POWER_MANAGEMENT_2 0x02
34#define WM9090_POWER_MANAGEMENT_3 0x03
35#define WM9090_CLOCKING_1 0x06
36#define WM9090_IN1_LINE_CONTROL 0x16
37#define WM9090_IN2_LINE_CONTROL 0x17
38#define WM9090_IN1_LINE_INPUT_A_VOLUME 0x18
39#define WM9090_IN1_LINE_INPUT_B_VOLUME 0x19
40#define WM9090_IN2_LINE_INPUT_A_VOLUME 0x1A
41#define WM9090_IN2_LINE_INPUT_B_VOLUME 0x1B
42#define WM9090_LEFT_OUTPUT_VOLUME 0x1C
43#define WM9090_RIGHT_OUTPUT_VOLUME 0x1D
44#define WM9090_SPKMIXL_ATTENUATION 0x22
45#define WM9090_SPKOUT_MIXERS 0x24
46#define WM9090_CLASSD3 0x25
47#define WM9090_SPEAKER_VOLUME_LEFT 0x26
48#define WM9090_OUTPUT_MIXER1 0x2D
49#define WM9090_OUTPUT_MIXER2 0x2E
50#define WM9090_OUTPUT_MIXER3 0x2F
51#define WM9090_OUTPUT_MIXER4 0x30
52#define WM9090_SPEAKER_MIXER 0x36
53#define WM9090_ANTIPOP2 0x39
54#define WM9090_WRITE_SEQUENCER_0 0x46
55#define WM9090_WRITE_SEQUENCER_1 0x47
56#define WM9090_WRITE_SEQUENCER_2 0x48
57#define WM9090_WRITE_SEQUENCER_3 0x49
58#define WM9090_WRITE_SEQUENCER_4 0x4A
59#define WM9090_WRITE_SEQUENCER_5 0x4B
60#define WM9090_CHARGE_PUMP_1 0x4C
61#define WM9090_DC_SERVO_0 0x54
62#define WM9090_DC_SERVO_1 0x55
63#define WM9090_DC_SERVO_3 0x57
64#define WM9090_DC_SERVO_READBACK_0 0x58
65#define WM9090_DC_SERVO_READBACK_1 0x59
66#define WM9090_DC_SERVO_READBACK_2 0x5A
67#define WM9090_ANALOGUE_HP_0 0x60
68#define WM9090_AGC_CONTROL_0 0x62
69#define WM9090_AGC_CONTROL_1 0x63
70#define WM9090_AGC_CONTROL_2 0x64
71
72#define WM9090_REGISTER_COUNT 40
73#define WM9090_MAX_REGISTER 0x64
74
75/*
76 * Field Definitions.
77 */
78
79/*
80 * R0 (0x00) - Software Reset
81 */
82#define WM9090_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
83#define WM9090_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
84#define WM9090_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
85
86/*
87 * R1 (0x01) - Power Management (1)
88 */
89#define WM9090_SPKOUTL_ENA 0x1000 /* SPKOUTL_ENA */
90#define WM9090_SPKOUTL_ENA_MASK 0x1000 /* SPKOUTL_ENA */
91#define WM9090_SPKOUTL_ENA_SHIFT 12 /* SPKOUTL_ENA */
92#define WM9090_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
93#define WM9090_HPOUT1L_ENA 0x0200 /* HPOUT1L_ENA */
94#define WM9090_HPOUT1L_ENA_MASK 0x0200 /* HPOUT1L_ENA */
95#define WM9090_HPOUT1L_ENA_SHIFT 9 /* HPOUT1L_ENA */
96#define WM9090_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
97#define WM9090_HPOUT1R_ENA 0x0100 /* HPOUT1R_ENA */
98#define WM9090_HPOUT1R_ENA_MASK 0x0100 /* HPOUT1R_ENA */
99#define WM9090_HPOUT1R_ENA_SHIFT 8 /* HPOUT1R_ENA */
100#define WM9090_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
101#define WM9090_OSC_ENA 0x0008 /* OSC_ENA */
102#define WM9090_OSC_ENA_MASK 0x0008 /* OSC_ENA */
103#define WM9090_OSC_ENA_SHIFT 3 /* OSC_ENA */
104#define WM9090_OSC_ENA_WIDTH 1 /* OSC_ENA */
105#define WM9090_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
106#define WM9090_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
107#define WM9090_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
108#define WM9090_BIAS_ENA 0x0001 /* BIAS_ENA */
109#define WM9090_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
110#define WM9090_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
111#define WM9090_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
112
113/*
114 * R2 (0x02) - Power Management (2)
115 */
116#define WM9090_TSHUT 0x8000 /* TSHUT */
117#define WM9090_TSHUT_MASK 0x8000 /* TSHUT */
118#define WM9090_TSHUT_SHIFT 15 /* TSHUT */
119#define WM9090_TSHUT_WIDTH 1 /* TSHUT */
120#define WM9090_TSHUT_ENA 0x4000 /* TSHUT_ENA */
121#define WM9090_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */
122#define WM9090_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */
123#define WM9090_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */
124#define WM9090_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
125#define WM9090_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */
126#define WM9090_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */
127#define WM9090_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */
128#define WM9090_IN1A_ENA 0x0080 /* IN1A_ENA */
129#define WM9090_IN1A_ENA_MASK 0x0080 /* IN1A_ENA */
130#define WM9090_IN1A_ENA_SHIFT 7 /* IN1A_ENA */
131#define WM9090_IN1A_ENA_WIDTH 1 /* IN1A_ENA */
132#define WM9090_IN1B_ENA 0x0040 /* IN1B_ENA */
133#define WM9090_IN1B_ENA_MASK 0x0040 /* IN1B_ENA */
134#define WM9090_IN1B_ENA_SHIFT 6 /* IN1B_ENA */
135#define WM9090_IN1B_ENA_WIDTH 1 /* IN1B_ENA */
136#define WM9090_IN2A_ENA 0x0020 /* IN2A_ENA */
137#define WM9090_IN2A_ENA_MASK 0x0020 /* IN2A_ENA */
138#define WM9090_IN2A_ENA_SHIFT 5 /* IN2A_ENA */
139#define WM9090_IN2A_ENA_WIDTH 1 /* IN2A_ENA */
140#define WM9090_IN2B_ENA 0x0010 /* IN2B_ENA */
141#define WM9090_IN2B_ENA_MASK 0x0010 /* IN2B_ENA */
142#define WM9090_IN2B_ENA_SHIFT 4 /* IN2B_ENA */
143#define WM9090_IN2B_ENA_WIDTH 1 /* IN2B_ENA */
144
145/*
146 * R3 (0x03) - Power Management (3)
147 */
148#define WM9090_AGC_ENA 0x4000 /* AGC_ENA */
149#define WM9090_AGC_ENA_MASK 0x4000 /* AGC_ENA */
150#define WM9090_AGC_ENA_SHIFT 14 /* AGC_ENA */
151#define WM9090_AGC_ENA_WIDTH 1 /* AGC_ENA */
152#define WM9090_SPKLVOL_ENA 0x0100 /* SPKLVOL_ENA */
153#define WM9090_SPKLVOL_ENA_MASK 0x0100 /* SPKLVOL_ENA */
154#define WM9090_SPKLVOL_ENA_SHIFT 8 /* SPKLVOL_ENA */
155#define WM9090_SPKLVOL_ENA_WIDTH 1 /* SPKLVOL_ENA */
156#define WM9090_MIXOUTL_ENA 0x0020 /* MIXOUTL_ENA */
157#define WM9090_MIXOUTL_ENA_MASK 0x0020 /* MIXOUTL_ENA */
158#define WM9090_MIXOUTL_ENA_SHIFT 5 /* MIXOUTL_ENA */
159#define WM9090_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
160#define WM9090_MIXOUTR_ENA 0x0010 /* MIXOUTR_ENA */
161#define WM9090_MIXOUTR_ENA_MASK 0x0010 /* MIXOUTR_ENA */
162#define WM9090_MIXOUTR_ENA_SHIFT 4 /* MIXOUTR_ENA */
163#define WM9090_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
164#define WM9090_SPKMIX_ENA 0x0008 /* SPKMIX_ENA */
165#define WM9090_SPKMIX_ENA_MASK 0x0008 /* SPKMIX_ENA */
166#define WM9090_SPKMIX_ENA_SHIFT 3 /* SPKMIX_ENA */
167#define WM9090_SPKMIX_ENA_WIDTH 1 /* SPKMIX_ENA */
168
169/*
170 * R6 (0x06) - Clocking 1
171 */
172#define WM9090_TOCLK_RATE 0x8000 /* TOCLK_RATE */
173#define WM9090_TOCLK_RATE_MASK 0x8000 /* TOCLK_RATE */
174#define WM9090_TOCLK_RATE_SHIFT 15 /* TOCLK_RATE */
175#define WM9090_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
176#define WM9090_TOCLK_ENA 0x4000 /* TOCLK_ENA */
177#define WM9090_TOCLK_ENA_MASK 0x4000 /* TOCLK_ENA */
178#define WM9090_TOCLK_ENA_SHIFT 14 /* TOCLK_ENA */
179#define WM9090_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
180
181/*
182 * R22 (0x16) - IN1 Line Control
183 */
184#define WM9090_IN1_DIFF 0x0002 /* IN1_DIFF */
185#define WM9090_IN1_DIFF_MASK 0x0002 /* IN1_DIFF */
186#define WM9090_IN1_DIFF_SHIFT 1 /* IN1_DIFF */
187#define WM9090_IN1_DIFF_WIDTH 1 /* IN1_DIFF */
188#define WM9090_IN1_CLAMP 0x0001 /* IN1_CLAMP */
189#define WM9090_IN1_CLAMP_MASK 0x0001 /* IN1_CLAMP */
190#define WM9090_IN1_CLAMP_SHIFT 0 /* IN1_CLAMP */
191#define WM9090_IN1_CLAMP_WIDTH 1 /* IN1_CLAMP */
192
193/*
194 * R23 (0x17) - IN2 Line Control
195 */
196#define WM9090_IN2_DIFF 0x0002 /* IN2_DIFF */
197#define WM9090_IN2_DIFF_MASK 0x0002 /* IN2_DIFF */
198#define WM9090_IN2_DIFF_SHIFT 1 /* IN2_DIFF */
199#define WM9090_IN2_DIFF_WIDTH 1 /* IN2_DIFF */
200#define WM9090_IN2_CLAMP 0x0001 /* IN2_CLAMP */
201#define WM9090_IN2_CLAMP_MASK 0x0001 /* IN2_CLAMP */
202#define WM9090_IN2_CLAMP_SHIFT 0 /* IN2_CLAMP */
203#define WM9090_IN2_CLAMP_WIDTH 1 /* IN2_CLAMP */
204
205/*
206 * R24 (0x18) - IN1 Line Input A Volume
207 */
208#define WM9090_IN1_VU 0x0100 /* IN1_VU */
209#define WM9090_IN1_VU_MASK 0x0100 /* IN1_VU */
210#define WM9090_IN1_VU_SHIFT 8 /* IN1_VU */
211#define WM9090_IN1_VU_WIDTH 1 /* IN1_VU */
212#define WM9090_IN1A_MUTE 0x0080 /* IN1A_MUTE */
213#define WM9090_IN1A_MUTE_MASK 0x0080 /* IN1A_MUTE */
214#define WM9090_IN1A_MUTE_SHIFT 7 /* IN1A_MUTE */
215#define WM9090_IN1A_MUTE_WIDTH 1 /* IN1A_MUTE */
216#define WM9090_IN1A_ZC 0x0040 /* IN1A_ZC */
217#define WM9090_IN1A_ZC_MASK 0x0040 /* IN1A_ZC */
218#define WM9090_IN1A_ZC_SHIFT 6 /* IN1A_ZC */
219#define WM9090_IN1A_ZC_WIDTH 1 /* IN1A_ZC */
220#define WM9090_IN1A_VOL_MASK 0x0007 /* IN1A_VOL - [2:0] */
221#define WM9090_IN1A_VOL_SHIFT 0 /* IN1A_VOL - [2:0] */
222#define WM9090_IN1A_VOL_WIDTH 3 /* IN1A_VOL - [2:0] */
223
224/*
225 * R25 (0x19) - IN1 Line Input B Volume
226 */
227#define WM9090_IN1_VU 0x0100 /* IN1_VU */
228#define WM9090_IN1_VU_MASK 0x0100 /* IN1_VU */
229#define WM9090_IN1_VU_SHIFT 8 /* IN1_VU */
230#define WM9090_IN1_VU_WIDTH 1 /* IN1_VU */
231#define WM9090_IN1B_MUTE 0x0080 /* IN1B_MUTE */
232#define WM9090_IN1B_MUTE_MASK 0x0080 /* IN1B_MUTE */
233#define WM9090_IN1B_MUTE_SHIFT 7 /* IN1B_MUTE */
234#define WM9090_IN1B_MUTE_WIDTH 1 /* IN1B_MUTE */
235#define WM9090_IN1B_ZC 0x0040 /* IN1B_ZC */
236#define WM9090_IN1B_ZC_MASK 0x0040 /* IN1B_ZC */
237#define WM9090_IN1B_ZC_SHIFT 6 /* IN1B_ZC */
238#define WM9090_IN1B_ZC_WIDTH 1 /* IN1B_ZC */
239#define WM9090_IN1B_VOL_MASK 0x0007 /* IN1B_VOL - [2:0] */
240#define WM9090_IN1B_VOL_SHIFT 0 /* IN1B_VOL - [2:0] */
241#define WM9090_IN1B_VOL_WIDTH 3 /* IN1B_VOL - [2:0] */
242
243/*
244 * R26 (0x1A) - IN2 Line Input A Volume
245 */
246#define WM9090_IN2_VU 0x0100 /* IN2_VU */
247#define WM9090_IN2_VU_MASK 0x0100 /* IN2_VU */
248#define WM9090_IN2_VU_SHIFT 8 /* IN2_VU */
249#define WM9090_IN2_VU_WIDTH 1 /* IN2_VU */
250#define WM9090_IN2A_MUTE 0x0080 /* IN2A_MUTE */
251#define WM9090_IN2A_MUTE_MASK 0x0080 /* IN2A_MUTE */
252#define WM9090_IN2A_MUTE_SHIFT 7 /* IN2A_MUTE */
253#define WM9090_IN2A_MUTE_WIDTH 1 /* IN2A_MUTE */
254#define WM9090_IN2A_ZC 0x0040 /* IN2A_ZC */
255#define WM9090_IN2A_ZC_MASK 0x0040 /* IN2A_ZC */
256#define WM9090_IN2A_ZC_SHIFT 6 /* IN2A_ZC */
257#define WM9090_IN2A_ZC_WIDTH 1 /* IN2A_ZC */
258#define WM9090_IN2A_VOL_MASK 0x0007 /* IN2A_VOL - [2:0] */
259#define WM9090_IN2A_VOL_SHIFT 0 /* IN2A_VOL - [2:0] */
260#define WM9090_IN2A_VOL_WIDTH 3 /* IN2A_VOL - [2:0] */
261
262/*
263 * R27 (0x1B) - IN2 Line Input B Volume
264 */
265#define WM9090_IN2_VU 0x0100 /* IN2_VU */
266#define WM9090_IN2_VU_MASK 0x0100 /* IN2_VU */
267#define WM9090_IN2_VU_SHIFT 8 /* IN2_VU */
268#define WM9090_IN2_VU_WIDTH 1 /* IN2_VU */
269#define WM9090_IN2B_MUTE 0x0080 /* IN2B_MUTE */
270#define WM9090_IN2B_MUTE_MASK 0x0080 /* IN2B_MUTE */
271#define WM9090_IN2B_MUTE_SHIFT 7 /* IN2B_MUTE */
272#define WM9090_IN2B_MUTE_WIDTH 1 /* IN2B_MUTE */
273#define WM9090_IN2B_ZC 0x0040 /* IN2B_ZC */
274#define WM9090_IN2B_ZC_MASK 0x0040 /* IN2B_ZC */
275#define WM9090_IN2B_ZC_SHIFT 6 /* IN2B_ZC */
276#define WM9090_IN2B_ZC_WIDTH 1 /* IN2B_ZC */
277#define WM9090_IN2B_VOL_MASK 0x0007 /* IN2B_VOL - [2:0] */
278#define WM9090_IN2B_VOL_SHIFT 0 /* IN2B_VOL - [2:0] */
279#define WM9090_IN2B_VOL_WIDTH 3 /* IN2B_VOL - [2:0] */
280
281/*
282 * R28 (0x1C) - Left Output Volume
283 */
284#define WM9090_HPOUT1_VU 0x0100 /* HPOUT1_VU */
285#define WM9090_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
286#define WM9090_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
287#define WM9090_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
288#define WM9090_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
289#define WM9090_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
290#define WM9090_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
291#define WM9090_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
292#define WM9090_HPOUT1L_MUTE 0x0040 /* HPOUT1L_MUTE */
293#define WM9090_HPOUT1L_MUTE_MASK 0x0040 /* HPOUT1L_MUTE */
294#define WM9090_HPOUT1L_MUTE_SHIFT 6 /* HPOUT1L_MUTE */
295#define WM9090_HPOUT1L_MUTE_WIDTH 1 /* HPOUT1L_MUTE */
296#define WM9090_HPOUT1L_VOL_MASK 0x003F /* HPOUT1L_VOL - [5:0] */
297#define WM9090_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [5:0] */
298#define WM9090_HPOUT1L_VOL_WIDTH 6 /* HPOUT1L_VOL - [5:0] */
299
300/*
301 * R29 (0x1D) - Right Output Volume
302 */
303#define WM9090_HPOUT1_VU 0x0100 /* HPOUT1_VU */
304#define WM9090_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
305#define WM9090_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
306#define WM9090_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
307#define WM9090_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
308#define WM9090_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
309#define WM9090_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
310#define WM9090_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
311#define WM9090_HPOUT1R_MUTE 0x0040 /* HPOUT1R_MUTE */
312#define WM9090_HPOUT1R_MUTE_MASK 0x0040 /* HPOUT1R_MUTE */
313#define WM9090_HPOUT1R_MUTE_SHIFT 6 /* HPOUT1R_MUTE */
314#define WM9090_HPOUT1R_MUTE_WIDTH 1 /* HPOUT1R_MUTE */
315#define WM9090_HPOUT1R_VOL_MASK 0x003F /* HPOUT1R_VOL - [5:0] */
316#define WM9090_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [5:0] */
317#define WM9090_HPOUT1R_VOL_WIDTH 6 /* HPOUT1R_VOL - [5:0] */
318
319/*
320 * R34 (0x22) - SPKMIXL Attenuation
321 */
322#define WM9090_SPKMIX_MUTE 0x0100 /* SPKMIX_MUTE */
323#define WM9090_SPKMIX_MUTE_MASK 0x0100 /* SPKMIX_MUTE */
324#define WM9090_SPKMIX_MUTE_SHIFT 8 /* SPKMIX_MUTE */
325#define WM9090_SPKMIX_MUTE_WIDTH 1 /* SPKMIX_MUTE */
326#define WM9090_IN1A_SPKMIX_VOL_MASK 0x00C0 /* IN1A_SPKMIX_VOL - [7:6] */
327#define WM9090_IN1A_SPKMIX_VOL_SHIFT 6 /* IN1A_SPKMIX_VOL - [7:6] */
328#define WM9090_IN1A_SPKMIX_VOL_WIDTH 2 /* IN1A_SPKMIX_VOL - [7:6] */
329#define WM9090_IN1B_SPKMIX_VOL_MASK 0x0030 /* IN1B_SPKMIX_VOL - [5:4] */
330#define WM9090_IN1B_SPKMIX_VOL_SHIFT 4 /* IN1B_SPKMIX_VOL - [5:4] */
331#define WM9090_IN1B_SPKMIX_VOL_WIDTH 2 /* IN1B_SPKMIX_VOL - [5:4] */
332#define WM9090_IN2A_SPKMIX_VOL_MASK 0x000C /* IN2A_SPKMIX_VOL - [3:2] */
333#define WM9090_IN2A_SPKMIX_VOL_SHIFT 2 /* IN2A_SPKMIX_VOL - [3:2] */
334#define WM9090_IN2A_SPKMIX_VOL_WIDTH 2 /* IN2A_SPKMIX_VOL - [3:2] */
335#define WM9090_IN2B_SPKMIX_VOL_MASK 0x0003 /* IN2B_SPKMIX_VOL - [1:0] */
336#define WM9090_IN2B_SPKMIX_VOL_SHIFT 0 /* IN2B_SPKMIX_VOL - [1:0] */
337#define WM9090_IN2B_SPKMIX_VOL_WIDTH 2 /* IN2B_SPKMIX_VOL - [1:0] */
338
339/*
340 * R36 (0x24) - SPKOUT Mixers
341 */
342#define WM9090_SPKMIXL_TO_SPKOUTL 0x0010 /* SPKMIXL_TO_SPKOUTL */
343#define WM9090_SPKMIXL_TO_SPKOUTL_MASK 0x0010 /* SPKMIXL_TO_SPKOUTL */
344#define WM9090_SPKMIXL_TO_SPKOUTL_SHIFT 4 /* SPKMIXL_TO_SPKOUTL */
345#define WM9090_SPKMIXL_TO_SPKOUTL_WIDTH 1 /* SPKMIXL_TO_SPKOUTL */
346
347/*
348 * R37 (0x25) - ClassD3
349 */
350#define WM9090_SPKOUTL_BOOST_MASK 0x0038 /* SPKOUTL_BOOST - [5:3] */
351#define WM9090_SPKOUTL_BOOST_SHIFT 3 /* SPKOUTL_BOOST - [5:3] */
352#define WM9090_SPKOUTL_BOOST_WIDTH 3 /* SPKOUTL_BOOST - [5:3] */
353
354/*
355 * R38 (0x26) - Speaker Volume Left
356 */
357#define WM9090_SPKOUT_VU 0x0100 /* SPKOUT_VU */
358#define WM9090_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
359#define WM9090_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
360#define WM9090_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
361#define WM9090_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */
362#define WM9090_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */
363#define WM9090_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */
364#define WM9090_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */
365#define WM9090_SPKOUTL_MUTE 0x0040 /* SPKOUTL_MUTE */
366#define WM9090_SPKOUTL_MUTE_MASK 0x0040 /* SPKOUTL_MUTE */
367#define WM9090_SPKOUTL_MUTE_SHIFT 6 /* SPKOUTL_MUTE */
368#define WM9090_SPKOUTL_MUTE_WIDTH 1 /* SPKOUTL_MUTE */
369#define WM9090_SPKOUTL_VOL_MASK 0x003F /* SPKOUTL_VOL - [5:0] */
370#define WM9090_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [5:0] */
371#define WM9090_SPKOUTL_VOL_WIDTH 6 /* SPKOUTL_VOL - [5:0] */
372
373/*
374 * R45 (0x2D) - Output Mixer1
375 */
376#define WM9090_IN1A_TO_MIXOUTL 0x0040 /* IN1A_TO_MIXOUTL */
377#define WM9090_IN1A_TO_MIXOUTL_MASK 0x0040 /* IN1A_TO_MIXOUTL */
378#define WM9090_IN1A_TO_MIXOUTL_SHIFT 6 /* IN1A_TO_MIXOUTL */
379#define WM9090_IN1A_TO_MIXOUTL_WIDTH 1 /* IN1A_TO_MIXOUTL */
380#define WM9090_IN2A_TO_MIXOUTL 0x0004 /* IN2A_TO_MIXOUTL */
381#define WM9090_IN2A_TO_MIXOUTL_MASK 0x0004 /* IN2A_TO_MIXOUTL */
382#define WM9090_IN2A_TO_MIXOUTL_SHIFT 2 /* IN2A_TO_MIXOUTL */
383#define WM9090_IN2A_TO_MIXOUTL_WIDTH 1 /* IN2A_TO_MIXOUTL */
384
385/*
386 * R46 (0x2E) - Output Mixer2
387 */
388#define WM9090_IN1A_TO_MIXOUTR 0x0040 /* IN1A_TO_MIXOUTR */
389#define WM9090_IN1A_TO_MIXOUTR_MASK 0x0040 /* IN1A_TO_MIXOUTR */
390#define WM9090_IN1A_TO_MIXOUTR_SHIFT 6 /* IN1A_TO_MIXOUTR */
391#define WM9090_IN1A_TO_MIXOUTR_WIDTH 1 /* IN1A_TO_MIXOUTR */
392#define WM9090_IN1B_TO_MIXOUTR 0x0010 /* IN1B_TO_MIXOUTR */
393#define WM9090_IN1B_TO_MIXOUTR_MASK 0x0010 /* IN1B_TO_MIXOUTR */
394#define WM9090_IN1B_TO_MIXOUTR_SHIFT 4 /* IN1B_TO_MIXOUTR */
395#define WM9090_IN1B_TO_MIXOUTR_WIDTH 1 /* IN1B_TO_MIXOUTR */
396#define WM9090_IN2A_TO_MIXOUTR 0x0004 /* IN2A_TO_MIXOUTR */
397#define WM9090_IN2A_TO_MIXOUTR_MASK 0x0004 /* IN2A_TO_MIXOUTR */
398#define WM9090_IN2A_TO_MIXOUTR_SHIFT 2 /* IN2A_TO_MIXOUTR */
399#define WM9090_IN2A_TO_MIXOUTR_WIDTH 1 /* IN2A_TO_MIXOUTR */
400#define WM9090_IN2B_TO_MIXOUTR 0x0001 /* IN2B_TO_MIXOUTR */
401#define WM9090_IN2B_TO_MIXOUTR_MASK 0x0001 /* IN2B_TO_MIXOUTR */
402#define WM9090_IN2B_TO_MIXOUTR_SHIFT 0 /* IN2B_TO_MIXOUTR */
403#define WM9090_IN2B_TO_MIXOUTR_WIDTH 1 /* IN2B_TO_MIXOUTR */
404
405/*
406 * R47 (0x2F) - Output Mixer3
407 */
408#define WM9090_MIXOUTL_MUTE 0x0100 /* MIXOUTL_MUTE */
409#define WM9090_MIXOUTL_MUTE_MASK 0x0100 /* MIXOUTL_MUTE */
410#define WM9090_MIXOUTL_MUTE_SHIFT 8 /* MIXOUTL_MUTE */
411#define WM9090_MIXOUTL_MUTE_WIDTH 1 /* MIXOUTL_MUTE */
412#define WM9090_IN1A_MIXOUTL_VOL_MASK 0x00C0 /* IN1A_MIXOUTL_VOL - [7:6] */
413#define WM9090_IN1A_MIXOUTL_VOL_SHIFT 6 /* IN1A_MIXOUTL_VOL - [7:6] */
414#define WM9090_IN1A_MIXOUTL_VOL_WIDTH 2 /* IN1A_MIXOUTL_VOL - [7:6] */
415#define WM9090_IN2A_MIXOUTL_VOL_MASK 0x000C /* IN2A_MIXOUTL_VOL - [3:2] */
416#define WM9090_IN2A_MIXOUTL_VOL_SHIFT 2 /* IN2A_MIXOUTL_VOL - [3:2] */
417#define WM9090_IN2A_MIXOUTL_VOL_WIDTH 2 /* IN2A_MIXOUTL_VOL - [3:2] */
418
419/*
420 * R48 (0x30) - Output Mixer4
421 */
422#define WM9090_MIXOUTR_MUTE 0x0100 /* MIXOUTR_MUTE */
423#define WM9090_MIXOUTR_MUTE_MASK 0x0100 /* MIXOUTR_MUTE */
424#define WM9090_MIXOUTR_MUTE_SHIFT 8 /* MIXOUTR_MUTE */
425#define WM9090_MIXOUTR_MUTE_WIDTH 1 /* MIXOUTR_MUTE */
426#define WM9090_IN1A_MIXOUTR_VOL_MASK 0x00C0 /* IN1A_MIXOUTR_VOL - [7:6] */
427#define WM9090_IN1A_MIXOUTR_VOL_SHIFT 6 /* IN1A_MIXOUTR_VOL - [7:6] */
428#define WM9090_IN1A_MIXOUTR_VOL_WIDTH 2 /* IN1A_MIXOUTR_VOL - [7:6] */
429#define WM9090_IN1B_MIXOUTR_VOL_MASK 0x0030 /* IN1B_MIXOUTR_VOL - [5:4] */
430#define WM9090_IN1B_MIXOUTR_VOL_SHIFT 4 /* IN1B_MIXOUTR_VOL - [5:4] */
431#define WM9090_IN1B_MIXOUTR_VOL_WIDTH 2 /* IN1B_MIXOUTR_VOL - [5:4] */
432#define WM9090_IN2A_MIXOUTR_VOL_MASK 0x000C /* IN2A_MIXOUTR_VOL - [3:2] */
433#define WM9090_IN2A_MIXOUTR_VOL_SHIFT 2 /* IN2A_MIXOUTR_VOL - [3:2] */
434#define WM9090_IN2A_MIXOUTR_VOL_WIDTH 2 /* IN2A_MIXOUTR_VOL - [3:2] */
435#define WM9090_IN2B_MIXOUTR_VOL_MASK 0x0003 /* IN2B_MIXOUTR_VOL - [1:0] */
436#define WM9090_IN2B_MIXOUTR_VOL_SHIFT 0 /* IN2B_MIXOUTR_VOL - [1:0] */
437#define WM9090_IN2B_MIXOUTR_VOL_WIDTH 2 /* IN2B_MIXOUTR_VOL - [1:0] */
438
439/*
440 * R54 (0x36) - Speaker Mixer
441 */
442#define WM9090_IN1A_TO_SPKMIX 0x0040 /* IN1A_TO_SPKMIX */
443#define WM9090_IN1A_TO_SPKMIX_MASK 0x0040 /* IN1A_TO_SPKMIX */
444#define WM9090_IN1A_TO_SPKMIX_SHIFT 6 /* IN1A_TO_SPKMIX */
445#define WM9090_IN1A_TO_SPKMIX_WIDTH 1 /* IN1A_TO_SPKMIX */
446#define WM9090_IN1B_TO_SPKMIX 0x0010 /* IN1B_TO_SPKMIX */
447#define WM9090_IN1B_TO_SPKMIX_MASK 0x0010 /* IN1B_TO_SPKMIX */
448#define WM9090_IN1B_TO_SPKMIX_SHIFT 4 /* IN1B_TO_SPKMIX */
449#define WM9090_IN1B_TO_SPKMIX_WIDTH 1 /* IN1B_TO_SPKMIX */
450#define WM9090_IN2A_TO_SPKMIX 0x0004 /* IN2A_TO_SPKMIX */
451#define WM9090_IN2A_TO_SPKMIX_MASK 0x0004 /* IN2A_TO_SPKMIX */
452#define WM9090_IN2A_TO_SPKMIX_SHIFT 2 /* IN2A_TO_SPKMIX */
453#define WM9090_IN2A_TO_SPKMIX_WIDTH 1 /* IN2A_TO_SPKMIX */
454#define WM9090_IN2B_TO_SPKMIX 0x0001 /* IN2B_TO_SPKMIX */
455#define WM9090_IN2B_TO_SPKMIX_MASK 0x0001 /* IN2B_TO_SPKMIX */
456#define WM9090_IN2B_TO_SPKMIX_SHIFT 0 /* IN2B_TO_SPKMIX */
457#define WM9090_IN2B_TO_SPKMIX_WIDTH 1 /* IN2B_TO_SPKMIX */
458
459/*
460 * R57 (0x39) - AntiPOP2
461 */
462#define WM9090_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */
463#define WM9090_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */
464#define WM9090_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */
465#define WM9090_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
466#define WM9090_VMID_ENA 0x0001 /* VMID_ENA */
467#define WM9090_VMID_ENA_MASK 0x0001 /* VMID_ENA */
468#define WM9090_VMID_ENA_SHIFT 0 /* VMID_ENA */
469#define WM9090_VMID_ENA_WIDTH 1 /* VMID_ENA */
470
471/*
472 * R70 (0x46) - Write Sequencer 0
473 */
474#define WM9090_WSEQ_ENA 0x0100 /* WSEQ_ENA */
475#define WM9090_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
476#define WM9090_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
477#define WM9090_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
478#define WM9090_WSEQ_WRITE_INDEX_MASK 0x000F /* WSEQ_WRITE_INDEX - [3:0] */
479#define WM9090_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [3:0] */
480#define WM9090_WSEQ_WRITE_INDEX_WIDTH 4 /* WSEQ_WRITE_INDEX - [3:0] */
481
482/*
483 * R71 (0x47) - Write Sequencer 1
484 */
485#define WM9090_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
486#define WM9090_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
487#define WM9090_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
488#define WM9090_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
489#define WM9090_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
490#define WM9090_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
491#define WM9090_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
492#define WM9090_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
493#define WM9090_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
494
495/*
496 * R72 (0x48) - Write Sequencer 2
497 */
498#define WM9090_WSEQ_EOS 0x4000 /* WSEQ_EOS */
499#define WM9090_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
500#define WM9090_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
501#define WM9090_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
502#define WM9090_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
503#define WM9090_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
504#define WM9090_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
505#define WM9090_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
506#define WM9090_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
507#define WM9090_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
508
509/*
510 * R73 (0x49) - Write Sequencer 3
511 */
512#define WM9090_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
513#define WM9090_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
514#define WM9090_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
515#define WM9090_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
516#define WM9090_WSEQ_START 0x0100 /* WSEQ_START */
517#define WM9090_WSEQ_START_MASK 0x0100 /* WSEQ_START */
518#define WM9090_WSEQ_START_SHIFT 8 /* WSEQ_START */
519#define WM9090_WSEQ_START_WIDTH 1 /* WSEQ_START */
520#define WM9090_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
521#define WM9090_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
522#define WM9090_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
523
524/*
525 * R74 (0x4A) - Write Sequencer 4
526 */
527#define WM9090_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
528#define WM9090_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
529#define WM9090_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
530#define WM9090_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
531
532/*
533 * R75 (0x4B) - Write Sequencer 5
534 */
535#define WM9090_WSEQ_CURRENT_INDEX_MASK 0x003F /* WSEQ_CURRENT_INDEX - [5:0] */
536#define WM9090_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [5:0] */
537#define WM9090_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [5:0] */
538
539/*
540 * R76 (0x4C) - Charge Pump 1
541 */
542#define WM9090_CP_ENA 0x8000 /* CP_ENA */
543#define WM9090_CP_ENA_MASK 0x8000 /* CP_ENA */
544#define WM9090_CP_ENA_SHIFT 15 /* CP_ENA */
545#define WM9090_CP_ENA_WIDTH 1 /* CP_ENA */
546
547/*
548 * R84 (0x54) - DC Servo 0
549 */
550#define WM9090_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
551#define WM9090_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
552#define WM9090_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
553#define WM9090_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
554#define WM9090_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
555#define WM9090_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
556#define WM9090_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
557#define WM9090_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
558#define WM9090_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
559#define WM9090_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
560#define WM9090_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
561#define WM9090_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
562#define WM9090_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
563#define WM9090_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
564#define WM9090_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
565#define WM9090_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
566#define WM9090_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
567#define WM9090_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
568#define WM9090_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
569#define WM9090_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
570#define WM9090_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
571#define WM9090_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
572#define WM9090_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
573#define WM9090_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
574#define WM9090_DCS_TRIG_DAC_WR_1 0x0008 /* DCS_TRIG_DAC_WR_1 */
575#define WM9090_DCS_TRIG_DAC_WR_1_MASK 0x0008 /* DCS_TRIG_DAC_WR_1 */
576#define WM9090_DCS_TRIG_DAC_WR_1_SHIFT 3 /* DCS_TRIG_DAC_WR_1 */
577#define WM9090_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
578#define WM9090_DCS_TRIG_DAC_WR_0 0x0004 /* DCS_TRIG_DAC_WR_0 */
579#define WM9090_DCS_TRIG_DAC_WR_0_MASK 0x0004 /* DCS_TRIG_DAC_WR_0 */
580#define WM9090_DCS_TRIG_DAC_WR_0_SHIFT 2 /* DCS_TRIG_DAC_WR_0 */
581#define WM9090_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
582#define WM9090_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
583#define WM9090_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
584#define WM9090_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
585#define WM9090_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
586#define WM9090_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
587#define WM9090_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
588#define WM9090_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
589#define WM9090_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
590
591/*
592 * R85 (0x55) - DC Servo 1
593 */
594#define WM9090_DCS_SERIES_NO_01_MASK 0x0FE0 /* DCS_SERIES_NO_01 - [11:5] */
595#define WM9090_DCS_SERIES_NO_01_SHIFT 5 /* DCS_SERIES_NO_01 - [11:5] */
596#define WM9090_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [11:5] */
597#define WM9090_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
598#define WM9090_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
599#define WM9090_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
600
601/*
602 * R87 (0x57) - DC Servo 3
603 */
604#define WM9090_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
605#define WM9090_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
606#define WM9090_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
607#define WM9090_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
608#define WM9090_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
609#define WM9090_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
610
611/*
612 * R88 (0x58) - DC Servo Readback 0
613 */
614#define WM9090_DCS_CAL_COMPLETE_MASK 0x0300 /* DCS_CAL_COMPLETE - [9:8] */
615#define WM9090_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [9:8] */
616#define WM9090_DCS_CAL_COMPLETE_WIDTH 2 /* DCS_CAL_COMPLETE - [9:8] */
617#define WM9090_DCS_DAC_WR_COMPLETE_MASK 0x0030 /* DCS_DAC_WR_COMPLETE - [5:4] */
618#define WM9090_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [5:4] */
619#define WM9090_DCS_DAC_WR_COMPLETE_WIDTH 2 /* DCS_DAC_WR_COMPLETE - [5:4] */
620#define WM9090_DCS_STARTUP_COMPLETE_MASK 0x0003 /* DCS_STARTUP_COMPLETE - [1:0] */
621#define WM9090_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [1:0] */
622#define WM9090_DCS_STARTUP_COMPLETE_WIDTH 2 /* DCS_STARTUP_COMPLETE - [1:0] */
623
624/*
625 * R89 (0x59) - DC Servo Readback 1
626 */
627#define WM9090_DCS_DAC_WR_VAL_1_RD_MASK 0x00FF /* DCS_DAC_WR_VAL_1_RD - [7:0] */
628#define WM9090_DCS_DAC_WR_VAL_1_RD_SHIFT 0 /* DCS_DAC_WR_VAL_1_RD - [7:0] */
629#define WM9090_DCS_DAC_WR_VAL_1_RD_WIDTH 8 /* DCS_DAC_WR_VAL_1_RD - [7:0] */
630
631/*
632 * R90 (0x5A) - DC Servo Readback 2
633 */
634#define WM9090_DCS_DAC_WR_VAL_0_RD_MASK 0x00FF /* DCS_DAC_WR_VAL_0_RD - [7:0] */
635#define WM9090_DCS_DAC_WR_VAL_0_RD_SHIFT 0 /* DCS_DAC_WR_VAL_0_RD - [7:0] */
636#define WM9090_DCS_DAC_WR_VAL_0_RD_WIDTH 8 /* DCS_DAC_WR_VAL_0_RD - [7:0] */
637
638/*
639 * R96 (0x60) - Analogue HP 0
640 */
641#define WM9090_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
642#define WM9090_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
643#define WM9090_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
644#define WM9090_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
645#define WM9090_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
646#define WM9090_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
647#define WM9090_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
648#define WM9090_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
649#define WM9090_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
650#define WM9090_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
651#define WM9090_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
652#define WM9090_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
653#define WM9090_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
654#define WM9090_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
655#define WM9090_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
656#define WM9090_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
657#define WM9090_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
658#define WM9090_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
659#define WM9090_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
660#define WM9090_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
661#define WM9090_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
662#define WM9090_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
663#define WM9090_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
664#define WM9090_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
665
666/*
667 * R98 (0x62) - AGC Control 0
668 */
669#define WM9090_AGC_CLIP_ENA 0x8000 /* AGC_CLIP_ENA */
670#define WM9090_AGC_CLIP_ENA_MASK 0x8000 /* AGC_CLIP_ENA */
671#define WM9090_AGC_CLIP_ENA_SHIFT 15 /* AGC_CLIP_ENA */
672#define WM9090_AGC_CLIP_ENA_WIDTH 1 /* AGC_CLIP_ENA */
673#define WM9090_AGC_CLIP_THR_MASK 0x0F00 /* AGC_CLIP_THR - [11:8] */
674#define WM9090_AGC_CLIP_THR_SHIFT 8 /* AGC_CLIP_THR - [11:8] */
675#define WM9090_AGC_CLIP_THR_WIDTH 4 /* AGC_CLIP_THR - [11:8] */
676#define WM9090_AGC_CLIP_ATK_MASK 0x0070 /* AGC_CLIP_ATK - [6:4] */
677#define WM9090_AGC_CLIP_ATK_SHIFT 4 /* AGC_CLIP_ATK - [6:4] */
678#define WM9090_AGC_CLIP_ATK_WIDTH 3 /* AGC_CLIP_ATK - [6:4] */
679#define WM9090_AGC_CLIP_DCY_MASK 0x0007 /* AGC_CLIP_DCY - [2:0] */
680#define WM9090_AGC_CLIP_DCY_SHIFT 0 /* AGC_CLIP_DCY - [2:0] */
681#define WM9090_AGC_CLIP_DCY_WIDTH 3 /* AGC_CLIP_DCY - [2:0] */
682
683/*
684 * R99 (0x63) - AGC Control 1
685 */
686#define WM9090_AGC_PWR_ENA 0x8000 /* AGC_PWR_ENA */
687#define WM9090_AGC_PWR_ENA_MASK 0x8000 /* AGC_PWR_ENA */
688#define WM9090_AGC_PWR_ENA_SHIFT 15 /* AGC_PWR_ENA */
689#define WM9090_AGC_PWR_ENA_WIDTH 1 /* AGC_PWR_ENA */
690#define WM9090_AGC_PWR_AVG 0x1000 /* AGC_PWR_AVG */
691#define WM9090_AGC_PWR_AVG_MASK 0x1000 /* AGC_PWR_AVG */
692#define WM9090_AGC_PWR_AVG_SHIFT 12 /* AGC_PWR_AVG */
693#define WM9090_AGC_PWR_AVG_WIDTH 1 /* AGC_PWR_AVG */
694#define WM9090_AGC_PWR_THR_MASK 0x0F00 /* AGC_PWR_THR - [11:8] */
695#define WM9090_AGC_PWR_THR_SHIFT 8 /* AGC_PWR_THR - [11:8] */
696#define WM9090_AGC_PWR_THR_WIDTH 4 /* AGC_PWR_THR - [11:8] */
697#define WM9090_AGC_PWR_ATK_MASK 0x0070 /* AGC_PWR_ATK - [6:4] */
698#define WM9090_AGC_PWR_ATK_SHIFT 4 /* AGC_PWR_ATK - [6:4] */
699#define WM9090_AGC_PWR_ATK_WIDTH 3 /* AGC_PWR_ATK - [6:4] */
700#define WM9090_AGC_PWR_DCY_MASK 0x0007 /* AGC_PWR_DCY - [2:0] */
701#define WM9090_AGC_PWR_DCY_SHIFT 0 /* AGC_PWR_DCY - [2:0] */
702#define WM9090_AGC_PWR_DCY_WIDTH 3 /* AGC_PWR_DCY - [2:0] */
703
704/*
705 * R100 (0x64) - AGC Control 2
706 */
707#define WM9090_AGC_RAMP 0x0100 /* AGC_RAMP */
708#define WM9090_AGC_RAMP_MASK 0x0100 /* AGC_RAMP */
709#define WM9090_AGC_RAMP_SHIFT 8 /* AGC_RAMP */
710#define WM9090_AGC_RAMP_WIDTH 1 /* AGC_RAMP */
711#define WM9090_AGC_MINGAIN_MASK 0x003F /* AGC_MINGAIN - [5:0] */
712#define WM9090_AGC_MINGAIN_SHIFT 0 /* AGC_MINGAIN - [5:0] */
713#define WM9090_AGC_MINGAIN_WIDTH 6 /* AGC_MINGAIN - [5:0] */
714
715#endif
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 2f48a8aae22c..28790a2ffe8d 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -632,9 +632,6 @@ static int wm9712_soc_resume(struct platform_device *pdev)
632 } 632 }
633 } 633 }
634 634
635 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
636 wm9712_set_bias_level(codec, SND_SOC_BIAS_ON);
637
638 return ret; 635 return ret;
639} 636}
640 637
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 2fca514fde58..34e0c91092fa 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -764,7 +764,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int source)
764static int wm9713_set_pll(struct snd_soc_codec *codec, 764static int wm9713_set_pll(struct snd_soc_codec *codec,
765 int pll_id, unsigned int freq_in, unsigned int freq_out) 765 int pll_id, unsigned int freq_in, unsigned int freq_out)
766{ 766{
767 struct wm9713_priv *wm9713 = codec->private_data; 767 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
768 u16 reg, reg2; 768 u16 reg, reg2;
769 struct _pll_div pll_div; 769 struct _pll_div pll_div;
770 770
@@ -1175,7 +1175,7 @@ static int wm9713_soc_resume(struct platform_device *pdev)
1175{ 1175{
1176 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1176 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1177 struct snd_soc_codec *codec = socdev->card->codec; 1177 struct snd_soc_codec *codec = socdev->card->codec;
1178 struct wm9713_priv *wm9713 = codec->private_data; 1178 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1179 int i, ret; 1179 int i, ret;
1180 u16 *cache = codec->reg_cache; 1180 u16 *cache = codec->reg_cache;
1181 1181
@@ -1201,9 +1201,6 @@ static int wm9713_soc_resume(struct platform_device *pdev)
1201 } 1201 }
1202 } 1202 }
1203 1203
1204 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
1205 wm9713_set_bias_level(codec, SND_SOC_BIAS_ON);
1206
1207 return ret; 1204 return ret;
1208} 1205}
1209 1206
@@ -1228,8 +1225,9 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1228 codec->reg_cache_size = sizeof(wm9713_reg); 1225 codec->reg_cache_size = sizeof(wm9713_reg);
1229 codec->reg_cache_step = 2; 1226 codec->reg_cache_step = 2;
1230 1227
1231 codec->private_data = kzalloc(sizeof(struct wm9713_priv), GFP_KERNEL); 1228 snd_soc_codec_set_drvdata(codec, kzalloc(sizeof(struct wm9713_priv),
1232 if (codec->private_data == NULL) { 1229 GFP_KERNEL));
1230 if (snd_soc_codec_get_drvdata(codec) == NULL) {
1233 ret = -ENOMEM; 1231 ret = -ENOMEM;
1234 goto priv_err; 1232 goto priv_err;
1235 } 1233 }
@@ -1280,7 +1278,7 @@ pcm_err:
1280 snd_soc_free_ac97_codec(codec); 1278 snd_soc_free_ac97_codec(codec);
1281 1279
1282codec_err: 1280codec_err:
1283 kfree(codec->private_data); 1281 kfree(snd_soc_codec_get_drvdata(codec));
1284 1282
1285priv_err: 1283priv_err:
1286 kfree(codec->reg_cache); 1284 kfree(codec->reg_cache);
@@ -1302,7 +1300,7 @@ static int wm9713_soc_remove(struct platform_device *pdev)
1302 snd_soc_dapm_free(socdev); 1300 snd_soc_dapm_free(socdev);
1303 snd_soc_free_pcms(socdev); 1301 snd_soc_free_pcms(socdev);
1304 snd_soc_free_ac97_codec(codec); 1302 snd_soc_free_ac97_codec(codec);
1305 kfree(codec->private_data); 1303 kfree(snd_soc_codec_get_drvdata(codec));
1306 kfree(codec->reg_cache); 1304 kfree(codec->reg_cache);
1307 kfree(codec); 1305 kfree(codec);
1308 return 0; 1306 return 0;
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index e1f225a3ac46..16f1a57da08a 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -91,7 +91,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
91 */ 91 */
92static void calibrate_dc_servo(struct snd_soc_codec *codec) 92static void calibrate_dc_servo(struct snd_soc_codec *codec)
93{ 93{
94 struct wm_hubs_data *hubs = codec->private_data; 94 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
95 u16 reg, reg_l, reg_r, dcs_cfg; 95 u16 reg, reg_l, reg_r, dcs_cfg;
96 96
97 /* Set for 32 series updates */ 97 /* Set for 32 series updates */
@@ -127,6 +127,8 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
127 break; 127 break;
128 } 128 }
129 129
130 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
131
130 /* HPOUT1L */ 132 /* HPOUT1L */
131 if (reg_l + hubs->dcs_codes > 0 && 133 if (reg_l + hubs->dcs_codes > 0 &&
132 reg_l + hubs->dcs_codes < 0xff) 134 reg_l + hubs->dcs_codes < 0xff)
@@ -139,6 +141,8 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
139 reg_r += hubs->dcs_codes; 141 reg_r += hubs->dcs_codes;
140 dcs_cfg |= reg_r; 142 dcs_cfg |= reg_r;
141 143
144 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
145
142 /* Do it */ 146 /* Do it */
143 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); 147 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
144 wait_for_dc_servo(codec, 148 wait_for_dc_servo(codec,
@@ -154,7 +158,7 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
154 struct snd_ctl_elem_value *ucontrol) 158 struct snd_ctl_elem_value *ucontrol)
155{ 159{
156 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 160 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
157 struct wm_hubs_data *hubs = codec->private_data; 161 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
158 int ret; 162 int ret;
159 163
160 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 164 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
@@ -327,7 +331,7 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w,
327 struct snd_kcontrol *kcontrol, int event) 331 struct snd_kcontrol *kcontrol, int event)
328{ 332{
329 struct snd_soc_codec *codec = w->codec; 333 struct snd_soc_codec *codec = w->codec;
330 struct wm_hubs_data *hubs = codec->private_data; 334 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
331 335
332 switch (event) { 336 switch (event) {
333 case SND_SOC_DAPM_PRE_PMU: 337 case SND_SOC_DAPM_PRE_PMU:
@@ -397,14 +401,14 @@ static int hp_event(struct snd_soc_dapm_widget *w,
397 401
398 case SND_SOC_DAPM_PRE_PMD: 402 case SND_SOC_DAPM_PRE_PMD:
399 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0, 403 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
400 WM8993_HPOUT1L_DLY | 404 WM8993_HPOUT1L_OUTP |
401 WM8993_HPOUT1R_DLY | 405 WM8993_HPOUT1R_OUTP |
402 WM8993_HPOUT1L_RMV_SHORT | 406 WM8993_HPOUT1L_RMV_SHORT |
403 WM8993_HPOUT1R_RMV_SHORT, 0); 407 WM8993_HPOUT1R_RMV_SHORT, 0);
404 408
405 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0, 409 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
406 WM8993_HPOUT1L_OUTP | 410 WM8993_HPOUT1L_DLY |
407 WM8993_HPOUT1R_OUTP, 0); 411 WM8993_HPOUT1R_DLY, 0);
408 412
409 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 413 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
410 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA, 414 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 047ee39418c0..6bbf001f6591 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -12,15 +12,38 @@ config SND_DAVINCI_SOC_I2S
12config SND_DAVINCI_SOC_MCASP 12config SND_DAVINCI_SOC_MCASP
13 tristate 13 tristate
14 14
15config SND_DAVINCI_SOC_VCIF
16 tristate
17
15config SND_DAVINCI_SOC_EVM 18config SND_DAVINCI_SOC_EVM
16 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" 19 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
17 depends on SND_DAVINCI_SOC 20 depends on SND_DAVINCI_SOC
18 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM 21 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM
19 select SND_DAVINCI_SOC_I2S 22 select SND_DAVINCI_SOC_I2S
20 select SND_SOC_TLV320AIC3X 23 select SND_SOC_TLV320AIC3X
21 help 24 help
22 Say Y if you want to add support for SoC audio on TI 25 Say Y if you want to add support for SoC audio on TI
23 DaVinci DM6446 or DM355 EVM platforms. 26 DaVinci DM6446, DM355 or DM365 EVM platforms.
27
28choice
29 prompt "DM365 codec select"
30 depends on SND_DAVINCI_SOC_EVM
31 depends on MACH_DAVINCI_DM365_EVM
32 default SND_DM365_EXTERNAL_CODEC
33
34config SND_DM365_AIC3X_CODEC
35 bool "Audio Codec - AIC3101"
36 help
37 Say Y if you want to add support for AIC3101 audio codec
38
39config SND_DM365_VOICE_CODEC
40 bool "Voice Codec - CQ93VC"
41 select MFD_DAVINCI_VOICECODEC
42 select SND_DAVINCI_SOC_VCIF
43 select SND_SOC_CQ0093VC
44 help
45 Say Y if you want to add support for SoC On-chip voice codec
46endchoice
24 47
25config SND_DM6467_SOC_EVM 48config SND_DM6467_SOC_EVM
26 tristate "SoC Audio support for DaVinci DM6467 EVM" 49 tristate "SoC Audio support for DaVinci DM6467 EVM"
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index a6939d71b988..a93679d618cd 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -2,10 +2,12 @@
2snd-soc-davinci-objs := davinci-pcm.o 2snd-soc-davinci-objs := davinci-pcm.o
3snd-soc-davinci-i2s-objs := davinci-i2s.o 3snd-soc-davinci-i2s-objs := davinci-i2s.o
4snd-soc-davinci-mcasp-objs:= davinci-mcasp.o 4snd-soc-davinci-mcasp-objs:= davinci-mcasp.o
5snd-soc-davinci-vcif-objs:= davinci-vcif.o
5 6
6obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o 7obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o
7obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o 8obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
8obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o 9obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o
10obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
9 11
10# DAVINCI Machine Support 12# DAVINCI Machine Support
11snd-soc-evm-objs := davinci-evm.o 13snd-soc-evm-objs := davinci-evm.o
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 7ccbe6684fc2..97f74d6a33e6 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -28,10 +28,12 @@
28#include <mach/mux.h> 28#include <mach/mux.h>
29 29
30#include "../codecs/tlv320aic3x.h" 30#include "../codecs/tlv320aic3x.h"
31#include "../codecs/cq93vc.h"
31#include "../codecs/spdif_transciever.h" 32#include "../codecs/spdif_transciever.h"
32#include "davinci-pcm.h" 33#include "davinci-pcm.h"
33#include "davinci-i2s.h" 34#include "davinci-i2s.h"
34#include "davinci-mcasp.h" 35#include "davinci-mcasp.h"
36#include "davinci-vcif.h"
35 37
36#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ 38#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
37 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF) 39 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
@@ -81,10 +83,24 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
81 return 0; 83 return 0;
82} 84}
83 85
86static int evm_spdif_hw_params(struct snd_pcm_substream *substream,
87 struct snd_pcm_hw_params *params)
88{
89 struct snd_soc_pcm_runtime *rtd = substream->private_data;
90 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
91
92 /* set cpu DAI configuration */
93 return snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
94}
95
84static struct snd_soc_ops evm_ops = { 96static struct snd_soc_ops evm_ops = {
85 .hw_params = evm_hw_params, 97 .hw_params = evm_hw_params,
86}; 98};
87 99
100static struct snd_soc_ops evm_spdif_ops = {
101 .hw_params = evm_spdif_hw_params,
102};
103
88/* davinci-evm machine dapm widgets */ 104/* davinci-evm machine dapm widgets */
89static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { 105static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
90 SND_SOC_DAPM_HP("Headphone Jack", NULL), 106 SND_SOC_DAPM_HP("Headphone Jack", NULL),
@@ -151,6 +167,22 @@ static struct snd_soc_dai_link evm_dai = {
151 .ops = &evm_ops, 167 .ops = &evm_ops,
152}; 168};
153 169
170static struct snd_soc_dai_link dm365_evm_dai = {
171#ifdef CONFIG_SND_DM365_AIC3X_CODEC
172 .name = "TLV320AIC3X",
173 .stream_name = "AIC3X",
174 .cpu_dai = &davinci_i2s_dai,
175 .codec_dai = &aic3x_dai,
176 .init = evm_aic3x_init,
177 .ops = &evm_ops,
178#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
179 .name = "Voice Codec - CQ93VC",
180 .stream_name = "CQ93",
181 .cpu_dai = &davinci_vcif_dai,
182 .codec_dai = &cq93vc_dai,
183#endif
184};
185
154static struct snd_soc_dai_link dm6467_evm_dai[] = { 186static struct snd_soc_dai_link dm6467_evm_dai[] = {
155 { 187 {
156 .name = "TLV320AIC3X", 188 .name = "TLV320AIC3X",
@@ -165,7 +197,7 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = {
165 .stream_name = "spdif", 197 .stream_name = "spdif",
166 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_DIT_DAI], 198 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_DIT_DAI],
167 .codec_dai = &dit_stub_dai, 199 .codec_dai = &dit_stub_dai,
168 .ops = &evm_ops, 200 .ops = &evm_spdif_ops,
169 }, 201 },
170}; 202};
171static struct snd_soc_dai_link da8xx_evm_dai = { 203static struct snd_soc_dai_link da8xx_evm_dai = {
@@ -177,7 +209,7 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
177 .ops = &evm_ops, 209 .ops = &evm_ops,
178}; 210};
179 211
180/* davinci dm6446, dm355 or dm365 evm audio machine driver */ 212/* davinci dm6446, dm355 evm audio machine driver */
181static struct snd_soc_card snd_soc_card_evm = { 213static struct snd_soc_card snd_soc_card_evm = {
182 .name = "DaVinci EVM", 214 .name = "DaVinci EVM",
183 .platform = &davinci_soc_platform, 215 .platform = &davinci_soc_platform,
@@ -185,6 +217,15 @@ static struct snd_soc_card snd_soc_card_evm = {
185 .num_links = 1, 217 .num_links = 1,
186}; 218};
187 219
220/* davinci dm365 evm audio machine driver */
221static struct snd_soc_card dm365_snd_soc_card_evm = {
222 .name = "DaVinci DM365 EVM",
223 .platform = &davinci_soc_platform,
224 .dai_link = &dm365_evm_dai,
225 .num_links = 1,
226};
227
228
188/* davinci dm6467 evm audio machine driver */ 229/* davinci dm6467 evm audio machine driver */
189static struct snd_soc_card dm6467_snd_soc_card_evm = { 230static struct snd_soc_card dm6467_snd_soc_card_evm = {
190 .name = "DaVinci DM6467 EVM", 231 .name = "DaVinci DM6467 EVM",
@@ -217,6 +258,17 @@ static struct snd_soc_device evm_snd_devdata = {
217}; 258};
218 259
219/* evm audio subsystem */ 260/* evm audio subsystem */
261static struct snd_soc_device dm365_evm_snd_devdata = {
262 .card = &dm365_snd_soc_card_evm,
263#ifdef CONFIG_SND_DM365_AIC3X_CODEC
264 .codec_dev = &soc_codec_dev_aic3x,
265 .codec_data = &aic3x_setup,
266#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
267 .codec_dev = &soc_codec_dev_cq93vc,
268#endif
269};
270
271/* evm audio subsystem */
220static struct snd_soc_device dm6467_evm_snd_devdata = { 272static struct snd_soc_device dm6467_evm_snd_devdata = {
221 .card = &dm6467_snd_soc_card_evm, 273 .card = &dm6467_snd_soc_card_evm,
222 .codec_dev = &soc_codec_dev_aic3x, 274 .codec_dev = &soc_codec_dev_aic3x,
@@ -244,12 +296,15 @@ static int __init evm_init(void)
244 int index; 296 int index;
245 int ret; 297 int ret;
246 298
247 if (machine_is_davinci_evm() || machine_is_davinci_dm365_evm()) { 299 if (machine_is_davinci_evm()) {
248 evm_snd_dev_data = &evm_snd_devdata; 300 evm_snd_dev_data = &evm_snd_devdata;
249 index = 0; 301 index = 0;
250 } else if (machine_is_davinci_dm355_evm()) { 302 } else if (machine_is_davinci_dm355_evm()) {
251 evm_snd_dev_data = &evm_snd_devdata; 303 evm_snd_dev_data = &evm_snd_devdata;
252 index = 1; 304 index = 1;
305 } else if (machine_is_davinci_dm365_evm()) {
306 evm_snd_dev_data = &dm365_evm_snd_devdata;
307 index = 0;
253 } else if (machine_is_davinci_dm6467_evm()) { 308 } else if (machine_is_davinci_dm6467_evm()) {
254 evm_snd_dev_data = &dm6467_evm_snd_devdata; 309 evm_snd_dev_data = &dm6467_evm_snd_devdata;
255 index = 0; 310 index = 0;
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
new file mode 100644
index 000000000000..9aa980d38231
--- /dev/null
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -0,0 +1,274 @@
1/*
2 * ALSA SoC Voice Codec Interface for TI DAVINCI processor
3 *
4 * Copyright (C) 2010 Texas Instruments.
5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/device.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <linux/io.h>
29#include <linux/mfd/davinci_voicecodec.h>
30
31#include <sound/core.h>
32#include <sound/pcm.h>
33#include <sound/pcm_params.h>
34#include <sound/initval.h>
35#include <sound/soc.h>
36
37#include "davinci-pcm.h"
38#include "davinci-i2s.h"
39#include "davinci-vcif.h"
40
41#define MOD_REG_BIT(val, mask, set) do { \
42 if (set) { \
43 val |= mask; \
44 } else { \
45 val &= ~mask; \
46 } \
47} while (0)
48
49struct davinci_vcif_dev {
50 struct davinci_vc *davinci_vc;
51 struct davinci_pcm_dma_params dma_params[2];
52};
53
54static void davinci_vcif_start(struct snd_pcm_substream *substream)
55{
56 struct snd_soc_pcm_runtime *rtd = substream->private_data;
57 struct davinci_vcif_dev *davinci_vcif_dev =
58 rtd->dai->cpu_dai->private_data;
59 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
60 u32 w;
61
62 /* Start the sample generator and enable transmitter/receiver */
63 w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
64
65 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
66 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1);
67 else
68 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1);
69
70 writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
71}
72
73static void davinci_vcif_stop(struct snd_pcm_substream *substream)
74{
75 struct snd_soc_pcm_runtime *rtd = substream->private_data;
76 struct davinci_vcif_dev *davinci_vcif_dev =
77 rtd->dai->cpu_dai->private_data;
78 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
79 u32 w;
80
81 /* Reset transmitter/receiver and sample rate/frame sync generators */
82 w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
83 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
84 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0);
85 else
86 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0);
87
88 writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
89}
90
91static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
92 struct snd_pcm_hw_params *params,
93 struct snd_soc_dai *dai)
94{
95 struct davinci_vcif_dev *davinci_vcif_dev = dai->private_data;
96 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
97 struct davinci_pcm_dma_params *dma_params =
98 &davinci_vcif_dev->dma_params[substream->stream];
99 u32 w;
100
101 /* Restart the codec before setup */
102 davinci_vcif_stop(substream);
103 davinci_vcif_start(substream);
104
105 /* General line settings */
106 writel(DAVINCI_VC_CTRL_MASK, davinci_vc->base + DAVINCI_VC_CTRL);
107
108 writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTCLR);
109
110 writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTEN);
111
112 w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
113
114 /* Determine xfer data type */
115 switch (params_format(params)) {
116 case SNDRV_PCM_FORMAT_U8:
117 dma_params->data_type = 0;
118
119 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
120 DAVINCI_VC_CTRL_RD_UNSIGNED |
121 DAVINCI_VC_CTRL_WD_BITS_8 |
122 DAVINCI_VC_CTRL_WD_UNSIGNED, 1);
123 break;
124 case SNDRV_PCM_FORMAT_S8:
125 dma_params->data_type = 1;
126
127 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
128 DAVINCI_VC_CTRL_WD_BITS_8, 1);
129
130 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_UNSIGNED |
131 DAVINCI_VC_CTRL_WD_UNSIGNED, 0);
132 break;
133 case SNDRV_PCM_FORMAT_S16_LE:
134 dma_params->data_type = 2;
135
136 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
137 DAVINCI_VC_CTRL_RD_UNSIGNED |
138 DAVINCI_VC_CTRL_WD_BITS_8 |
139 DAVINCI_VC_CTRL_WD_UNSIGNED, 0);
140 break;
141 default:
142 printk(KERN_WARNING "davinci-vcif: unsupported PCM format");
143 return -EINVAL;
144 }
145
146 dma_params->acnt = dma_params->data_type;
147
148 writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
149
150 return 0;
151}
152
153static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
154 struct snd_soc_dai *dai)
155{
156 int ret = 0;
157
158 switch (cmd) {
159 case SNDRV_PCM_TRIGGER_START:
160 case SNDRV_PCM_TRIGGER_RESUME:
161 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
162 davinci_vcif_start(substream);
163 case SNDRV_PCM_TRIGGER_STOP:
164 case SNDRV_PCM_TRIGGER_SUSPEND:
165 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
166 davinci_vcif_stop(substream);
167 break;
168 default:
169 ret = -EINVAL;
170 }
171
172 return ret;
173}
174
175#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000
176
177static struct snd_soc_dai_ops davinci_vcif_dai_ops = {
178 .trigger = davinci_vcif_trigger,
179 .hw_params = davinci_vcif_hw_params,
180};
181
182struct snd_soc_dai davinci_vcif_dai = {
183 .name = "davinci-vcif",
184 .playback = {
185 .channels_min = 1,
186 .channels_max = 2,
187 .rates = DAVINCI_VCIF_RATES,
188 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
189 .capture = {
190 .channels_min = 1,
191 .channels_max = 2,
192 .rates = DAVINCI_VCIF_RATES,
193 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
194 .ops = &davinci_vcif_dai_ops,
195
196};
197EXPORT_SYMBOL_GPL(davinci_vcif_dai);
198
199static int davinci_vcif_probe(struct platform_device *pdev)
200{
201 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
202 struct davinci_vcif_dev *davinci_vcif_dev;
203 int ret;
204
205 davinci_vcif_dev = kzalloc(sizeof(struct davinci_vcif_dev), GFP_KERNEL);
206 if (!davinci_vc) {
207 dev_dbg(&pdev->dev,
208 "could not allocate memory for private data\n");
209 return -ENOMEM;
210 }
211
212 /* DMA tx params */
213 davinci_vcif_dev->davinci_vc = davinci_vc;
214 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel =
215 davinci_vc->davinci_vcif.dma_tx_channel;
216 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
217 davinci_vc->davinci_vcif.dma_tx_addr;
218
219 /* DMA rx params */
220 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel =
221 davinci_vc->davinci_vcif.dma_rx_channel;
222 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
223 davinci_vc->davinci_vcif.dma_rx_addr;
224
225 davinci_vcif_dai.dev = &pdev->dev;
226 davinci_vcif_dai.capture.dma_data = davinci_vcif_dev->dma_params;
227 davinci_vcif_dai.playback.dma_data = davinci_vcif_dev->dma_params;
228 davinci_vcif_dai.private_data = davinci_vcif_dev;
229
230 ret = snd_soc_register_dai(&davinci_vcif_dai);
231 if (ret != 0) {
232 dev_err(&pdev->dev, "could not register dai\n");
233 goto fail;
234 }
235
236 return 0;
237
238fail:
239 kfree(davinci_vcif_dev);
240
241 return ret;
242}
243
244static int davinci_vcif_remove(struct platform_device *pdev)
245{
246 snd_soc_unregister_dai(&davinci_vcif_dai);
247
248 return 0;
249}
250
251static struct platform_driver davinci_vcif_driver = {
252 .probe = davinci_vcif_probe,
253 .remove = davinci_vcif_remove,
254 .driver = {
255 .name = "davinci_vcif",
256 .owner = THIS_MODULE,
257 },
258};
259
260static int __init davinci_vcif_init(void)
261{
262 return platform_driver_probe(&davinci_vcif_driver, davinci_vcif_probe);
263}
264module_init(davinci_vcif_init);
265
266static void __exit davinci_vcif_exit(void)
267{
268 platform_driver_unregister(&davinci_vcif_driver);
269}
270module_exit(davinci_vcif_exit);
271
272MODULE_AUTHOR("Miguel Aguilar");
273MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC Voice Codec Interface");
274MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/davinci-vcif.h b/sound/soc/davinci/davinci-vcif.h
new file mode 100644
index 000000000000..571c9948724f
--- /dev/null
+++ b/sound/soc/davinci/davinci-vcif.h
@@ -0,0 +1,28 @@
1/*
2 * ALSA SoC Voice Codec Interface for TI DAVINCI processor
3 *
4 * Copyright (C) 2010 Texas Instruments.
5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef _DAVINCI_VCIF_H
24#define _DAVINCI_VCIF_H
25
26extern struct snd_soc_dai davinci_vcif_dai;
27
28#endif
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 7174b4c710de..eba9b9d257a1 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -11,3 +11,11 @@ config SND_IMX_SOC
11config SND_MXC_SOC_SSI 11config SND_MXC_SOC_SSI
12 tristate 12 tristate
13 13
14config SND_MXC_SOC_WM1133_EV1
15 tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted"
16 depends on SND_IMX_SOC && EXPERIMENTAL
17 select SND_SOC_WM8350
18 select SND_MXC_SOC_SSI
19 help
20 Enable support for audio on the i.MX31ADS with the WM1133-EV1
21 PMIC board with WM8835x fitted.
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index 9f8bb92ddfcc..2d203635ac11 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -9,4 +9,7 @@ obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o
9 9
10# i.MX Machine Support 10# i.MX Machine Support
11snd-soc-phycore-ac97-objs := phycore-ac97.o 11snd-soc-phycore-ac97-objs := phycore-ac97.o
12snd-soc-wm1133-ev1-objs := wm1133-ev1.o
13
12obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o 14obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
15obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c
new file mode 100644
index 000000000000..a6e7d9497639
--- /dev/null
+++ b/sound/soc/imx/wm1133-ev1.c
@@ -0,0 +1,308 @@
1/*
2 * wm1133-ev1.c - Audio for WM1133-EV1 on i.MX31ADS
3 *
4 * Copyright (c) 2010 Wolfson Microelectronics plc
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * Based on an earlier driver for the same hardware by Liam Girdwood.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/platform_device.h>
16#include <linux/clk.h>
17#include <sound/core.h>
18#include <sound/jack.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23
24#include <mach/audmux.h>
25
26#include "imx-ssi.h"
27#include "../codecs/wm8350.h"
28
29/* There is a silicon mic on the board optionally connected via a solder pad
30 * SP1. Define this to enable it.
31 */
32#undef USE_SIMIC
33
34struct _wm8350_audio {
35 unsigned int channels;
36 snd_pcm_format_t format;
37 unsigned int rate;
38 unsigned int sysclk;
39 unsigned int bclkdiv;
40 unsigned int clkdiv;
41 unsigned int lr_rate;
42};
43
44/* in order of power consumption per rate (lowest first) */
45static const struct _wm8350_audio wm8350_audio[] = {
46 /* 16bit mono modes */
47 {1, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000 >> 1,
48 WM8350_BCLK_DIV_48, WM8350_DACDIV_3, 16,},
49
50 /* 16 bit stereo modes */
51 {2, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000,
52 WM8350_BCLK_DIV_48, WM8350_DACDIV_6, 32,},
53 {2, SNDRV_PCM_FORMAT_S16_LE, 16000, 12288000,
54 WM8350_BCLK_DIV_24, WM8350_DACDIV_3, 32,},
55 {2, SNDRV_PCM_FORMAT_S16_LE, 32000, 12288000,
56 WM8350_BCLK_DIV_12, WM8350_DACDIV_1_5, 32,},
57 {2, SNDRV_PCM_FORMAT_S16_LE, 48000, 12288000,
58 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
59 {2, SNDRV_PCM_FORMAT_S16_LE, 96000, 24576000,
60 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
61 {2, SNDRV_PCM_FORMAT_S16_LE, 11025, 11289600,
62 WM8350_BCLK_DIV_32, WM8350_DACDIV_4, 32,},
63 {2, SNDRV_PCM_FORMAT_S16_LE, 22050, 11289600,
64 WM8350_BCLK_DIV_16, WM8350_DACDIV_2, 32,},
65 {2, SNDRV_PCM_FORMAT_S16_LE, 44100, 11289600,
66 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
67 {2, SNDRV_PCM_FORMAT_S16_LE, 88200, 22579200,
68 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
69
70 /* 24bit stereo modes */
71 {2, SNDRV_PCM_FORMAT_S24_LE, 48000, 12288000,
72 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
73 {2, SNDRV_PCM_FORMAT_S24_LE, 96000, 24576000,
74 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
75 {2, SNDRV_PCM_FORMAT_S24_LE, 44100, 11289600,
76 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
77 {2, SNDRV_PCM_FORMAT_S24_LE, 88200, 22579200,
78 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
79};
80
81static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream,
82 struct snd_pcm_hw_params *params)
83{
84 struct snd_soc_pcm_runtime *rtd = substream->private_data;
85 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
86 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
87 int i, found = 0;
88 snd_pcm_format_t format = params_format(params);
89 unsigned int rate = params_rate(params);
90 unsigned int channels = params_channels(params);
91 u32 dai_format;
92
93 /* find the correct audio parameters */
94 for (i = 0; i < ARRAY_SIZE(wm8350_audio); i++) {
95 if (rate == wm8350_audio[i].rate &&
96 format == wm8350_audio[i].format &&
97 channels == wm8350_audio[i].channels) {
98 found = 1;
99 break;
100 }
101 }
102 if (!found)
103 return -EINVAL;
104
105 /* codec FLL input is 14.75 MHz from MCLK */
106 snd_soc_dai_set_pll(codec_dai, 0, 0, 14750000, wm8350_audio[i].sysclk);
107
108 dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
109 SND_SOC_DAIFMT_CBM_CFM;
110
111 /* set codec DAI configuration */
112 snd_soc_dai_set_fmt(codec_dai, dai_format);
113
114 /* set cpu DAI configuration */
115 snd_soc_dai_set_fmt(cpu_dai, dai_format);
116
117 /* TODO: The SSI driver should figure this out for us */
118 switch (channels) {
119 case 2:
120 snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
121 break;
122 case 1:
123 snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffe, 0xffffffe, 1, 0);
124 break;
125 default:
126 return -EINVAL;
127 }
128
129 /* set MCLK as the codec system clock for DAC and ADC */
130 snd_soc_dai_set_sysclk(codec_dai, WM8350_MCLK_SEL_PLL_MCLK,
131 wm8350_audio[i].sysclk, SND_SOC_CLOCK_IN);
132
133 /* set codec BCLK division for sample rate */
134 snd_soc_dai_set_clkdiv(codec_dai, WM8350_BCLK_CLKDIV,
135 wm8350_audio[i].bclkdiv);
136
137 /* DAI is synchronous and clocked with DAC LRCLK & ADC LRC */
138 snd_soc_dai_set_clkdiv(codec_dai,
139 WM8350_DACLR_CLKDIV, wm8350_audio[i].lr_rate);
140 snd_soc_dai_set_clkdiv(codec_dai,
141 WM8350_ADCLR_CLKDIV, wm8350_audio[i].lr_rate);
142
143 /* now configure DAC and ADC clocks */
144 snd_soc_dai_set_clkdiv(codec_dai,
145 WM8350_DAC_CLKDIV, wm8350_audio[i].clkdiv);
146
147 snd_soc_dai_set_clkdiv(codec_dai,
148 WM8350_ADC_CLKDIV, wm8350_audio[i].clkdiv);
149
150 return 0;
151}
152
153static struct snd_soc_ops wm1133_ev1_ops = {
154 .hw_params = wm1133_ev1_hw_params,
155};
156
157static const struct snd_soc_dapm_widget wm1133_ev1_widgets[] = {
158#ifdef USE_SIMIC
159 SND_SOC_DAPM_MIC("SiMIC", NULL),
160#endif
161 SND_SOC_DAPM_MIC("Mic1 Jack", NULL),
162 SND_SOC_DAPM_MIC("Mic2 Jack", NULL),
163 SND_SOC_DAPM_LINE("Line In Jack", NULL),
164 SND_SOC_DAPM_LINE("Line Out Jack", NULL),
165 SND_SOC_DAPM_HP("Headphone Jack", NULL),
166};
167
168/* imx32ads soc_card audio map */
169static const struct snd_soc_dapm_route wm1133_ev1_map[] = {
170
171#ifdef USE_SIMIC
172 /* SiMIC --> IN1LN (with automatic bias) via SP1 */
173 { "IN1LN", NULL, "Mic Bias" },
174 { "Mic Bias", NULL, "SiMIC" },
175#endif
176
177 /* Mic 1 Jack --> IN1LN and IN1LP (with automatic bias) */
178 { "IN1LN", NULL, "Mic Bias" },
179 { "IN1LP", NULL, "Mic1 Jack" },
180 { "Mic Bias", NULL, "Mic1 Jack" },
181
182 /* Mic 2 Jack --> IN1RN and IN1RP (with automatic bias) */
183 { "IN1RN", NULL, "Mic Bias" },
184 { "IN1RP", NULL, "Mic2 Jack" },
185 { "Mic Bias", NULL, "Mic2 Jack" },
186
187 /* Line in Jack --> AUX (L+R) */
188 { "IN3R", NULL, "Line In Jack" },
189 { "IN3L", NULL, "Line In Jack" },
190
191 /* Out1 --> Headphone Jack */
192 { "Headphone Jack", NULL, "OUT1R" },
193 { "Headphone Jack", NULL, "OUT1L" },
194
195 /* Out1 --> Line Out Jack */
196 { "Line Out Jack", NULL, "OUT2R" },
197 { "Line Out Jack", NULL, "OUT2L" },
198};
199
200static struct snd_soc_jack hp_jack;
201
202static struct snd_soc_jack_pin hp_jack_pins[] = {
203 { .pin = "Headphone Jack", .mask = SND_JACK_HEADPHONE },
204};
205
206static struct snd_soc_jack mic_jack;
207
208static struct snd_soc_jack_pin mic_jack_pins[] = {
209 { .pin = "Mic1 Jack", .mask = SND_JACK_MICROPHONE },
210 { .pin = "Mic2 Jack", .mask = SND_JACK_MICROPHONE },
211};
212
213static int wm1133_ev1_init(struct snd_soc_codec *codec)
214{
215 struct snd_soc_card *card = codec->socdev->card;
216
217 snd_soc_dapm_new_controls(codec, wm1133_ev1_widgets,
218 ARRAY_SIZE(wm1133_ev1_widgets));
219
220 snd_soc_dapm_add_routes(codec, wm1133_ev1_map,
221 ARRAY_SIZE(wm1133_ev1_map));
222
223 /* Headphone jack detection */
224 snd_soc_jack_new(card, "Headphone", SND_JACK_HEADPHONE, &hp_jack);
225 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
226 hp_jack_pins);
227 wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
228
229 /* Microphone jack detection */
230 snd_soc_jack_new(card, "Microphone",
231 SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack);
232 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
233 mic_jack_pins);
234 wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
235 SND_JACK_BTN_0);
236
237 snd_soc_dapm_force_enable_pin(codec, "Mic Bias");
238
239 return 0;
240}
241
242
243static struct snd_soc_dai_link wm1133_ev1_dai = {
244 .name = "WM1133-EV1",
245 .stream_name = "Audio",
246 .cpu_dai = &imx_ssi_pcm_dai[0],
247 .codec_dai = &wm8350_dai,
248 .init = wm1133_ev1_init,
249 .ops = &wm1133_ev1_ops,
250 .symmetric_rates = 1,
251};
252
253static struct snd_soc_card wm1133_ev1 = {
254 .name = "WM1133-EV1",
255 .platform = &imx_soc_platform,
256 .dai_link = &wm1133_ev1_dai,
257 .num_links = 1,
258};
259
260static struct snd_soc_device wm1133_ev1_snd_devdata = {
261 .card = &wm1133_ev1,
262 .codec_dev = &soc_codec_dev_wm8350,
263};
264
265static struct platform_device *wm1133_ev1_snd_device;
266
267static int __init wm1133_ev1_audio_init(void)
268{
269 int ret;
270 unsigned int ptcr, pdcr;
271
272 /* SSI0 mastered by port 5 */
273 ptcr = MXC_AUDMUX_V2_PTCR_SYN |
274 MXC_AUDMUX_V2_PTCR_TFSDIR |
275 MXC_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) |
276 MXC_AUDMUX_V2_PTCR_TCLKDIR |
277 MXC_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
278 pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
279 mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr);
280
281 ptcr = MXC_AUDMUX_V2_PTCR_SYN;
282 pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0);
283 mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr);
284
285 wm1133_ev1_snd_device = platform_device_alloc("soc-audio", -1);
286 if (!wm1133_ev1_snd_device)
287 return -ENOMEM;
288
289 platform_set_drvdata(wm1133_ev1_snd_device, &wm1133_ev1_snd_devdata);
290 wm1133_ev1_snd_devdata.dev = &wm1133_ev1_snd_device->dev;
291 ret = platform_device_add(wm1133_ev1_snd_device);
292
293 if (ret)
294 platform_device_put(wm1133_ev1_snd_device);
295
296 return ret;
297}
298module_init(wm1133_ev1_audio_init);
299
300static void __exit wm1133_ev1_audio_exit(void)
301{
302 platform_device_unregister(wm1133_ev1_snd_device);
303}
304module_exit(wm1133_ev1_audio_exit);
305
306MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
307MODULE_DESCRIPTION("Audio for WM1133-EV1 on i.MX31ADS");
308MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index f11963c21873..d542ea2ff6be 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -18,6 +18,16 @@ config SND_OMAP_SOC_N810
18 help 18 help
19 Say Y if you want to add support for SoC audio on Nokia N810. 19 Say Y if you want to add support for SoC audio on Nokia N810.
20 20
21config SND_OMAP_SOC_RX51
22 tristate "SoC Audio support for Nokia RX-51"
23 depends on SND_OMAP_SOC && MACH_NOKIA_RX51
24 select OMAP_MCBSP
25 select SND_OMAP_SOC_MCBSP
26 select SND_SOC_TLV320AIC3X
27 help
28 Say Y if you want to add support for SoC audio on Nokia RX-51
29 hardware. This is also known as Nokia N900 product.
30
21config SND_OMAP_SOC_AMS_DELTA 31config SND_OMAP_SOC_AMS_DELTA
22 tristate "SoC Audio support for Amstrad E3 (Delta) videophone" 32 tristate "SoC Audio support for Amstrad E3 (Delta) videophone"
23 depends on SND_OMAP_SOC && MACH_AMS_DELTA 33 depends on SND_OMAP_SOC && MACH_AMS_DELTA
@@ -88,6 +98,15 @@ config SND_OMAP_SOC_SDP3430
88 Say Y if you want to add support for SoC audio on Texas Instruments 98 Say Y if you want to add support for SoC audio on Texas Instruments
89 SDP3430. 99 SDP3430.
90 100
101config SND_OMAP_SOC_SDP4430
102 tristate "SoC Audio support for Texas Instruments SDP4430"
103 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP
104 select SND_OMAP_SOC_MCPDM
105 select SND_SOC_TWL6040
106 help
107 Say Y if you want to add support for SoC audio on Texas Instruments
108 SDP4430.
109
91config SND_OMAP_SOC_OMAP3_PANDORA 110config SND_OMAP_SOC_OMAP3_PANDORA
92 tristate "SoC Audio support for OMAP3 Pandora" 111 tristate "SoC Audio support for OMAP3 Pandora"
93 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA 112 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 0bc00ca14b37..ba9fc650db28 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
9 9
10# OMAP Machine Support 10# OMAP Machine Support
11snd-soc-n810-objs := n810.o 11snd-soc-n810-objs := n810.o
12snd-soc-rx51-objs := rx51.o
12snd-soc-ams-delta-objs := ams-delta.o 13snd-soc-ams-delta-objs := ams-delta.o
13snd-soc-osk5912-objs := osk5912.o 14snd-soc-osk5912-objs := osk5912.o
14snd-soc-overo-objs := overo.o 15snd-soc-overo-objs := overo.o
@@ -16,12 +17,14 @@ snd-soc-omap2evm-objs := omap2evm.o
16snd-soc-omap3evm-objs := omap3evm.o 17snd-soc-omap3evm-objs := omap3evm.o
17snd-soc-am3517evm-objs := am3517evm.o 18snd-soc-am3517evm-objs := am3517evm.o
18snd-soc-sdp3430-objs := sdp3430.o 19snd-soc-sdp3430-objs := sdp3430.o
20snd-soc-sdp4430-objs := sdp4430.o
19snd-soc-omap3pandora-objs := omap3pandora.o 21snd-soc-omap3pandora-objs := omap3pandora.o
20snd-soc-omap3beagle-objs := omap3beagle.o 22snd-soc-omap3beagle-objs := omap3beagle.o
21snd-soc-zoom2-objs := zoom2.o 23snd-soc-zoom2-objs := zoom2.o
22snd-soc-igep0020-objs := igep0020.o 24snd-soc-igep0020-objs := igep0020.o
23 25
24obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 26obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
27obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o
25obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o 28obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
26obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 29obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
27obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o 30obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
@@ -29,6 +32,7 @@ obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
29obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o 32obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o
30obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o 33obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
31obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o 34obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
35obj-$(CONFIG_SND_OMAP_SOC_SDP4430) += snd-soc-sdp4430.o
32obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o 36obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
33obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o 37obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
34obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o 38obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c
index 1dab4c14874d..90b8bf71c893 100644
--- a/sound/soc/omap/mcpdm.c
+++ b/sound/soc/omap/mcpdm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * mcpdm.c -- McPDM interface driver 2 * mcpdm.c -- McPDM interface driver
3 * 3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com> 4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com>
5 * Copyright (C) 2009 - Texas Instruments, Inc. 5 * Copyright (C) 2009 - Texas Instruments, Inc.
@@ -39,46 +39,46 @@ static struct omap_mcpdm *mcpdm;
39 39
40static inline void omap_mcpdm_write(u16 reg, u32 val) 40static inline void omap_mcpdm_write(u16 reg, u32 val)
41{ 41{
42 __raw_writel(val, mcpdm->io_base + reg); 42 __raw_writel(val, mcpdm->io_base + reg);
43} 43}
44 44
45static inline int omap_mcpdm_read(u16 reg) 45static inline int omap_mcpdm_read(u16 reg)
46{ 46{
47 return __raw_readl(mcpdm->io_base + reg); 47 return __raw_readl(mcpdm->io_base + reg);
48} 48}
49 49
50static void omap_mcpdm_reg_dump(void) 50static void omap_mcpdm_reg_dump(void)
51{ 51{
52 dev_dbg(mcpdm->dev, "***********************\n"); 52 dev_dbg(mcpdm->dev, "***********************\n");
53 dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n", 53 dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n",
54 omap_mcpdm_read(MCPDM_IRQSTATUS_RAW)); 54 omap_mcpdm_read(MCPDM_IRQSTATUS_RAW));
55 dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n", 55 dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n",
56 omap_mcpdm_read(MCPDM_IRQSTATUS)); 56 omap_mcpdm_read(MCPDM_IRQSTATUS));
57 dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n", 57 dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n",
58 omap_mcpdm_read(MCPDM_IRQENABLE_SET)); 58 omap_mcpdm_read(MCPDM_IRQENABLE_SET));
59 dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n", 59 dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n",
60 omap_mcpdm_read(MCPDM_IRQENABLE_CLR)); 60 omap_mcpdm_read(MCPDM_IRQENABLE_CLR));
61 dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n", 61 dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n",
62 omap_mcpdm_read(MCPDM_IRQWAKE_EN)); 62 omap_mcpdm_read(MCPDM_IRQWAKE_EN));
63 dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n", 63 dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n",
64 omap_mcpdm_read(MCPDM_DMAENABLE_SET)); 64 omap_mcpdm_read(MCPDM_DMAENABLE_SET));
65 dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n", 65 dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n",
66 omap_mcpdm_read(MCPDM_DMAENABLE_CLR)); 66 omap_mcpdm_read(MCPDM_DMAENABLE_CLR));
67 dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n", 67 dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n",
68 omap_mcpdm_read(MCPDM_DMAWAKEEN)); 68 omap_mcpdm_read(MCPDM_DMAWAKEEN));
69 dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n", 69 dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n",
70 omap_mcpdm_read(MCPDM_CTRL)); 70 omap_mcpdm_read(MCPDM_CTRL));
71 dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n", 71 dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n",
72 omap_mcpdm_read(MCPDM_DN_DATA)); 72 omap_mcpdm_read(MCPDM_DN_DATA));
73 dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n", 73 dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n",
74 omap_mcpdm_read(MCPDM_UP_DATA)); 74 omap_mcpdm_read(MCPDM_UP_DATA));
75 dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n", 75 dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n",
76 omap_mcpdm_read(MCPDM_FIFO_CTRL_DN)); 76 omap_mcpdm_read(MCPDM_FIFO_CTRL_DN));
77 dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n", 77 dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n",
78 omap_mcpdm_read(MCPDM_FIFO_CTRL_UP)); 78 omap_mcpdm_read(MCPDM_FIFO_CTRL_UP));
79 dev_dbg(mcpdm->dev, "DN_OFFSET: 0x%04x\n", 79 dev_dbg(mcpdm->dev, "DN_OFFSET: 0x%04x\n",
80 omap_mcpdm_read(MCPDM_DN_OFFSET)); 80 omap_mcpdm_read(MCPDM_DN_OFFSET));
81 dev_dbg(mcpdm->dev, "***********************\n"); 81 dev_dbg(mcpdm->dev, "***********************\n");
82} 82}
83 83
84/* 84/*
@@ -87,26 +87,26 @@ static void omap_mcpdm_reg_dump(void)
87 */ 87 */
88static void omap_mcpdm_reset_capture(int reset) 88static void omap_mcpdm_reset_capture(int reset)
89{ 89{
90 int ctrl = omap_mcpdm_read(MCPDM_CTRL); 90 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
91 91
92 if (reset) 92 if (reset)
93 ctrl |= SW_UP_RST; 93 ctrl |= SW_UP_RST;
94 else 94 else
95 ctrl &= ~SW_UP_RST; 95 ctrl &= ~SW_UP_RST;
96 96
97 omap_mcpdm_write(MCPDM_CTRL, ctrl); 97 omap_mcpdm_write(MCPDM_CTRL, ctrl);
98} 98}
99 99
100static void omap_mcpdm_reset_playback(int reset) 100static void omap_mcpdm_reset_playback(int reset)
101{ 101{
102 int ctrl = omap_mcpdm_read(MCPDM_CTRL); 102 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
103 103
104 if (reset) 104 if (reset)
105 ctrl |= SW_DN_RST; 105 ctrl |= SW_DN_RST;
106 else 106 else
107 ctrl &= ~SW_DN_RST; 107 ctrl &= ~SW_DN_RST;
108 108
109 omap_mcpdm_write(MCPDM_CTRL, ctrl); 109 omap_mcpdm_write(MCPDM_CTRL, ctrl);
110} 110}
111 111
112/* 112/*
@@ -115,14 +115,14 @@ static void omap_mcpdm_reset_playback(int reset)
115 */ 115 */
116void omap_mcpdm_start(int stream) 116void omap_mcpdm_start(int stream)
117{ 117{
118 int ctrl = omap_mcpdm_read(MCPDM_CTRL); 118 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
119 119
120 if (stream) 120 if (stream)
121 ctrl |= mcpdm->up_channels; 121 ctrl |= mcpdm->up_channels;
122 else 122 else
123 ctrl |= mcpdm->dn_channels; 123 ctrl |= mcpdm->dn_channels;
124 124
125 omap_mcpdm_write(MCPDM_CTRL, ctrl); 125 omap_mcpdm_write(MCPDM_CTRL, ctrl);
126} 126}
127 127
128/* 128/*
@@ -131,14 +131,14 @@ void omap_mcpdm_start(int stream)
131 */ 131 */
132void omap_mcpdm_stop(int stream) 132void omap_mcpdm_stop(int stream)
133{ 133{
134 int ctrl = omap_mcpdm_read(MCPDM_CTRL); 134 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
135 135
136 if (stream) 136 if (stream)
137 ctrl &= ~mcpdm->up_channels; 137 ctrl &= ~mcpdm->up_channels;
138 else 138 else
139 ctrl &= ~mcpdm->dn_channels; 139 ctrl &= ~mcpdm->dn_channels;
140 140
141 omap_mcpdm_write(MCPDM_CTRL, ctrl); 141 omap_mcpdm_write(MCPDM_CTRL, ctrl);
142} 142}
143 143
144/* 144/*
@@ -147,38 +147,38 @@ void omap_mcpdm_stop(int stream)
147 */ 147 */
148int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink) 148int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink)
149{ 149{
150 int irq_mask = 0; 150 int irq_mask = 0;
151 int ctrl; 151 int ctrl;
152 152
153 if (!uplink) 153 if (!uplink)
154 return -EINVAL; 154 return -EINVAL;
155 155
156 mcpdm->uplink = uplink; 156 mcpdm->uplink = uplink;
157 157
158 /* Enable irq request generation */ 158 /* Enable irq request generation */
159 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK; 159 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
160 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask); 160 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
161 161
162 /* Configure uplink threshold */ 162 /* Configure uplink threshold */
163 if (uplink->threshold > UP_THRES_MAX) 163 if (uplink->threshold > UP_THRES_MAX)
164 uplink->threshold = UP_THRES_MAX; 164 uplink->threshold = UP_THRES_MAX;
165 165
166 omap_mcpdm_write(MCPDM_FIFO_CTRL_UP, uplink->threshold); 166 omap_mcpdm_write(MCPDM_FIFO_CTRL_UP, uplink->threshold);
167 167
168 /* Configure DMA controller */ 168 /* Configure DMA controller */
169 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_UP_ENABLE); 169 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_UP_ENABLE);
170 170
171 /* Set pdm out format */ 171 /* Set pdm out format */
172 ctrl = omap_mcpdm_read(MCPDM_CTRL); 172 ctrl = omap_mcpdm_read(MCPDM_CTRL);
173 ctrl &= ~PDMOUTFORMAT; 173 ctrl &= ~PDMOUTFORMAT;
174 ctrl |= uplink->format & PDMOUTFORMAT; 174 ctrl |= uplink->format & PDMOUTFORMAT;
175 175
176 /* Uplink channels */ 176 /* Uplink channels */
177 mcpdm->up_channels = uplink->channels & (PDM_UP_MASK | PDM_STATUS_MASK); 177 mcpdm->up_channels = uplink->channels & (PDM_UP_MASK | PDM_STATUS_MASK);
178 178
179 omap_mcpdm_write(MCPDM_CTRL, ctrl); 179 omap_mcpdm_write(MCPDM_CTRL, ctrl);
180 180
181 return 0; 181 return 0;
182} 182}
183 183
184/* 184/*
@@ -187,38 +187,38 @@ int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink)
187 */ 187 */
188int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink) 188int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink)
189{ 189{
190 int irq_mask = 0; 190 int irq_mask = 0;
191 int ctrl; 191 int ctrl;
192 192
193 if (!downlink) 193 if (!downlink)
194 return -EINVAL; 194 return -EINVAL;
195 195
196 mcpdm->downlink = downlink; 196 mcpdm->downlink = downlink;
197 197
198 /* Enable irq request generation */ 198 /* Enable irq request generation */
199 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK; 199 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
200 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask); 200 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
201 201
202 /* Configure uplink threshold */ 202 /* Configure uplink threshold */
203 if (downlink->threshold > DN_THRES_MAX) 203 if (downlink->threshold > DN_THRES_MAX)
204 downlink->threshold = DN_THRES_MAX; 204 downlink->threshold = DN_THRES_MAX;
205 205
206 omap_mcpdm_write(MCPDM_FIFO_CTRL_DN, downlink->threshold); 206 omap_mcpdm_write(MCPDM_FIFO_CTRL_DN, downlink->threshold);
207 207
208 /* Enable DMA request generation */ 208 /* Enable DMA request generation */
209 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_DN_ENABLE); 209 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_DN_ENABLE);
210 210
211 /* Set pdm out format */ 211 /* Set pdm out format */
212 ctrl = omap_mcpdm_read(MCPDM_CTRL); 212 ctrl = omap_mcpdm_read(MCPDM_CTRL);
213 ctrl &= ~PDMOUTFORMAT; 213 ctrl &= ~PDMOUTFORMAT;
214 ctrl |= downlink->format & PDMOUTFORMAT; 214 ctrl |= downlink->format & PDMOUTFORMAT;
215 215
216 /* Downlink channels */ 216 /* Downlink channels */
217 mcpdm->dn_channels = downlink->channels & (PDM_DN_MASK | PDM_CMD_MASK); 217 mcpdm->dn_channels = downlink->channels & (PDM_DN_MASK | PDM_CMD_MASK);
218 218
219 omap_mcpdm_write(MCPDM_CTRL, ctrl); 219 omap_mcpdm_write(MCPDM_CTRL, ctrl);
220 220
221 return 0; 221 return 0;
222} 222}
223 223
224/* 224/*
@@ -227,24 +227,24 @@ int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink)
227 */ 227 */
228int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink) 228int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink)
229{ 229{
230 int irq_mask = 0; 230 int irq_mask = 0;
231 231
232 if (!uplink) 232 if (!uplink)
233 return -EINVAL; 233 return -EINVAL;
234 234
235 /* Disable irq request generation */ 235 /* Disable irq request generation */
236 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK; 236 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
237 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask); 237 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
238 238
239 /* Disable DMA request generation */ 239 /* Disable DMA request generation */
240 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_UP_ENABLE); 240 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_UP_ENABLE);
241 241
242 /* Clear Downlink channels */ 242 /* Clear Downlink channels */
243 mcpdm->up_channels = 0; 243 mcpdm->up_channels = 0;
244 244
245 mcpdm->uplink = NULL; 245 mcpdm->uplink = NULL;
246 246
247 return 0; 247 return 0;
248} 248}
249 249
250/* 250/*
@@ -253,124 +253,124 @@ int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink)
253 */ 253 */
254int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink) 254int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink)
255{ 255{
256 int irq_mask = 0; 256 int irq_mask = 0;
257 257
258 if (!downlink) 258 if (!downlink)
259 return -EINVAL; 259 return -EINVAL;
260 260
261 /* Disable irq request generation */ 261 /* Disable irq request generation */
262 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK; 262 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
263 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask); 263 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
264 264
265 /* Disable DMA request generation */ 265 /* Disable DMA request generation */
266 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_DN_ENABLE); 266 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_DN_ENABLE);
267 267
268 /* clear Downlink channels */ 268 /* clear Downlink channels */
269 mcpdm->dn_channels = 0; 269 mcpdm->dn_channels = 0;
270 270
271 mcpdm->downlink = NULL; 271 mcpdm->downlink = NULL;
272 272
273 return 0; 273 return 0;
274} 274}
275 275
276static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id) 276static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id)
277{ 277{
278 struct omap_mcpdm *mcpdm_irq = dev_id; 278 struct omap_mcpdm *mcpdm_irq = dev_id;
279 int irq_status; 279 int irq_status;
280 280
281 irq_status = omap_mcpdm_read(MCPDM_IRQSTATUS); 281 irq_status = omap_mcpdm_read(MCPDM_IRQSTATUS);
282 282
283 /* Acknowledge irq event */ 283 /* Acknowledge irq event */
284 omap_mcpdm_write(MCPDM_IRQSTATUS, irq_status); 284 omap_mcpdm_write(MCPDM_IRQSTATUS, irq_status);
285 285
286 if (irq & MCPDM_DN_IRQ_FULL) { 286 if (irq & MCPDM_DN_IRQ_FULL) {
287 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status); 287 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
288 omap_mcpdm_reset_playback(1); 288 omap_mcpdm_reset_playback(1);
289 omap_mcpdm_playback_open(mcpdm_irq->downlink); 289 omap_mcpdm_playback_open(mcpdm_irq->downlink);
290 omap_mcpdm_reset_playback(0); 290 omap_mcpdm_reset_playback(0);
291 } 291 }
292 292
293 if (irq & MCPDM_DN_IRQ_EMPTY) { 293 if (irq & MCPDM_DN_IRQ_EMPTY) {
294 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status); 294 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
295 omap_mcpdm_reset_playback(1); 295 omap_mcpdm_reset_playback(1);
296 omap_mcpdm_playback_open(mcpdm_irq->downlink); 296 omap_mcpdm_playback_open(mcpdm_irq->downlink);
297 omap_mcpdm_reset_playback(0); 297 omap_mcpdm_reset_playback(0);
298 } 298 }
299 299
300 if (irq & MCPDM_DN_IRQ) { 300 if (irq & MCPDM_DN_IRQ) {
301 dev_dbg(mcpdm_irq->dev, "DN write request\n"); 301 dev_dbg(mcpdm_irq->dev, "DN write request\n");
302 } 302 }
303 303
304 if (irq & MCPDM_UP_IRQ_FULL) { 304 if (irq & MCPDM_UP_IRQ_FULL) {
305 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status); 305 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
306 omap_mcpdm_reset_capture(1); 306 omap_mcpdm_reset_capture(1);
307 omap_mcpdm_capture_open(mcpdm_irq->uplink); 307 omap_mcpdm_capture_open(mcpdm_irq->uplink);
308 omap_mcpdm_reset_capture(0); 308 omap_mcpdm_reset_capture(0);
309 } 309 }
310 310
311 if (irq & MCPDM_UP_IRQ_EMPTY) { 311 if (irq & MCPDM_UP_IRQ_EMPTY) {
312 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status); 312 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
313 omap_mcpdm_reset_capture(1); 313 omap_mcpdm_reset_capture(1);
314 omap_mcpdm_capture_open(mcpdm_irq->uplink); 314 omap_mcpdm_capture_open(mcpdm_irq->uplink);
315 omap_mcpdm_reset_capture(0); 315 omap_mcpdm_reset_capture(0);
316 } 316 }
317 317
318 if (irq & MCPDM_UP_IRQ) { 318 if (irq & MCPDM_UP_IRQ) {
319 dev_dbg(mcpdm_irq->dev, "UP write request\n"); 319 dev_dbg(mcpdm_irq->dev, "UP write request\n");
320 } 320 }
321 321
322 return IRQ_HANDLED; 322 return IRQ_HANDLED;
323} 323}
324 324
325int omap_mcpdm_request(void) 325int omap_mcpdm_request(void)
326{ 326{
327 int ret; 327 int ret;
328 328
329 clk_enable(mcpdm->clk); 329 clk_enable(mcpdm->clk);
330 330
331 spin_lock(&mcpdm->lock); 331 spin_lock(&mcpdm->lock);
332 332
333 if (!mcpdm->free) { 333 if (!mcpdm->free) {
334 dev_err(mcpdm->dev, "McPDM interface is in use\n"); 334 dev_err(mcpdm->dev, "McPDM interface is in use\n");
335 spin_unlock(&mcpdm->lock); 335 spin_unlock(&mcpdm->lock);
336 ret = -EBUSY; 336 ret = -EBUSY;
337 goto err; 337 goto err;
338 } 338 }
339 mcpdm->free = 0; 339 mcpdm->free = 0;
340 340
341 spin_unlock(&mcpdm->lock); 341 spin_unlock(&mcpdm->lock);
342 342
343 /* Disable lines while request is ongoing */ 343 /* Disable lines while request is ongoing */
344 omap_mcpdm_write(MCPDM_CTRL, 0x00); 344 omap_mcpdm_write(MCPDM_CTRL, 0x00);
345 345
346 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, 346 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler,
347 0, "McPDM", (void *)mcpdm); 347 0, "McPDM", (void *)mcpdm);
348 if (ret) { 348 if (ret) {
349 dev_err(mcpdm->dev, "Request for McPDM IRQ failed\n"); 349 dev_err(mcpdm->dev, "Request for McPDM IRQ failed\n");
350 goto err; 350 goto err;
351 } 351 }
352 352
353 return 0; 353 return 0;
354 354
355err: 355err:
356 clk_disable(mcpdm->clk); 356 clk_disable(mcpdm->clk);
357 return ret; 357 return ret;
358} 358}
359 359
360void omap_mcpdm_free(void) 360void omap_mcpdm_free(void)
361{ 361{
362 spin_lock(&mcpdm->lock); 362 spin_lock(&mcpdm->lock);
363 if (mcpdm->free) { 363 if (mcpdm->free) {
364 dev_err(mcpdm->dev, "McPDM interface is already free\n"); 364 dev_err(mcpdm->dev, "McPDM interface is already free\n");
365 spin_unlock(&mcpdm->lock); 365 spin_unlock(&mcpdm->lock);
366 return; 366 return;
367 } 367 }
368 mcpdm->free = 1; 368 mcpdm->free = 1;
369 spin_unlock(&mcpdm->lock); 369 spin_unlock(&mcpdm->lock);
370 370
371 clk_disable(mcpdm->clk); 371 clk_disable(mcpdm->clk);
372 372
373 free_irq(mcpdm->irq, (void *)mcpdm); 373 free_irq(mcpdm->irq, (void *)mcpdm);
374} 374}
375 375
376/* Enable/disable DC offset cancelation for the analog 376/* Enable/disable DC offset cancelation for the analog
@@ -378,108 +378,108 @@ void omap_mcpdm_free(void)
378 */ 378 */
379int omap_mcpdm_set_offset(int offset1, int offset2) 379int omap_mcpdm_set_offset(int offset1, int offset2)
380{ 380{
381 int offset; 381 int offset;
382 382
383 if ((offset1 > DN_OFST_MAX) || (offset2 > DN_OFST_MAX)) 383 if ((offset1 > DN_OFST_MAX) || (offset2 > DN_OFST_MAX))
384 return -EINVAL; 384 return -EINVAL;
385 385
386 offset = (offset1 << DN_OFST_RX1) | (offset2 << DN_OFST_RX2); 386 offset = (offset1 << DN_OFST_RX1) | (offset2 << DN_OFST_RX2);
387 387
388 /* offset cancellation for channel 1 */ 388 /* offset cancellation for channel 1 */
389 if (offset1) 389 if (offset1)
390 offset |= DN_OFST_RX1_EN; 390 offset |= DN_OFST_RX1_EN;
391 else 391 else
392 offset &= ~DN_OFST_RX1_EN; 392 offset &= ~DN_OFST_RX1_EN;
393 393
394 /* offset cancellation for channel 2 */ 394 /* offset cancellation for channel 2 */
395 if (offset2) 395 if (offset2)
396 offset |= DN_OFST_RX2_EN; 396 offset |= DN_OFST_RX2_EN;
397 else 397 else
398 offset &= ~DN_OFST_RX2_EN; 398 offset &= ~DN_OFST_RX2_EN;
399 399
400 omap_mcpdm_write(MCPDM_DN_OFFSET, offset); 400 omap_mcpdm_write(MCPDM_DN_OFFSET, offset);
401 401
402 return 0; 402 return 0;
403} 403}
404 404
405static int __devinit omap_mcpdm_probe(struct platform_device *pdev) 405static int __devinit omap_mcpdm_probe(struct platform_device *pdev)
406{ 406{
407 struct resource *res; 407 struct resource *res;
408 int ret = 0; 408 int ret = 0;
409 409
410 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL); 410 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
411 if (!mcpdm) { 411 if (!mcpdm) {
412 ret = -ENOMEM; 412 ret = -ENOMEM;
413 goto exit; 413 goto exit;
414 } 414 }
415 415
416 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 416 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
417 if (res == NULL) { 417 if (res == NULL) {
418 dev_err(&pdev->dev, "no resource\n"); 418 dev_err(&pdev->dev, "no resource\n");
419 goto err_resource; 419 goto err_resource;
420 } 420 }
421 421
422 spin_lock_init(&mcpdm->lock); 422 spin_lock_init(&mcpdm->lock);
423 mcpdm->free = 1; 423 mcpdm->free = 1;
424 mcpdm->io_base = ioremap(res->start, resource_size(res)); 424 mcpdm->io_base = ioremap(res->start, resource_size(res));
425 if (!mcpdm->io_base) { 425 if (!mcpdm->io_base) {
426 ret = -ENOMEM; 426 ret = -ENOMEM;
427 goto err_resource; 427 goto err_resource;
428 } 428 }
429 429
430 mcpdm->irq = platform_get_irq(pdev, 0); 430 mcpdm->irq = platform_get_irq(pdev, 0);
431 431
432 mcpdm->clk = clk_get(&pdev->dev, "pdm_ck"); 432 mcpdm->clk = clk_get(&pdev->dev, "pdm_ck");
433 if (IS_ERR(mcpdm->clk)) { 433 if (IS_ERR(mcpdm->clk)) {
434 ret = PTR_ERR(mcpdm->clk); 434 ret = PTR_ERR(mcpdm->clk);
435 dev_err(&pdev->dev, "unable to get pdm_ck: %d\n", ret); 435 dev_err(&pdev->dev, "unable to get pdm_ck: %d\n", ret);
436 goto err_clk; 436 goto err_clk;
437 } 437 }
438 438
439 mcpdm->dev = &pdev->dev; 439 mcpdm->dev = &pdev->dev;
440 platform_set_drvdata(pdev, mcpdm); 440 platform_set_drvdata(pdev, mcpdm);
441 441
442 return 0; 442 return 0;
443 443
444err_clk: 444err_clk:
445 iounmap(mcpdm->io_base); 445 iounmap(mcpdm->io_base);
446err_resource: 446err_resource:
447 kfree(mcpdm); 447 kfree(mcpdm);
448exit: 448exit:
449 return ret; 449 return ret;
450} 450}
451 451
452static int __devexit omap_mcpdm_remove(struct platform_device *pdev) 452static int __devexit omap_mcpdm_remove(struct platform_device *pdev)
453{ 453{
454 struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev); 454 struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev);
455 455
456 platform_set_drvdata(pdev, NULL); 456 platform_set_drvdata(pdev, NULL);
457 457
458 clk_put(mcpdm_ptr->clk); 458 clk_put(mcpdm_ptr->clk);
459 459
460 iounmap(mcpdm_ptr->io_base); 460 iounmap(mcpdm_ptr->io_base);
461 461
462 mcpdm_ptr->clk = NULL; 462 mcpdm_ptr->clk = NULL;
463 mcpdm_ptr->free = 0; 463 mcpdm_ptr->free = 0;
464 mcpdm_ptr->dev = NULL; 464 mcpdm_ptr->dev = NULL;
465 465
466 kfree(mcpdm_ptr); 466 kfree(mcpdm_ptr);
467 467
468 return 0; 468 return 0;
469} 469}
470 470
471static struct platform_driver omap_mcpdm_driver = { 471static struct platform_driver omap_mcpdm_driver = {
472 .probe = omap_mcpdm_probe, 472 .probe = omap_mcpdm_probe,
473 .remove = __devexit_p(omap_mcpdm_remove), 473 .remove = __devexit_p(omap_mcpdm_remove),
474 .driver = { 474 .driver = {
475 .name = "omap-mcpdm", 475 .name = "omap-mcpdm",
476 }, 476 },
477}; 477};
478 478
479static struct platform_device *omap_mcpdm_device; 479static struct platform_device *omap_mcpdm_device;
480 480
481static int __init omap_mcpdm_init(void) 481static int __init omap_mcpdm_init(void)
482{ 482{
483 return platform_driver_register(&omap_mcpdm_driver); 483 return platform_driver_register(&omap_mcpdm_driver);
484} 484}
485arch_initcall(omap_mcpdm_init); 485arch_initcall(omap_mcpdm_init);
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 8ad9dc901007..6f44cb4d30b8 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -256,6 +256,31 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
256 return err; 256 return err;
257} 257}
258 258
259static snd_pcm_sframes_t omap_mcbsp_dai_delay(
260 struct snd_pcm_substream *substream,
261 struct snd_soc_dai *dai)
262{
263 struct snd_soc_pcm_runtime *rtd = substream->private_data;
264 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
265 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
266 u16 fifo_use;
267 snd_pcm_sframes_t delay;
268
269 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
270 fifo_use = omap_mcbsp_get_tx_delay(mcbsp_data->bus_id);
271 else
272 fifo_use = omap_mcbsp_get_rx_delay(mcbsp_data->bus_id);
273
274 /*
275 * Divide the used locations with the channel count to get the
276 * FIFO usage in samples (don't care about partial samples in the
277 * buffer).
278 */
279 delay = fifo_use / substream->runtime->channels;
280
281 return delay;
282}
283
259static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, 284static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
260 struct snd_pcm_hw_params *params, 285 struct snd_pcm_hw_params *params,
261 struct snd_soc_dai *dai) 286 struct snd_soc_dai *dai)
@@ -295,8 +320,18 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
295 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; 320 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
296 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; 321 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
297 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode; 322 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
298 omap_mcbsp_dai_dma_params[id][substream->stream].data_type = 323 switch (params_format(params)) {
299 OMAP_DMA_DATA_TYPE_S16; 324 case SNDRV_PCM_FORMAT_S16_LE:
325 omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
326 OMAP_DMA_DATA_TYPE_S16;
327 break;
328 case SNDRV_PCM_FORMAT_S32_LE:
329 omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
330 OMAP_DMA_DATA_TYPE_S32;
331 break;
332 default:
333 return -EINVAL;
334 }
300 335
301 snd_soc_dai_set_dma_data(cpu_dai, substream, 336 snd_soc_dai_set_dma_data(cpu_dai, substream,
302 &omap_mcbsp_dai_dma_params[id][substream->stream]); 337 &omap_mcbsp_dai_dma_params[id][substream->stream]);
@@ -308,7 +343,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
308 343
309 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; 344 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
310 wpf = channels = params_channels(params); 345 wpf = channels = params_channels(params);
311 if (channels == 2 && format == SND_SOC_DAIFMT_I2S) { 346 if (channels == 2 && (format == SND_SOC_DAIFMT_I2S ||
347 format == SND_SOC_DAIFMT_LEFT_J)) {
312 /* Use dual-phase frames */ 348 /* Use dual-phase frames */
313 regs->rcr2 |= RPHASE; 349 regs->rcr2 |= RPHASE;
314 regs->xcr2 |= XPHASE; 350 regs->xcr2 |= XPHASE;
@@ -330,6 +366,14 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
330 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16); 366 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16);
331 regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_16); 367 regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_16);
332 break; 368 break;
369 case SNDRV_PCM_FORMAT_S32_LE:
370 /* Set word lengths */
371 wlen = 32;
372 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_32);
373 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_32);
374 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_32);
375 regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_32);
376 break;
333 default: 377 default:
334 /* Unsupported PCM format */ 378 /* Unsupported PCM format */
335 return -EINVAL; 379 return -EINVAL;
@@ -353,6 +397,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
353 /* Set FS period and length in terms of bit clock periods */ 397 /* Set FS period and length in terms of bit clock periods */
354 switch (format) { 398 switch (format) {
355 case SND_SOC_DAIFMT_I2S: 399 case SND_SOC_DAIFMT_I2S:
400 case SND_SOC_DAIFMT_LEFT_J:
356 regs->srgr2 |= FPER(framesize - 1); 401 regs->srgr2 |= FPER(framesize - 1);
357 regs->srgr1 |= FWID((framesize >> 1) - 1); 402 regs->srgr1 |= FWID((framesize >> 1) - 1);
358 break; 403 break;
@@ -404,6 +449,14 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
404 regs->rcr2 |= RDATDLY(1); 449 regs->rcr2 |= RDATDLY(1);
405 regs->xcr2 |= XDATDLY(1); 450 regs->xcr2 |= XDATDLY(1);
406 break; 451 break;
452 case SND_SOC_DAIFMT_LEFT_J:
453 /* 0-bit data delay */
454 regs->rcr2 |= RDATDLY(0);
455 regs->xcr2 |= XDATDLY(0);
456 regs->spcr1 |= RJUST(2);
457 /* Invert FS polarity configuration */
458 temp_fmt ^= SND_SOC_DAIFMT_NB_IF;
459 break;
407 case SND_SOC_DAIFMT_DSP_A: 460 case SND_SOC_DAIFMT_DSP_A:
408 /* 1-bit data delay */ 461 /* 1-bit data delay */
409 regs->rcr2 |= RDATDLY(1); 462 regs->rcr2 |= RDATDLY(1);
@@ -609,6 +662,7 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = {
609 .startup = omap_mcbsp_dai_startup, 662 .startup = omap_mcbsp_dai_startup,
610 .shutdown = omap_mcbsp_dai_shutdown, 663 .shutdown = omap_mcbsp_dai_shutdown,
611 .trigger = omap_mcbsp_dai_trigger, 664 .trigger = omap_mcbsp_dai_trigger,
665 .delay = omap_mcbsp_dai_delay,
612 .hw_params = omap_mcbsp_dai_hw_params, 666 .hw_params = omap_mcbsp_dai_hw_params,
613 .set_fmt = omap_mcbsp_dai_set_dai_fmt, 667 .set_fmt = omap_mcbsp_dai_set_dai_fmt,
614 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, 668 .set_clkdiv = omap_mcbsp_dai_set_clkdiv,
@@ -623,13 +677,15 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = {
623 .channels_min = 1, \ 677 .channels_min = 1, \
624 .channels_max = 16, \ 678 .channels_max = 16, \
625 .rates = OMAP_MCBSP_RATES, \ 679 .rates = OMAP_MCBSP_RATES, \
626 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 680 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
681 SNDRV_PCM_FMTBIT_S32_LE, \
627 }, \ 682 }, \
628 .capture = { \ 683 .capture = { \
629 .channels_min = 1, \ 684 .channels_min = 1, \
630 .channels_max = 16, \ 685 .channels_max = 16, \
631 .rates = OMAP_MCBSP_RATES, \ 686 .rates = OMAP_MCBSP_RATES, \
632 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 687 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
688 SNDRV_PCM_FMTBIT_S32_LE, \
633 }, \ 689 }, \
634 .ops = &omap_mcbsp_dai_ops, \ 690 .ops = &omap_mcbsp_dai_ops, \
635 .private_data = &mcbsp_data[(link_id)].bus_id, \ 691 .private_data = &mcbsp_data[(link_id)].bus_id, \
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index de10f76baded..87ce842fa2e8 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -188,8 +188,6 @@ static int omap3pandora_out_init(struct snd_soc_codec *codec)
188 int ret; 188 int ret;
189 189
190 /* All TWL4030 output pins are floating */ 190 /* All TWL4030 output pins are floating */
191 snd_soc_dapm_nc_pin(codec, "OUTL");
192 snd_soc_dapm_nc_pin(codec, "OUTR");
193 snd_soc_dapm_nc_pin(codec, "EARPIECE"); 191 snd_soc_dapm_nc_pin(codec, "EARPIECE");
194 snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); 192 snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
195 snd_soc_dapm_nc_pin(codec, "PREDRIVER"); 193 snd_soc_dapm_nc_pin(codec, "PREDRIVER");
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
new file mode 100644
index 000000000000..47d831ef2dbb
--- /dev/null
+++ b/sound/soc/omap/rx51.c
@@ -0,0 +1,294 @@
1/*
2 * rx51.c -- SoC audio for Nokia RX-51
3 *
4 * Copyright (C) 2008 - 2009 Nokia Corporation
5 *
6 * Contact: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 * Eduardo Valentin <eduardo.valentin@nokia.com>
8 * Jarkko Nikula <jhnikula@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#include <linux/delay.h>
27#include <linux/gpio.h>
28#include <linux/platform_device.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33
34#include <asm/mach-types.h>
35
36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38#include "../codecs/tlv320aic3x.h"
39
40/*
41 * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This
42 * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c
43 */
44#define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7)
45
46static int rx51_spk_func;
47static int rx51_dmic_func;
48
49static void rx51_ext_control(struct snd_soc_codec *codec)
50{
51 if (rx51_spk_func)
52 snd_soc_dapm_enable_pin(codec, "Ext Spk");
53 else
54 snd_soc_dapm_disable_pin(codec, "Ext Spk");
55 if (rx51_dmic_func)
56 snd_soc_dapm_enable_pin(codec, "DMic");
57 else
58 snd_soc_dapm_disable_pin(codec, "DMic");
59
60 snd_soc_dapm_sync(codec);
61}
62
63static int rx51_startup(struct snd_pcm_substream *substream)
64{
65 struct snd_pcm_runtime *runtime = substream->runtime;
66 struct snd_soc_pcm_runtime *rtd = substream->private_data;
67 struct snd_soc_codec *codec = rtd->socdev->card->codec;
68
69 snd_pcm_hw_constraint_minmax(runtime,
70 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
71 rx51_ext_control(codec);
72
73 return 0;
74}
75
76static int rx51_hw_params(struct snd_pcm_substream *substream,
77 struct snd_pcm_hw_params *params)
78{
79 struct snd_soc_pcm_runtime *rtd = substream->private_data;
80 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
81 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
82 int err;
83
84 /* Set codec DAI configuration */
85 err = snd_soc_dai_set_fmt(codec_dai,
86 SND_SOC_DAIFMT_DSP_A |
87 SND_SOC_DAIFMT_IB_NF |
88 SND_SOC_DAIFMT_CBM_CFM);
89 if (err < 0)
90 return err;
91
92 /* Set cpu DAI configuration */
93 err = snd_soc_dai_set_fmt(cpu_dai,
94 SND_SOC_DAIFMT_DSP_A |
95 SND_SOC_DAIFMT_IB_NF |
96 SND_SOC_DAIFMT_CBM_CFM);
97 if (err < 0)
98 return err;
99
100 /* Set the codec system clock for DAC and ADC */
101 return snd_soc_dai_set_sysclk(codec_dai, 0, 19200000,
102 SND_SOC_CLOCK_IN);
103}
104
105static struct snd_soc_ops rx51_ops = {
106 .startup = rx51_startup,
107 .hw_params = rx51_hw_params,
108};
109
110static int rx51_get_spk(struct snd_kcontrol *kcontrol,
111 struct snd_ctl_elem_value *ucontrol)
112{
113 ucontrol->value.integer.value[0] = rx51_spk_func;
114
115 return 0;
116}
117
118static int rx51_set_spk(struct snd_kcontrol *kcontrol,
119 struct snd_ctl_elem_value *ucontrol)
120{
121 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
122
123 if (rx51_spk_func == ucontrol->value.integer.value[0])
124 return 0;
125
126 rx51_spk_func = ucontrol->value.integer.value[0];
127 rx51_ext_control(codec);
128
129 return 1;
130}
131
132static int rx51_spk_event(struct snd_soc_dapm_widget *w,
133 struct snd_kcontrol *k, int event)
134{
135 if (SND_SOC_DAPM_EVENT_ON(event))
136 gpio_set_value(RX51_SPEAKER_AMP_TWL_GPIO, 1);
137 else
138 gpio_set_value(RX51_SPEAKER_AMP_TWL_GPIO, 0);
139
140 return 0;
141}
142
143static int rx51_get_input(struct snd_kcontrol *kcontrol,
144 struct snd_ctl_elem_value *ucontrol)
145{
146 ucontrol->value.integer.value[0] = rx51_dmic_func;
147
148 return 0;
149}
150
151static int rx51_set_input(struct snd_kcontrol *kcontrol,
152 struct snd_ctl_elem_value *ucontrol)
153{
154 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
155
156 if (rx51_dmic_func == ucontrol->value.integer.value[0])
157 return 0;
158
159 rx51_dmic_func = ucontrol->value.integer.value[0];
160 rx51_ext_control(codec);
161
162 return 1;
163}
164
165static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
166 SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
167 SND_SOC_DAPM_MIC("DMic", NULL),
168};
169
170static const struct snd_soc_dapm_route audio_map[] = {
171 {"Ext Spk", NULL, "HPLOUT"},
172 {"Ext Spk", NULL, "HPROUT"},
173
174 {"DMic Rate 64", NULL, "Mic Bias 2V"},
175 {"Mic Bias 2V", NULL, "DMic"},
176};
177
178static const char *spk_function[] = {"Off", "On"};
179static const char *input_function[] = {"ADC", "Digital Mic"};
180
181static const struct soc_enum rx51_enum[] = {
182 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
183 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_function), input_function),
184};
185
186static const struct snd_kcontrol_new aic34_rx51_controls[] = {
187 SOC_ENUM_EXT("Speaker Function", rx51_enum[0],
188 rx51_get_spk, rx51_set_spk),
189 SOC_ENUM_EXT("Input Select", rx51_enum[1],
190 rx51_get_input, rx51_set_input),
191};
192
193static int rx51_aic34_init(struct snd_soc_codec *codec)
194{
195 int err;
196
197 /* Set up NC codec pins */
198 snd_soc_dapm_nc_pin(codec, "MIC3L");
199 snd_soc_dapm_nc_pin(codec, "MIC3R");
200 snd_soc_dapm_nc_pin(codec, "LINE1R");
201
202 /* Add RX-51 specific controls */
203 err = snd_soc_add_controls(codec, aic34_rx51_controls,
204 ARRAY_SIZE(aic34_rx51_controls));
205 if (err < 0)
206 return err;
207
208 /* Add RX-51 specific widgets */
209 snd_soc_dapm_new_controls(codec, aic34_dapm_widgets,
210 ARRAY_SIZE(aic34_dapm_widgets));
211
212 /* Set up RX-51 specific audio path audio_map */
213 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
214
215 snd_soc_dapm_sync(codec);
216
217 return 0;
218}
219
220/* Digital audio interface glue - connects codec <--> CPU */
221static struct snd_soc_dai_link rx51_dai[] = {
222 {
223 .name = "TLV320AIC34",
224 .stream_name = "AIC34",
225 .cpu_dai = &omap_mcbsp_dai[0],
226 .codec_dai = &aic3x_dai,
227 .init = rx51_aic34_init,
228 .ops = &rx51_ops,
229 },
230};
231
232/* Audio private data */
233static struct aic3x_setup_data rx51_aic34_setup = {
234 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
235 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
236};
237
238/* Audio card */
239static struct snd_soc_card rx51_sound_card = {
240 .name = "RX-51",
241 .dai_link = rx51_dai,
242 .num_links = ARRAY_SIZE(rx51_dai),
243 .platform = &omap_soc_platform,
244};
245
246/* Audio subsystem */
247static struct snd_soc_device rx51_snd_devdata = {
248 .card = &rx51_sound_card,
249 .codec_dev = &soc_codec_dev_aic3x,
250 .codec_data = &rx51_aic34_setup,
251};
252
253static struct platform_device *rx51_snd_device;
254
255static int __init rx51_soc_init(void)
256{
257 int err;
258
259 if (!machine_is_nokia_rx51())
260 return -ENODEV;
261
262 rx51_snd_device = platform_device_alloc("soc-audio", -1);
263 if (!rx51_snd_device) {
264 err = -ENOMEM;
265 goto err1;
266 }
267
268 platform_set_drvdata(rx51_snd_device, &rx51_snd_devdata);
269 rx51_snd_devdata.dev = &rx51_snd_device->dev;
270 *(unsigned int *)rx51_dai[0].cpu_dai->private_data = 1; /* McBSP2 */
271
272 err = platform_device_add(rx51_snd_device);
273 if (err)
274 goto err2;
275
276 return 0;
277err2:
278 platform_device_put(rx51_snd_device);
279err1:
280
281 return err;
282}
283
284static void __exit rx51_soc_exit(void)
285{
286 platform_device_unregister(rx51_snd_device);
287}
288
289module_init(rx51_soc_init);
290module_exit(rx51_soc_exit);
291
292MODULE_AUTHOR("Nokia Corporation");
293MODULE_DESCRIPTION("ALSA SoC Nokia RX-51");
294MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
new file mode 100644
index 000000000000..4ebbde6b565f
--- /dev/null
+++ b/sound/soc/omap/sdp4430.c
@@ -0,0 +1,233 @@
1/*
2 * sdp4430.c -- SoC audio for TI OMAP4430 SDP
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28
29#include <asm/mach-types.h>
30#include <plat/hardware.h>
31#include <plat/mux.h>
32
33#include "mcpdm.h"
34#include "omap-mcpdm.h"
35#include "omap-pcm.h"
36#include "../codecs/twl6040.h"
37
38static int twl6040_power_mode;
39
40static int sdp4430_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params)
42{
43 struct snd_soc_pcm_runtime *rtd = substream->private_data;
44 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
45 int clk_id, freq;
46 int ret;
47
48 if (twl6040_power_mode) {
49 clk_id = TWL6040_SYSCLK_SEL_HPPLL;
50 freq = 38400000;
51 } else {
52 clk_id = TWL6040_SYSCLK_SEL_LPPLL;
53 freq = 32768;
54 }
55
56 /* set the codec mclk */
57 ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq,
58 SND_SOC_CLOCK_IN);
59 if (ret) {
60 printk(KERN_ERR "can't set codec system clock\n");
61 return ret;
62 }
63}
64
65static struct snd_soc_ops sdp4430_ops = {
66 .hw_params = sdp4430_hw_params,
67};
68
69static int sdp4430_get_power_mode(struct snd_kcontrol *kcontrol,
70 struct snd_ctl_elem_value *ucontrol)
71{
72 ucontrol->value.integer.value[0] = twl6040_power_mode;
73 return 0;
74}
75
76static int sdp4430_set_power_mode(struct snd_kcontrol *kcontrol,
77 struct snd_ctl_elem_value *ucontrol)
78{
79 if (twl6040_power_mode == ucontrol->value.integer.value[0])
80 return 0;
81
82 twl6040_power_mode = ucontrol->value.integer.value[0];
83
84 return 1;
85}
86
87static const char *power_texts[] = {"Low-Power", "High-Performance"};
88
89static const struct soc_enum sdp4430_enum[] = {
90 SOC_ENUM_SINGLE_EXT(2, power_texts),
91};
92
93static const struct snd_kcontrol_new sdp4430_controls[] = {
94 SOC_ENUM_EXT("TWL6040 Power Mode", sdp4430_enum[0],
95 sdp4430_get_power_mode, sdp4430_set_power_mode),
96};
97
98/* SDP4430 machine DAPM */
99static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
100 SND_SOC_DAPM_MIC("Ext Mic", NULL),
101 SND_SOC_DAPM_SPK("Ext Spk", NULL),
102 SND_SOC_DAPM_MIC("Headset Mic", NULL),
103 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
104 SND_SOC_DAPM_SPK("Earphone Spk", NULL),
105};
106
107static const struct snd_soc_dapm_route audio_map[] = {
108 /* External Mics: MAINMIC, SUBMIC with bias*/
109 {"MAINMIC", NULL, "Main Mic Bias"},
110 {"SUBMIC", NULL, "Main Mic Bias"},
111 {"Main Mic Bias", NULL, "Ext Mic"},
112
113 /* External Speakers: HFL, HFR */
114 {"Ext Spk", NULL, "HFL"},
115 {"Ext Spk", NULL, "HFR"},
116
117 /* Headset Mic: HSMIC with bias */
118 {"HSMIC", NULL, "Headset Mic Bias"},
119 {"Headset Mic Bias", NULL, "Headset Mic"},
120
121 /* Headset Stereophone (Headphone): HSOL, HSOR */
122 {"Headset Stereophone", NULL, "HSOL"},
123 {"Headset Stereophone", NULL, "HSOR"},
124
125 /* Earphone speaker */
126 {"Earphone Spk", NULL, "EP"},
127};
128
129static int sdp4430_twl6040_init(struct snd_soc_codec *codec)
130{
131 int ret;
132
133 /* Add SDP4430 specific controls */
134 ret = snd_soc_add_controls(codec, sdp4430_controls,
135 ARRAY_SIZE(sdp4430_controls));
136 if (ret)
137 return ret;
138
139 /* Add SDP4430 specific widgets */
140 ret = snd_soc_dapm_new_controls(codec, sdp4430_twl6040_dapm_widgets,
141 ARRAY_SIZE(sdp4430_twl6040_dapm_widgets));
142 if (ret)
143 return ret;
144
145 /* Set up SDP4430 specific audio path audio_map */
146 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
147
148 /* SDP4430 connected pins */
149 snd_soc_dapm_enable_pin(codec, "Ext Mic");
150 snd_soc_dapm_enable_pin(codec, "Ext Spk");
151 snd_soc_dapm_enable_pin(codec, "Headset Mic");
152 snd_soc_dapm_enable_pin(codec, "Headset Stereophone");
153
154 /* TWL6040 not connected pins */
155 snd_soc_dapm_nc_pin(codec, "AFML");
156 snd_soc_dapm_nc_pin(codec, "AFMR");
157
158 ret = snd_soc_dapm_sync(codec);
159
160 return ret;
161}
162
163/* Digital audio interface glue - connects codec <--> CPU */
164static struct snd_soc_dai_link sdp4430_dai = {
165 .name = "TWL6040",
166 .stream_name = "TWL6040",
167 .cpu_dai = &omap_mcpdm_dai,
168 .codec_dai = &twl6040_dai,
169 .init = sdp4430_twl6040_init,
170 .ops = &sdp4430_ops,
171};
172
173/* Audio machine driver */
174static struct snd_soc_card snd_soc_sdp4430 = {
175 .name = "SDP4430",
176 .platform = &omap_soc_platform,
177 .dai_link = &sdp4430_dai,
178 .num_links = 1,
179};
180
181/* Audio subsystem */
182static struct snd_soc_device sdp4430_snd_devdata = {
183 .card = &snd_soc_sdp4430,
184 .codec_dev = &soc_codec_dev_twl6040,
185};
186
187static struct platform_device *sdp4430_snd_device;
188
189static int __init sdp4430_soc_init(void)
190{
191 int ret;
192
193 if (!machine_is_omap_4430sdp()) {
194 pr_debug("Not SDP4430!\n");
195 return -ENODEV;
196 }
197 printk(KERN_INFO "SDP4430 SoC init\n");
198
199 sdp4430_snd_device = platform_device_alloc("soc-audio", -1);
200 if (!sdp4430_snd_device) {
201 printk(KERN_ERR "Platform device allocation failed\n");
202 return -ENOMEM;
203 }
204
205 platform_set_drvdata(sdp4430_snd_device, &sdp4430_snd_devdata);
206 sdp4430_snd_devdata.dev = &sdp4430_snd_device->dev;
207
208 ret = platform_device_add(sdp4430_snd_device);
209 if (ret)
210 goto err;
211
212 /* Codec starts in HP mode */
213 twl6040_power_mode = 1;
214
215 return 0;
216
217err:
218 printk(KERN_ERR "Unable to add platform device\n");
219 platform_device_put(sdp4430_snd_device);
220 return ret;
221}
222module_init(sdp4430_soc_init);
223
224static void __exit sdp4430_soc_exit(void)
225{
226 platform_device_unregister(sdp4430_snd_device);
227}
228module_exit(sdp4430_soc_exit);
229
230MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
231MODULE_DESCRIPTION("ALSA SoC SDP4430");
232MODULE_LICENSE("GPL");
233
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index f90a2ac888cf..50a94ee76ecc 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -181,9 +181,6 @@ static int zoom2_twl4030_init(struct snd_soc_codec *codec)
181 snd_soc_dapm_nc_pin(codec, "CARKITMIC"); 181 snd_soc_dapm_nc_pin(codec, "CARKITMIC");
182 snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); 182 snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
183 snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); 183 snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
184
185 snd_soc_dapm_nc_pin(codec, "OUTL");
186 snd_soc_dapm_nc_pin(codec, "OUTR");
187 snd_soc_dapm_nc_pin(codec, "EARPIECE"); 184 snd_soc_dapm_nc_pin(codec, "EARPIECE");
188 snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); 185 snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
189 snd_soc_dapm_nc_pin(codec, "PREDRIVER"); 186 snd_soc_dapm_nc_pin(codec, "PREDRIVER");
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 376e14a9c273..495a36fba360 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -42,6 +42,14 @@ config SND_PXA2XX_SOC_SPITZ
42 Say Y if you want to add support for SoC audio on Sharp 42 Say Y if you want to add support for SoC audio on Sharp
43 Zaurus SL-Cxx00 models (Spitz, Borzoi and Akita). 43 Zaurus SL-Cxx00 models (Spitz, Borzoi and Akita).
44 44
45config SND_PXA2XX_SOC_Z2
46 tristate "SoC Audio support for Zipit Z2"
47 depends on SND_PXA2XX_SOC && MACH_ZIPIT2
48 select SND_PXA2XX_SOC_I2S
49 select SND_SOC_WM8750
50 help
51 Say Y if you want to add support for SoC audio on Zipit Z2.
52
45config SND_PXA2XX_SOC_POODLE 53config SND_PXA2XX_SOC_POODLE
46 tristate "SoC Audio support for Poodle" 54 tristate "SoC Audio support for Poodle"
47 depends on SND_PXA2XX_SOC && MACH_POODLE 55 depends on SND_PXA2XX_SOC && MACH_POODLE
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index f3e08fd40ca2..caa03d8f4789 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -22,6 +22,7 @@ snd-soc-palm27x-objs := palm27x.o
22snd-soc-zylonite-objs := zylonite.o 22snd-soc-zylonite-objs := zylonite.o
23snd-soc-magician-objs := magician.o 23snd-soc-magician-objs := magician.o
24snd-soc-mioa701-objs := mioa701_wm9713.o 24snd-soc-mioa701-objs := mioa701_wm9713.o
25snd-soc-z2-objs := z2.o
25snd-soc-imote2-objs := imote2.o 26snd-soc-imote2-objs := imote2.o
26snd-soc-raumfeld-objs := raumfeld.o 27snd-soc-raumfeld-objs := raumfeld.o
27 28
@@ -36,6 +37,7 @@ obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
36obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o 37obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
37obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o 38obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
38obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o 39obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
40obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o
39obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 41obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
40obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o 42obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
41obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o 43obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index c4cd2acaacb4..1941a357e8c4 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -322,19 +322,44 @@ static struct snd_soc_card snd_soc_spitz = {
322 .num_links = 1, 322 .num_links = 1,
323}; 323};
324 324
325/* spitz audio private data */
326static struct wm8750_setup_data spitz_wm8750_setup = {
327 .i2c_bus = 0,
328 .i2c_address = 0x1b,
329};
330
331/* spitz audio subsystem */ 325/* spitz audio subsystem */
332static struct snd_soc_device spitz_snd_devdata = { 326static struct snd_soc_device spitz_snd_devdata = {
333 .card = &snd_soc_spitz, 327 .card = &snd_soc_spitz,
334 .codec_dev = &soc_codec_dev_wm8750, 328 .codec_dev = &soc_codec_dev_wm8750,
335 .codec_data = &spitz_wm8750_setup,
336}; 329};
337 330
331/*
332 * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
333 * New drivers should register the wm8750 I2C device in the machine
334 * setup code (under arch/arm for ARM systems).
335 */
336static int wm8750_i2c_register(void)
337{
338 struct i2c_board_info info;
339 struct i2c_adapter *adapter;
340 struct i2c_client *client;
341
342 memset(&info, 0, sizeof(struct i2c_board_info));
343 info.addr = 0x1b;
344 strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
345
346 adapter = i2c_get_adapter(0);
347 if (!adapter) {
348 printk(KERN_ERR "can't get i2c adapter 0\n");
349 return -ENODEV;
350 }
351
352 client = i2c_new_device(adapter, &info);
353 i2c_put_adapter(adapter);
354 if (!client) {
355 printk(KERN_ERR "can't add i2c device at 0x%x\n",
356 (unsigned int)info.addr);
357 return -ENODEV;
358 }
359
360 return 0;
361}
362
338static struct platform_device *spitz_snd_device; 363static struct platform_device *spitz_snd_device;
339 364
340static int __init spitz_init(void) 365static int __init spitz_init(void)
@@ -344,6 +369,10 @@ static int __init spitz_init(void)
344 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) 369 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
345 return -ENODEV; 370 return -ENODEV;
346 371
372 ret = wm8750_i2c_setup();
373 if (ret != 0)
374 return ret;
375
347 spitz_snd_device = platform_device_alloc("soc-audio", -1); 376 spitz_snd_device = platform_device_alloc("soc-audio", -1);
348 if (!spitz_snd_device) 377 if (!spitz_snd_device)
349 return -ENOMEM; 378 return -ENOMEM;
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
new file mode 100644
index 000000000000..4e4d2fa8ddc5
--- /dev/null
+++ b/sound/soc/pxa/z2.c
@@ -0,0 +1,246 @@
1/*
2 * linux/sound/soc/pxa/z2.c
3 *
4 * SoC Audio driver for Aeronix Zipit Z2
5 *
6 * Copyright (C) 2009 Ken McGuire <kenm@desertweyr.com>
7 * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/timer.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/gpio.h>
20
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25#include <sound/jack.h>
26
27#include <asm/mach-types.h>
28#include <mach/hardware.h>
29#include <mach/audio.h>
30#include <mach/z2.h>
31
32#include "../codecs/wm8750.h"
33#include "pxa2xx-pcm.h"
34#include "pxa2xx-i2s.h"
35
36static struct snd_soc_card snd_soc_z2;
37
38static int z2_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
44 unsigned int clk = 0;
45 int ret = 0;
46
47 switch (params_rate(params)) {
48 case 8000:
49 case 16000:
50 case 48000:
51 case 96000:
52 clk = 12288000;
53 break;
54 case 11025:
55 case 22050:
56 case 44100:
57 clk = 11289600;
58 break;
59 }
60
61 /* set codec DAI configuration */
62 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
63 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
64 if (ret < 0)
65 return ret;
66
67 /* set cpu DAI configuration */
68 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
69 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
70 if (ret < 0)
71 return ret;
72
73 /* set the codec system clock for DAC and ADC */
74 ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
75 SND_SOC_CLOCK_IN);
76 if (ret < 0)
77 return ret;
78
79 /* set the I2S system clock as input (unused) */
80 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
81 SND_SOC_CLOCK_IN);
82 if (ret < 0)
83 return ret;
84
85 return 0;
86}
87
88static struct snd_soc_jack hs_jack;
89
90/* Headset jack detection DAPM pins */
91static struct snd_soc_jack_pin hs_jack_pins[] = {
92 {
93 .pin = "Mic Jack",
94 .mask = SND_JACK_MICROPHONE,
95 },
96 {
97 .pin = "Headphone Jack",
98 .mask = SND_JACK_HEADPHONE,
99 },
100};
101
102/* Headset jack detection gpios */
103static struct snd_soc_jack_gpio hs_jack_gpios[] = {
104 {
105 .gpio = GPIO37_ZIPITZ2_HEADSET_DETECT,
106 .name = "hsdet-gpio",
107 .report = SND_JACK_HEADSET,
108 .debounce_time = 200,
109 },
110};
111
112/* z2 machine dapm widgets */
113static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
114 SND_SOC_DAPM_HP("Headphone Jack", NULL),
115 SND_SOC_DAPM_MIC("Mic Jack", NULL),
116 SND_SOC_DAPM_SPK("Ext Spk", NULL),
117
118 /* headset is a mic and mono headphone */
119 SND_SOC_DAPM_HP("Headset Jack", NULL),
120};
121
122/* Z2 machine audio_map */
123static const struct snd_soc_dapm_route audio_map[] = {
124
125 /* headphone connected to LOUT1, ROUT1 */
126 {"Headphone Jack", NULL, "LOUT1"},
127 {"Headphone Jack", NULL, "ROUT1"},
128
129 /* ext speaker connected to LOUT2, ROUT2 */
130 {"Ext Spk", NULL , "ROUT2"},
131 {"Ext Spk", NULL , "LOUT2"},
132
133 /* mic is connected to R input 2 - with bias */
134 {"RINPUT2", NULL, "Mic Bias"},
135 {"Mic Bias", NULL, "Mic Jack"},
136};
137
138/*
139 * Logic for a wm8750 as connected on a Z2 Device
140 */
141static int z2_wm8750_init(struct snd_soc_codec *codec)
142{
143 int ret;
144
145 /* NC codec pins */
146 snd_soc_dapm_disable_pin(codec, "LINPUT3");
147 snd_soc_dapm_disable_pin(codec, "RINPUT3");
148 snd_soc_dapm_disable_pin(codec, "OUT3");
149 snd_soc_dapm_disable_pin(codec, "MONO");
150
151 /* Add z2 specific widgets */
152 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
153 ARRAY_SIZE(wm8750_dapm_widgets));
154
155 /* Set up z2 specific audio paths */
156 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
157
158 ret = snd_soc_dapm_sync(codec);
159 if (ret)
160 goto err;
161
162 /* Jack detection API stuff */
163 ret = snd_soc_jack_new(&snd_soc_z2, "Headset Jack", SND_JACK_HEADSET,
164 &hs_jack);
165 if (ret)
166 goto err;
167
168 ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
169 hs_jack_pins);
170 if (ret)
171 goto err;
172
173 ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
174 hs_jack_gpios);
175 if (ret)
176 goto err;
177
178 return 0;
179
180err:
181 return ret;
182}
183
184static struct snd_soc_ops z2_ops = {
185 .hw_params = z2_hw_params,
186};
187
188/* z2 digital audio interface glue - connects codec <--> CPU */
189static struct snd_soc_dai_link z2_dai = {
190 .name = "wm8750",
191 .stream_name = "WM8750",
192 .cpu_dai = &pxa_i2s_dai,
193 .codec_dai = &wm8750_dai,
194 .init = z2_wm8750_init,
195 .ops = &z2_ops,
196};
197
198/* z2 audio machine driver */
199static struct snd_soc_card snd_soc_z2 = {
200 .name = "Z2",
201 .platform = &pxa2xx_soc_platform,
202 .dai_link = &z2_dai,
203 .num_links = 1,
204};
205
206/* z2 audio subsystem */
207static struct snd_soc_device z2_snd_devdata = {
208 .card = &snd_soc_z2,
209 .codec_dev = &soc_codec_dev_wm8750,
210};
211
212static struct platform_device *z2_snd_device;
213
214static int __init z2_init(void)
215{
216 int ret;
217
218 if (!machine_is_zipit2())
219 return -ENODEV;
220
221 z2_snd_device = platform_device_alloc("soc-audio", -1);
222 if (!z2_snd_device)
223 return -ENOMEM;
224
225 platform_set_drvdata(z2_snd_device, &z2_snd_devdata);
226 z2_snd_devdata.dev = &z2_snd_device->dev;
227 ret = platform_device_add(z2_snd_device);
228
229 if (ret)
230 platform_device_put(z2_snd_device);
231
232 return ret;
233}
234
235static void __exit z2_exit(void)
236{
237 platform_device_unregister(z2_snd_device);
238}
239
240module_init(z2_init);
241module_exit(z2_exit);
242
243MODULE_AUTHOR("Ken McGuire <kenm@desertweyr.com>, "
244 "Marek Vasut <marek.vasut@gmail.com>");
245MODULE_DESCRIPTION("ALSA SoC ZipitZ2");
246MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index 15fe57e5a232..2a7cc222d098 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -24,6 +24,11 @@ config SND_S3C64XX_SOC_I2S
24 select SND_S3C_I2SV2_SOC 24 select SND_S3C_I2SV2_SOC
25 select S3C64XX_DMA 25 select S3C64XX_DMA
26 26
27config SND_S3C64XX_SOC_I2S_V4
28 tristate
29 select SND_S3C_I2SV2_SOC
30 select S3C64XX_DMA
31
27config SND_S3C_SOC_PCM 32config SND_S3C_SOC_PCM
28 tristate 33 tristate
29 34
@@ -59,12 +64,11 @@ config SND_S3C24XX_SOC_JIVE_WM8750
59 64
60config SND_S3C64XX_SOC_WM8580 65config SND_S3C64XX_SOC_WM8580
61 tristate "SoC I2S Audio support for WM8580 on SMDK64XX" 66 tristate "SoC I2S Audio support for WM8580 on SMDK64XX"
62 depends on SND_S3C24XX_SOC && (MACH_SMDK6400 || MACH_SMDK6410) 67 depends on SND_S3C24XX_SOC && MACH_SMDK6410
63 depends on BROKEN
64 select SND_SOC_WM8580 68 select SND_SOC_WM8580
65 select SND_S3C64XX_SOC_I2S 69 select SND_S3C64XX_SOC_I2S_V4
66 help 70 help
67 Sat Y if you want to add support for SoC audio on the SMDK64XX. 71 Say Y if you want to add support for SoC audio on the SMDK6410.
68 72
69config SND_S3C24XX_SOC_SMDK2443_WM9710 73config SND_S3C24XX_SOC_SMDK2443_WM9710
70 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" 74 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index df071a376fa2..81d8dc503f87 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -4,6 +4,7 @@ snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o 4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o 5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o
6snd-soc-s3c-ac97-objs := s3c-ac97.o 6snd-soc-s3c-ac97-objs := s3c-ac97.o
7snd-soc-s3c64xx-i2s-v4-objs := s3c64xx-i2s-v4.o
7snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o 8snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
8snd-soc-s3c-pcm-objs := s3c-pcm.o 9snd-soc-s3c-pcm-objs := s3c-pcm.o
9 10
@@ -12,6 +13,7 @@ obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
12obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o 13obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o
13obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o 14obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
14obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o 15obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o
16obj-$(CONFIG_SND_S3C64XX_SOC_I2S_V4) += snd-soc-s3c64xx-i2s-v4.o
15obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o 17obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
16obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-s3c-pcm.o 18obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-s3c-pcm.o
17 19
diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c
index 59dc2c6b56d9..8c108b121c10 100644
--- a/sound/soc/s3c24xx/jive_wm8750.c
+++ b/sound/soc/s3c24xx/jive_wm8750.c
@@ -70,7 +70,7 @@ static int jive_hw_params(struct snd_pcm_substream *substream,
70 } 70 }
71 71
72 s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params), 72 s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params),
73 s3c2412_get_iisclk()); 73 s3c_i2sv2_get_clock(cpu_dai));
74 74
75 /* set codec DAI configuration */ 75 /* set codec DAI configuration */
76 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 76 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
@@ -152,15 +152,10 @@ static struct snd_soc_card snd_soc_machine_jive = {
152 .num_links = 1, 152 .num_links = 1,
153}; 153};
154 154
155/* jive audio private data */
156static struct wm8750_setup_data jive_wm8750_setup = {
157};
158
159/* jive audio subsystem */ 155/* jive audio subsystem */
160static struct snd_soc_device jive_snd_devdata = { 156static struct snd_soc_device jive_snd_devdata = {
161 .card = &snd_soc_machine_jive, 157 .card = &snd_soc_machine_jive,
162 .codec_dev = &soc_codec_dev_wm8750, 158 .codec_dev = &soc_codec_dev_wm8750,
163 .codec_data = &jive_wm8750_setup,
164}; 159};
165 160
166static struct platform_device *jive_snd_device; 161static struct platform_device *jive_snd_device;
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
index dea83d30a5c9..209c25994c7e 100644
--- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
@@ -362,6 +362,14 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
362 snd_soc_dapm_disable_pin(codec, "Handset Mic"); 362 snd_soc_dapm_disable_pin(codec, "Handset Mic");
363 snd_soc_dapm_disable_pin(codec, "Handset Spk"); 363 snd_soc_dapm_disable_pin(codec, "Handset Spk");
364 364
365 /* allow audio paths from the GSM modem to run during suspend */
366 snd_soc_dapm_ignore_suspend(codec, "Stereo Out");
367 snd_soc_dapm_ignore_suspend(codec, "GSM Line Out");
368 snd_soc_dapm_ignore_suspend(codec, "GSM Line In");
369 snd_soc_dapm_ignore_suspend(codec, "Headset Mic");
370 snd_soc_dapm_ignore_suspend(codec, "Handset Mic");
371 snd_soc_dapm_ignore_suspend(codec, "Handset Spk");
372
365 snd_soc_dapm_sync(codec); 373 snd_soc_dapm_sync(codec);
366 374
367 return 0; 375 return 0;
diff --git a/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h b/sound/soc/s3c24xx/regs-i2s-v2.h
index abf2fbc2eb2f..5e5e5680580b 100644
--- a/arch/arm/plat-samsung/include/plat/regs-s3c2412-iis.h
+++ b/sound/soc/s3c24xx/regs-i2s-v2.h
@@ -20,6 +20,24 @@
20#define S3C2412_IISTXD (0x10) 20#define S3C2412_IISTXD (0x10)
21#define S3C2412_IISRXD (0x14) 21#define S3C2412_IISRXD (0x14)
22 22
23#define S5PC1XX_IISFICS 0x18
24#define S5PC1XX_IISTXDS 0x1C
25
26#define S5PC1XX_IISCON_SW_RST (1 << 31)
27#define S5PC1XX_IISCON_FRXOFSTATUS (1 << 26)
28#define S5PC1XX_IISCON_FRXORINTEN (1 << 25)
29#define S5PC1XX_IISCON_FTXSURSTAT (1 << 24)
30#define S5PC1XX_IISCON_FTXSURINTEN (1 << 23)
31#define S5PC1XX_IISCON_TXSDMAPAUSE (1 << 20)
32#define S5PC1XX_IISCON_TXSDMACTIVE (1 << 18)
33
34#define S3C64XX_IISCON_FTXURSTATUS (1 << 17)
35#define S3C64XX_IISCON_FTXURINTEN (1 << 16)
36#define S3C64XX_IISCON_TXFIFO2_EMPTY (1 << 15)
37#define S3C64XX_IISCON_TXFIFO1_EMPTY (1 << 14)
38#define S3C64XX_IISCON_TXFIFO2_FULL (1 << 13)
39#define S3C64XX_IISCON_TXFIFO1_FULL (1 << 12)
40
23#define S3C2412_IISCON_LRINDEX (1 << 11) 41#define S3C2412_IISCON_LRINDEX (1 << 11)
24#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10) 42#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10)
25#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9) 43#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9)
@@ -33,18 +51,30 @@
33#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) 51#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1)
34#define S3C2412_IISCON_IIS_ACTIVE (1 << 0) 52#define S3C2412_IISCON_IIS_ACTIVE (1 << 0)
35 53
54#define S5PC1XX_IISMOD_OPCLK_CDCLK_OUT (0 << 30)
55#define S5PC1XX_IISMOD_OPCLK_CDCLK_IN (1 << 30)
56#define S5PC1XX_IISMOD_OPCLK_BCLK_OUT (2 << 30)
57#define S5PC1XX_IISMOD_OPCLK_PCLK (3 << 30)
58#define S5PC1XX_IISMOD_OPCLK_MASK (3 << 30)
59#define S5PC1XX_IISMOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */
60#define S5PC1XX_IISMOD_BLCS_MASK 0x3
61#define S5PC1XX_IISMOD_BLCS_SHIFT 26
62#define S5PC1XX_IISMOD_BLCP_MASK 0x3
63#define S5PC1XX_IISMOD_BLCP_SHIFT 24
64
65#define S3C64XX_IISMOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */
66#define S3C64XX_IISMOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */
67#define S3C64XX_IISMOD_C1DD_HHALF (1 << 19)
68#define S3C64XX_IISMOD_C1DD_LHALF (1 << 18)
69#define S3C64XX_IISMOD_DC2_EN (1 << 17)
70#define S3C64XX_IISMOD_DC1_EN (1 << 16)
36#define S3C64XX_IISMOD_BLC_16BIT (0 << 13) 71#define S3C64XX_IISMOD_BLC_16BIT (0 << 13)
37#define S3C64XX_IISMOD_BLC_8BIT (1 << 13) 72#define S3C64XX_IISMOD_BLC_8BIT (1 << 13)
38#define S3C64XX_IISMOD_BLC_24BIT (2 << 13) 73#define S3C64XX_IISMOD_BLC_24BIT (2 << 13)
39#define S3C64XX_IISMOD_BLC_MASK (3 << 13) 74#define S3C64XX_IISMOD_BLC_MASK (3 << 13)
40 75
41#define S3C64XX_IISMOD_IMS_PCLK (0 << 10) 76#define S3C2412_IISMOD_IMS_SYSMUX (1 << 10)
42#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10) 77#define S3C2412_IISMOD_SLAVE (1 << 11)
43
44#define S3C2412_IISMOD_MASTER_INTERNAL (0 << 10)
45#define S3C2412_IISMOD_MASTER_EXTERNAL (1 << 10)
46#define S3C2412_IISMOD_SLAVE (2 << 10)
47#define S3C2412_IISMOD_MASTER_MASK (3 << 10)
48#define S3C2412_IISMOD_MODE_TXONLY (0 << 8) 78#define S3C2412_IISMOD_MODE_TXONLY (0 << 8)
49#define S3C2412_IISMOD_MODE_RXONLY (1 << 8) 79#define S3C2412_IISMOD_MODE_RXONLY (1 << 8)
50#define S3C2412_IISMOD_MODE_TXRX (2 << 8) 80#define S3C2412_IISMOD_MODE_TXRX (2 << 8)
@@ -71,12 +101,15 @@
71 101
72#define S3C2412_IISPSR_PSREN (1 << 15) 102#define S3C2412_IISPSR_PSREN (1 << 15)
73 103
104#define S3C64XX_IISFIC_TX2COUNT(x) (((x) >> 24) & 0xf)
105#define S3C64XX_IISFIC_TX1COUNT(x) (((x) >> 16) & 0xf)
106
74#define S3C2412_IISFIC_TXFLUSH (1 << 15) 107#define S3C2412_IISFIC_TXFLUSH (1 << 15)
75#define S3C2412_IISFIC_RXFLUSH (1 << 7) 108#define S3C2412_IISFIC_RXFLUSH (1 << 7)
76#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf) 109#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf)
77#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf) 110#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf)
78 111
79 112#define S5PC1XX_IISFICS_TXFLUSH (1 << 15)
113#define S5PC1XX_IISFICS_TXCOUNT(x) (((x) >> 8) & 0x7f)
80 114
81#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */ 115#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */
82
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index 88515946b6c0..13311c8cf965 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -16,24 +16,17 @@
16 * option) any later version. 16 * option) any later version.
17 */ 17 */
18 18
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/device.h>
22#include <linux/delay.h> 19#include <linux/delay.h>
23#include <linux/clk.h> 20#include <linux/clk.h>
24#include <linux/kernel.h>
25#include <linux/io.h> 21#include <linux/io.h>
26 22
27#include <sound/core.h>
28#include <sound/pcm.h> 23#include <sound/pcm.h>
29#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
30#include <sound/initval.h>
31#include <sound/soc.h> 25#include <sound/soc.h>
32 26
33#include <plat/regs-s3c2412-iis.h>
34
35#include <mach/dma.h> 27#include <mach/dma.h>
36 28
29#include "regs-i2s-v2.h"
37#include "s3c-i2s-v2.h" 30#include "s3c-i2s-v2.h"
38#include "s3c-dma.h" 31#include "s3c-dma.h"
39 32
@@ -272,35 +265,14 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
272 iismod = readl(i2s->regs + S3C2412_IISMOD); 265 iismod = readl(i2s->regs + S3C2412_IISMOD);
273 pr_debug("hw_params r: IISMOD: %x \n", iismod); 266 pr_debug("hw_params r: IISMOD: %x \n", iismod);
274 267
275#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
276#define IISMOD_MASTER_MASK S3C2412_IISMOD_MASTER_MASK
277#define IISMOD_SLAVE S3C2412_IISMOD_SLAVE
278#define IISMOD_MASTER S3C2412_IISMOD_MASTER_INTERNAL
279#endif
280
281#if defined(CONFIG_PLAT_S3C64XX)
282/* From Rev1.1 datasheet, we have two master and two slave modes:
283 * IMS[11:10]:
284 * 00 = master mode, fed from PCLK
285 * 01 = master mode, fed from CLKAUDIO
286 * 10 = slave mode, using PCLK
287 * 11 = slave mode, using I2SCLK
288 */
289#define IISMOD_MASTER_MASK (1 << 11)
290#define IISMOD_SLAVE (1 << 11)
291#define IISMOD_MASTER (0 << 11)
292#endif
293
294 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 268 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
295 case SND_SOC_DAIFMT_CBM_CFM: 269 case SND_SOC_DAIFMT_CBM_CFM:
296 i2s->master = 0; 270 i2s->master = 0;
297 iismod &= ~IISMOD_MASTER_MASK; 271 iismod |= S3C2412_IISMOD_SLAVE;
298 iismod |= IISMOD_SLAVE;
299 break; 272 break;
300 case SND_SOC_DAIFMT_CBS_CFS: 273 case SND_SOC_DAIFMT_CBS_CFS:
301 i2s->master = 1; 274 i2s->master = 1;
302 iismod &= ~IISMOD_MASTER_MASK; 275 iismod &= ~S3C2412_IISMOD_SLAVE;
303 iismod |= IISMOD_MASTER;
304 break; 276 break;
305 default: 277 default:
306 pr_err("unknwon master/slave format\n"); 278 pr_err("unknwon master/slave format\n");
@@ -332,7 +304,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
332 return 0; 304 return 0;
333} 305}
334 306
335static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, 307static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream,
336 struct snd_pcm_hw_params *params, 308 struct snd_pcm_hw_params *params,
337 struct snd_soc_dai *socdai) 309 struct snd_soc_dai *socdai)
338{ 310{
@@ -355,37 +327,67 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
355 iismod = readl(i2s->regs + S3C2412_IISMOD); 327 iismod = readl(i2s->regs + S3C2412_IISMOD);
356 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); 328 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
357 329
358#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) 330 iismod &= ~S3C64XX_IISMOD_BLC_MASK;
331 /* Sample size */
359 switch (params_format(params)) { 332 switch (params_format(params)) {
360 case SNDRV_PCM_FORMAT_S8: 333 case SNDRV_PCM_FORMAT_S8:
361 iismod |= S3C2412_IISMOD_8BIT; 334 iismod |= S3C64XX_IISMOD_BLC_8BIT;
362 break; 335 break;
363 case SNDRV_PCM_FORMAT_S16_LE: 336 case SNDRV_PCM_FORMAT_S16_LE:
364 iismod &= ~S3C2412_IISMOD_8BIT; 337 break;
338 case SNDRV_PCM_FORMAT_S24_LE:
339 iismod |= S3C64XX_IISMOD_BLC_24BIT;
365 break; 340 break;
366 } 341 }
367#endif
368 342
369#ifdef CONFIG_PLAT_S3C64XX 343 writel(iismod, i2s->regs + S3C2412_IISMOD);
370 iismod &= ~(S3C64XX_IISMOD_BLC_MASK | S3C2412_IISMOD_BCLK_MASK); 344 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
371 /* Sample size */ 345
372 switch (params_format(params)) { 346 return 0;
373 case SNDRV_PCM_FORMAT_S8: 347}
374 /* 8 bit sample, 16fs BCLK */ 348
375 iismod |= (S3C64XX_IISMOD_BLC_8BIT | S3C2412_IISMOD_BCLK_16FS); 349static int s3c_i2sv2_set_sysclk(struct snd_soc_dai *cpu_dai,
350 int clk_id, unsigned int freq, int dir)
351{
352 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
353 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
354
355 pr_debug("Entered %s\n", __func__);
356 pr_debug("%s r: IISMOD: %x\n", __func__, iismod);
357
358 switch (clk_id) {
359 case S3C_I2SV2_CLKSRC_PCLK:
360 iismod &= ~S3C2412_IISMOD_IMS_SYSMUX;
376 break; 361 break;
377 case SNDRV_PCM_FORMAT_S16_LE: 362
378 /* 16 bit sample, 32fs BCLK */ 363 case S3C_I2SV2_CLKSRC_AUDIOBUS:
364 iismod |= S3C2412_IISMOD_IMS_SYSMUX;
379 break; 365 break;
380 case SNDRV_PCM_FORMAT_S24_LE: 366
381 /* 24 bit sample, 48fs BCLK */ 367 case S3C_I2SV2_CLKSRC_CDCLK:
382 iismod |= (S3C64XX_IISMOD_BLC_24BIT | S3C2412_IISMOD_BCLK_48FS); 368 /* Error if controller doesn't have the CDCLKCON bit */
369 if (!(i2s->feature & S3C_FEATURE_CDCLKCON))
370 return -EINVAL;
371
372 switch (dir) {
373 case SND_SOC_CLOCK_IN:
374 iismod |= S3C64XX_IISMOD_CDCLKCON;
375 break;
376 case SND_SOC_CLOCK_OUT:
377 iismod &= ~S3C64XX_IISMOD_CDCLKCON;
378 break;
379 default:
380 return -EINVAL;
381 }
383 break; 382 break;
383
384 default:
385 return -EINVAL;
384 } 386 }
385#endif
386 387
387 writel(iismod, i2s->regs + S3C2412_IISMOD); 388 writel(iismod, i2s->regs + S3C2412_IISMOD);
388 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); 389 pr_debug("%s w: IISMOD: %x\n", __func__, iismod);
390
389 return 0; 391 return 0;
390} 392}
391 393
@@ -472,29 +474,25 @@ static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
472 474
473 switch (div_id) { 475 switch (div_id) {
474 case S3C_I2SV2_DIV_BCLK: 476 case S3C_I2SV2_DIV_BCLK:
475 if (div > 3) { 477 switch (div) {
476 /* convert value to bit field */ 478 case 16:
477 479 div = S3C2412_IISMOD_BCLK_16FS;
478 switch (div) { 480 break;
479 case 16:
480 div = S3C2412_IISMOD_BCLK_16FS;
481 break;
482 481
483 case 32: 482 case 32:
484 div = S3C2412_IISMOD_BCLK_32FS; 483 div = S3C2412_IISMOD_BCLK_32FS;
485 break; 484 break;
486 485
487 case 24: 486 case 24:
488 div = S3C2412_IISMOD_BCLK_24FS; 487 div = S3C2412_IISMOD_BCLK_24FS;
489 break; 488 break;
490 489
491 case 48: 490 case 48:
492 div = S3C2412_IISMOD_BCLK_48FS; 491 div = S3C2412_IISMOD_BCLK_48FS;
493 break; 492 break;
494 493
495 default: 494 default:
496 return -EINVAL; 495 return -EINVAL;
497 }
498 } 496 }
499 497
500 reg = readl(i2s->regs + S3C2412_IISMOD); 498 reg = readl(i2s->regs + S3C2412_IISMOD);
@@ -505,29 +503,25 @@ static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
505 break; 503 break;
506 504
507 case S3C_I2SV2_DIV_RCLK: 505 case S3C_I2SV2_DIV_RCLK:
508 if (div > 3) { 506 switch (div) {
509 /* convert value to bit field */ 507 case 256:
510 508 div = S3C2412_IISMOD_RCLK_256FS;
511 switch (div) { 509 break;
512 case 256:
513 div = S3C2412_IISMOD_RCLK_256FS;
514 break;
515 510
516 case 384: 511 case 384:
517 div = S3C2412_IISMOD_RCLK_384FS; 512 div = S3C2412_IISMOD_RCLK_384FS;
518 break; 513 break;
519 514
520 case 512: 515 case 512:
521 div = S3C2412_IISMOD_RCLK_512FS; 516 div = S3C2412_IISMOD_RCLK_512FS;
522 break; 517 break;
523 518
524 case 768: 519 case 768:
525 div = S3C2412_IISMOD_RCLK_768FS; 520 div = S3C2412_IISMOD_RCLK_768FS;
526 break; 521 break;
527 522
528 default: 523 default:
529 return -EINVAL; 524 return -EINVAL;
530 }
531 } 525 }
532 526
533 reg = readl(i2s->regs + S3C2412_IISMOD); 527 reg = readl(i2s->regs + S3C2412_IISMOD);
@@ -553,6 +547,33 @@ static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
553 return 0; 547 return 0;
554} 548}
555 549
550static snd_pcm_sframes_t s3c2412_i2s_delay(struct snd_pcm_substream *substream,
551 struct snd_soc_dai *dai)
552{
553 struct s3c_i2sv2_info *i2s = to_info(dai);
554 u32 reg = readl(i2s->regs + S3C2412_IISFIC);
555 snd_pcm_sframes_t delay;
556
557 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
558 delay = S3C2412_IISFIC_TXCOUNT(reg);
559 else
560 delay = S3C2412_IISFIC_RXCOUNT(reg);
561
562 return delay;
563}
564
565struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai)
566{
567 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
568 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
569
570 if (iismod & S3C2412_IISMOD_IMS_SYSMUX)
571 return i2s->iis_cclk;
572 else
573 return i2s->iis_pclk;
574}
575EXPORT_SYMBOL_GPL(s3c_i2sv2_get_clock);
576
556/* default table of all avaialable root fs divisors */ 577/* default table of all avaialable root fs divisors */
557static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 }; 578static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 };
558 579
@@ -735,9 +756,15 @@ int s3c_i2sv2_register_dai(struct snd_soc_dai *dai)
735 struct snd_soc_dai_ops *ops = dai->ops; 756 struct snd_soc_dai_ops *ops = dai->ops;
736 757
737 ops->trigger = s3c2412_i2s_trigger; 758 ops->trigger = s3c2412_i2s_trigger;
738 ops->hw_params = s3c2412_i2s_hw_params; 759 if (!ops->hw_params)
760 ops->hw_params = s3c_i2sv2_hw_params;
739 ops->set_fmt = s3c2412_i2s_set_fmt; 761 ops->set_fmt = s3c2412_i2s_set_fmt;
740 ops->set_clkdiv = s3c2412_i2s_set_clkdiv; 762 ops->set_clkdiv = s3c2412_i2s_set_clkdiv;
763 ops->set_sysclk = s3c_i2sv2_set_sysclk;
764
765 /* Allow overriding by (for example) IISv4 */
766 if (!ops->delay)
767 ops->delay = s3c2412_i2s_delay;
741 768
742 dai->suspend = s3c2412_i2s_suspend; 769 dai->suspend = s3c2412_i2s_suspend;
743 dai->resume = s3c2412_i2s_resume; 770 dai->resume = s3c2412_i2s_resume;
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/s3c24xx/s3c-i2s-v2.h
index ecf8eaaed1db..766f43a13d8b 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.h
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.h
@@ -25,10 +25,20 @@
25#define S3C_I2SV2_DIV_RCLK (2) 25#define S3C_I2SV2_DIV_RCLK (2)
26#define S3C_I2SV2_DIV_PRESCALER (3) 26#define S3C_I2SV2_DIV_PRESCALER (3)
27 27
28#define S3C_I2SV2_CLKSRC_PCLK 0
29#define S3C_I2SV2_CLKSRC_AUDIOBUS 1
30#define S3C_I2SV2_CLKSRC_CDCLK 2
31
32/* Set this flag for I2S controllers that have the bit IISMOD[12]
33 * bridge/break RCLK signal and external Xi2sCDCLK pin.
34 */
35#define S3C_FEATURE_CDCLKCON (1 << 0)
36
28/** 37/**
29 * struct s3c_i2sv2_info - S3C I2S-V2 information 38 * struct s3c_i2sv2_info - S3C I2S-V2 information
30 * @dev: The parent device passed to use from the probe. 39 * @dev: The parent device passed to use from the probe.
31 * @regs: The pointer to the device registe block. 40 * @regs: The pointer to the device registe block.
41 * @feature: Set of bit-flags indicating features of the controller.
32 * @master: True if the I2S core is the I2S bit clock master. 42 * @master: True if the I2S core is the I2S bit clock master.
33 * @dma_playback: DMA information for playback channel. 43 * @dma_playback: DMA information for playback channel.
34 * @dma_capture: DMA information for capture channel. 44 * @dma_capture: DMA information for capture channel.
@@ -43,9 +53,10 @@ struct s3c_i2sv2_info {
43 struct device *dev; 53 struct device *dev;
44 void __iomem *regs; 54 void __iomem *regs;
45 55
56 u32 feature;
57
46 struct clk *iis_pclk; 58 struct clk *iis_pclk;
47 struct clk *iis_cclk; 59 struct clk *iis_cclk;
48 struct clk *iis_clk;
49 60
50 unsigned char master; 61 unsigned char master;
51 62
@@ -57,6 +68,8 @@ struct s3c_i2sv2_info {
57 u32 suspend_iispsr; 68 u32 suspend_iispsr;
58}; 69};
59 70
71extern struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai);
72
60struct s3c_i2sv2_rate_calc { 73struct s3c_i2sv2_rate_calc {
61 unsigned int clk_div; /* for prescaler */ 74 unsigned int clk_div; /* for prescaler */
62 unsigned int fs_div; /* for root frame clock */ 75 unsigned int fs_div; /* for root frame clock */
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index 359e59346ba2..709adef9d043 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -32,12 +32,11 @@
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <mach/hardware.h> 33#include <mach/hardware.h>
34 34
35#include <plat/regs-s3c2412-iis.h>
36
37#include <mach/regs-gpio.h> 35#include <mach/regs-gpio.h>
38#include <mach/dma.h> 36#include <mach/dma.h>
39 37
40#include "s3c-dma.h" 38#include "s3c-dma.h"
39#include "regs-i2s-v2.h"
41#include "s3c2412-i2s.h" 40#include "s3c2412-i2s.h"
42 41
43#define S3C2412_I2S_DEBUG 0 42#define S3C2412_I2S_DEBUG 0
@@ -66,44 +65,11 @@ static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
66 65
67static struct s3c_i2sv2_info s3c2412_i2s; 66static struct s3c_i2sv2_info s3c2412_i2s;
68 67
69/* 68static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
70 * Set S3C2412 Clock source
71 */
72static int s3c2412_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
73 int clk_id, unsigned int freq, int dir)
74{ 69{
75 u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); 70 return cpu_dai->private_data;
76
77 pr_debug("%s(%p, %d, %u, %d)\n", __func__, cpu_dai, clk_id,
78 freq, dir);
79
80 switch (clk_id) {
81 case S3C2412_CLKSRC_PCLK:
82 s3c2412_i2s.master = 1;
83 iismod &= ~S3C2412_IISMOD_MASTER_MASK;
84 iismod |= S3C2412_IISMOD_MASTER_INTERNAL;
85 break;
86 case S3C2412_CLKSRC_I2SCLK:
87 s3c2412_i2s.master = 0;
88 iismod &= ~S3C2412_IISMOD_MASTER_MASK;
89 iismod |= S3C2412_IISMOD_MASTER_EXTERNAL;
90 break;
91 default:
92 return -EINVAL;
93 }
94
95 writel(iismod, s3c2412_i2s.regs + S3C2412_IISMOD);
96 return 0;
97} 71}
98 72
99
100struct clk *s3c2412_get_iisclk(void)
101{
102 return s3c2412_i2s.iis_clk;
103}
104EXPORT_SYMBOL_GPL(s3c2412_get_iisclk);
105
106
107static int s3c2412_i2s_probe(struct platform_device *pdev, 73static int s3c2412_i2s_probe(struct platform_device *pdev,
108 struct snd_soc_dai *dai) 74 struct snd_soc_dai *dai)
109{ 75{
@@ -142,13 +108,48 @@ static int s3c2412_i2s_probe(struct platform_device *pdev,
142 return 0; 108 return 0;
143} 109}
144 110
111static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
112 struct snd_pcm_hw_params *params,
113 struct snd_soc_dai *cpu_dai)
114{
115 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
116 struct s3c_dma_params *dma_data;
117 u32 iismod;
118
119 pr_debug("Entered %s\n", __func__);
120
121 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
122 dma_data = i2s->dma_playback;
123 else
124 dma_data = i2s->dma_capture;
125
126 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
127
128 iismod = readl(i2s->regs + S3C2412_IISMOD);
129 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
130
131 switch (params_format(params)) {
132 case SNDRV_PCM_FORMAT_S8:
133 iismod |= S3C2412_IISMOD_8BIT;
134 break;
135 case SNDRV_PCM_FORMAT_S16_LE:
136 iismod &= ~S3C2412_IISMOD_8BIT;
137 break;
138 }
139
140 writel(iismod, i2s->regs + S3C2412_IISMOD);
141 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
142
143 return 0;
144}
145
145#define S3C2412_I2S_RATES \ 146#define S3C2412_I2S_RATES \
146 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ 147 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
147 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 148 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
148 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 149 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
149 150
150static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = { 151static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = {
151 .set_sysclk = s3c2412_i2s_set_sysclk, 152 .hw_params = s3c2412_i2s_hw_params,
152}; 153};
153 154
154struct snd_soc_dai s3c2412_i2s_dai = { 155struct snd_soc_dai s3c2412_i2s_dai = {
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/s3c24xx/s3c2412-i2s.h
index 92848e54be16..0b5686b4d5c3 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.h
+++ b/sound/soc/s3c24xx/s3c2412-i2s.h
@@ -21,10 +21,8 @@
21#define S3C2412_DIV_RCLK S3C_I2SV2_DIV_RCLK 21#define S3C2412_DIV_RCLK S3C_I2SV2_DIV_RCLK
22#define S3C2412_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER 22#define S3C2412_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
23 23
24#define S3C2412_CLKSRC_PCLK (0) 24#define S3C2412_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK
25#define S3C2412_CLKSRC_I2SCLK (1) 25#define S3C2412_CLKSRC_I2SCLK S3C_I2SV2_CLKSRC_AUDIOBUS
26
27extern struct clk *s3c2412_get_iisclk(void);
28 26
29extern struct snd_soc_dai s3c2412_i2s_dai; 27extern struct snd_soc_dai s3c2412_i2s_dai;
30 28
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
new file mode 100644
index 000000000000..06db130030a1
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
@@ -0,0 +1,209 @@
1/* sound/soc/s3c24xx/s3c64xx-i2s-v4.c
2 *
3 * ALSA SoC Audio Layer - S3C64XX I2Sv4 driver
4 * Copyright (c) 2010 Samsung Electronics Co. Ltd
5 * Author: Jaswinder Singh <jassi.brar@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/clk.h>
13#include <linux/gpio.h>
14#include <linux/io.h>
15
16#include <sound/soc.h>
17#include <sound/pcm_params.h>
18
19#include <mach/gpio-bank-c.h>
20#include <mach/gpio-bank-h.h>
21#include <plat/gpio-cfg.h>
22
23#include <mach/map.h>
24#include <mach/dma.h>
25
26#include "s3c-dma.h"
27#include "regs-i2s-v2.h"
28#include "s3c64xx-i2s.h"
29
30static struct s3c2410_dma_client s3c64xx_dma_client_out = {
31 .name = "I2Sv4 PCM Stereo out"
32};
33
34static struct s3c2410_dma_client s3c64xx_dma_client_in = {
35 .name = "I2Sv4 PCM Stereo in"
36};
37
38static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_out;
39static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_in;
40static struct s3c_i2sv2_info s3c64xx_i2sv4;
41
42struct snd_soc_dai s3c64xx_i2s_v4_dai;
43EXPORT_SYMBOL_GPL(s3c64xx_i2s_v4_dai);
44
45static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
46{
47 return cpu_dai->private_data;
48}
49
50static int s3c64xx_i2sv4_probe(struct platform_device *pdev,
51 struct snd_soc_dai *dai)
52{
53 /* configure GPIO for i2s port */
54 s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_I2S_V40_DO0);
55 s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_I2S_V40_DO1);
56 s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2);
57 s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK);
58 s3c_gpio_cfgpin(S3C64XX_GPH(7), S3C64XX_GPH7_I2S_V40_CDCLK);
59 s3c_gpio_cfgpin(S3C64XX_GPH(8), S3C64XX_GPH8_I2S_V40_LRCLK);
60 s3c_gpio_cfgpin(S3C64XX_GPH(9), S3C64XX_GPH9_I2S_V40_DI);
61
62 return 0;
63}
64
65static int s3c_i2sv4_hw_params(struct snd_pcm_substream *substream,
66 struct snd_pcm_hw_params *params,
67 struct snd_soc_dai *cpu_dai)
68{
69 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
70 struct s3c_dma_params *dma_data;
71 u32 iismod;
72
73 dev_dbg(cpu_dai->dev, "Entered %s\n", __func__);
74
75 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
76 dma_data = i2s->dma_playback;
77 else
78 dma_data = i2s->dma_capture;
79
80 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
81
82 iismod = readl(i2s->regs + S3C2412_IISMOD);
83 dev_dbg(cpu_dai->dev, "%s: r: IISMOD: %x\n", __func__, iismod);
84
85 iismod &= ~S3C64XX_IISMOD_BLC_MASK;
86 switch (params_format(params)) {
87 case SNDRV_PCM_FORMAT_S8:
88 iismod |= S3C64XX_IISMOD_BLC_8BIT;
89 break;
90 case SNDRV_PCM_FORMAT_S16_LE:
91 break;
92 case SNDRV_PCM_FORMAT_S24_LE:
93 iismod |= S3C64XX_IISMOD_BLC_24BIT;
94 break;
95 }
96
97 writel(iismod, i2s->regs + S3C2412_IISMOD);
98 dev_dbg(cpu_dai->dev, "%s: w: IISMOD: %x\n", __func__, iismod);
99
100 return 0;
101}
102
103static struct snd_soc_dai_ops s3c64xx_i2sv4_dai_ops = {
104 .hw_params = s3c_i2sv4_hw_params,
105};
106
107static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev)
108{
109 struct s3c_i2sv2_info *i2s;
110 struct snd_soc_dai *dai;
111 int ret;
112
113 i2s = &s3c64xx_i2sv4;
114 dai = &s3c64xx_i2s_v4_dai;
115
116 if (dai->dev) {
117 dev_dbg(dai->dev, "%s: \
118 I2Sv4 instance already registered!\n", __func__);
119 return -EBUSY;
120 }
121
122 dai->dev = &pdev->dev;
123 dai->name = "s3c64xx-i2s-v4";
124 dai->id = 0;
125 dai->symmetric_rates = 1;
126 dai->playback.channels_min = 2;
127 dai->playback.channels_max = 2;
128 dai->playback.rates = S3C64XX_I2S_RATES;
129 dai->playback.formats = S3C64XX_I2S_FMTS;
130 dai->capture.channels_min = 2;
131 dai->capture.channels_max = 2;
132 dai->capture.rates = S3C64XX_I2S_RATES;
133 dai->capture.formats = S3C64XX_I2S_FMTS;
134 dai->probe = s3c64xx_i2sv4_probe;
135 dai->ops = &s3c64xx_i2sv4_dai_ops;
136
137 i2s->feature |= S3C_FEATURE_CDCLKCON;
138
139 i2s->dma_capture = &s3c64xx_i2sv4_pcm_stereo_in;
140 i2s->dma_playback = &s3c64xx_i2sv4_pcm_stereo_out;
141
142 i2s->dma_capture->channel = DMACH_HSI_I2SV40_RX;
143 i2s->dma_capture->dma_addr = S3C64XX_PA_IISV4 + S3C2412_IISRXD;
144 i2s->dma_playback->channel = DMACH_HSI_I2SV40_TX;
145 i2s->dma_playback->dma_addr = S3C64XX_PA_IISV4 + S3C2412_IISTXD;
146
147 i2s->dma_capture->client = &s3c64xx_dma_client_in;
148 i2s->dma_capture->dma_size = 4;
149 i2s->dma_playback->client = &s3c64xx_dma_client_out;
150 i2s->dma_playback->dma_size = 4;
151
152 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
153 if (IS_ERR(i2s->iis_cclk)) {
154 dev_err(&pdev->dev, "failed to get audio-bus\n");
155 ret = PTR_ERR(i2s->iis_cclk);
156 goto err;
157 }
158
159 clk_enable(i2s->iis_cclk);
160
161 ret = s3c_i2sv2_probe(pdev, dai, i2s, 0);
162 if (ret)
163 goto err_clk;
164
165 ret = s3c_i2sv2_register_dai(dai);
166 if (ret != 0)
167 goto err_i2sv2;
168
169 return 0;
170
171err_i2sv2:
172 /* Not implemented for I2Sv2 core yet */
173err_clk:
174 clk_put(i2s->iis_cclk);
175err:
176 return ret;
177}
178
179static __devexit int s3c64xx_i2sv4_dev_remove(struct platform_device *pdev)
180{
181 dev_err(&pdev->dev, "Device removal not yet supported\n");
182 return 0;
183}
184
185static struct platform_driver s3c64xx_i2sv4_driver = {
186 .probe = s3c64xx_i2sv4_dev_probe,
187 .remove = s3c64xx_i2sv4_dev_remove,
188 .driver = {
189 .name = "s3c64xx-iis-v4",
190 .owner = THIS_MODULE,
191 },
192};
193
194static int __init s3c64xx_i2sv4_init(void)
195{
196 return platform_driver_register(&s3c64xx_i2sv4_driver);
197}
198module_init(s3c64xx_i2sv4_init);
199
200static void __exit s3c64xx_i2sv4_exit(void)
201{
202 platform_driver_unregister(&s3c64xx_i2sv4_driver);
203}
204module_exit(s3c64xx_i2sv4_exit);
205
206/* Module information */
207MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
208MODULE_DESCRIPTION("S3C64XX I2Sv4 SoC Interface");
209MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index a72c251401ac..1d85cb85a7d2 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -12,16 +12,12 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/device.h>
18#include <linux/clk.h> 15#include <linux/clk.h>
19#include <linux/gpio.h> 16#include <linux/gpio.h>
20#include <linux/io.h> 17#include <linux/io.h>
21 18
22#include <sound/soc.h> 19#include <sound/soc.h>
23 20
24#include <plat/regs-s3c2412-iis.h>
25#include <mach/gpio-bank-d.h> 21#include <mach/gpio-bank-d.h>
26#include <mach/gpio-bank-e.h> 22#include <mach/gpio-bank-e.h>
27#include <plat/gpio-cfg.h> 23#include <plat/gpio-cfg.h>
@@ -30,6 +26,7 @@
30#include <mach/dma.h> 26#include <mach/dma.h>
31 27
32#include "s3c-dma.h" 28#include "s3c-dma.h"
29#include "regs-i2s-v2.h"
33#include "s3c64xx-i2s.h" 30#include "s3c64xx-i2s.h"
34 31
35/* The value should be set to maximum of the total number 32/* The value should be set to maximum of the total number
@@ -57,55 +54,6 @@ static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
57 return cpu_dai->private_data; 54 return cpu_dai->private_data;
58} 55}
59 56
60static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
61 int clk_id, unsigned int freq, int dir)
62{
63 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
64 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
65
66 switch (clk_id) {
67 case S3C64XX_CLKSRC_PCLK:
68 iismod &= ~S3C64XX_IISMOD_IMS_SYSMUX;
69 break;
70
71 case S3C64XX_CLKSRC_MUX:
72 iismod |= S3C64XX_IISMOD_IMS_SYSMUX;
73 break;
74
75 case S3C64XX_CLKSRC_CDCLK:
76 switch (dir) {
77 case SND_SOC_CLOCK_IN:
78 iismod |= S3C64XX_IISMOD_CDCLKCON;
79 break;
80 case SND_SOC_CLOCK_OUT:
81 iismod &= ~S3C64XX_IISMOD_CDCLKCON;
82 break;
83 default:
84 return -EINVAL;
85 }
86 break;
87
88 default:
89 return -EINVAL;
90 }
91
92 writel(iismod, i2s->regs + S3C2412_IISMOD);
93
94 return 0;
95}
96
97struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
98{
99 struct s3c_i2sv2_info *i2s = to_info(dai);
100 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
101
102 if (iismod & S3C64XX_IISMOD_IMS_SYSMUX)
103 return i2s->iis_cclk;
104 else
105 return i2s->iis_pclk;
106}
107EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
108
109static int s3c64xx_i2s_probe(struct platform_device *pdev, 57static int s3c64xx_i2s_probe(struct platform_device *pdev,
110 struct snd_soc_dai *dai) 58 struct snd_soc_dai *dai)
111{ 59{
@@ -130,18 +78,7 @@ static int s3c64xx_i2s_probe(struct platform_device *pdev,
130} 78}
131 79
132 80
133#define S3C64XX_I2S_RATES \ 81static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops;
134 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
135 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
136 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
137
138#define S3C64XX_I2S_FMTS \
139 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
140 SNDRV_PCM_FMTBIT_S24_LE)
141
142static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = {
143 .set_sysclk = s3c64xx_i2s_set_sysclk,
144};
145 82
146static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) 83static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
147{ 84{
@@ -171,6 +108,8 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
171 dai->probe = s3c64xx_i2s_probe; 108 dai->probe = s3c64xx_i2s_probe;
172 dai->ops = &s3c64xx_i2s_dai_ops; 109 dai->ops = &s3c64xx_i2s_dai_ops;
173 110
111 i2s->feature |= S3C_FEATURE_CDCLKCON;
112
174 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; 113 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
175 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; 114 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
176 115
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
index abe7253b55fc..7a40f43d1d51 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.h
@@ -23,12 +23,20 @@ struct clk;
23#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK 23#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK
24#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER 24#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
25 25
26#define S3C64XX_CLKSRC_PCLK (0) 26#define S3C64XX_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK
27#define S3C64XX_CLKSRC_MUX (1) 27#define S3C64XX_CLKSRC_MUX S3C_I2SV2_CLKSRC_AUDIOBUS
28#define S3C64XX_CLKSRC_CDCLK (2) 28#define S3C64XX_CLKSRC_CDCLK S3C_I2SV2_CLKSRC_CDCLK
29 29
30extern struct snd_soc_dai s3c64xx_i2s_dai[]; 30#define S3C64XX_I2S_RATES \
31 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
32 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
33 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
34
35#define S3C64XX_I2S_FMTS \
36 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
37 SNDRV_PCM_FMTBIT_S24_LE)
31 38
32extern struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai); 39extern struct snd_soc_dai s3c64xx_i2s_dai[];
40extern struct snd_soc_dai s3c64xx_i2s_v4_dai;
33 41
34#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ 42#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */
diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c
index efe4901213a3..07e8e51d10d6 100644
--- a/sound/soc/s3c24xx/smdk64xx_wm8580.c
+++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c
@@ -22,8 +22,6 @@
22#include "s3c-dma.h" 22#include "s3c-dma.h"
23#include "s3c64xx-i2s.h" 23#include "s3c64xx-i2s.h"
24 24
25#define S3C64XX_I2S_V4 2
26
27/* SMDK64XX has a 12MHZ crystal attached to WM8580 */ 25/* SMDK64XX has a 12MHZ crystal attached to WM8580 */
28#define SMDK64XX_WM8580_FREQ 12000000 26#define SMDK64XX_WM8580_FREQ 12000000
29 27
@@ -215,7 +213,7 @@ static struct snd_soc_dai_link smdk64xx_dai[] = {
215{ /* Primary Playback i/f */ 213{ /* Primary Playback i/f */
216 .name = "WM8580 PAIF RX", 214 .name = "WM8580 PAIF RX",
217 .stream_name = "Playback", 215 .stream_name = "Playback",
218 .cpu_dai = &s3c64xx_i2s_dai[S3C64XX_I2S_V4], 216 .cpu_dai = &s3c64xx_i2s_v4_dai,
219 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFRX], 217 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFRX],
220 .init = smdk64xx_wm8580_init_paifrx, 218 .init = smdk64xx_wm8580_init_paifrx,
221 .ops = &smdk64xx_ops, 219 .ops = &smdk64xx_ops,
@@ -223,7 +221,7 @@ static struct snd_soc_dai_link smdk64xx_dai[] = {
223{ /* Primary Capture i/f */ 221{ /* Primary Capture i/f */
224 .name = "WM8580 PAIF TX", 222 .name = "WM8580 PAIF TX",
225 .stream_name = "Capture", 223 .stream_name = "Capture",
226 .cpu_dai = &s3c64xx_i2s_dai[S3C64XX_I2S_V4], 224 .cpu_dai = &s3c64xx_i2s_v4_dai,
227 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFTX], 225 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFTX],
228 .init = smdk64xx_wm8580_init_paiftx, 226 .init = smdk64xx_wm8580_init_paiftx,
229 .ops = &smdk64xx_ops, 227 .ops = &smdk64xx_ops,
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index f07f6d8b93e1..a1d14bc3c76f 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -1,5 +1,5 @@
1menu "SoC Audio support for SuperH" 1menu "SoC Audio support for SuperH"
2 depends on SUPERH 2 depends on SUPERH || ARCH_SHMOBILE
3 3
4config SND_SOC_PCM_SH7760 4config SND_SOC_PCM_SH7760
5 tristate "SoC Audio support for Renesas SH7760" 5 tristate "SoC Audio support for Renesas SH7760"
@@ -22,7 +22,6 @@ config SND_SOC_SH4_SSI
22 22
23config SND_SOC_SH4_FSI 23config SND_SOC_SH4_FSI
24 tristate "SH4 FSI support" 24 tristate "SH4 FSI support"
25 depends on CPU_SUBTYPE_SH7724
26 help 25 help
27 This option enables FSI sound support 26 This option enables FSI sound support
28 27
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index 5263ab18f827..be018542314e 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -22,11 +22,25 @@
22#include <sound/sh_fsi.h> 22#include <sound/sh_fsi.h>
23#include <../sound/soc/codecs/ak4642.h> 23#include <../sound/soc/codecs/ak4642.h>
24 24
25static int fsi_ak4642_dai_init(struct snd_soc_codec *codec)
26{
27 int ret;
28
29 ret = snd_soc_dai_set_fmt(&ak4642_dai, SND_SOC_DAIFMT_CBM_CFM);
30 if (ret < 0)
31 return ret;
32
33 ret = snd_soc_dai_set_sysclk(&ak4642_dai, 0, 11289600, 0);
34
35 return ret;
36}
37
25static struct snd_soc_dai_link fsi_dai_link = { 38static struct snd_soc_dai_link fsi_dai_link = {
26 .name = "AK4642", 39 .name = "AK4642",
27 .stream_name = "AK4642", 40 .stream_name = "AK4642",
28 .cpu_dai = &fsi_soc_dai[0], /* fsi */ 41 .cpu_dai = &fsi_soc_dai[0], /* fsi */
29 .codec_dai = &ak4642_dai, 42 .codec_dai = &ak4642_dai,
43 .init = fsi_ak4642_dai_init,
30 .ops = NULL, 44 .ops = NULL,
31}; 45};
32 46
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 8dc966f45c36..3396a0db06ba 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -41,14 +41,19 @@
41#define MUTE_ST 0x0028 41#define MUTE_ST 0x0028
42#define REG_END MUTE_ST 42#define REG_END MUTE_ST
43 43
44
45#define CPU_INT_ST 0x01F4
46#define CPU_IEMSK 0x01F8
47#define CPU_IMSK 0x01FC
44#define INT_ST 0x0200 48#define INT_ST 0x0200
45#define IEMSK 0x0204 49#define IEMSK 0x0204
46#define IMSK 0x0208 50#define IMSK 0x0208
47#define MUTE 0x020C 51#define MUTE 0x020C
48#define CLK_RST 0x0210 52#define CLK_RST 0x0210
49#define SOFT_RST 0x0214 53#define SOFT_RST 0x0214
50#define MREG_START INT_ST 54#define FIFO_SZ 0x0218
51#define MREG_END SOFT_RST 55#define MREG_START CPU_INT_ST
56#define MREG_END FIFO_SZ
52 57
53/* DO_FMT */ 58/* DO_FMT */
54/* DI_FMT */ 59/* DI_FMT */
@@ -80,6 +85,17 @@
80#define INT_A_IN (1 << 4) 85#define INT_A_IN (1 << 4)
81#define INT_A_OUT (1 << 0) 86#define INT_A_OUT (1 << 0)
82 87
88/* SOFT_RST */
89#define PBSR (1 << 12) /* Port B Software Reset */
90#define PASR (1 << 8) /* Port A Software Reset */
91#define IR (1 << 4) /* Interrupt Reset */
92#define FSISR (1 << 0) /* Software Reset */
93
94/* FIFO_SZ */
95#define OUT_SZ_MASK 0x7
96#define BO_SZ_SHIFT 8
97#define AO_SZ_SHIFT 0
98
83#define FSI_RATES SNDRV_PCM_RATE_8000_96000 99#define FSI_RATES SNDRV_PCM_RATE_8000_96000
84 100
85#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 101#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
@@ -105,11 +121,18 @@ struct fsi_priv {
105 int periods; 121 int periods;
106}; 122};
107 123
124struct fsi_regs {
125 u32 int_st;
126 u32 iemsk;
127 u32 imsk;
128};
129
108struct fsi_master { 130struct fsi_master {
109 void __iomem *base; 131 void __iomem *base;
110 int irq; 132 int irq;
111 struct fsi_priv fsia; 133 struct fsi_priv fsia;
112 struct fsi_priv fsib; 134 struct fsi_priv fsib;
135 struct fsi_regs *regs;
113 struct sh_fsi_platform_info *info; 136 struct sh_fsi_platform_info *info;
114 spinlock_t lock; 137 spinlock_t lock;
115}; 138};
@@ -317,7 +340,7 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
317/************************************************************************ 340/************************************************************************
318 341
319 342
320 ctrl function 343 irq function
321 344
322 345
323************************************************************************/ 346************************************************************************/
@@ -326,8 +349,8 @@ static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
326 u32 data = fsi_port_ab_io_bit(fsi, is_play); 349 u32 data = fsi_port_ab_io_bit(fsi, is_play);
327 struct fsi_master *master = fsi_get_master(fsi); 350 struct fsi_master *master = fsi_get_master(fsi);
328 351
329 fsi_master_mask_set(master, IMSK, data, data); 352 fsi_master_mask_set(master, master->regs->imsk, data, data);
330 fsi_master_mask_set(master, IEMSK, data, data); 353 fsi_master_mask_set(master, master->regs->iemsk, data, data);
331} 354}
332 355
333static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 356static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
@@ -335,10 +358,39 @@ static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
335 u32 data = fsi_port_ab_io_bit(fsi, is_play); 358 u32 data = fsi_port_ab_io_bit(fsi, is_play);
336 struct fsi_master *master = fsi_get_master(fsi); 359 struct fsi_master *master = fsi_get_master(fsi);
337 360
338 fsi_master_mask_set(master, IMSK, data, 0); 361 fsi_master_mask_set(master, master->regs->imsk, data, 0);
339 fsi_master_mask_set(master, IEMSK, data, 0); 362 fsi_master_mask_set(master, master->regs->iemsk, data, 0);
363}
364
365static u32 fsi_irq_get_status(struct fsi_master *master)
366{
367 return fsi_master_read(master, master->regs->int_st);
368}
369
370static void fsi_irq_clear_all_status(struct fsi_master *master)
371{
372 fsi_master_write(master, master->regs->int_st, 0x0000000);
340} 373}
341 374
375static void fsi_irq_clear_status(struct fsi_priv *fsi)
376{
377 u32 data = 0;
378 struct fsi_master *master = fsi_get_master(fsi);
379
380 data |= fsi_port_ab_io_bit(fsi, 0);
381 data |= fsi_port_ab_io_bit(fsi, 1);
382
383 /* clear interrupt factor */
384 fsi_master_mask_set(master, master->regs->int_st, data, 0);
385}
386
387/************************************************************************
388
389
390 ctrl function
391
392
393************************************************************************/
342static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 394static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
343{ 395{
344 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4); 396 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
@@ -350,41 +402,61 @@ static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
350 fsi_master_mask_set(master, CLK_RST, val, 0); 402 fsi_master_mask_set(master, CLK_RST, val, 0);
351} 403}
352 404
353static void fsi_irq_init(struct fsi_priv *fsi, int is_play) 405static void fsi_fifo_init(struct fsi_priv *fsi,
406 int is_play,
407 struct snd_soc_dai *dai)
354{ 408{
355 u32 data; 409 struct fsi_master *master = fsi_get_master(fsi);
356 u32 ctrl; 410 u32 ctrl, shift, i;
357 411
358 data = fsi_port_ab_io_bit(fsi, is_play); 412 /* get on-chip RAM capacity */
359 ctrl = is_play ? DOFF_CTL : DIFF_CTL; 413 shift = fsi_master_read(master, FIFO_SZ);
414 shift >>= fsi_is_port_a(fsi) ? AO_SZ_SHIFT : BO_SZ_SHIFT;
415 shift &= OUT_SZ_MASK;
416 fsi->fifo_max = 256 << shift;
417 dev_dbg(dai->dev, "fifo = %d words\n", fsi->fifo_max);
360 418
361 /* set IMSK */ 419 /*
362 fsi_irq_disable(fsi, is_play); 420 * The maximum number of sample data varies depending
421 * on the number of channels selected for the format.
422 *
423 * FIFOs are used in 4-channel units in 3-channel mode
424 * and in 8-channel units in 5- to 7-channel mode
425 * meaning that more FIFOs than the required size of DPRAM
426 * are used.
427 *
428 * ex) if 256 words of DP-RAM is connected
429 * 1 channel: 256 (256 x 1 = 256)
430 * 2 channels: 128 (128 x 2 = 256)
431 * 3 channels: 64 ( 64 x 3 = 192)
432 * 4 channels: 64 ( 64 x 4 = 256)
433 * 5 channels: 32 ( 32 x 5 = 160)
434 * 6 channels: 32 ( 32 x 6 = 192)
435 * 7 channels: 32 ( 32 x 7 = 224)
436 * 8 channels: 32 ( 32 x 8 = 256)
437 */
438 for (i = 1; i < fsi->chan; i <<= 1)
439 fsi->fifo_max >>= 1;
440 dev_dbg(dai->dev, "%d channel %d store\n", fsi->chan, fsi->fifo_max);
441
442 ctrl = is_play ? DOFF_CTL : DIFF_CTL;
363 443
364 /* set interrupt generation factor */ 444 /* set interrupt generation factor */
365 fsi_reg_write(fsi, ctrl, IRQ_HALF); 445 fsi_reg_write(fsi, ctrl, IRQ_HALF);
366 446
367 /* clear FIFO */ 447 /* clear FIFO */
368 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 448 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
369
370 /* clear interrupt factor */
371 fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
372} 449}
373 450
374static void fsi_soft_all_reset(struct fsi_master *master) 451static void fsi_soft_all_reset(struct fsi_master *master)
375{ 452{
376 u32 status = fsi_master_read(master, SOFT_RST);
377
378 /* port AB reset */ 453 /* port AB reset */
379 status &= 0x000000ff; 454 fsi_master_mask_set(master, SOFT_RST, PASR | PBSR, 0);
380 fsi_master_write(master, SOFT_RST, status);
381 mdelay(10); 455 mdelay(10);
382 456
383 /* soft reset */ 457 /* soft reset */
384 status &= 0x000000f0; 458 fsi_master_mask_set(master, SOFT_RST, FSISR, 0);
385 fsi_master_write(master, SOFT_RST, status); 459 fsi_master_mask_set(master, SOFT_RST, FSISR, FSISR);
386 status |= 0x00000001;
387 fsi_master_write(master, SOFT_RST, status);
388 mdelay(10); 460 mdelay(10);
389} 461}
390 462
@@ -559,12 +631,11 @@ static int fsi_data_pop(struct fsi_priv *fsi, int startup)
559static irqreturn_t fsi_interrupt(int irq, void *data) 631static irqreturn_t fsi_interrupt(int irq, void *data)
560{ 632{
561 struct fsi_master *master = data; 633 struct fsi_master *master = data;
562 u32 status = fsi_master_read(master, SOFT_RST) & ~0x00000010; 634 u32 int_st = fsi_irq_get_status(master);
563 u32 int_st = fsi_master_read(master, INT_ST);
564 635
565 /* clear irq status */ 636 /* clear irq status */
566 fsi_master_write(master, SOFT_RST, status); 637 fsi_master_mask_set(master, SOFT_RST, IR, 0);
567 fsi_master_write(master, SOFT_RST, status | 0x00000010); 638 fsi_master_mask_set(master, SOFT_RST, IR, IR);
568 639
569 if (int_st & INT_A_OUT) 640 if (int_st & INT_A_OUT)
570 fsi_data_push(&master->fsia, 0); 641 fsi_data_push(&master->fsia, 0);
@@ -575,7 +646,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
575 if (int_st & INT_B_IN) 646 if (int_st & INT_B_IN)
576 fsi_data_pop(&master->fsib, 0); 647 fsi_data_pop(&master->fsib, 0);
577 648
578 fsi_master_write(master, INT_ST, 0x0000000); 649 fsi_irq_clear_all_status(master);
579 650
580 return IRQ_HANDLED; 651 return IRQ_HANDLED;
581} 652}
@@ -669,29 +740,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
669 dev_err(dai->dev, "unknown format.\n"); 740 dev_err(dai->dev, "unknown format.\n");
670 return -EINVAL; 741 return -EINVAL;
671 } 742 }
672
673 switch (fsi->chan) {
674 case 1:
675 fsi->fifo_max = 256;
676 break;
677 case 2:
678 fsi->fifo_max = 128;
679 break;
680 case 3:
681 case 4:
682 fsi->fifo_max = 64;
683 break;
684 case 5:
685 case 6:
686 case 7:
687 case 8:
688 fsi->fifo_max = 32;
689 break;
690 default:
691 dev_err(dai->dev, "channel size error.\n");
692 return -EINVAL;
693 }
694
695 fsi_reg_write(fsi, reg, data); 743 fsi_reg_write(fsi, reg, data);
696 744
697 /* 745 /*
@@ -700,8 +748,12 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
700 if (is_master) 748 if (is_master)
701 fsi_clk_ctrl(fsi, 1); 749 fsi_clk_ctrl(fsi, 1);
702 750
703 /* irq setting */ 751 /* irq clear */
704 fsi_irq_init(fsi, is_play); 752 fsi_irq_disable(fsi, is_play);
753 fsi_irq_clear_status(fsi);
754
755 /* fifo init */
756 fsi_fifo_init(fsi, is_play, dai);
705 757
706 return ret; 758 return ret;
707} 759}
@@ -913,6 +965,7 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
913static int fsi_probe(struct platform_device *pdev) 965static int fsi_probe(struct platform_device *pdev)
914{ 966{
915 struct fsi_master *master; 967 struct fsi_master *master;
968 const struct platform_device_id *id_entry;
916 struct resource *res; 969 struct resource *res;
917 unsigned int irq; 970 unsigned int irq;
918 int ret; 971 int ret;
@@ -922,6 +975,12 @@ static int fsi_probe(struct platform_device *pdev)
922 return -ENODEV; 975 return -ENODEV;
923 } 976 }
924 977
978 id_entry = pdev->id_entry;
979 if (!id_entry) {
980 dev_err(&pdev->dev, "unknown fsi device\n");
981 return -ENODEV;
982 }
983
925 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 984 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
926 irq = platform_get_irq(pdev, 0); 985 irq = platform_get_irq(pdev, 0);
927 if (!res || (int)irq <= 0) { 986 if (!res || (int)irq <= 0) {
@@ -950,6 +1009,7 @@ static int fsi_probe(struct platform_device *pdev)
950 master->fsia.master = master; 1009 master->fsia.master = master;
951 master->fsib.base = master->base + 0x40; 1010 master->fsib.base = master->base + 0x40;
952 master->fsib.master = master; 1011 master->fsib.master = master;
1012 master->regs = (struct fsi_regs *)id_entry->driver_data;
953 spin_lock_init(&master->lock); 1013 spin_lock_init(&master->lock);
954 1014
955 pm_runtime_enable(&pdev->dev); 1015 pm_runtime_enable(&pdev->dev);
@@ -962,7 +1022,8 @@ static int fsi_probe(struct platform_device *pdev)
962 1022
963 fsi_soft_all_reset(master); 1023 fsi_soft_all_reset(master);
964 1024
965 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 1025 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED,
1026 id_entry->name, master);
966 if (ret) { 1027 if (ret) {
967 dev_err(&pdev->dev, "irq request err\n"); 1028 dev_err(&pdev->dev, "irq request err\n");
968 goto exit_iounmap; 1029 goto exit_iounmap;
@@ -1029,6 +1090,23 @@ static struct dev_pm_ops fsi_pm_ops = {
1029 .runtime_resume = fsi_runtime_nop, 1090 .runtime_resume = fsi_runtime_nop,
1030}; 1091};
1031 1092
1093static struct fsi_regs fsi_regs = {
1094 .int_st = INT_ST,
1095 .iemsk = IEMSK,
1096 .imsk = IMSK,
1097};
1098
1099static struct fsi_regs fsi2_regs = {
1100 .int_st = CPU_INT_ST,
1101 .iemsk = CPU_IEMSK,
1102 .imsk = CPU_IMSK,
1103};
1104
1105static struct platform_device_id fsi_id_table[] = {
1106 { "sh_fsi", (kernel_ulong_t)&fsi_regs },
1107 { "sh_fsi2", (kernel_ulong_t)&fsi2_regs },
1108};
1109
1032static struct platform_driver fsi_driver = { 1110static struct platform_driver fsi_driver = {
1033 .driver = { 1111 .driver = {
1034 .name = "sh_fsi", 1112 .name = "sh_fsi",
@@ -1036,6 +1114,7 @@ static struct platform_driver fsi_driver = {
1036 }, 1114 },
1037 .probe = fsi_probe, 1115 .probe = fsi_probe,
1038 .remove = fsi_remove, 1116 .remove = fsi_remove,
1117 .id_table = fsi_id_table,
1039}; 1118};
1040 1119
1041static int __init fsi_mobile_init(void) 1120static int __init fsi_mobile_init(void)
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 5869dc3be781..472af38188c1 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -44,6 +44,8 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
44 return 0; 44 return 0;
45 } 45 }
46 46
47 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
48
47 ret = codec->hw_write(codec->control_data, data, 2); 49 ret = codec->hw_write(codec->control_data, data, 2);
48 if (ret == 2) 50 if (ret == 2)
49 return 0; 51 return 0;
@@ -112,6 +114,8 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
112 return 0; 114 return 0;
113 } 115 }
114 116
117 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
118
115 ret = codec->hw_write(codec->control_data, data, 2); 119 ret = codec->hw_write(codec->control_data, data, 2);
116 if (ret == 2) 120 if (ret == 2)
117 return 0; 121 return 0;
@@ -159,7 +163,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
159 163
160 BUG_ON(codec->volatile_register); 164 BUG_ON(codec->volatile_register);
161 165
162 data[0] = reg & 0xff; 166 reg &= 0xff;
167 data[0] = reg;
163 data[1] = value & 0xff; 168 data[1] = value & 0xff;
164 169
165 if (reg < codec->reg_cache_size) 170 if (reg < codec->reg_cache_size)
@@ -170,6 +175,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
170 return 0; 175 return 0;
171 } 176 }
172 177
178 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
179
173 if (codec->hw_write(codec->control_data, data, 2) == 2) 180 if (codec->hw_write(codec->control_data, data, 2) == 2)
174 return 0; 181 return 0;
175 else 182 else
@@ -180,6 +187,7 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
180 unsigned int reg) 187 unsigned int reg)
181{ 188{
182 u8 *cache = codec->reg_cache; 189 u8 *cache = codec->reg_cache;
190 reg &= 0xff;
183 if (reg >= codec->reg_cache_size) 191 if (reg >= codec->reg_cache_size)
184 return -1; 192 return -1;
185 return cache[reg]; 193 return cache[reg];
@@ -203,6 +211,8 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
203 return 0; 211 return 0;
204 } 212 }
205 213
214 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
215
206 if (codec->hw_write(codec->control_data, data, 3) == 3) 216 if (codec->hw_write(codec->control_data, data, 3) == 3)
207 return 0; 217 return 0;
208 else 218 else
@@ -226,6 +236,40 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
226} 236}
227 237
228#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 238#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
239static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
240 unsigned int r)
241{
242 struct i2c_msg xfer[2];
243 u8 reg = r;
244 u8 data;
245 int ret;
246 struct i2c_client *client = codec->control_data;
247
248 /* Write register */
249 xfer[0].addr = client->addr;
250 xfer[0].flags = 0;
251 xfer[0].len = 1;
252 xfer[0].buf = &reg;
253
254 /* Read data */
255 xfer[1].addr = client->addr;
256 xfer[1].flags = I2C_M_RD;
257 xfer[1].len = 1;
258 xfer[1].buf = &data;
259
260 ret = i2c_transfer(client->adapter, xfer, 2);
261 if (ret != 2) {
262 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
263 return 0;
264 }
265
266 return data;
267}
268#else
269#define snd_soc_8_8_read_i2c NULL
270#endif
271
272#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
229static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, 273static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
230 unsigned int r) 274 unsigned int r)
231{ 275{
@@ -326,6 +370,8 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
326 return 0; 370 return 0;
327 } 371 }
328 372
373 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
374
329 ret = codec->hw_write(codec->control_data, data, 3); 375 ret = codec->hw_write(codec->control_data, data, 3);
330 if (ret == 3) 376 if (ret == 3)
331 return 0; 377 return 0;
@@ -366,6 +412,86 @@ static int snd_soc_16_8_spi_write(void *control_data, const char *data,
366#define snd_soc_16_8_spi_write NULL 412#define snd_soc_16_8_spi_write NULL
367#endif 413#endif
368 414
415#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
416static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
417 unsigned int r)
418{
419 struct i2c_msg xfer[2];
420 u16 reg = cpu_to_be16(r);
421 u16 data;
422 int ret;
423 struct i2c_client *client = codec->control_data;
424
425 /* Write register */
426 xfer[0].addr = client->addr;
427 xfer[0].flags = 0;
428 xfer[0].len = 2;
429 xfer[0].buf = (u8 *)&reg;
430
431 /* Read data */
432 xfer[1].addr = client->addr;
433 xfer[1].flags = I2C_M_RD;
434 xfer[1].len = 2;
435 xfer[1].buf = (u8 *)&data;
436
437 ret = i2c_transfer(client->adapter, xfer, 2);
438 if (ret != 2) {
439 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
440 return 0;
441 }
442
443 return be16_to_cpu(data);
444}
445#else
446#define snd_soc_16_16_read_i2c NULL
447#endif
448
449static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
450 unsigned int reg)
451{
452 u16 *cache = codec->reg_cache;
453
454 if (reg >= codec->reg_cache_size ||
455 snd_soc_codec_volatile_register(codec, reg)) {
456 if (codec->cache_only)
457 return -EINVAL;
458
459 return codec->hw_read(codec, reg);
460 }
461
462 return cache[reg];
463}
464
465static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
466 unsigned int value)
467{
468 u16 *cache = codec->reg_cache;
469 u8 data[4];
470 int ret;
471
472 data[0] = (reg >> 8) & 0xff;
473 data[1] = reg & 0xff;
474 data[2] = (value >> 8) & 0xff;
475 data[3] = value & 0xff;
476
477 if (reg < codec->reg_cache_size)
478 cache[reg] = value;
479
480 if (codec->cache_only) {
481 codec->cache_sync = 1;
482 return 0;
483 }
484
485 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
486
487 ret = codec->hw_write(codec->control_data, data, 4);
488 if (ret == 4)
489 return 0;
490 if (ret < 0)
491 return ret;
492 else
493 return -EIO;
494}
369 495
370static struct { 496static struct {
371 int addr_bits; 497 int addr_bits;
@@ -388,6 +514,7 @@ static struct {
388 { 514 {
389 .addr_bits = 8, .data_bits = 8, 515 .addr_bits = 8, .data_bits = 8,
390 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read, 516 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
517 .i2c_read = snd_soc_8_8_read_i2c,
391 }, 518 },
392 { 519 {
393 .addr_bits = 8, .data_bits = 16, 520 .addr_bits = 8, .data_bits = 16,
@@ -400,6 +527,11 @@ static struct {
400 .i2c_read = snd_soc_16_8_read_i2c, 527 .i2c_read = snd_soc_16_8_read_i2c,
401 .spi_write = snd_soc_16_8_spi_write, 528 .spi_write = snd_soc_16_8_spi_write,
402 }, 529 },
530 {
531 .addr_bits = 16, .data_bits = 16,
532 .write = snd_soc_16_16_write, .read = snd_soc_16_16_read,
533 .i2c_read = snd_soc_16_16_read_i2c,
534 },
403}; 535};
404 536
405/** 537/**
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index ad7f9528d751..998569d60330 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -316,7 +316,7 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
316 316
317 if (codec_dai->symmetric_rates || cpu_dai->symmetric_rates || 317 if (codec_dai->symmetric_rates || cpu_dai->symmetric_rates ||
318 machine->symmetric_rates) { 318 machine->symmetric_rates) {
319 dev_dbg(card->dev, "Symmetry forces %dHz rate\n", 319 dev_dbg(card->dev, "Symmetry forces %dHz rate\n",
320 machine->rate); 320 machine->rate);
321 321
322 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 322 ret = snd_pcm_hw_constraint_minmax(substream->runtime,
@@ -405,6 +405,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
405 codec_dai->playback.formats & cpu_dai->playback.formats; 405 codec_dai->playback.formats & cpu_dai->playback.formats;
406 runtime->hw.rates = 406 runtime->hw.rates =
407 codec_dai->playback.rates & cpu_dai->playback.rates; 407 codec_dai->playback.rates & cpu_dai->playback.rates;
408 if (codec_dai->playback.rates
409 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
410 runtime->hw.rates |= cpu_dai->playback.rates;
411 if (cpu_dai->playback.rates
412 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
413 runtime->hw.rates |= codec_dai->playback.rates;
408 } else { 414 } else {
409 runtime->hw.rate_min = 415 runtime->hw.rate_min =
410 max(codec_dai->capture.rate_min, 416 max(codec_dai->capture.rate_min,
@@ -422,6 +428,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
422 codec_dai->capture.formats & cpu_dai->capture.formats; 428 codec_dai->capture.formats & cpu_dai->capture.formats;
423 runtime->hw.rates = 429 runtime->hw.rates =
424 codec_dai->capture.rates & cpu_dai->capture.rates; 430 codec_dai->capture.rates & cpu_dai->capture.rates;
431 if (codec_dai->capture.rates
432 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
433 runtime->hw.rates |= cpu_dai->capture.rates;
434 if (cpu_dai->capture.rates
435 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
436 runtime->hw.rates |= codec_dai->capture.rates;
425 } 437 }
426 438
427 snd_pcm_limit_hw_rates(runtime); 439 snd_pcm_limit_hw_rates(runtime);
@@ -455,12 +467,15 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
455 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, 467 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
456 runtime->hw.rate_max); 468 runtime->hw.rate_max);
457 469
458 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 470 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
459 cpu_dai->playback.active = codec_dai->playback.active = 1; 471 cpu_dai->playback.active++;
460 else 472 codec_dai->playback.active++;
461 cpu_dai->capture.active = codec_dai->capture.active = 1; 473 } else {
462 cpu_dai->active = codec_dai->active = 1; 474 cpu_dai->capture.active++;
463 cpu_dai->runtime = runtime; 475 codec_dai->capture.active++;
476 }
477 cpu_dai->active++;
478 codec_dai->active++;
464 card->codec->active++; 479 card->codec->active++;
465 mutex_unlock(&pcm_mutex); 480 mutex_unlock(&pcm_mutex);
466 return 0; 481 return 0;
@@ -536,15 +551,16 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
536 551
537 mutex_lock(&pcm_mutex); 552 mutex_lock(&pcm_mutex);
538 553
539 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 554 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
540 cpu_dai->playback.active = codec_dai->playback.active = 0; 555 cpu_dai->playback.active--;
541 else 556 codec_dai->playback.active--;
542 cpu_dai->capture.active = codec_dai->capture.active = 0; 557 } else {
543 558 cpu_dai->capture.active--;
544 if (codec_dai->playback.active == 0 && 559 codec_dai->capture.active--;
545 codec_dai->capture.active == 0) {
546 cpu_dai->active = codec_dai->active = 0;
547 } 560 }
561
562 cpu_dai->active--;
563 codec_dai->active--;
548 codec->active--; 564 codec->active--;
549 565
550 /* Muting the DAC suppresses artifacts caused during digital 566 /* Muting the DAC suppresses artifacts caused during digital
@@ -564,7 +580,6 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
564 580
565 if (platform->pcm_ops->close) 581 if (platform->pcm_ops->close)
566 platform->pcm_ops->close(substream); 582 platform->pcm_ops->close(substream);
567 cpu_dai->runtime = NULL;
568 583
569 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 584 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
570 /* start delayed pop wq here for playback streams */ 585 /* start delayed pop wq here for playback streams */
@@ -802,6 +817,41 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
802 return 0; 817 return 0;
803} 818}
804 819
820/*
821 * soc level wrapper for pointer callback
822 * If cpu_dai, codec_dai, platform driver has the delay callback, than
823 * the runtime->delay will be updated accordingly.
824 */
825static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
826{
827 struct snd_soc_pcm_runtime *rtd = substream->private_data;
828 struct snd_soc_device *socdev = rtd->socdev;
829 struct snd_soc_card *card = socdev->card;
830 struct snd_soc_platform *platform = card->platform;
831 struct snd_soc_dai_link *machine = rtd->dai;
832 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
833 struct snd_soc_dai *codec_dai = machine->codec_dai;
834 struct snd_pcm_runtime *runtime = substream->runtime;
835 snd_pcm_uframes_t offset = 0;
836 snd_pcm_sframes_t delay = 0;
837
838 if (platform->pcm_ops->pointer)
839 offset = platform->pcm_ops->pointer(substream);
840
841 if (cpu_dai->ops->delay)
842 delay += cpu_dai->ops->delay(substream, cpu_dai);
843
844 if (codec_dai->ops->delay)
845 delay += codec_dai->ops->delay(substream, codec_dai);
846
847 if (platform->delay)
848 delay += platform->delay(substream, codec_dai);
849
850 runtime->delay = delay;
851
852 return offset;
853}
854
805/* ASoC PCM operations */ 855/* ASoC PCM operations */
806static struct snd_pcm_ops soc_pcm_ops = { 856static struct snd_pcm_ops soc_pcm_ops = {
807 .open = soc_pcm_open, 857 .open = soc_pcm_open,
@@ -810,6 +860,7 @@ static struct snd_pcm_ops soc_pcm_ops = {
810 .hw_free = soc_pcm_hw_free, 860 .hw_free = soc_pcm_hw_free,
811 .prepare = soc_pcm_prepare, 861 .prepare = soc_pcm_prepare,
812 .trigger = soc_pcm_trigger, 862 .trigger = soc_pcm_trigger,
863 .pointer = soc_pcm_pointer,
813}; 864};
814 865
815#ifdef CONFIG_PM 866#ifdef CONFIG_PM
@@ -843,23 +894,35 @@ static int soc_suspend(struct device *dev)
843 /* mute any active DAC's */ 894 /* mute any active DAC's */
844 for (i = 0; i < card->num_links; i++) { 895 for (i = 0; i < card->num_links; i++) {
845 struct snd_soc_dai *dai = card->dai_link[i].codec_dai; 896 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
897
898 if (card->dai_link[i].ignore_suspend)
899 continue;
900
846 if (dai->ops->digital_mute && dai->playback.active) 901 if (dai->ops->digital_mute && dai->playback.active)
847 dai->ops->digital_mute(dai, 1); 902 dai->ops->digital_mute(dai, 1);
848 } 903 }
849 904
850 /* suspend all pcms */ 905 /* suspend all pcms */
851 for (i = 0; i < card->num_links; i++) 906 for (i = 0; i < card->num_links; i++) {
907 if (card->dai_link[i].ignore_suspend)
908 continue;
909
852 snd_pcm_suspend_all(card->dai_link[i].pcm); 910 snd_pcm_suspend_all(card->dai_link[i].pcm);
911 }
853 912
854 if (card->suspend_pre) 913 if (card->suspend_pre)
855 card->suspend_pre(pdev, PMSG_SUSPEND); 914 card->suspend_pre(pdev, PMSG_SUSPEND);
856 915
857 for (i = 0; i < card->num_links; i++) { 916 for (i = 0; i < card->num_links; i++) {
858 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 917 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
918
919 if (card->dai_link[i].ignore_suspend)
920 continue;
921
859 if (cpu_dai->suspend && !cpu_dai->ac97_control) 922 if (cpu_dai->suspend && !cpu_dai->ac97_control)
860 cpu_dai->suspend(cpu_dai); 923 cpu_dai->suspend(cpu_dai);
861 if (platform->suspend) 924 if (platform->suspend)
862 platform->suspend(cpu_dai); 925 platform->suspend(&card->dai_link[i]);
863 } 926 }
864 927
865 /* close any waiting streams and save state */ 928 /* close any waiting streams and save state */
@@ -868,6 +931,10 @@ static int soc_suspend(struct device *dev)
868 931
869 for (i = 0; i < codec->num_dai; i++) { 932 for (i = 0; i < codec->num_dai; i++) {
870 char *stream = codec->dai[i].playback.stream_name; 933 char *stream = codec->dai[i].playback.stream_name;
934
935 if (card->dai_link[i].ignore_suspend)
936 continue;
937
871 if (stream != NULL) 938 if (stream != NULL)
872 snd_soc_dapm_stream_event(codec, stream, 939 snd_soc_dapm_stream_event(codec, stream,
873 SND_SOC_DAPM_STREAM_SUSPEND); 940 SND_SOC_DAPM_STREAM_SUSPEND);
@@ -877,11 +944,26 @@ static int soc_suspend(struct device *dev)
877 SND_SOC_DAPM_STREAM_SUSPEND); 944 SND_SOC_DAPM_STREAM_SUSPEND);
878 } 945 }
879 946
880 if (codec_dev->suspend) 947 /* If there are paths active then the CODEC will be held with
881 codec_dev->suspend(pdev, PMSG_SUSPEND); 948 * bias _ON and should not be suspended. */
949 if (codec_dev->suspend) {
950 switch (codec->bias_level) {
951 case SND_SOC_BIAS_STANDBY:
952 case SND_SOC_BIAS_OFF:
953 codec_dev->suspend(pdev, PMSG_SUSPEND);
954 break;
955 default:
956 dev_dbg(socdev->dev, "CODEC is on over suspend\n");
957 break;
958 }
959 }
882 960
883 for (i = 0; i < card->num_links; i++) { 961 for (i = 0; i < card->num_links; i++) {
884 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 962 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
963
964 if (card->dai_link[i].ignore_suspend)
965 continue;
966
885 if (cpu_dai->suspend && cpu_dai->ac97_control) 967 if (cpu_dai->suspend && cpu_dai->ac97_control)
886 cpu_dai->suspend(cpu_dai); 968 cpu_dai->suspend(cpu_dai);
887 } 969 }
@@ -913,20 +995,44 @@ static void soc_resume_deferred(struct work_struct *work)
913 995
914 dev_dbg(socdev->dev, "starting resume work\n"); 996 dev_dbg(socdev->dev, "starting resume work\n");
915 997
998 /* Bring us up into D2 so that DAPM starts enabling things */
999 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D2);
1000
916 if (card->resume_pre) 1001 if (card->resume_pre)
917 card->resume_pre(pdev); 1002 card->resume_pre(pdev);
918 1003
919 for (i = 0; i < card->num_links; i++) { 1004 for (i = 0; i < card->num_links; i++) {
920 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 1005 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
1006
1007 if (card->dai_link[i].ignore_suspend)
1008 continue;
1009
921 if (cpu_dai->resume && cpu_dai->ac97_control) 1010 if (cpu_dai->resume && cpu_dai->ac97_control)
922 cpu_dai->resume(cpu_dai); 1011 cpu_dai->resume(cpu_dai);
923 } 1012 }
924 1013
925 if (codec_dev->resume) 1014 /* If the CODEC was idle over suspend then it will have been
926 codec_dev->resume(pdev); 1015 * left with bias OFF or STANDBY and suspended so we must now
1016 * resume. Otherwise the suspend was suppressed.
1017 */
1018 if (codec_dev->resume) {
1019 switch (codec->bias_level) {
1020 case SND_SOC_BIAS_STANDBY:
1021 case SND_SOC_BIAS_OFF:
1022 codec_dev->resume(pdev);
1023 break;
1024 default:
1025 dev_dbg(socdev->dev, "CODEC was on over suspend\n");
1026 break;
1027 }
1028 }
927 1029
928 for (i = 0; i < codec->num_dai; i++) { 1030 for (i = 0; i < codec->num_dai; i++) {
929 char *stream = codec->dai[i].playback.stream_name; 1031 char *stream = codec->dai[i].playback.stream_name;
1032
1033 if (card->dai_link[i].ignore_suspend)
1034 continue;
1035
930 if (stream != NULL) 1036 if (stream != NULL)
931 snd_soc_dapm_stream_event(codec, stream, 1037 snd_soc_dapm_stream_event(codec, stream,
932 SND_SOC_DAPM_STREAM_RESUME); 1038 SND_SOC_DAPM_STREAM_RESUME);
@@ -939,16 +1045,24 @@ static void soc_resume_deferred(struct work_struct *work)
939 /* unmute any active DACs */ 1045 /* unmute any active DACs */
940 for (i = 0; i < card->num_links; i++) { 1046 for (i = 0; i < card->num_links; i++) {
941 struct snd_soc_dai *dai = card->dai_link[i].codec_dai; 1047 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
1048
1049 if (card->dai_link[i].ignore_suspend)
1050 continue;
1051
942 if (dai->ops->digital_mute && dai->playback.active) 1052 if (dai->ops->digital_mute && dai->playback.active)
943 dai->ops->digital_mute(dai, 0); 1053 dai->ops->digital_mute(dai, 0);
944 } 1054 }
945 1055
946 for (i = 0; i < card->num_links; i++) { 1056 for (i = 0; i < card->num_links; i++) {
947 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 1057 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
1058
1059 if (card->dai_link[i].ignore_suspend)
1060 continue;
1061
948 if (cpu_dai->resume && !cpu_dai->ac97_control) 1062 if (cpu_dai->resume && !cpu_dai->ac97_control)
949 cpu_dai->resume(cpu_dai); 1063 cpu_dai->resume(cpu_dai);
950 if (platform->resume) 1064 if (platform->resume)
951 platform->resume(cpu_dai); 1065 platform->resume(&card->dai_link[i]);
952 } 1066 }
953 1067
954 if (card->resume_post) 1068 if (card->resume_post)
@@ -1233,26 +1347,25 @@ static int soc_remove(struct platform_device *pdev)
1233 struct snd_soc_platform *platform = card->platform; 1347 struct snd_soc_platform *platform = card->platform;
1234 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 1348 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
1235 1349
1236 if (!card->instantiated) 1350 if (card->instantiated) {
1237 return 0; 1351 run_delayed_work(&card->delayed_work);
1238 1352
1239 run_delayed_work(&card->delayed_work); 1353 if (platform->remove)
1354 platform->remove(pdev);
1240 1355
1241 if (platform->remove) 1356 if (codec_dev->remove)
1242 platform->remove(pdev); 1357 codec_dev->remove(pdev);
1243 1358
1244 if (codec_dev->remove) 1359 for (i = 0; i < card->num_links; i++) {
1245 codec_dev->remove(pdev); 1360 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
1361 if (cpu_dai->remove)
1362 cpu_dai->remove(pdev, cpu_dai);
1363 }
1246 1364
1247 for (i = 0; i < card->num_links; i++) { 1365 if (card->remove)
1248 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 1366 card->remove(pdev);
1249 if (cpu_dai->remove)
1250 cpu_dai->remove(pdev, cpu_dai);
1251 } 1367 }
1252 1368
1253 if (card->remove)
1254 card->remove(pdev);
1255
1256 snd_soc_unregister_card(card); 1369 snd_soc_unregister_card(card);
1257 1370
1258 return 0; 1371 return 0;
@@ -1336,7 +1449,6 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
1336 dai_link->pcm = pcm; 1449 dai_link->pcm = pcm;
1337 pcm->private_data = rtd; 1450 pcm->private_data = rtd;
1338 soc_pcm_ops.mmap = platform->pcm_ops->mmap; 1451 soc_pcm_ops.mmap = platform->pcm_ops->mmap;
1339 soc_pcm_ops.pointer = platform->pcm_ops->pointer;
1340 soc_pcm_ops.ioctl = platform->pcm_ops->ioctl; 1452 soc_pcm_ops.ioctl = platform->pcm_ops->ioctl;
1341 soc_pcm_ops.copy = platform->pcm_ops->copy; 1453 soc_pcm_ops.copy = platform->pcm_ops->copy;
1342 soc_pcm_ops.silence = platform->pcm_ops->silence; 1454 soc_pcm_ops.silence = platform->pcm_ops->silence;
@@ -1906,18 +2018,22 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
1906{ 2018{
1907 struct soc_mixer_control *mc = 2019 struct soc_mixer_control *mc =
1908 (struct soc_mixer_control *)kcontrol->private_value; 2020 (struct soc_mixer_control *)kcontrol->private_value;
1909 int max = mc->max; 2021 int platform_max;
1910 unsigned int shift = mc->shift; 2022 unsigned int shift = mc->shift;
1911 unsigned int rshift = mc->rshift; 2023 unsigned int rshift = mc->rshift;
1912 2024
1913 if (max == 1 && !strstr(kcontrol->id.name, " Volume")) 2025 if (!mc->platform_max)
2026 mc->platform_max = mc->max;
2027 platform_max = mc->platform_max;
2028
2029 if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume"))
1914 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 2030 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1915 else 2031 else
1916 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2032 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1917 2033
1918 uinfo->count = shift == rshift ? 1 : 2; 2034 uinfo->count = shift == rshift ? 1 : 2;
1919 uinfo->value.integer.min = 0; 2035 uinfo->value.integer.min = 0;
1920 uinfo->value.integer.max = max; 2036 uinfo->value.integer.max = platform_max;
1921 return 0; 2037 return 0;
1922} 2038}
1923EXPORT_SYMBOL_GPL(snd_soc_info_volsw); 2039EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
@@ -2015,16 +2131,20 @@ int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
2015{ 2131{
2016 struct soc_mixer_control *mc = 2132 struct soc_mixer_control *mc =
2017 (struct soc_mixer_control *)kcontrol->private_value; 2133 (struct soc_mixer_control *)kcontrol->private_value;
2018 int max = mc->max; 2134 int platform_max;
2019 2135
2020 if (max == 1 && !strstr(kcontrol->id.name, " Volume")) 2136 if (!mc->platform_max)
2137 mc->platform_max = mc->max;
2138 platform_max = mc->platform_max;
2139
2140 if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume"))
2021 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 2141 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2022 else 2142 else
2023 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2143 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2024 2144
2025 uinfo->count = 2; 2145 uinfo->count = 2;
2026 uinfo->value.integer.min = 0; 2146 uinfo->value.integer.min = 0;
2027 uinfo->value.integer.max = max; 2147 uinfo->value.integer.max = platform_max;
2028 return 0; 2148 return 0;
2029} 2149}
2030EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r); 2150EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r);
@@ -2125,13 +2245,17 @@ int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
2125{ 2245{
2126 struct soc_mixer_control *mc = 2246 struct soc_mixer_control *mc =
2127 (struct soc_mixer_control *)kcontrol->private_value; 2247 (struct soc_mixer_control *)kcontrol->private_value;
2128 int max = mc->max; 2248 int platform_max;
2129 int min = mc->min; 2249 int min = mc->min;
2130 2250
2251 if (!mc->platform_max)
2252 mc->platform_max = mc->max;
2253 platform_max = mc->platform_max;
2254
2131 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2255 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2132 uinfo->count = 2; 2256 uinfo->count = 2;
2133 uinfo->value.integer.min = 0; 2257 uinfo->value.integer.min = 0;
2134 uinfo->value.integer.max = max-min; 2258 uinfo->value.integer.max = platform_max - min;
2135 return 0; 2259 return 0;
2136} 2260}
2137EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8); 2261EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8);
@@ -2190,6 +2314,45 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
2190EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); 2314EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
2191 2315
2192/** 2316/**
2317 * snd_soc_limit_volume - Set new limit to an existing volume control.
2318 *
2319 * @codec: where to look for the control
2320 * @name: Name of the control
2321 * @max: new maximum limit
2322 *
2323 * Return 0 for success, else error.
2324 */
2325int snd_soc_limit_volume(struct snd_soc_codec *codec,
2326 const char *name, int max)
2327{
2328 struct snd_card *card = codec->card;
2329 struct snd_kcontrol *kctl;
2330 struct soc_mixer_control *mc;
2331 int found = 0;
2332 int ret = -EINVAL;
2333
2334 /* Sanity check for name and max */
2335 if (unlikely(!name || max <= 0))
2336 return -EINVAL;
2337
2338 list_for_each_entry(kctl, &card->controls, list) {
2339 if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) {
2340 found = 1;
2341 break;
2342 }
2343 }
2344 if (found) {
2345 mc = (struct soc_mixer_control *)kctl->private_value;
2346 if (max <= mc->max) {
2347 mc->platform_max = max;
2348 ret = 0;
2349 }
2350 }
2351 return ret;
2352}
2353EXPORT_SYMBOL_GPL(snd_soc_limit_volume);
2354
2355/**
2193 * snd_soc_dai_set_sysclk - configure DAI system or master clock. 2356 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
2194 * @dai: DAI 2357 * @dai: DAI
2195 * @clk_id: DAI specific clock ID 2358 * @clk_id: DAI specific clock ID
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7c28f401f436..03cb7c05ebec 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -98,7 +98,6 @@ static void pop_dbg(u32 pop_time, const char *fmt, ...)
98 98
99 if (pop_time) { 99 if (pop_time) {
100 vprintk(fmt, args); 100 vprintk(fmt, args);
101 pop_wait(pop_time);
102 } 101 }
103 102
104 va_end(args); 103 va_end(args);
@@ -315,62 +314,14 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
315 pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n", 314 pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n",
316 widget->name, widget->power ? "on" : "off", 315 widget->name, widget->power ? "on" : "off",
317 codec->pop_time); 316 codec->pop_time);
318 snd_soc_write(codec, widget->reg, new);
319 pop_wait(codec->pop_time); 317 pop_wait(codec->pop_time);
318 snd_soc_write(codec, widget->reg, new);
320 } 319 }
321 pr_debug("reg %x old %x new %x change %d\n", widget->reg, 320 pr_debug("reg %x old %x new %x change %d\n", widget->reg,
322 old, new, change); 321 old, new, change);
323 return change; 322 return change;
324} 323}
325 324
326/* ramps the volume up or down to minimise pops before or after a
327 * DAPM power event */
328static int dapm_set_pga(struct snd_soc_dapm_widget *widget, int power)
329{
330 const struct snd_kcontrol_new *k = widget->kcontrols;
331
332 if (widget->muted && !power)
333 return 0;
334 if (!widget->muted && power)
335 return 0;
336
337 if (widget->num_kcontrols && k) {
338 struct soc_mixer_control *mc =
339 (struct soc_mixer_control *)k->private_value;
340 unsigned int reg = mc->reg;
341 unsigned int shift = mc->shift;
342 int max = mc->max;
343 unsigned int mask = (1 << fls(max)) - 1;
344 unsigned int invert = mc->invert;
345
346 if (power) {
347 int i;
348 /* power up has happended, increase volume to last level */
349 if (invert) {
350 for (i = max; i > widget->saved_value; i--)
351 snd_soc_update_bits(widget->codec, reg, mask, i);
352 } else {
353 for (i = 0; i < widget->saved_value; i++)
354 snd_soc_update_bits(widget->codec, reg, mask, i);
355 }
356 widget->muted = 0;
357 } else {
358 /* power down is about to occur, decrease volume to mute */
359 int val = snd_soc_read(widget->codec, reg);
360 int i = widget->saved_value = (val >> shift) & mask;
361 if (invert) {
362 for (; i < mask; i++)
363 snd_soc_update_bits(widget->codec, reg, mask, i);
364 } else {
365 for (; i > 0; i--)
366 snd_soc_update_bits(widget->codec, reg, mask, i);
367 }
368 widget->muted = 1;
369 }
370 }
371 return 0;
372}
373
374/* create new dapm mixer control */ 325/* create new dapm mixer control */
375static int dapm_new_mixer(struct snd_soc_codec *codec, 326static int dapm_new_mixer(struct snd_soc_codec *codec,
376 struct snd_soc_dapm_widget *w) 327 struct snd_soc_dapm_widget *w)
@@ -465,20 +416,10 @@ err:
465static int dapm_new_pga(struct snd_soc_codec *codec, 416static int dapm_new_pga(struct snd_soc_codec *codec,
466 struct snd_soc_dapm_widget *w) 417 struct snd_soc_dapm_widget *w)
467{ 418{
468 struct snd_kcontrol *kcontrol; 419 if (w->num_kcontrols)
469 int ret = 0; 420 pr_err("asoc: PGA controls not supported: '%s'\n", w->name);
470
471 if (!w->num_kcontrols)
472 return -EINVAL;
473 421
474 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); 422 return 0;
475 ret = snd_ctl_add(codec->card, kcontrol);
476 if (ret < 0) {
477 printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name);
478 return ret;
479 }
480
481 return ret;
482} 423}
483 424
484/* reset 'walked' bit for each dapm path */ 425/* reset 'walked' bit for each dapm path */
@@ -490,6 +431,25 @@ static inline void dapm_clear_walk(struct snd_soc_codec *codec)
490 p->walked = 0; 431 p->walked = 0;
491} 432}
492 433
434/* We implement power down on suspend by checking the power state of
435 * the ALSA card - when we are suspending the ALSA state for the card
436 * is set to D3.
437 */
438static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
439{
440 struct snd_soc_codec *codec = widget->codec;
441
442 switch (snd_power_get_state(codec->card)) {
443 case SNDRV_CTL_POWER_D3hot:
444 case SNDRV_CTL_POWER_D3cold:
445 if (widget->ignore_suspend)
446 pr_debug("%s ignoring suspend\n", widget->name);
447 return widget->ignore_suspend;
448 default:
449 return 1;
450 }
451}
452
493/* 453/*
494 * Recursively check for a completed path to an active or physically connected 454 * Recursively check for a completed path to an active or physically connected
495 * output widget. Returns number of complete paths. 455 * output widget. Returns number of complete paths.
@@ -506,7 +466,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
506 case snd_soc_dapm_adc: 466 case snd_soc_dapm_adc:
507 case snd_soc_dapm_aif_out: 467 case snd_soc_dapm_aif_out:
508 if (widget->active) 468 if (widget->active)
509 return 1; 469 return snd_soc_dapm_suspend_check(widget);
510 default: 470 default:
511 break; 471 break;
512 } 472 }
@@ -514,12 +474,12 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
514 if (widget->connected) { 474 if (widget->connected) {
515 /* connected pin ? */ 475 /* connected pin ? */
516 if (widget->id == snd_soc_dapm_output && !widget->ext) 476 if (widget->id == snd_soc_dapm_output && !widget->ext)
517 return 1; 477 return snd_soc_dapm_suspend_check(widget);
518 478
519 /* connected jack or spk ? */ 479 /* connected jack or spk ? */
520 if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk || 480 if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk ||
521 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources))) 481 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources)))
522 return 1; 482 return snd_soc_dapm_suspend_check(widget);
523 } 483 }
524 484
525 list_for_each_entry(path, &widget->sinks, list_source) { 485 list_for_each_entry(path, &widget->sinks, list_source) {
@@ -552,7 +512,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
552 case snd_soc_dapm_dac: 512 case snd_soc_dapm_dac:
553 case snd_soc_dapm_aif_in: 513 case snd_soc_dapm_aif_in:
554 if (widget->active) 514 if (widget->active)
555 return 1; 515 return snd_soc_dapm_suspend_check(widget);
556 default: 516 default:
557 break; 517 break;
558 } 518 }
@@ -560,16 +520,16 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
560 if (widget->connected) { 520 if (widget->connected) {
561 /* connected pin ? */ 521 /* connected pin ? */
562 if (widget->id == snd_soc_dapm_input && !widget->ext) 522 if (widget->id == snd_soc_dapm_input && !widget->ext)
563 return 1; 523 return snd_soc_dapm_suspend_check(widget);
564 524
565 /* connected VMID/Bias for lower pops */ 525 /* connected VMID/Bias for lower pops */
566 if (widget->id == snd_soc_dapm_vmid) 526 if (widget->id == snd_soc_dapm_vmid)
567 return 1; 527 return snd_soc_dapm_suspend_check(widget);
568 528
569 /* connected jack ? */ 529 /* connected jack ? */
570 if (widget->id == snd_soc_dapm_mic || 530 if (widget->id == snd_soc_dapm_mic ||
571 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks))) 531 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks)))
572 return 1; 532 return snd_soc_dapm_suspend_check(widget);
573 } 533 }
574 534
575 list_for_each_entry(path, &widget->sources, list_sink) { 535 list_for_each_entry(path, &widget->sources, list_sink) {
@@ -634,16 +594,8 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
634 return ret; 594 return ret;
635 } 595 }
636 596
637 /* Lower PGA volume to reduce pops */
638 if (w->id == snd_soc_dapm_pga && !w->power)
639 dapm_set_pga(w, w->power);
640
641 dapm_update_bits(w); 597 dapm_update_bits(w);
642 598
643 /* Raise PGA volume to reduce pops */
644 if (w->id == snd_soc_dapm_pga && w->power)
645 dapm_set_pga(w, w->power);
646
647 /* power up post event */ 599 /* power up post event */
648 if (w->power && w->event && 600 if (w->power && w->event &&
649 (w->event_flags & SND_SOC_DAPM_POST_PMU)) { 601 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
@@ -810,10 +762,6 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
810 pr_err("%s: pre event failed: %d\n", 762 pr_err("%s: pre event failed: %d\n",
811 w->name, ret); 763 w->name, ret);
812 } 764 }
813
814 /* Lower PGA volume to reduce pops */
815 if (w->id == snd_soc_dapm_pga && !w->power)
816 dapm_set_pga(w, w->power);
817 } 765 }
818 766
819 if (reg >= 0) { 767 if (reg >= 0) {
@@ -825,10 +773,6 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
825 } 773 }
826 774
827 list_for_each_entry(w, pending, power_list) { 775 list_for_each_entry(w, pending, power_list) {
828 /* Raise PGA volume to reduce pops */
829 if (w->id == snd_soc_dapm_pga && w->power)
830 dapm_set_pga(w, w->power);
831
832 /* power up post event */ 776 /* power up post event */
833 if (w->power && w->event && 777 if (w->power && w->event &&
834 (w->event_flags & SND_SOC_DAPM_POST_PMU)) { 778 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
@@ -973,19 +917,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
973 if (!w->power_check) 917 if (!w->power_check)
974 continue; 918 continue;
975 919
976 /* If we're suspending then pull down all the 920 if (!w->force)
977 * power. */
978 switch (event) {
979 case SND_SOC_DAPM_STREAM_SUSPEND:
980 power = 0;
981 break;
982
983 default:
984 power = w->power_check(w); 921 power = w->power_check(w);
985 if (power) 922 else
986 sys_power = 1; 923 power = 1;
987 break; 924 if (power)
988 } 925 sys_power = 1;
989 926
990 if (w->power == power) 927 if (w->power == power)
991 continue; 928 continue;
@@ -1076,6 +1013,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
1076 1013
1077 pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n", 1014 pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n",
1078 codec->pop_time); 1015 codec->pop_time);
1016 pop_wait(codec->pop_time);
1079 1017
1080 return 0; 1018 return 0;
1081} 1019}
@@ -1338,6 +1276,9 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
1338 if (!strcmp(w->name, pin)) { 1276 if (!strcmp(w->name, pin)) {
1339 pr_debug("dapm: %s: pin %s\n", codec->name, pin); 1277 pr_debug("dapm: %s: pin %s\n", codec->name, pin);
1340 w->connected = status; 1278 w->connected = status;
1279 /* Allow disabling of forced pins */
1280 if (status == 0)
1281 w->force = 0;
1341 return 0; 1282 return 0;
1342 } 1283 }
1343 } 1284 }
@@ -1594,12 +1535,6 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
1594 unsigned int invert = mc->invert; 1535 unsigned int invert = mc->invert;
1595 unsigned int mask = (1 << fls(max)) - 1; 1536 unsigned int mask = (1 << fls(max)) - 1;
1596 1537
1597 /* return the saved value if we are powered down */
1598 if (widget->id == snd_soc_dapm_pga && !widget->power) {
1599 ucontrol->value.integer.value[0] = widget->saved_value;
1600 return 0;
1601 }
1602
1603 ucontrol->value.integer.value[0] = 1538 ucontrol->value.integer.value[0] =
1604 (snd_soc_read(widget->codec, reg) >> shift) & mask; 1539 (snd_soc_read(widget->codec, reg) >> shift) & mask;
1605 if (shift != rshift) 1540 if (shift != rshift)
@@ -1659,13 +1594,6 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1659 mutex_lock(&widget->codec->mutex); 1594 mutex_lock(&widget->codec->mutex);
1660 widget->value = val; 1595 widget->value = val;
1661 1596
1662 /* save volume value if the widget is powered down */
1663 if (widget->id == snd_soc_dapm_pga && !widget->power) {
1664 widget->saved_value = val;
1665 mutex_unlock(&widget->codec->mutex);
1666 return 1;
1667 }
1668
1669 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { 1597 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
1670 if (val) 1598 if (val)
1671 /* new connection */ 1599 /* new connection */
@@ -2094,18 +2022,8 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
2094 w->active = 0; 2022 w->active = 0;
2095 break; 2023 break;
2096 case SND_SOC_DAPM_STREAM_SUSPEND: 2024 case SND_SOC_DAPM_STREAM_SUSPEND:
2097 if (w->active)
2098 w->suspend = 1;
2099 w->active = 0;
2100 break;
2101 case SND_SOC_DAPM_STREAM_RESUME: 2025 case SND_SOC_DAPM_STREAM_RESUME:
2102 if (w->suspend) {
2103 w->active = 1;
2104 w->suspend = 0;
2105 }
2106 break;
2107 case SND_SOC_DAPM_STREAM_PAUSE_PUSH: 2026 case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
2108 break;
2109 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: 2027 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
2110 break; 2028 break;
2111 } 2029 }
@@ -2135,6 +2053,36 @@ int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin)
2135EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); 2053EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
2136 2054
2137/** 2055/**
2056 * snd_soc_dapm_force_enable_pin - force a pin to be enabled
2057 * @codec: SoC codec
2058 * @pin: pin name
2059 *
2060 * Enables input/output pin regardless of any other state. This is
2061 * intended for use with microphone bias supplies used in microphone
2062 * jack detection.
2063 *
2064 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2065 * do any widget power switching.
2066 */
2067int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec, const char *pin)
2068{
2069 struct snd_soc_dapm_widget *w;
2070
2071 list_for_each_entry(w, &codec->dapm_widgets, list) {
2072 if (!strcmp(w->name, pin)) {
2073 pr_debug("dapm: %s: pin %s\n", codec->name, pin);
2074 w->connected = 1;
2075 w->force = 1;
2076 return 0;
2077 }
2078 }
2079
2080 pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin);
2081 return -EINVAL;
2082}
2083EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
2084
2085/**
2138 * snd_soc_dapm_disable_pin - disable pin. 2086 * snd_soc_dapm_disable_pin - disable pin.
2139 * @codec: SoC codec 2087 * @codec: SoC codec
2140 * @pin: pin name 2088 * @pin: pin name
@@ -2192,6 +2140,33 @@ int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin)
2192EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); 2140EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
2193 2141
2194/** 2142/**
2143 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
2144 * @codec: audio codec
2145 * @pin: audio signal pin endpoint (or start point)
2146 *
2147 * Mark the given endpoint or pin as ignoring suspend. When the
2148 * system is disabled a path between two endpoints flagged as ignoring
2149 * suspend will not be disabled. The path must already be enabled via
2150 * normal means at suspend time, it will not be turned on if it was not
2151 * already enabled.
2152 */
2153int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin)
2154{
2155 struct snd_soc_dapm_widget *w;
2156
2157 list_for_each_entry(w, &codec->dapm_widgets, list) {
2158 if (!strcmp(w->name, pin)) {
2159 w->ignore_suspend = 1;
2160 return 0;
2161 }
2162 }
2163
2164 pr_err("Unknown DAPM pin: %s\n", pin);
2165 return -EINVAL;
2166}
2167EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
2168
2169/**
2195 * snd_soc_dapm_free - free dapm resources 2170 * snd_soc_dapm_free - free dapm resources
2196 * @socdev: SoC device 2171 * @socdev: SoC device
2197 * 2172 *
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 3c07a94c2e30..29159e1781d0 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -37,6 +37,7 @@ int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type,
37{ 37{
38 jack->card = card; 38 jack->card = card;
39 INIT_LIST_HEAD(&jack->pins); 39 INIT_LIST_HEAD(&jack->pins);
40 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
40 41
41 return snd_jack_new(card->codec->card, id, type, &jack->jack); 42 return snd_jack_new(card->codec->card, id, type, &jack->jack);
42} 43}
@@ -63,10 +64,9 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
63 int enable; 64 int enable;
64 int oldstatus; 65 int oldstatus;
65 66
66 if (!jack) { 67 if (!jack)
67 WARN_ON_ONCE(!jack);
68 return; 68 return;
69 } 69
70 codec = jack->card->codec; 70 codec = jack->card->codec;
71 71
72 mutex_lock(&codec->mutex); 72 mutex_lock(&codec->mutex);
@@ -93,6 +93,9 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
93 snd_soc_dapm_disable_pin(codec, pin->pin); 93 snd_soc_dapm_disable_pin(codec, pin->pin);
94 } 94 }
95 95
96 /* Report before the DAPM sync to help users updating micbias status */
97 blocking_notifier_call_chain(&jack->notifier, status, NULL);
98
96 snd_soc_dapm_sync(codec); 99 snd_soc_dapm_sync(codec);
97 100
98 snd_jack_report(jack->jack, status); 101 snd_jack_report(jack->jack, status);
@@ -143,6 +146,40 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
143} 146}
144EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins); 147EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins);
145 148
149/**
150 * snd_soc_jack_notifier_register - Register a notifier for jack status
151 *
152 * @jack: ASoC jack
153 * @nb: Notifier block to register
154 *
155 * Register for notification of the current status of the jack. Note
156 * that it is not possible to report additional jack events in the
157 * callback from the notifier, this is intended to support
158 * applications such as enabling electrical detection only when a
159 * mechanical detection event has occurred.
160 */
161void snd_soc_jack_notifier_register(struct snd_soc_jack *jack,
162 struct notifier_block *nb)
163{
164 blocking_notifier_chain_register(&jack->notifier, nb);
165}
166EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_register);
167
168/**
169 * snd_soc_jack_notifier_unregister - Unregister a notifier for jack status
170 *
171 * @jack: ASoC jack
172 * @nb: Notifier block to unregister
173 *
174 * Stop notifying for status changes.
175 */
176void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack,
177 struct notifier_block *nb)
178{
179 blocking_notifier_chain_unregister(&jack->notifier, nb);
180}
181EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_unregister);
182
146#ifdef CONFIG_GPIOLIB 183#ifdef CONFIG_GPIOLIB
147/* gpio detect */ 184/* gpio detect */
148static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) 185static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)