aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiam Girdwood <lrg@slimlogic.co.uk>2010-03-17 16:15:21 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-08-12 09:00:00 -0400
commitf0fba2ad1b6b53d5360125c41953b7afcd6deff0 (patch)
treef6ad50905f8daa616593c978d7ae992e73241180
parentbda7d2a862e6b788bca2d02d38a07966a9c92e48 (diff)
ASoC: multi-component - ASoC Multi-Component Support
This patch extends the ASoC API to allow sound cards to have more than one CODEC and more than one platform DMA controller. This is achieved by dividing some current ASoC structures that contain both driver data and device data into structures that only either contain device data or driver data. i.e. struct snd_soc_codec ---> struct snd_soc_codec (device data) +-> struct snd_soc_codec_driver (driver data) struct snd_soc_platform ---> struct snd_soc_platform (device data) +-> struct snd_soc_platform_driver (driver data) struct snd_soc_dai ---> struct snd_soc_dai (device data) +-> struct snd_soc_dai_driver (driver data) struct snd_soc_device ---> deleted This now allows ASoC to be more tightly aligned with the Linux driver model and also means that every ASoC codec, platform and (platform) DAI is a kernel device. ASoC component private data is now stored as device private data. The ASoC sound card struct snd_soc_card has also been updated to store lists of it's components rather than a pointer to a codec and platform. The PCM runtime struct soc_pcm_runtime now has pointers to all its components. This patch adds DAPM support for ASoC multi-component and removes struct snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec or runtime PCM level basis rather than using snd_soc_socdev. Other notable multi-component changes:- * Stream operations now de-reference less structures. * close_delayed work() now runs on a DAI basis rather than looping all DAIs in a card. * PM suspend()/resume() operations can now handle N CODECs and Platforms per sound card. * Added soc_bind_dai_link() to bind the component devices to the sound card. * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove DAI link components. * sysfs entries can now be registered per component per card. * snd_soc_new_pcms() functionailty rolled into dai_link_probe(). * snd_soc_register_codec() now does all the codec list and mutex init. This patch changes the probe() and remove() of the CODEC drivers as follows:- o Make CODEC driver a platform driver o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core. o Removed all static codec pointers (drivers now support > 1 codec dev) o snd_soc_register_pcms() now done by core. o snd_soc_register_dai() folded into snd_soc_register_codec(). CS4270 portions: Acked-by: Timur Tabi <timur@freescale.com> Some TLV320aic23 and Cirrus platform fixes. Signed-off-by: Ryan Mallon <ryan@bluewatersys.com> TI CODEC and OMAP fixes Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Samsung platform and misc fixes :- Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Reviewed-by: Jassi Brar <jassi.brar@samsung.com> Signed-off-by: Seungwhan Youn <sw.youn@samsung.com> MPC8610 and PPC fixes. Signed-off-by: Timur Tabi <timur@freescale.com> i.MX fixes and some core fixes. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> J4740 platform fixes:- Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> CC: Tony Lindgren <tony@atomide.com> CC: Nicolas Ferre <nicolas.ferre@atmel.com> CC: Kevin Hilman <khilman@deeprootsystems.com> CC: Sascha Hauer <s.hauer@pengutronix.de> CC: Atsushi Nemoto <anemo@mba.ocn.ne.jp> CC: Kuninori Morimoto <morimoto.kuninori@renesas.com> CC: Daniel Gloeckner <dg@emlix.com> CC: Manuel Lauss <mano@roarinelk.homelinux.net> CC: Mike Frysinger <vapier.adi@gmail.com> CC: Arnaud Patard <apatard@mandriva.com> CC: Wan ZongShun <mcuos.com@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r--arch/arm/mach-davinci/devices.c13
-rw-r--r--arch/arm/mach-ep93xx/core.c6
-rw-r--r--arch/arm/mach-kirkwood/common.c6
-rw-r--r--arch/arm/mach-mx2/clock_imx27.c4
-rw-r--r--arch/arm/mach-mx2/devices.c2
-rw-r--r--arch/arm/mach-mx3/clock-imx31.c4
-rw-r--r--arch/arm/mach-mx3/clock-imx35.c4
-rw-r--r--arch/arm/mach-mx3/devices.c4
-rw-r--r--arch/arm/mach-omap1/devices.c26
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c15
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c14
-rw-r--r--arch/arm/mach-omap2/board-zoom2.c28
-rw-r--r--arch/arm/mach-omap2/devices.c39
-rw-r--r--arch/arm/mach-omap2/include/mach/board-zoom.h2
-rw-r--r--arch/arm/mach-pxa/devices.c25
-rw-r--r--arch/arm/mach-pxa/devices.h6
-rw-r--r--arch/arm/mach-pxa/pxa27x.c4
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c5
-rw-r--r--arch/arm/mach-pxa/zylonite.c11
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c13
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c1
-rw-r--r--arch/arm/plat-mxc/audmux-v2.c4
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h7
-rw-r--r--arch/arm/plat-s3c24xx/devs.c30
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h2
-rw-r--r--drivers/input/misc/twl4030-vibra.c4
-rw-r--r--drivers/mfd/twl-core.c6
-rw-r--r--drivers/mfd/twl4030-codec.c8
-rw-r--r--include/linux/i2c/twl.h6
-rw-r--r--include/sound/sh_fsi.h4
-rw-r--r--include/sound/soc-dai.h98
-rw-r--r--include/sound/soc-dapm.h8
-rw-r--r--include/sound/soc-of-simple.h25
-rw-r--r--include/sound/soc.h236
-rw-r--r--include/sound/tlv320aic3x.h43
-rw-r--r--sound/soc/atmel/atmel-pcm.c59
-rw-r--r--sound/soc/atmel/atmel-pcm.h3
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c97
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.h1
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c65
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c51
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c35
-rw-r--r--sound/soc/au1x/db1200.c35
-rw-r--r--sound/soc/au1x/dbdma2.c19
-rw-r--r--sound/soc/au1x/psc-ac97.c20
-rw-r--r--sound/soc/au1x/psc-i2s.c21
-rw-r--r--sound/soc/au1x/psc.h3
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c43
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.h3
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c41
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.h2
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c23
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c23
-rw-r--r--sound/soc/blackfin/bf5xx-ad1980.c19
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c22
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c44
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.h3
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c45
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.h14
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c38
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c43
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.h3
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c15
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.h2
-rw-r--r--sound/soc/codecs/ac97.c124
-rw-r--r--sound/soc/codecs/ac97.h19
-rw-r--r--sound/soc/codecs/ad1836.c191
-rw-r--r--sound/soc/codecs/ad1836.h2
-rw-r--r--sound/soc/codecs/ad193x.c217
-rw-r--r--sound/soc/codecs/ad193x.h3
-rw-r--r--sound/soc/codecs/ad1980.c107
-rw-r--r--sound/soc/codecs/ad1980.h3
-rw-r--r--sound/soc/codecs/ad73311.c66
-rw-r--r--sound/soc/codecs/ad73311.h2
-rw-r--r--sound/soc/codecs/ads117x.c72
-rw-r--r--sound/soc/codecs/ads117x.h4
-rw-r--r--sound/soc/codecs/ak4104.c149
-rw-r--r--sound/soc/codecs/ak4104.h7
-rw-r--r--sound/soc/codecs/ak4535.c236
-rw-r--r--sound/soc/codecs/ak4535.h8
-rw-r--r--sound/soc/codecs/ak4642.c175
-rw-r--r--sound/soc/codecs/ak4642.h20
-rw-r--r--sound/soc/codecs/ak4671.c141
-rw-r--r--sound/soc/codecs/ak4671.h3
-rw-r--r--sound/soc/codecs/cq93vc.c132
-rw-r--r--sound/soc/codecs/cq93vc.h29
-rw-r--r--sound/soc/codecs/cs4270.c393
-rw-r--r--sound/soc/codecs/cs4270.h28
-rw-r--r--sound/soc/codecs/cs42l51.c293
-rw-r--r--sound/soc/codecs/cs42l51.h2
-rw-r--r--sound/soc/codecs/cx20442.c173
-rw-r--r--sound/soc/codecs/cx20442.h2
-rw-r--r--sound/soc/codecs/da7210.c157
-rw-r--r--sound/soc/codecs/da7210.h24
-rw-r--r--sound/soc/codecs/jz4740.c116
-rw-r--r--sound/soc/codecs/jz4740.h20
-rw-r--r--sound/soc/codecs/pcm3008.c92
-rw-r--r--sound/soc/codecs/pcm3008.h3
-rw-r--r--sound/soc/codecs/spdif_transciever.c102
-rw-r--r--sound/soc/codecs/spdif_transciever.h18
-rw-r--r--sound/soc/codecs/ssm2602.c219
-rw-r--r--sound/soc/codecs/ssm2602.h3
-rw-r--r--sound/soc/codecs/stac9766.c118
-rw-r--r--sound/soc/codecs/stac9766.h4
-rw-r--r--sound/soc/codecs/tlv320aic23.c182
-rw-r--r--sound/soc/codecs/tlv320aic23.h3
-rw-r--r--sound/soc/codecs/tlv320aic26.c180
-rw-r--r--sound/soc/codecs/tlv320aic26.h3
-rw-r--r--sound/soc/codecs/tlv320aic3x.c223
-rw-r--r--sound/soc/codecs/tlv320aic3x.h43
-rw-r--r--sound/soc/codecs/tlv320dac33.c249
-rw-r--r--sound/soc/codecs/tlv320dac33.h3
-rw-r--r--sound/soc/codecs/twl4030.c231
-rw-r--r--sound/soc/codecs/twl4030.h55
-rw-r--r--sound/soc/codecs/twl6040.c170
-rw-r--r--sound/soc/codecs/twl6040.h3
-rw-r--r--sound/soc/codecs/uda134x.c154
-rw-r--r--sound/soc/codecs/uda134x.h3
-rw-r--r--sound/soc/codecs/uda1380.c211
-rw-r--r--sound/soc/codecs/uda1380.h3
-rw-r--r--sound/soc/codecs/wm2000.h3
-rw-r--r--sound/soc/codecs/wm8350.c231
-rw-r--r--sound/soc/codecs/wm8350.h3
-rw-r--r--sound/soc/codecs/wm8400.c181
-rw-r--r--sound/soc/codecs/wm8400.h3
-rw-r--r--sound/soc/codecs/wm8510.c290
-rw-r--r--sound/soc/codecs/wm8510.h3
-rw-r--r--sound/soc/codecs/wm8523.c180
-rw-r--r--sound/soc/codecs/wm8523.h3
-rw-r--r--sound/soc/codecs/wm8580.c186
-rw-r--r--sound/soc/codecs/wm8580.h3
-rw-r--r--sound/soc/codecs/wm8711.c206
-rw-r--r--sound/soc/codecs/wm8711.h3
-rw-r--r--sound/soc/codecs/wm8727.c106
-rw-r--r--sound/soc/codecs/wm8727.h21
-rw-r--r--sound/soc/codecs/wm8728.c294
-rw-r--r--sound/soc/codecs/wm8728.h9
-rw-r--r--sound/soc/codecs/wm8731.c217
-rw-r--r--sound/soc/codecs/wm8731.h3
-rw-r--r--sound/soc/codecs/wm8741.c204
-rw-r--r--sound/soc/codecs/wm8741.h3
-rw-r--r--sound/soc/codecs/wm8750.c269
-rw-r--r--sound/soc/codecs/wm8750.h9
-rw-r--r--sound/soc/codecs/wm8753.c407
-rw-r--r--sound/soc/codecs/wm8753.h3
-rw-r--r--sound/soc/codecs/wm8776.c251
-rw-r--r--sound/soc/codecs/wm8776.h3
-rw-r--r--sound/soc/codecs/wm8900.c251
-rw-r--r--sound/soc/codecs/wm8900.h3
-rw-r--r--sound/soc/codecs/wm8903.c268
-rw-r--r--sound/soc/codecs/wm8903.h3
-rw-r--r--sound/soc/codecs/wm8904.c208
-rw-r--r--sound/soc/codecs/wm8904.h3
-rw-r--r--sound/soc/codecs/wm8940.c199
-rw-r--r--sound/soc/codecs/wm8940.h2
-rw-r--r--sound/soc/codecs/wm8955.c184
-rw-r--r--sound/soc/codecs/wm8955.h3
-rw-r--r--sound/soc/codecs/wm8960.c209
-rw-r--r--sound/soc/codecs/wm8960.h3
-rw-r--r--sound/soc/codecs/wm8961.c241
-rw-r--r--sound/soc/codecs/wm8961.h3
-rw-r--r--sound/soc/codecs/wm8971.c250
-rw-r--r--sound/soc/codecs/wm8971.h8
-rw-r--r--sound/soc/codecs/wm8974.c171
-rw-r--r--sound/soc/codecs/wm8974.h3
-rw-r--r--sound/soc/codecs/wm8978.c190
-rw-r--r--sound/soc/codecs/wm8978.h3
-rw-r--r--sound/soc/codecs/wm8988.c266
-rw-r--r--sound/soc/codecs/wm8988.h3
-rw-r--r--sound/soc/codecs/wm8990.c226
-rw-r--r--sound/soc/codecs/wm8990.h8
-rw-r--r--sound/soc/codecs/wm8993.c307
-rw-r--r--sound/soc/codecs/wm8993.h3
-rw-r--r--sound/soc/codecs/wm8994.c230
-rw-r--r--sound/soc/codecs/wm8994.h3
-rw-r--r--sound/soc/codecs/wm9081.c208
-rw-r--r--sound/soc/codecs/wm9081.h3
-rw-r--r--sound/soc/codecs/wm9090.c183
-rw-r--r--sound/soc/codecs/wm9090.h2
-rw-r--r--sound/soc/codecs/wm9705.c116
-rw-r--r--sound/soc/codecs/wm9705.h3
-rw-r--r--sound/soc/codecs/wm9712.c124
-rw-r--r--sound/soc/codecs/wm9712.h3
-rw-r--r--sound/soc/codecs/wm9713.c131
-rw-r--r--sound/soc/codecs/wm9713.h3
-rw-r--r--sound/soc/davinci/davinci-evm.c109
-rw-r--r--sound/soc/davinci/davinci-i2s.c44
-rw-r--r--sound/soc/davinci/davinci-i2s.h2
-rw-r--r--sound/soc/davinci/davinci-mcasp.c32
-rw-r--r--sound/soc/davinci/davinci-mcasp.h2
-rw-r--r--sound/soc/davinci/davinci-pcm.c45
-rw-r--r--sound/soc/davinci/davinci-pcm.h3
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c27
-rw-r--r--sound/soc/davinci/davinci-vcif.c25
-rw-r--r--sound/soc/davinci/davinci-vcif.h28
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c34
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.h18
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c37
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.h2
-rw-r--r--sound/soc/ep93xx/snappercl15.c24
-rw-r--r--sound/soc/fsl/Kconfig3
-rw-r--r--sound/soc/fsl/Makefile3
-rw-r--r--sound/soc/fsl/efika-audio-fabric.c20
-rw-r--r--sound/soc/fsl/fsl_dma.c312
-rw-r--r--sound/soc/fsl/fsl_dma.h20
-rw-r--r--sound/soc/fsl/fsl_ssi.c249
-rw-r--r--sound/soc/fsl/fsl_ssi.h26
-rw-r--r--sound/soc/fsl/mpc5200_dma.c66
-rw-r--r--sound/soc/fsl/mpc5200_dma.h5
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c34
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.h2
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c19
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c658
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c21
-rw-r--r--sound/soc/fsl/soc-of-simple.c172
-rw-r--r--sound/soc/imx/Kconfig16
-rw-r--r--sound/soc/imx/Makefile10
-rw-r--r--sound/soc/imx/eukrea-tlv320.c16
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c43
-rw-r--r--sound/soc/imx/imx-pcm-fiq.c68
-rw-r--r--sound/soc/imx/imx-ssi.c148
-rw-r--r--sound/soc/imx/imx-ssi.h7
-rw-r--r--sound/soc/imx/phycore-ac97.c19
-rw-r--r--sound/soc/imx/wm1133-ev1.c27
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c104
-rw-r--r--sound/soc/jz4740/jz4740-i2s.h2
-rw-r--r--sound/soc/jz4740/jz4740-pcm.c18
-rw-r--r--sound/soc/jz4740/jz4740-pcm.h2
-rw-r--r--sound/soc/jz4740/qi_lb60.c20
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c64
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.h17
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c52
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.h17
-rw-r--r--sound/soc/kirkwood/kirkwood-openrd.c21
-rw-r--r--sound/soc/nuc900/nuc900-ac97.c12
-rw-r--r--sound/soc/nuc900/nuc900-audio.c16
-rw-r--r--sound/soc/nuc900/nuc900-audio.h4
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c38
-rw-r--r--sound/soc/omap/am3517evm.c25
-rw-r--r--sound/soc/omap/ams-delta.c98
-rw-r--r--sound/soc/omap/igep0020.c22
-rw-r--r--sound/soc/omap/mcpdm.c19
-rw-r--r--sound/soc/omap/mcpdm.h2
-rw-r--r--sound/soc/omap/n810.c42
-rw-r--r--sound/soc/omap/omap-mcbsp.c123
-rw-r--r--sound/soc/omap/omap-mcbsp.h2
-rw-r--r--sound/soc/omap/omap-mcpdm.c71
-rw-r--r--sound/soc/omap/omap-mcpdm.h29
-rw-r--r--sound/soc/omap/omap-pcm.c47
-rw-r--r--sound/soc/omap/omap-pcm.h2
-rw-r--r--sound/soc/omap/omap2evm.c25
-rw-r--r--sound/soc/omap/omap3beagle.c23
-rw-r--r--sound/soc/omap/omap3evm.c30
-rw-r--r--sound/soc/omap/omap3pandora.c36
-rw-r--r--sound/soc/omap/osk5912.c24
-rw-r--r--sound/soc/omap/overo.c22
-rw-r--r--sound/soc/omap/rx51.c37
-rw-r--r--sound/soc/omap/sdp3430.c56
-rw-r--r--sound/soc/omap/sdp4430.c23
-rw-r--r--sound/soc/omap/zoom2.c64
-rw-r--r--sound/soc/pxa/corgi.c25
-rw-r--r--sound/soc/pxa/e740_wm9705.c26
-rw-r--r--sound/soc/pxa/e750_wm9705.c26
-rw-r--r--sound/soc/pxa/e800_wm9712.c26
-rw-r--r--sound/soc/pxa/em-x270.c21
-rw-r--r--sound/soc/pxa/imote2.c20
-rw-r--r--sound/soc/pxa/magician.c35
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c33
-rw-r--r--sound/soc/pxa/palm27x.c27
-rw-r--r--sound/soc/pxa/poodle.c27
-rw-r--r--sound/soc/pxa/pxa-ssp.c148
-rw-r--r--sound/soc/pxa/pxa-ssp.h2
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c45
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.h2
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c89
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.h2
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c45
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.h19
-rw-r--r--sound/soc/pxa/raumfeld.c114
-rw-r--r--sound/soc/pxa/spitz.c62
-rw-r--r--sound/soc/pxa/tosa.c27
-rw-r--r--sound/soc/pxa/z2.c26
-rw-r--r--sound/soc/pxa/zylonite.c40
-rw-r--r--sound/soc/s3c24xx/jive_wm8750.c23
-rw-r--r--sound/soc/s3c24xx/ln2440sbc_alc650.c17
-rw-r--r--sound/soc/s3c24xx/neo1973_gta02_wm8753.c58
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c37
-rw-r--r--sound/soc/s3c24xx/s3c-ac97.c21
-rw-r--r--sound/soc/s3c24xx/s3c-ac97.h2
-rw-r--r--sound/soc/s3c24xx/s3c-dma.c45
-rw-r--r--sound/soc/s3c24xx/s3c-dma.h1
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c50
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.h13
-rw-r--r--sound/soc/s3c24xx/s3c-pcm.c41
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c53
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.h2
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c39
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.h2
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec.c15
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec.h4
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec_hermes.c25
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c21
-rw-r--r--sound/soc/s3c24xx/s3c24xx_uda134x.c21
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s-v4.c123
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c205
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h2
-rw-r--r--sound/soc/s3c24xx/smartq_wm8987.c15
-rw-r--r--sound/soc/s3c24xx/smdk2443_wm9710.c17
-rw-r--r--sound/soc/s3c24xx/smdk64xx_wm8580.c33
-rw-r--r--sound/soc/s3c24xx/smdk_wm9713.c38
-rw-r--r--sound/soc/s6000/s6000-i2s.c56
-rw-r--r--sound/soc/s6000/s6000-i2s.h2
-rw-r--r--sound/soc/s6000/s6000-pcm.c100
-rw-r--r--sound/soc/s6000/s6000-pcm.h2
-rw-r--r--sound/soc/s6000/s6105-ipcam.c31
-rw-r--r--sound/soc/sh/dma-sh7760.c53
-rw-r--r--sound/soc/sh/fsi-ak4642.c24
-rw-r--r--sound/soc/sh/fsi-da7210.c22
-rw-r--r--sound/soc/sh/fsi.c47
-rw-r--r--sound/soc/sh/hac.c46
-rw-r--r--sound/soc/sh/migor.c29
-rw-r--r--sound/soc/sh/sh7760-ac97.c25
-rw-r--r--sound/soc/sh/siu.h5
-rw-r--r--sound/soc/sh/siu_dai.c66
-rw-r--r--sound/soc/sh/siu_pcm.c32
-rw-r--r--sound/soc/sh/ssi.c55
-rw-r--r--sound/soc/soc-cache.c34
-rw-r--r--sound/soc/soc-core.c1665
-rw-r--r--sound/soc/soc-dapm.c88
-rw-r--r--sound/soc/soc-jack.c10
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c55
-rw-r--r--sound/soc/txx9/txx9aclc-generic.c24
-rw-r--r--sound/soc/txx9/txx9aclc.c141
-rw-r--r--sound/soc/txx9/txx9aclc.h13
334 files changed, 8543 insertions, 13316 deletions
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 8b7201e4c79..de40e9c787e 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -295,6 +295,18 @@ static void davinci_init_wdt(void)
295 295
296/*-------------------------------------------------------------------------*/ 296/*-------------------------------------------------------------------------*/
297 297
298struct platform_device davinci_pcm_device = {
299 .name = "davinci-pcm-audio",
300 .id = -1,
301};
302
303static void davinci_init_pcm(void)
304{
305 platform_device_register(&davinci_pcm_device);
306}
307
308/*-------------------------------------------------------------------------*/
309
298struct davinci_timer_instance davinci_timer_instance[2] = { 310struct davinci_timer_instance davinci_timer_instance[2] = {
299 { 311 {
300 .base = DAVINCI_TIMER0_BASE, 312 .base = DAVINCI_TIMER0_BASE,
@@ -315,6 +327,7 @@ static int __init davinci_init_devices(void)
315 /* please keep these calls, and their implementations above, 327 /* please keep these calls, and their implementations above,
316 * in alphabetical order so they're easier to sort through. 328 * in alphabetical order so they're easier to sort through.
317 */ 329 */
330 davinci_init_pcm();
318 davinci_init_wdt(); 331 davinci_init_wdt();
319 332
320 return 0; 333 return 0;
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index b4ee5409eb7..b5261d44b26 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -732,9 +732,15 @@ static struct platform_device ep93xx_i2s_device = {
732 .resource = ep93xx_i2s_resource, 732 .resource = ep93xx_i2s_resource,
733}; 733};
734 734
735static struct platform_device ep93xx_pcm_device = {
736 .name = "ep93xx-pcm-audio",
737 .id = -1,
738};
739
735void __init ep93xx_register_i2s(void) 740void __init ep93xx_register_i2s(void)
736{ 741{
737 platform_device_register(&ep93xx_i2s_device); 742 platform_device_register(&ep93xx_i2s_device);
743 platform_device_register(&ep93xx_pcm_device);
738} 744}
739 745
740#define EP93XX_SYSCON_DEVCFG_I2S_MASK (EP93XX_SYSCON_DEVCFG_I2SONSSP | \ 746#define EP93XX_SYSCON_DEVCFG_I2S_MASK (EP93XX_SYSCON_DEVCFG_I2SONSSP | \
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index e1f3efedbcf..07690132cdb 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -896,10 +896,16 @@ static struct platform_device kirkwood_i2s_device = {
896 }, 896 },
897}; 897};
898 898
899static struct platform_device kirkwood_pcm_device = {
900 .name = "kirkwood-pcm",
901 .id = -1,
902};
903
899void __init kirkwood_audio_init(void) 904void __init kirkwood_audio_init(void)
900{ 905{
901 kirkwood_clk_ctrl |= CGC_AUDIO; 906 kirkwood_clk_ctrl |= CGC_AUDIO;
902 platform_device_register(&kirkwood_i2s_device); 907 platform_device_register(&kirkwood_i2s_device);
908 platform_device_register(&kirkwood_pcm_device);
903} 909}
904 910
905/***************************************************************************** 911/*****************************************************************************
diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c
index 0f0823c8b17..379de9c5933 100644
--- a/arch/arm/mach-mx2/clock_imx27.c
+++ b/arch/arm/mach-mx2/clock_imx27.c
@@ -653,8 +653,8 @@ static struct clk_lookup lookups[] = {
653 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1) 653 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1)
654 _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk) 654 _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk)
655 _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1) 655 _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1)
656 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) 656 _REGISTER_CLOCK("imx-ssi-dai.0", NULL, ssi1_clk)
657 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) 657 _REGISTER_CLOCK("imx-ssi-dai.1", NULL, ssi2_clk)
658 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) 658 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
659 _REGISTER_CLOCK(NULL, "vpu", vpu_clk) 659 _REGISTER_CLOCK(NULL, "vpu", vpu_clk)
660 _REGISTER_CLOCK(NULL, "dma", dma_clk) 660 _REGISTER_CLOCK(NULL, "dma", dma_clk)
diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c
index a0aeb8a4adc..2354d67a10d 100644
--- a/arch/arm/mach-mx2/devices.c
+++ b/arch/arm/mach-mx2/devices.c
@@ -415,7 +415,7 @@ struct platform_device mxc_usbh2 = {
415 }; \ 415 }; \
416 \ 416 \
417 struct platform_device imx_ssi_device ## n = { \ 417 struct platform_device imx_ssi_device ## n = { \
418 .name = "imx-ssi", \ 418 .name = "imx-ssi-dai", \
419 .id = n, \ 419 .id = n, \
420 .num_resources = ARRAY_SIZE(imx_ssi_resources ## n), \ 420 .num_resources = ARRAY_SIZE(imx_ssi_resources ## n), \
421 .resource = imx_ssi_resources ## n, \ 421 .resource = imx_ssi_resources ## n, \
diff --git a/arch/arm/mach-mx3/clock-imx31.c b/arch/arm/mach-mx3/clock-imx31.c
index 9a9eb6de612..9b52a67abf2 100644
--- a/arch/arm/mach-mx3/clock-imx31.c
+++ b/arch/arm/mach-mx3/clock-imx31.c
@@ -558,8 +558,8 @@ static struct clk_lookup lookups[] = {
558 _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) 558 _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
559 _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) 559 _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
560 _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) 560 _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
561 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) 561 _REGISTER_CLOCK("imx-ssi-dai.0", NULL, ssi1_clk)
562 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) 562 _REGISTER_CLOCK("imx-ssi-dai.1", NULL, ssi2_clk)
563 _REGISTER_CLOCK(NULL, "firi", firi_clk) 563 _REGISTER_CLOCK(NULL, "firi", firi_clk)
564 _REGISTER_CLOCK(NULL, "ata", ata_clk) 564 _REGISTER_CLOCK(NULL, "ata", ata_clk)
565 _REGISTER_CLOCK(NULL, "rtic", rtic_clk) 565 _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c
index 9f3e943e223..7b5acd5aa7c 100644
--- a/arch/arm/mach-mx3/clock-imx35.c
+++ b/arch/arm/mach-mx3/clock-imx35.c
@@ -464,8 +464,8 @@ static struct clk_lookup lookups[] = {
464 _REGISTER_CLOCK(NULL, "sdma", sdma_clk) 464 _REGISTER_CLOCK(NULL, "sdma", sdma_clk)
465 _REGISTER_CLOCK(NULL, "spba", spba_clk) 465 _REGISTER_CLOCK(NULL, "spba", spba_clk)
466 _REGISTER_CLOCK(NULL, "spdif", spdif_clk) 466 _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
467 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) 467 _REGISTER_CLOCK("imx-ssi-dai.0", NULL, ssi1_clk)
468 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) 468 _REGISTER_CLOCK("imx-ssi-dai.1", NULL, ssi2_clk)
469 _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) 469 _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
470 _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) 470 _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
471 _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) 471 _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index db7acd6e910..27cfc39106a 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -562,14 +562,14 @@ static struct resource imx_ssi_resources1[] = {
562}; 562};
563 563
564struct platform_device imx_ssi_device0 = { 564struct platform_device imx_ssi_device0 = {
565 .name = "imx-ssi", 565 .name = "imx-ssi-dai",
566 .id = 0, 566 .id = 0,
567 .num_resources = ARRAY_SIZE(imx_ssi_resources0), 567 .num_resources = ARRAY_SIZE(imx_ssi_resources0),
568 .resource = imx_ssi_resources0, 568 .resource = imx_ssi_resources0,
569}; 569};
570 570
571struct platform_device imx_ssi_device1 = { 571struct platform_device imx_ssi_device1 = {
572 .name = "imx-ssi", 572 .name = "imx-ssi-dai",
573 .id = 1, 573 .id = 1,
574 .num_resources = ARRAY_SIZE(imx_ssi_resources1), 574 .num_resources = ARRAY_SIZE(imx_ssi_resources1),
575 .resource = imx_ssi_resources1, 575 .resource = imx_ssi_resources1,
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 379100c1763..eb98eb8d373 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -25,6 +25,7 @@
25#include <mach/gpio.h> 25#include <mach/gpio.h>
26#include <plat/mmc.h> 26#include <plat/mmc.h>
27#include <plat/omap7xx.h> 27#include <plat/omap7xx.h>
28#include <plat/mcbsp.h>
28 29
29/*-------------------------------------------------------------------------*/ 30/*-------------------------------------------------------------------------*/
30 31
@@ -267,6 +268,30 @@ static inline void omap_init_sti(void)
267static inline void omap_init_sti(void) {} 268static inline void omap_init_sti(void) {}
268#endif 269#endif
269 270
271#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
272
273static struct platform_device omap_pcm = {
274 .name = "omap-pcm-audio",
275 .id = -1,
276};
277
278OMAP_MCBSP_PLATFORM_DEVICE(1);
279OMAP_MCBSP_PLATFORM_DEVICE(2);
280OMAP_MCBSP_PLATFORM_DEVICE(3);
281
282static void omap_init_audio(void)
283{
284 platform_device_register(&omap_mcbsp1);
285 platform_device_register(&omap_mcbsp2);
286 if (!cpu_is_omap7xx())
287 platform_device_register(&omap_mcbsp3);
288 platform_device_register(&omap_pcm);
289}
290
291#else
292static inline void omap_init_audio(void) {}
293#endif
294
270/*-------------------------------------------------------------------------*/ 295/*-------------------------------------------------------------------------*/
271 296
272/* 297/*
@@ -299,6 +324,7 @@ static int __init omap1_init_devices(void)
299 omap_init_rtc(); 324 omap_init_rtc();
300 omap_init_spi100k(); 325 omap_init_spi100k();
301 omap_init_sti(); 326 omap_init_sti();
327 omap_init_audio();
302 328
303 return 0; 329 return 0;
304} 330}
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 3ccc34ebdcc..04df912a7b5 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -20,6 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/usb/musb.h> 22#include <linux/usb/musb.h>
23#include <sound/tlv320aic3x.h>
23 24
24#include <asm/mach/arch.h> 25#include <asm/mach/arch.h>
25#include <asm/mach-types.h> 26#include <asm/mach-types.h>
@@ -612,11 +613,25 @@ static int n8x0_menelaus_late_init(struct device *dev)
612 return 0; 613 return 0;
613} 614}
614 615
616static struct aic3x_setup_data n810_aic33_setup = {
617 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
618 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
619};
620
621static struct aic3x_pdata n810_aic33_data = {
622 .setup = &n810_aic33_setup,
623 .gpio_reset = -1,
624};
625
615static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] = { 626static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] = {
616 { 627 {
617 I2C_BOARD_INFO("menelaus", 0x72), 628 I2C_BOARD_INFO("menelaus", 0x72),
618 .irq = INT_24XX_SYS_NIRQ, 629 .irq = INT_24XX_SYS_NIRQ,
619 }, 630 },
631 {
632 I2C_BOARD_INFO("tlv320aic3x", 0x1b),
633 .platform_data = &n810_aic33_data,
634 },
620}; 635};
621 636
622static struct menelaus_platform_data n8x0_menelaus_platform_data = { 637static struct menelaus_platform_data n8x0_menelaus_platform_data = {
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index abdf321c2d4..28978c08bce 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -23,6 +23,7 @@
23#include <linux/gpio.h> 23#include <linux/gpio.h>
24#include <linux/gpio_keys.h> 24#include <linux/gpio_keys.h>
25#include <linux/mmc/host.h> 25#include <linux/mmc/host.h>
26#include <sound/tlv320aic3x.h>
26 27
27#include <plat/mcspi.h> 28#include <plat/mcspi.h>
28#include <plat/mux.h> 29#include <plat/mux.h>
@@ -686,7 +687,6 @@ static struct twl4030_power_data rx51_t2scripts_data __initdata = {
686}; 687};
687 688
688 689
689
690static struct twl4030_platform_data rx51_twldata __initdata = { 690static struct twl4030_platform_data rx51_twldata __initdata = {
691 .irq_base = TWL4030_IRQ_BASE, 691 .irq_base = TWL4030_IRQ_BASE,
692 .irq_end = TWL4030_IRQ_END, 692 .irq_end = TWL4030_IRQ_END,
@@ -716,9 +716,21 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = {
716 }, 716 },
717}; 717};
718 718
719/* Audio setup data */
720static struct aic3x_setup_data rx51_aic34_setup = {
721 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
722 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
723};
724
725static struct aic3x_pdata rx51_aic34_data = {
726 .setup = &rx51_aic34_setup,
727 .gpio_reset = 60,
728};
729
719static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = { 730static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
720 { 731 {
721 I2C_BOARD_INFO("tlv320aic3x", 0x18), 732 I2C_BOARD_INFO("tlv320aic3x", 0x18),
733 .platform_data = &rx51_aic34_data,
722 }, 734 },
723}; 735};
724 736
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 803ef14cbf2..410fe006c0f 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/input.h> 15#include <linux/input.h>
16#include <linux/gpio.h> 16#include <linux/gpio.h>
17#include <linux/i2c/twl.h>
17 18
18#include <asm/mach-types.h> 19#include <asm/mach-types.h>
19#include <asm/mach/arch.h> 20#include <asm/mach/arch.h>
@@ -34,8 +35,11 @@ static void __init omap_zoom2_init_irq(void)
34 omap_gpio_init(); 35 omap_gpio_init();
35} 36}
36 37
37/* REVISIT: These audio entries can be removed once MFD code is merged */ 38/* EXTMUTE callback function */
38#if 0 39void zoom2_set_hs_extmute(int mute)
40{
41 gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute);
42}
39 43
40static struct twl4030_madc_platform_data zoom2_madc_data = { 44static struct twl4030_madc_platform_data zoom2_madc_data = {
41 .irq_line = 1, 45 .irq_line = 1,
@@ -43,6 +47,9 @@ static struct twl4030_madc_platform_data zoom2_madc_data = {
43 47
44static struct twl4030_codec_audio_data zoom2_audio_data = { 48static struct twl4030_codec_audio_data zoom2_audio_data = {
45 .audio_mclk = 26000000, 49 .audio_mclk = 26000000,
50 .ramp_delay_value = 3, /* 161 ms */
51 .hs_extmute = 1,
52 .set_hs_extmute = zoom2_set_hs_extmute,
46}; 53};
47 54
48static struct twl4030_codec_data zoom2_codec_data = { 55static struct twl4030_codec_data zoom2_codec_data = {
@@ -64,10 +71,24 @@ static struct twl4030_platform_data zoom2_twldata = {
64 .vmmc1 = &zoom2_vmmc1, 71 .vmmc1 = &zoom2_vmmc1,
65 .vmmc2 = &zoom2_vmmc2, 72 .vmmc2 = &zoom2_vmmc2,
66 .vsim = &zoom2_vsim, 73 .vsim = &zoom2_vsim,
74};
67 75
76static struct i2c_board_info __initdata zoom2_i2c_boardinfo[] = {
77 {
78 I2C_BOARD_INFO("twl4030", 0x48),
79 .flags = I2C_CLIENT_WAKE,
80 .irq = INT_34XX_SYS_NIRQ,
81 .platform_data = &zoom2_twldata,
82 },
68}; 83};
69 84
70#endif 85static int __init omap3_zoom2_i2c_init(void)
86{
87 omap_register_i2c_bus(1, 2600, zoom2_i2c_boardinfo,
88 ARRAY_SIZE(zoom2_i2c_boardinfo));
89 return 0;
90}
91
71 92
72#ifdef CONFIG_OMAP_MUX 93#ifdef CONFIG_OMAP_MUX
73static struct omap_board_mux board_mux[] __initdata = { 94static struct omap_board_mux board_mux[] __initdata = {
@@ -81,6 +102,7 @@ static void __init omap_zoom2_init(void)
81{ 102{
82 omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); 103 omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
83 zoom_peripherals_init(); 104 zoom_peripherals_init();
105 omap3_zoom2_i2c_init();
84 zoom_debugboard_init(); 106 zoom_debugboard_init();
85} 107}
86 108
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 03e6c9ed82a..f9a5961d23a 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -29,6 +29,7 @@
29#include <mach/gpio.h> 29#include <mach/gpio.h>
30#include <plat/mmc.h> 30#include <plat/mmc.h>
31#include <plat/dma.h> 31#include <plat/dma.h>
32#include <plat/mcbsp.h>
32 33
33#include "mux.h" 34#include "mux.h"
34 35
@@ -289,6 +290,43 @@ static inline void omap_init_sti(void)
289static inline void omap_init_sti(void) {} 290static inline void omap_init_sti(void) {}
290#endif 291#endif
291 292
293#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
294
295static struct platform_device omap_pcm = {
296 .name = "omap-pcm-audio",
297 .id = -1,
298};
299
300/*
301 * OMAP2420 has 2 McBSP ports
302 * OMAP2430 has 5 McBSP ports
303 * OMAP3 has 5 McBSP ports
304 * OMAP4 has 4 McBSP ports
305 */
306OMAP_MCBSP_PLATFORM_DEVICE(1);
307OMAP_MCBSP_PLATFORM_DEVICE(2);
308OMAP_MCBSP_PLATFORM_DEVICE(3);
309OMAP_MCBSP_PLATFORM_DEVICE(4);
310OMAP_MCBSP_PLATFORM_DEVICE(5);
311
312static void omap_init_audio(void)
313{
314 platform_device_register(&omap_mcbsp1);
315 platform_device_register(&omap_mcbsp2);
316 if (cpu_is_omap243x() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
317 platform_device_register(&omap_mcbsp3);
318 platform_device_register(&omap_mcbsp4);
319 }
320 if (cpu_is_omap243x() || cpu_is_omap34xx())
321 platform_device_register(&omap_mcbsp5);
322
323 platform_device_register(&omap_pcm);
324}
325
326#else
327static inline void omap_init_audio(void) {}
328#endif
329
292#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) 330#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
293 331
294#include <plat/mcspi.h> 332#include <plat/mcspi.h>
@@ -901,6 +939,7 @@ static int __init omap2_init_devices(void)
901 * in alphabetical order so they're easier to sort through. 939 * in alphabetical order so they're easier to sort through.
902 */ 940 */
903 omap_hsmmc_reset(); 941 omap_hsmmc_reset();
942 omap_init_audio();
904 omap_init_camera(); 943 omap_init_camera();
905 omap_init_mbox(); 944 omap_init_mbox();
906 omap_init_mcspi(); 945 omap_init_mcspi();
diff --git a/arch/arm/mach-omap2/include/mach/board-zoom.h b/arch/arm/mach-omap2/include/mach/board-zoom.h
index c93b29e21b7..b6a010fc8bd 100644
--- a/arch/arm/mach-omap2/include/mach/board-zoom.h
+++ b/arch/arm/mach-omap2/include/mach/board-zoom.h
@@ -3,3 +3,5 @@
3 */ 3 */
4extern int __init zoom_debugboard_init(void); 4extern int __init zoom_debugboard_init(void);
5extern void __init zoom_peripherals_init(void); 5extern void __init zoom_peripherals_init(void);
6
7#define ZOOM2_HEADSET_EXTMUTE_GPIO 153
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 8e10db148f1..200c31a2730 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -340,6 +340,31 @@ struct platform_device pxa_device_i2s = {
340 .num_resources = ARRAY_SIZE(pxai2s_resources), 340 .num_resources = ARRAY_SIZE(pxai2s_resources),
341}; 341};
342 342
343struct platform_device pxa_device_asoc_ssp1 = {
344 .name = "pxa-ssp-dai",
345 .id = 0,
346};
347
348struct platform_device pxa_device_asoc_ssp2= {
349 .name = "pxa-ssp-dai",
350 .id = 1,
351};
352
353struct platform_device pxa_device_asoc_ssp3 = {
354 .name = "pxa-ssp-dai",
355 .id = 2,
356};
357
358struct platform_device pxa_device_asoc_ssp4 = {
359 .name = "pxa-ssp-dai",
360 .id = 3,
361};
362
363struct platform_device pxa_device_asoc_platform = {
364 .name = "pxa-pcm-audio",
365 .id = -1,
366};
367
343static u64 pxaficp_dmamask = ~(u32)0; 368static u64 pxaficp_dmamask = ~(u32)0;
344 369
345struct platform_device pxa_device_ficp = { 370struct platform_device pxa_device_ficp = {
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
index 93817d99761..506fd5753cc 100644
--- a/arch/arm/mach-pxa/devices.h
+++ b/arch/arm/mach-pxa/devices.h
@@ -37,4 +37,10 @@ extern struct platform_device pxa3xx_device_i2c_power;
37 37
38extern struct platform_device pxa3xx_device_gcu; 38extern struct platform_device pxa3xx_device_gcu;
39 39
40extern struct platform_device pxa_device_asoc_platform;
41extern struct platform_device pxa_device_asoc_ssp1;
42extern struct platform_device pxa_device_asoc_ssp2;
43extern struct platform_device pxa_device_asoc_ssp3;
44extern struct platform_device pxa_device_asoc_ssp4;
45
40void __init pxa_register_device(struct platform_device *dev, void *data); 46void __init pxa_register_device(struct platform_device *dev, void *data);
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 0af36177ff0..465008293a2 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -384,6 +384,10 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
384static struct platform_device *devices[] __initdata = { 384static struct platform_device *devices[] __initdata = {
385 &pxa27x_device_udc, 385 &pxa27x_device_udc,
386 &pxa_device_i2s, 386 &pxa_device_i2s,
387 &pxa_device_asoc_ssp1,
388 &pxa_device_asoc_ssp2,
389 &pxa_device_asoc_ssp3,
390 &pxa_device_asoc_platform,
387 &sa1100_device_rtc, 391 &sa1100_device_rtc,
388 &pxa_device_rtc, 392 &pxa_device_rtc,
389 &pxa27x_device_ssp1, 393 &pxa27x_device_ssp1,
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index f544e58e153..f7a3b158ca9 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -597,6 +597,11 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
597static struct platform_device *devices[] __initdata = { 597static struct platform_device *devices[] __initdata = {
598 &pxa27x_device_udc, 598 &pxa27x_device_udc,
599 &pxa_device_i2s, 599 &pxa_device_i2s,
600 &pxa_device_asoc_ssp1,
601 &pxa_device_asoc_ssp2,
602 &pxa_device_asoc_ssp3,
603 &pxa_device_asoc_ssp4,
604 &pxa_device_asoc_platform,
600 &sa1100_device_rtc, 605 &sa1100_device_rtc,
601 &pxa_device_rtc, 606 &pxa_device_rtc,
602 &pxa27x_device_ssp1, 607 &pxa27x_device_ssp1,
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index c479cbecf78..5ba9d99a1bf 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -45,6 +45,16 @@ int wm9713_irq;
45int lcd_id; 45int lcd_id;
46int lcd_orientation; 46int lcd_orientation;
47 47
48struct platform_device pxa_device_wm9713_audio = {
49 .name = "wm9713-codec",
50 .id = -1,
51};
52
53static void __init zylonite_init_wm9713_audio(void)
54{
55 platform_device_register(&pxa_device_wm9713_audio);
56}
57
48static struct resource smc91x_resources[] = { 58static struct resource smc91x_resources[] = {
49 [0] = { 59 [0] = {
50 .start = ZYLONITE_ETH_PHYS + 0x300, 60 .start = ZYLONITE_ETH_PHYS + 0x300,
@@ -408,6 +418,7 @@ static void __init zylonite_init(void)
408 zylonite_init_nand(); 418 zylonite_init_nand();
409 zylonite_init_leds(); 419 zylonite_init_leds();
410 zylonite_init_ohci(); 420 zylonite_init_ohci();
421 zylonite_init_wm9713_audio();
411} 422}
412 423
413MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") 424MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
index c3e9e73bd0f..55ae1b0afae 100644
--- a/arch/arm/mach-s3c64xx/dev-audio.c
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -333,3 +333,16 @@ void __init s3c64xx_ac97_setup_gpio(int num)
333 else 333 else
334 s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe; 334 s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
335} 335}
336
337static u64 s3c_device_audio_dmamask = 0xffffffffUL;
338
339struct platform_device s3c_device_pcm = {
340 .name = "s3c24xx-pcm-audio",
341 .id = -1,
342 .dev = {
343 .dma_mask = &s3c_device_audio_dmamask,
344 .coherent_dma_mask = 0xffffffffUL
345 }
346};
347EXPORT_SYMBOL(s3c_device_pcm);
348
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index d9a03555f88..362fc76ee72 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -256,6 +256,7 @@ static struct platform_device *smdk6410_devices[] __initdata = {
256 &s3c_device_fb, 256 &s3c_device_fb,
257 &s3c_device_ohci, 257 &s3c_device_ohci,
258 &s3c_device_usb_hsotg, 258 &s3c_device_usb_hsotg,
259 &s3c_device_pcm,
259 &s3c64xx_device_iisv4, 260 &s3c64xx_device_iisv4,
260 261
261#ifdef CONFIG_REGULATOR 262#ifdef CONFIG_REGULATOR
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
index 0c2cc5cd4d8..7c479e4fa99 100644
--- a/arch/arm/plat-mxc/audmux-v2.c
+++ b/arch/arm/plat-mxc/audmux-v2.c
@@ -49,9 +49,9 @@ static const char *audmux_port_string(int port)
49{ 49{
50 switch (port) { 50 switch (port) {
51 case MX31_AUDMUX_PORT1_SSI0: 51 case MX31_AUDMUX_PORT1_SSI0:
52 return "imx-ssi.0"; 52 return "imx-ssi-dai.0";
53 case MX31_AUDMUX_PORT2_SSI1: 53 case MX31_AUDMUX_PORT2_SSI1:
54 return "imx-ssi.1"; 54 return "imx-ssi-dai.1";
55 case MX31_AUDMUX_PORT3_SSI_PINS_3: 55 case MX31_AUDMUX_PORT3_SSI_PINS_3:
56 return "SSI3"; 56 return "SSI3";
57 case MX31_AUDMUX_PORT4_SSI_PINS_4: 57 case MX31_AUDMUX_PORT4_SSI_PINS_4:
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index b4ff6a11a8f..5b20103e68e 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -30,6 +30,13 @@
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <plat/clock.h> 31#include <plat/clock.h>
32 32
33/* macro for building platform_device for McBSP ports */
34#define OMAP_MCBSP_PLATFORM_DEVICE(port_nr) \
35static struct platform_device omap_mcbsp##port_nr = { \
36 .name = "omap-mcbsp-dai", \
37 .id = OMAP_MCBSP##port_nr, \
38}
39
33#define OMAP7XX_MCBSP1_BASE 0xfffb1000 40#define OMAP7XX_MCBSP1_BASE 0xfffb1000
34#define OMAP7XX_MCBSP2_BASE 0xfffb1800 41#define OMAP7XX_MCBSP2_BASE 0xfffb1800
35 42
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index 452e18438b4..9f8ee5e3861 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -481,7 +481,7 @@ static struct resource s3c_ac97_resource[] = {
481 }, 481 },
482}; 482};
483 483
484static u64 s3c_device_ac97_dmamask = 0xffffffffUL; 484static u64 s3c_device_audio_dmamask = 0xffffffffUL;
485 485
486struct platform_device s3c_device_ac97 = { 486struct platform_device s3c_device_ac97 = {
487 .name = "s3c-ac97", 487 .name = "s3c-ac97",
@@ -489,11 +489,37 @@ struct platform_device s3c_device_ac97 = {
489 .num_resources = ARRAY_SIZE(s3c_ac97_resource), 489 .num_resources = ARRAY_SIZE(s3c_ac97_resource),
490 .resource = s3c_ac97_resource, 490 .resource = s3c_ac97_resource,
491 .dev = { 491 .dev = {
492 .dma_mask = &s3c_device_ac97_dmamask, 492 .dma_mask = &s3c_device_audio_dmamask,
493 .coherent_dma_mask = 0xffffffffUL 493 .coherent_dma_mask = 0xffffffffUL
494 } 494 }
495}; 495};
496 496
497EXPORT_SYMBOL(s3c_device_ac97); 497EXPORT_SYMBOL(s3c_device_ac97);
498 498
499/* ASoC PCM DMA */
500
501struct platform_device s3c_device_pcm = {
502 .name = "s3c24xx-pcm-audio",
503 .id = -1,
504 .dev = {
505 .dma_mask = &s3c_device_audio_dmamask,
506 .coherent_dma_mask = 0xffffffffUL
507 }
508};
509
510EXPORT_SYMBOL(s3c_device_pcm);
511
512/* ASoC I2S */
513
514struct platform_device s3c2412_device_iis = {
515 .name = "s3c2412-iis",
516 .id = -1,
517 .dev = {
518 .dma_mask = &s3c_device_audio_dmamask,
519 .coherent_dma_mask = 0xffffffffUL
520 }
521};
522
523EXPORT_SYMBOL(s3c2412_device_iis);
524
499#endif // CONFIG_CPU_S32440 525#endif // CONFIG_CPU_S32440
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index e6144e4b911..9ea6786d459 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -32,6 +32,8 @@ extern struct platform_device s3c64xx_device_iisv4;
32extern struct platform_device s3c64xx_device_spi0; 32extern struct platform_device s3c64xx_device_spi0;
33extern struct platform_device s3c64xx_device_spi1; 33extern struct platform_device s3c64xx_device_spi1;
34 34
35extern struct platform_device s3c_device_pcm;
36
35extern struct platform_device s3c64xx_device_pcm0; 37extern struct platform_device s3c64xx_device_pcm0;
36extern struct platform_device s3c64xx_device_pcm1; 38extern struct platform_device s3c64xx_device_pcm1;
37 39
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
index 4f9b2afc24e..014dd4ad0d4 100644
--- a/drivers/input/misc/twl4030-vibra.c
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -271,7 +271,7 @@ static struct platform_driver twl4030_vibra_driver = {
271 .probe = twl4030_vibra_probe, 271 .probe = twl4030_vibra_probe,
272 .remove = __devexit_p(twl4030_vibra_remove), 272 .remove = __devexit_p(twl4030_vibra_remove),
273 .driver = { 273 .driver = {
274 .name = "twl4030_codec_vibra", 274 .name = "twl4030-vibra",
275 .owner = THIS_MODULE, 275 .owner = THIS_MODULE,
276#ifdef CONFIG_PM 276#ifdef CONFIG_PM
277 .pm = &twl4030_vibra_pm_ops, 277 .pm = &twl4030_vibra_pm_ops,
@@ -291,7 +291,7 @@ static void __exit twl4030_vibra_exit(void)
291} 291}
292module_exit(twl4030_vibra_exit); 292module_exit(twl4030_vibra_exit);
293 293
294MODULE_ALIAS("platform:twl4030_codec_vibra"); 294MODULE_ALIAS("platform:twl4030-vibra");
295 295
296MODULE_DESCRIPTION("TWL4030 Vibra driver"); 296MODULE_DESCRIPTION("TWL4030 Vibra driver");
297MODULE_LICENSE("GPL"); 297MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 720e099e506..5d0fb60a4c1 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -698,17 +698,17 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
698 698
699 if (twl_has_codec() && pdata->codec && twl_class_is_4030()) { 699 if (twl_has_codec() && pdata->codec && twl_class_is_4030()) {
700 sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; 700 sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
701 child = add_child(sub_chip_id, "twl4030_codec", 701 child = add_child(sub_chip_id, "twl4030-audio",
702 pdata->codec, sizeof(*pdata->codec), 702 pdata->codec, sizeof(*pdata->codec),
703 false, 0, 0); 703 false, 0, 0);
704 if (IS_ERR(child)) 704 if (IS_ERR(child))
705 return PTR_ERR(child); 705 return PTR_ERR(child);
706 } 706 }
707 707
708 /* Phoenix*/ 708 /* Phoenix codec driver is probed directly atm */
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, "twl6040_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/twl4030-codec.c b/drivers/mfd/twl4030-codec.c
index add6f67d803..9a4b196d6de 100644
--- a/drivers/mfd/twl4030-codec.c
+++ b/drivers/mfd/twl4030-codec.c
@@ -207,14 +207,14 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
207 207
208 if (pdata->audio) { 208 if (pdata->audio) {
209 cell = &codec->cells[childs]; 209 cell = &codec->cells[childs];
210 cell->name = "twl4030_codec_audio"; 210 cell->name = "twl4030-codec";
211 cell->platform_data = pdata->audio; 211 cell->platform_data = pdata->audio;
212 cell->data_size = sizeof(*pdata->audio); 212 cell->data_size = sizeof(*pdata->audio);
213 childs++; 213 childs++;
214 } 214 }
215 if (pdata->vibra) { 215 if (pdata->vibra) {
216 cell = &codec->cells[childs]; 216 cell = &codec->cells[childs];
217 cell->name = "twl4030_codec_vibra"; 217 cell->name = "twl4030-vibra";
218 cell->platform_data = pdata->vibra; 218 cell->platform_data = pdata->vibra;
219 cell->data_size = sizeof(*pdata->vibra); 219 cell->data_size = sizeof(*pdata->vibra);
220 childs++; 220 childs++;
@@ -249,14 +249,14 @@ static int __devexit twl4030_codec_remove(struct platform_device *pdev)
249 return 0; 249 return 0;
250} 250}
251 251
252MODULE_ALIAS("platform:twl4030_codec"); 252MODULE_ALIAS("platform:twl4030-audio");
253 253
254static struct platform_driver twl4030_codec_driver = { 254static struct platform_driver twl4030_codec_driver = {
255 .probe = twl4030_codec_probe, 255 .probe = twl4030_codec_probe,
256 .remove = __devexit_p(twl4030_codec_remove), 256 .remove = __devexit_p(twl4030_codec_remove),
257 .driver = { 257 .driver = {
258 .owner = THIS_MODULE, 258 .owner = THIS_MODULE,
259 .name = "twl4030_codec", 259 .name = "twl4030-audio",
260 }, 260 },
261}; 261};
262 262
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 6de90bfc6ac..4793d8a7f48 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -553,8 +553,12 @@ extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
553extern int twl4030_remove_script(u8 flags); 553extern int twl4030_remove_script(u8 flags);
554 554
555struct twl4030_codec_audio_data { 555struct twl4030_codec_audio_data {
556 unsigned int audio_mclk; 556 unsigned int audio_mclk; /* not used, will be removed */
557 unsigned int digimic_delay; /* in ms */
557 unsigned int ramp_delay_value; 558 unsigned int ramp_delay_value;
559 unsigned int offset_cncl_path;
560 unsigned int check_defaults:1;
561 unsigned int reset_registers:1;
558 unsigned int hs_extmute:1; 562 unsigned int hs_extmute:1;
559 void (*set_hs_extmute)(int mute); 563 void (*set_hs_extmute)(int mute);
560}; 564};
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
index 9d51d6f3589..3fd6456d07d 100644
--- a/include/sound/sh_fsi.h
+++ b/include/sound/sh_fsi.h
@@ -114,7 +114,7 @@ struct sh_fsi_platform_info {
114 int (*set_rate)(int is_porta, int rate); /* for master mode */ 114 int (*set_rate)(int is_porta, int rate); /* for master mode */
115}; 115};
116 116
117extern struct snd_soc_dai fsi_soc_dai[2]; 117extern struct snd_soc_dai_driver fsi_soc_dai[2];
118extern struct snd_soc_platform fsi_soc_platform; 118extern struct snd_soc_platform_driver fsi_soc_platform;
119 119
120#endif /* __SOUND_FSI_H */ 120#endif /* __SOUND_FSI_H */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 377693a1438..e7b68024800 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -91,15 +91,17 @@ struct snd_pcm_substream;
91 SNDRV_PCM_FMTBIT_S32_LE |\ 91 SNDRV_PCM_FMTBIT_S32_LE |\
92 SNDRV_PCM_FMTBIT_S32_BE) 92 SNDRV_PCM_FMTBIT_S32_BE)
93 93
94struct snd_soc_dai_ops; 94struct snd_soc_dai_driver;
95struct snd_soc_dai; 95struct snd_soc_dai;
96struct snd_ac97_bus_ops; 96struct snd_ac97_bus_ops;
97 97
98/* Digital Audio Interface registration */ 98/* Digital Audio Interface registration */
99int snd_soc_register_dai(struct snd_soc_dai *dai); 99int snd_soc_register_dai(struct device *dev,
100void snd_soc_unregister_dai(struct snd_soc_dai *dai); 100 struct snd_soc_dai_driver *dai_drv);
101int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count); 101void snd_soc_unregister_dai(struct device *dev);
102void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count); 102int snd_soc_register_dais(struct device *dev,
103 struct snd_soc_dai_driver *dai_drv, size_t count);
104void snd_soc_unregister_dais(struct device *dev, size_t count);
103 105
104/* Digital Audio Interface clocking API.*/ 106/* Digital Audio Interface clocking API.*/
105int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, 107int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
@@ -126,16 +128,6 @@ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
126/* Digital Audio Interface mute */ 128/* Digital Audio Interface mute */
127int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute); 129int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
128 130
129/*
130 * Digital Audio Interface.
131 *
132 * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97
133 * operations and capabilities. Codec and platform drivers will register this
134 * structure for every DAI they have.
135 *
136 * This structure covers the clocking, formating and ALSA operations for each
137 * interface.
138 */
139struct snd_soc_dai_ops { 131struct snd_soc_dai_ops {
140 /* 132 /*
141 * DAI clocking configuration, all optional. 133 * DAI clocking configuration, all optional.
@@ -191,24 +183,24 @@ struct snd_soc_dai_ops {
191}; 183};
192 184
193/* 185/*
194 * Digital Audio Interface runtime data. 186 * Digital Audio Interface Driver.
195 * 187 *
196 * Holds runtime data for a DAI. 188 * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97
189 * operations and capabilities. Codec and platform drivers will register this
190 * structure for every DAI they have.
191 *
192 * This structure covers the clocking, formating and ALSA operations for each
193 * interface.
197 */ 194 */
198struct snd_soc_dai { 195struct snd_soc_dai_driver {
199 /* DAI description */ 196 /* DAI description */
200 char *name; 197 const char *name;
201 unsigned int id; 198 unsigned int id;
202 int ac97_control; 199 int ac97_control;
203 200
204 struct device *dev; 201 /* DAI driver callbacks */
205 void *ac97_pdata; /* platform_data for the ac97 codec */ 202 int (*probe)(struct snd_soc_dai *dai);
206 203 int (*remove)(struct snd_soc_dai *dai);
207 /* DAI callbacks */
208 int (*probe)(struct platform_device *pdev,
209 struct snd_soc_dai *dai);
210 void (*remove)(struct platform_device *pdev,
211 struct snd_soc_dai *dai);
212 int (*suspend)(struct snd_soc_dai *dai); 204 int (*suspend)(struct snd_soc_dai *dai);
213 int (*resume)(struct snd_soc_dai *dai); 205 int (*resume)(struct snd_soc_dai *dai);
214 206
@@ -219,26 +211,51 @@ struct snd_soc_dai {
219 struct snd_soc_pcm_stream capture; 211 struct snd_soc_pcm_stream capture;
220 struct snd_soc_pcm_stream playback; 212 struct snd_soc_pcm_stream playback;
221 unsigned int symmetric_rates:1; 213 unsigned int symmetric_rates:1;
214};
215
216/*
217 * Digital Audio Interface runtime data.
218 *
219 * Holds runtime data for a DAI.
220 */
221struct snd_soc_dai {
222 const char *name;
223 int id;
224 struct device *dev;
225 void *ac97_pdata; /* platform_data for the ac97 codec */
226
227 /* driver ops */
228 struct snd_soc_dai_driver *driver;
222 229
223 /* DAI runtime info */ 230 /* DAI runtime info */
224 struct snd_soc_codec *codec; 231 unsigned int capture_active:1; /* stream is in use */
232 unsigned int playback_active:1; /* stream is in use */
233 unsigned int symmetric_rates:1;
234 struct snd_pcm_runtime *runtime;
225 unsigned int active; 235 unsigned int active;
226 unsigned char pop_wait:1; 236 unsigned char pop_wait:1;
237 unsigned char probed:1;
227 238
228 /* DAI private data */ 239 /* DAI DMA data */
229 void *private_data; 240 void *playback_dma_data;
241 void *capture_dma_data;
230 242
231 /* parent platform */ 243 /* parent platform/codec */
232 struct snd_soc_platform *platform; 244 union {
245 struct snd_soc_platform *platform;
246 struct snd_soc_codec *codec;
247 };
248 struct snd_soc_card *card;
233 249
234 struct list_head list; 250 struct list_head list;
251 struct list_head card_list;
235}; 252};
236 253
237static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai, 254static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
238 const struct snd_pcm_substream *ss) 255 const struct snd_pcm_substream *ss)
239{ 256{
240 return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 257 return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
241 dai->playback.dma_data : dai->capture.dma_data; 258 dai->playback_dma_data : dai->capture_dma_data;
242} 259}
243 260
244static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai, 261static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
@@ -246,9 +263,20 @@ static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
246 void *data) 263 void *data)
247{ 264{
248 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) 265 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
249 dai->playback.dma_data = data; 266 dai->playback_dma_data = data;
250 else 267 else
251 dai->capture.dma_data = data; 268 dai->capture_dma_data = data;
269}
270
271static inline void snd_soc_dai_set_drvdata(struct snd_soc_dai *dai,
272 void *data)
273{
274 dev_set_drvdata(dai->dev, data);
275}
276
277static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai)
278{
279 return dev_get_drvdata(dai->dev);
252} 280}
253 281
254#endif 282#endif
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index c5d9987bc89..c4a445651ca 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -322,14 +322,14 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
322 322
323/* dapm path setup */ 323/* dapm path setup */
324int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec); 324int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec);
325void snd_soc_dapm_free(struct snd_soc_device *socdev); 325void snd_soc_dapm_free(struct snd_soc_codec *codec);
326int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, 326int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
327 const struct snd_soc_dapm_route *route, int num); 327 const struct snd_soc_dapm_route *route, int num);
328 328
329/* dapm events */ 329/* dapm events */
330int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, 330int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
331 int event); 331 const char *stream, int event);
332void snd_soc_dapm_shutdown(struct snd_soc_device *socdev); 332void snd_soc_dapm_shutdown(struct snd_soc_card *card);
333 333
334/* dapm sys fs - used by the core */ 334/* dapm sys fs - used by the core */
335int snd_soc_dapm_sys_add(struct device *dev); 335int snd_soc_dapm_sys_add(struct device *dev);
diff --git a/include/sound/soc-of-simple.h b/include/sound/soc-of-simple.h
deleted file mode 100644
index a064e1934a5..00000000000
--- a/include/sound/soc-of-simple.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * OF helpers for ALSA SoC
3 *
4 * Copyright (C) 2008, Secret Lab Technologies Ltd.
5 */
6
7#ifndef _INCLUDE_SOC_OF_H_
8#define _INCLUDE_SOC_OF_H_
9
10#if defined(CONFIG_SND_SOC_OF_SIMPLE) || defined(CONFIG_SND_SOC_OF_SIMPLE_MODULE)
11
12#include <linux/of.h>
13#include <sound/soc.h>
14
15int of_snd_soc_register_codec(struct snd_soc_codec_device *codec_dev,
16 void *codec_data, struct snd_soc_dai *dai,
17 struct device_node *node);
18
19int of_snd_soc_register_platform(struct snd_soc_platform *platform,
20 struct device_node *node,
21 struct snd_soc_dai *cpu_dai);
22
23#endif
24
25#endif /* _INCLUDE_SOC_OF_H_ */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 65e9d03ed4f..d31e8b7b2d5 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -228,13 +228,17 @@ struct snd_soc_ops;
228struct snd_soc_dai_mode; 228struct snd_soc_dai_mode;
229struct snd_soc_pcm_runtime; 229struct snd_soc_pcm_runtime;
230struct snd_soc_dai; 230struct snd_soc_dai;
231struct snd_soc_dai_driver;
231struct snd_soc_platform; 232struct snd_soc_platform;
232struct snd_soc_dai_link; 233struct snd_soc_dai_link;
234struct snd_soc_platform_driver;
233struct snd_soc_codec; 235struct snd_soc_codec;
236struct snd_soc_codec_driver;
234struct soc_enum; 237struct soc_enum;
235struct snd_soc_ac97_ops; 238struct snd_soc_ac97_ops;
236struct snd_soc_jack; 239struct snd_soc_jack;
237struct snd_soc_jack_pin; 240struct snd_soc_jack_pin;
241
238#ifdef CONFIG_GPIOLIB 242#ifdef CONFIG_GPIOLIB
239struct snd_soc_jack_gpio; 243struct snd_soc_jack_gpio;
240#endif 244#endif
@@ -249,19 +253,18 @@ enum snd_soc_control_type {
249 SND_SOC_SPI, 253 SND_SOC_SPI,
250}; 254};
251 255
252int snd_soc_register_platform(struct snd_soc_platform *platform); 256int snd_soc_register_platform(struct device *dev,
253void snd_soc_unregister_platform(struct snd_soc_platform *platform); 257 struct snd_soc_platform_driver *platform_drv);
254int snd_soc_register_codec(struct snd_soc_codec *codec); 258void snd_soc_unregister_platform(struct device *dev);
255void snd_soc_unregister_codec(struct snd_soc_codec *codec); 259int snd_soc_register_codec(struct device *dev,
260 struct snd_soc_codec_driver *codec_drv,
261 struct snd_soc_dai_driver *dai_drv, int num_dai);
262void snd_soc_unregister_codec(struct device *dev);
256int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg); 263int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg);
257int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, 264int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
258 int addr_bits, int data_bits, 265 int addr_bits, int data_bits,
259 enum snd_soc_control_type control); 266 enum snd_soc_control_type control);
260 267
261/* pcm <-> DAI connect */
262void snd_soc_free_pcms(struct snd_soc_device *socdev);
263int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid);
264
265/* Utility functions to get clock rates from various things */ 268/* Utility functions to get clock rates from various things */
266int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); 269int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
267int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params); 270int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
@@ -273,7 +276,7 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
273 const struct snd_pcm_hardware *hw); 276 const struct snd_pcm_hardware *hw);
274 277
275/* Jack reporting */ 278/* Jack reporting */
276int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type, 279int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
277 struct snd_soc_jack *jack); 280 struct snd_soc_jack *jack);
278void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask); 281void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask);
279int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, 282int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
@@ -390,7 +393,7 @@ struct snd_soc_jack_gpio {
390 393
391struct snd_soc_jack { 394struct snd_soc_jack {
392 struct snd_jack *jack; 395 struct snd_jack *jack;
393 struct snd_soc_card *card; 396 struct snd_soc_codec *codec;
394 struct list_head pins; 397 struct list_head pins;
395 int status; 398 int status;
396 struct blocking_notifier_head notifier; 399 struct blocking_notifier_head notifier;
@@ -398,15 +401,13 @@ struct snd_soc_jack {
398 401
399/* SoC PCM stream information */ 402/* SoC PCM stream information */
400struct snd_soc_pcm_stream { 403struct snd_soc_pcm_stream {
401 char *stream_name; 404 const char *stream_name;
402 u64 formats; /* SNDRV_PCM_FMTBIT_* */ 405 u64 formats; /* SNDRV_PCM_FMTBIT_* */
403 unsigned int rates; /* SNDRV_PCM_RATE_* */ 406 unsigned int rates; /* SNDRV_PCM_RATE_* */
404 unsigned int rate_min; /* min rate */ 407 unsigned int rate_min; /* min rate */
405 unsigned int rate_max; /* max rate */ 408 unsigned int rate_max; /* max rate */
406 unsigned int channels_min; /* min channels */ 409 unsigned int channels_min; /* min channels */
407 unsigned int channels_max; /* max channels */ 410 unsigned int channels_max; /* max channels */
408 unsigned int active; /* stream is in use */
409 void *dma_data; /* used by platform code */
410}; 411};
411 412
412/* SoC audio ops */ 413/* SoC audio ops */
@@ -419,44 +420,35 @@ struct snd_soc_ops {
419 int (*trigger)(struct snd_pcm_substream *, int); 420 int (*trigger)(struct snd_pcm_substream *, int);
420}; 421};
421 422
422/* SoC Audio Codec */ 423/* SoC Audio Codec device */
423struct snd_soc_codec { 424struct snd_soc_codec {
424 char *name; 425 const char *name;
425 struct module *owner; 426 int id;
426 struct mutex mutex;
427 struct device *dev; 427 struct device *dev;
428 struct snd_soc_device *socdev; 428 struct snd_soc_codec_driver *driver;
429 429
430 struct mutex mutex;
431 struct snd_soc_card *card;
430 struct list_head list; 432 struct list_head list;
431 433 struct list_head card_list;
432 /* callbacks */ 434 int num_dai;
433 int (*set_bias_level)(struct snd_soc_codec *,
434 enum snd_soc_bias_level level);
435 435
436 /* runtime */ 436 /* runtime */
437 struct snd_card *card;
438 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ 437 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
439 unsigned int active; 438 unsigned int active;
440 unsigned int pcm_devs; 439 unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
441 void *drvdata; 440 unsigned int cache_only:1; /* Suppress writes to hardware */
441 unsigned int cache_sync:1; /* Cache needs to be synced to hardware */
442 unsigned int suspended:1; /* Codec is in suspend PM state */
443 unsigned int probed:1; /* Codec has been probed */
444 unsigned int ac97_registered:1; /* Codec has been AC97 registered */
445 unsigned int sysfs_registered:1; /* codec has been sysfs registered */
442 446
443 /* codec IO */ 447 /* codec IO */
444 void *control_data; /* codec control (i2c/3wire) data */ 448 void *control_data; /* codec control (i2c/3wire) data */
445 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
446 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
447 int (*display_register)(struct snd_soc_codec *, char *,
448 size_t, unsigned int);
449 int (*volatile_register)(unsigned int);
450 int (*readable_register)(unsigned int);
451 hw_write_t hw_write; 449 hw_write_t hw_write;
452 unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); 450 unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
453 void *reg_cache; 451 void *reg_cache;
454 short reg_cache_size;
455 short reg_cache_step;
456
457 unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
458 unsigned int cache_only:1; /* Suppress writes to hardware */
459 unsigned int cache_sync:1; /* Cache needs to be synced to hardware */
460 452
461 /* dapm */ 453 /* dapm */
462 u32 pop_time; 454 u32 pop_time;
@@ -466,10 +458,6 @@ struct snd_soc_codec {
466 enum snd_soc_bias_level suspend_bias_level; 458 enum snd_soc_bias_level suspend_bias_level;
467 struct delayed_work delayed_work; 459 struct delayed_work delayed_work;
468 460
469 /* codec DAI's */
470 struct snd_soc_dai *dai;
471 unsigned int num_dai;
472
473#ifdef CONFIG_DEBUG_FS 461#ifdef CONFIG_DEBUG_FS
474 struct dentry *debugfs_codec_root; 462 struct dentry *debugfs_codec_root;
475 struct dentry *debugfs_reg; 463 struct dentry *debugfs_reg;
@@ -478,23 +466,40 @@ struct snd_soc_codec {
478#endif 466#endif
479}; 467};
480 468
481/* codec device */ 469/* codec driver */
482struct snd_soc_codec_device { 470struct snd_soc_codec_driver {
483 int (*probe)(struct platform_device *pdev); 471
484 int (*remove)(struct platform_device *pdev); 472 /* driver ops */
485 int (*suspend)(struct platform_device *pdev, pm_message_t state); 473 int (*probe)(struct snd_soc_codec *);
486 int (*resume)(struct platform_device *pdev); 474 int (*remove)(struct snd_soc_codec *);
475 int (*suspend)(struct snd_soc_codec *,
476 pm_message_t state);
477 int (*resume)(struct snd_soc_codec *);
478
479 /* codec IO */
480 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
481 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
482 int (*display_register)(struct snd_soc_codec *, char *,
483 size_t, unsigned int);
484 int (*volatile_register)(unsigned int);
485 int (*readable_register)(unsigned int);
486 short reg_cache_size;
487 short reg_cache_step;
488 short reg_word_size;
489 const void *reg_cache_default;
490
491 /* codec bias level */
492 int (*set_bias_level)(struct snd_soc_codec *,
493 enum snd_soc_bias_level level);
487}; 494};
488 495
489/* SoC platform interface */ 496/* SoC platform interface */
490struct snd_soc_platform { 497struct snd_soc_platform_driver {
491 char *name;
492 struct list_head list;
493 498
494 int (*probe)(struct platform_device *pdev); 499 int (*probe)(struct snd_soc_platform *);
495 int (*remove)(struct platform_device *pdev); 500 int (*remove)(struct snd_soc_platform *);
496 int (*suspend)(struct snd_soc_dai_link *dai_link); 501 int (*suspend)(struct snd_soc_dai *dai);
497 int (*resume)(struct snd_soc_dai_link *dai_link); 502 int (*resume)(struct snd_soc_dai *dai);
498 503
499 /* pcm creation and destruction */ 504 /* pcm creation and destruction */
500 int (*pcm_new)(struct snd_card *, struct snd_soc_dai *, 505 int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
@@ -509,23 +514,31 @@ struct snd_soc_platform {
509 struct snd_soc_dai *); 514 struct snd_soc_dai *);
510 515
511 /* platform stream ops */ 516 /* platform stream ops */
512 struct snd_pcm_ops *pcm_ops; 517 struct snd_pcm_ops *ops;
513}; 518};
514 519
515/* SoC machine DAI configuration, glues a codec and cpu DAI together */ 520struct snd_soc_platform {
516struct snd_soc_dai_link { 521 const char *name;
517 char *name; /* Codec name */ 522 int id;
518 char *stream_name; /* Stream name */ 523 struct device *dev;
524 struct snd_soc_platform_driver *driver;
519 525
520 /* DAI */ 526 unsigned int suspended:1; /* platform is suspended */
521 struct snd_soc_dai *codec_dai; 527 unsigned int probed:1;
522 struct snd_soc_dai *cpu_dai;
523 528
524 /* machine stream operations */ 529 struct snd_soc_card *card;
525 struct snd_soc_ops *ops; 530 struct list_head list;
531 struct list_head card_list;
532};
526 533
527 /* codec/machine specific init - e.g. add machine controls */ 534struct snd_soc_dai_link {
528 int (*init)(struct snd_soc_codec *codec); 535 /* config - must be set by machine driver */
536 const char *name; /* Codec name */
537 const char *stream_name; /* Stream name */
538 const char *codec_name; /* for multi-codec */
539 const char *platform_name; /* for multi-platform */
540 const char *cpu_dai_name;
541 const char *codec_dai_name;
529 542
530 /* Keep DAI active over suspend */ 543 /* Keep DAI active over suspend */
531 unsigned int ignore_suspend:1; 544 unsigned int ignore_suspend:1;
@@ -533,21 +546,24 @@ struct snd_soc_dai_link {
533 /* Symmetry requirements */ 546 /* Symmetry requirements */
534 unsigned int symmetric_rates:1; 547 unsigned int symmetric_rates:1;
535 548
536 /* Symmetry data - only valid if symmetry is being enforced */ 549 /* codec/machine specific init - e.g. add machine controls */
537 unsigned int rate; 550 int (*init)(struct snd_soc_pcm_runtime *rtd);
538 551
539 /* DAI pcm */ 552 /* machine stream operations */
540 struct snd_pcm *pcm; 553 struct snd_soc_ops *ops;
541}; 554};
542 555
543/* SoC card */ 556/* SoC card */
544struct snd_soc_card { 557struct snd_soc_card {
545 char *name; 558 const char *name;
546 struct device *dev; 559 struct device *dev;
560 struct snd_card *snd_card;
561 struct module *owner;
547 562
548 struct list_head list; 563 struct list_head list;
564 struct mutex mutex;
549 565
550 int instantiated; 566 bool instantiated;
551 567
552 int (*probe)(struct platform_device *pdev); 568 int (*probe)(struct platform_device *pdev);
553 int (*remove)(struct platform_device *pdev); 569 int (*remove)(struct platform_device *pdev);
@@ -568,28 +584,38 @@ struct snd_soc_card {
568 /* CPU <--> Codec DAI links */ 584 /* CPU <--> Codec DAI links */
569 struct snd_soc_dai_link *dai_link; 585 struct snd_soc_dai_link *dai_link;
570 int num_links; 586 int num_links;
587 struct snd_soc_pcm_runtime *rtd;
588 int num_rtd;
571 589
572 struct snd_soc_device *socdev;
573
574 struct snd_soc_codec *codec;
575
576 struct snd_soc_platform *platform;
577 struct delayed_work delayed_work;
578 struct work_struct deferred_resume_work; 590 struct work_struct deferred_resume_work;
591
592 /* lists of probed devices belonging to this card */
593 struct list_head codec_dev_list;
594 struct list_head platform_dev_list;
595 struct list_head dai_dev_list;
579}; 596};
580 597
581/* SoC Device - the audio subsystem */ 598/* SoC machine DAI configuration, glues a codec and cpu DAI together */
582struct snd_soc_device { 599struct snd_soc_pcm_runtime {
583 struct device *dev; 600 struct device dev;
584 struct snd_soc_card *card; 601 struct snd_soc_card *card;
585 struct snd_soc_codec_device *codec_dev; 602 struct snd_soc_dai_link *dai_link;
586 void *codec_data; 603
587}; 604 unsigned int complete:1;
605 unsigned int dev_registered:1;
588 606
589/* runtime channel data */ 607 /* Symmetry data - only valid if symmetry is being enforced */
590struct snd_soc_pcm_runtime { 608 unsigned int rate;
591 struct snd_soc_dai_link *dai; 609 long pmdown_time;
592 struct snd_soc_device *socdev; 610
611 /* runtime devices */
612 struct snd_pcm *pcm;
613 struct snd_soc_codec *codec;
614 struct snd_soc_platform *platform;
615 struct snd_soc_dai *codec_dai;
616 struct snd_soc_dai *cpu_dai;
617
618 struct delayed_work delayed_work;
593}; 619};
594 620
595/* mixer control */ 621/* mixer control */
@@ -615,24 +641,48 @@ struct soc_enum {
615static inline unsigned int snd_soc_read(struct snd_soc_codec *codec, 641static inline unsigned int snd_soc_read(struct snd_soc_codec *codec,
616 unsigned int reg) 642 unsigned int reg)
617{ 643{
618 return codec->read(codec, reg); 644 return codec->driver->read(codec, reg);
619} 645}
620 646
621static inline unsigned int snd_soc_write(struct snd_soc_codec *codec, 647static inline unsigned int snd_soc_write(struct snd_soc_codec *codec,
622 unsigned int reg, unsigned int val) 648 unsigned int reg, unsigned int val)
623{ 649{
624 return codec->write(codec, reg, val); 650 return codec->driver->write(codec, reg, val);
625} 651}
626 652
653/* device driver data */
654
627static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec, 655static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
628 void *data) 656 void *data)
629{ 657{
630 codec->drvdata = data; 658 dev_set_drvdata(codec->dev, data);
631} 659}
632 660
633static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec) 661static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
634{ 662{
635 return codec->drvdata; 663 return dev_get_drvdata(codec->dev);
664}
665
666static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform,
667 void *data)
668{
669 dev_set_drvdata(platform->dev, data);
670}
671
672static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform)
673{
674 return dev_get_drvdata(platform->dev);
675}
676
677static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
678 void *data)
679{
680 dev_set_drvdata(&rtd->dev, data);
681}
682
683static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
684{
685 return dev_get_drvdata(&rtd->dev);
636} 686}
637 687
638#include <sound/soc-dai.h> 688#include <sound/soc-dai.h>
diff --git a/include/sound/tlv320aic3x.h b/include/sound/tlv320aic3x.h
index b1a5f34e5cf..99e0308bf2c 100644
--- a/include/sound/tlv320aic3x.h
+++ b/include/sound/tlv320aic3x.h
@@ -10,8 +10,49 @@
10#ifndef __TLV320AIC3x_H__ 10#ifndef __TLV320AIC3x_H__
11#define __TLV320AIC3x_H__ 11#define __TLV320AIC3x_H__
12 12
13/* GPIO API */
14enum {
15 AIC3X_GPIO1_FUNC_DISABLED = 0,
16 AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1,
17 AIC3X_GPIO1_FUNC_CLOCK_MUX = 2,
18 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3,
19 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4,
20 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5,
21 AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6,
22 AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7,
23 AIC3X_GPIO1_FUNC_INPUT = 8,
24 AIC3X_GPIO1_FUNC_OUTPUT = 9,
25 AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10,
26 AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11,
27 AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12,
28 AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13,
29 AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14,
30 AIC3X_GPIO1_FUNC_ALL_IRQ = 16
31};
32
33enum {
34 AIC3X_GPIO2_FUNC_DISABLED = 0,
35 AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2,
36 AIC3X_GPIO2_FUNC_INPUT = 3,
37 AIC3X_GPIO2_FUNC_OUTPUT = 4,
38 AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5,
39 AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8,
40 AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9,
41 AIC3X_GPIO2_FUNC_ALL_IRQ = 10,
42 AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11,
43 AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12,
44 AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13,
45 AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14,
46 AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15
47};
48
49struct aic3x_setup_data {
50 unsigned int gpio_func[2];
51};
52
13struct aic3x_pdata { 53struct aic3x_pdata {
14 int gpio_reset; /* < 0 if not used */ 54 int gpio_reset; /* < 0 if not used */
55 struct aic3x_setup_data *setup;
15}; 56};
16 57
17#endif \ No newline at end of file 58#endif
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index dc5249fba85..d0e75323ec1 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -179,7 +179,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
179 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 179 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
180 runtime->dma_bytes = params_buffer_bytes(params); 180 runtime->dma_bytes = params_buffer_bytes(params);
181 181
182 prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 182 prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
183 prtd->params->dma_intr_handler = atmel_pcm_dma_irq; 183 prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
184 184
185 prtd->dma_buffer = runtime->dma_addr; 185 prtd->dma_buffer = runtime->dma_addr;
@@ -374,14 +374,14 @@ static int atmel_pcm_new(struct snd_card *card,
374 if (!card->dev->coherent_dma_mask) 374 if (!card->dev->coherent_dma_mask)
375 card->dev->coherent_dma_mask = 0xffffffff; 375 card->dev->coherent_dma_mask = 0xffffffff;
376 376
377 if (dai->playback.channels_min) { 377 if (dai->driver->playback.channels_min) {
378 ret = atmel_pcm_preallocate_dma_buffer(pcm, 378 ret = atmel_pcm_preallocate_dma_buffer(pcm,
379 SNDRV_PCM_STREAM_PLAYBACK); 379 SNDRV_PCM_STREAM_PLAYBACK);
380 if (ret) 380 if (ret)
381 goto out; 381 goto out;
382 } 382 }
383 383
384 if (dai->capture.channels_min) { 384 if (dai->driver->capture.channels_min) {
385 pr_debug("at32-pcm:" 385 pr_debug("at32-pcm:"
386 "Allocating PCM capture DMA buffer\n"); 386 "Allocating PCM capture DMA buffer\n");
387 ret = atmel_pcm_preallocate_dma_buffer(pcm, 387 ret = atmel_pcm_preallocate_dma_buffer(pcm,
@@ -414,12 +414,9 @@ static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
414} 414}
415 415
416#ifdef CONFIG_PM 416#ifdef CONFIG_PM
417static int atmel_pcm_suspend(struct snd_soc_dai_link *dai_link) 417static int atmel_pcm_suspend(struct snd_soc_dai *dai)
418{ 418{
419 struct snd_pcm *pcm = dai_link->pcm; 419 struct snd_pcm_runtime *runtime = dai->runtime;
420 struct snd_pcm_str *stream = &pcm->streams[0];
421 struct snd_pcm_substream *substream = stream->substream;
422 struct snd_pcm_runtime *runtime = substream->runtime;
423 struct atmel_runtime_data *prtd; 420 struct atmel_runtime_data *prtd;
424 struct atmel_pcm_dma_params *params; 421 struct atmel_pcm_dma_params *params;
425 422
@@ -441,12 +438,9 @@ static int atmel_pcm_suspend(struct snd_soc_dai_link *dai_link)
441 return 0; 438 return 0;
442} 439}
443 440
444static int atmel_pcm_resume(struct snd_soc_dai_link *dai_link) 441static int atmel_pcm_resume(struct snd_soc_dai *dai)
445{ 442{
446 struct snd_pcm *pcm = dai_link->pcm; 443 struct snd_pcm_runtime *runtime = dai->runtime;
447 struct snd_pcm_str *stream = &pcm->streams[0];
448 struct snd_pcm_substream *substream = stream->substream;
449 struct snd_pcm_runtime *runtime = substream->runtime;
450 struct atmel_runtime_data *prtd; 444 struct atmel_runtime_data *prtd;
451 struct atmel_pcm_dma_params *params; 445 struct atmel_pcm_dma_params *params;
452 446
@@ -470,27 +464,46 @@ static int atmel_pcm_resume(struct snd_soc_dai_link *dai_link)
470#define atmel_pcm_resume NULL 464#define atmel_pcm_resume NULL
471#endif 465#endif
472 466
473struct snd_soc_platform atmel_soc_platform = { 467static struct snd_soc_platform_driver atmel_soc_platform = {
474 .name = "atmel-audio", 468 .ops = &atmel_pcm_ops,
475 .pcm_ops = &atmel_pcm_ops,
476 .pcm_new = atmel_pcm_new, 469 .pcm_new = atmel_pcm_new,
477 .pcm_free = atmel_pcm_free_dma_buffers, 470 .pcm_free = atmel_pcm_free_dma_buffers,
478 .suspend = atmel_pcm_suspend, 471 .suspend = atmel_pcm_suspend,
479 .resume = atmel_pcm_resume, 472 .resume = atmel_pcm_resume,
480}; 473};
481EXPORT_SYMBOL_GPL(atmel_soc_platform);
482 474
483static int __init atmel_pcm_modinit(void) 475static int __devinit atmel_soc_platform_probe(struct platform_device *pdev)
476{
477 return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform);
478}
479
480static int __devexit atmel_soc_platform_remove(struct platform_device *pdev)
481{
482 snd_soc_unregister_platform(&pdev->dev);
483 return 0;
484}
485
486static struct platform_driver atmel_pcm_driver = {
487 .driver = {
488 .name = "atmel-pcm-audio",
489 .owner = THIS_MODULE,
490 },
491
492 .probe = atmel_soc_platform_probe,
493 .remove = __devexit_p(atmel_soc_platform_remove),
494};
495
496static int __init snd_atmel_pcm_init(void)
484{ 497{
485 return snd_soc_register_platform(&atmel_soc_platform); 498 return platform_driver_register(&atmel_pcm_driver);
486} 499}
487module_init(atmel_pcm_modinit); 500module_init(snd_atmel_pcm_init);
488 501
489static void __exit atmel_pcm_modexit(void) 502static void __exit snd_atmel_pcm_exit(void)
490{ 503{
491 snd_soc_unregister_platform(&atmel_soc_platform); 504 platform_driver_unregister(&atmel_pcm_driver);
492} 505}
493module_exit(atmel_pcm_modexit); 506module_exit(snd_atmel_pcm_exit);
494 507
495MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); 508MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
496MODULE_DESCRIPTION("Atmel PCM module"); 509MODULE_DESCRIPTION("Atmel PCM module");
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
index ec9b2824b66..2597329302e 100644
--- a/sound/soc/atmel/atmel-pcm.h
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -74,9 +74,6 @@ struct atmel_pcm_dma_params {
74 void (*dma_intr_handler)(u32, struct snd_pcm_substream *); 74 void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
75}; 75};
76 76
77extern struct snd_soc_platform atmel_soc_platform;
78
79
80/* 77/*
81 * SSC register access (since ssc_writel() / ssc_readl() require literal name) 78 * SSC register access (since ssc_writel() / ssc_readl() require literal name)
82 */ 79 */
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index c85844d4845..eabf66af12c 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -205,8 +205,7 @@ static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
205static int atmel_ssc_startup(struct snd_pcm_substream *substream, 205static int atmel_ssc_startup(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai) 206 struct snd_soc_dai *dai)
207{ 207{
208 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 208 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
209 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
210 int dir_mask; 209 int dir_mask;
211 210
212 pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n", 211 pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
@@ -235,8 +234,7 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
235static void atmel_ssc_shutdown(struct snd_pcm_substream *substream, 234static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
236 struct snd_soc_dai *dai) 235 struct snd_soc_dai *dai)
237{ 236{
238 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 237 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
239 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
240 struct atmel_pcm_dma_params *dma_params; 238 struct atmel_pcm_dma_params *dma_params;
241 int dir, dir_mask; 239 int dir, dir_mask;
242 240
@@ -338,7 +336,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
338 struct snd_soc_dai *dai) 336 struct snd_soc_dai *dai)
339{ 337{
340 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 338 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
341 int id = rtd->dai->cpu_dai->id; 339 int id = dai->id;
342 struct atmel_ssc_info *ssc_p = &ssc_info[id]; 340 struct atmel_ssc_info *ssc_p = &ssc_info[id];
343 struct atmel_pcm_dma_params *dma_params; 341 struct atmel_pcm_dma_params *dma_params;
344 int dir, channels, bits; 342 int dir, channels, bits;
@@ -368,7 +366,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
368 * function. It should not be used for other purposes 366 * function. It should not be used for other purposes
369 * as it is common to all substreams. 367 * as it is common to all substreams.
370 */ 368 */
371 snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params); 369 snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_params);
372 370
373 channels = params_channels(params); 371 channels = params_channels(params);
374 372
@@ -605,8 +603,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
605static int atmel_ssc_prepare(struct snd_pcm_substream *substream, 603static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
606 struct snd_soc_dai *dai) 604 struct snd_soc_dai *dai)
607{ 605{
608 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 606 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
609 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
610 struct atmel_pcm_dma_params *dma_params; 607 struct atmel_pcm_dma_params *dma_params;
611 int dir; 608 int dir;
612 609
@@ -690,6 +687,32 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
690# define atmel_ssc_resume NULL 687# define atmel_ssc_resume NULL
691#endif /* CONFIG_PM */ 688#endif /* CONFIG_PM */
692 689
690static int atmel_ssc_probe(struct snd_soc_dai *dai)
691{
692 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
693 int ret = 0;
694
695 snd_soc_dai_set_drvdata(dai, ssc_p);
696
697 /*
698 * Request SSC device
699 */
700 ssc_p->ssc = ssc_request(dai->id);
701 if (IS_ERR(ssc_p->ssc)) {
702 printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id);
703 ret = PTR_ERR(ssc_p->ssc);
704 }
705
706 return ret;
707}
708
709static int atmel_ssc_remove(struct snd_soc_dai *dai)
710{
711 struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai);
712
713 ssc_free(ssc_p->ssc);
714 return 0;
715}
693 716
694#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000) 717#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000)
695 718
@@ -705,9 +728,11 @@ static struct snd_soc_dai_ops atmel_ssc_dai_ops = {
705 .set_clkdiv = atmel_ssc_set_dai_clkdiv, 728 .set_clkdiv = atmel_ssc_set_dai_clkdiv,
706}; 729};
707 730
708struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = { 731static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
709 { .name = "atmel-ssc0", 732 {
710 .id = 0, 733 .name = "atmel-ssc-dai.0",
734 .probe = atmel_ssc_probe,
735 .remove = atmel_ssc_remove,
711 .suspend = atmel_ssc_suspend, 736 .suspend = atmel_ssc_suspend,
712 .resume = atmel_ssc_resume, 737 .resume = atmel_ssc_resume,
713 .playback = { 738 .playback = {
@@ -721,11 +746,12 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
721 .rates = ATMEL_SSC_RATES, 746 .rates = ATMEL_SSC_RATES,
722 .formats = ATMEL_SSC_FORMATS,}, 747 .formats = ATMEL_SSC_FORMATS,},
723 .ops = &atmel_ssc_dai_ops, 748 .ops = &atmel_ssc_dai_ops,
724 .private_data = &ssc_info[0],
725 }, 749 },
726#if NUM_SSC_DEVICES == 3 750#if NUM_SSC_DEVICES == 3
727 { .name = "atmel-ssc1", 751 {
728 .id = 1, 752 .name = "atmel-ssc-dai.1",
753 .probe = atmel_ssc_probe,
754 .remove = atmel_ssc_remove,
729 .suspend = atmel_ssc_suspend, 755 .suspend = atmel_ssc_suspend,
730 .resume = atmel_ssc_resume, 756 .resume = atmel_ssc_resume,
731 .playback = { 757 .playback = {
@@ -739,10 +765,11 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
739 .rates = ATMEL_SSC_RATES, 765 .rates = ATMEL_SSC_RATES,
740 .formats = ATMEL_SSC_FORMATS,}, 766 .formats = ATMEL_SSC_FORMATS,},
741 .ops = &atmel_ssc_dai_ops, 767 .ops = &atmel_ssc_dai_ops,
742 .private_data = &ssc_info[1],
743 }, 768 },
744 { .name = "atmel-ssc2", 769 {
745 .id = 2, 770 .name = "atmel-ssc-dai.2",
771 .probe = atmel_ssc_probe,
772 .remove = atmel_ssc_remove,
746 .suspend = atmel_ssc_suspend, 773 .suspend = atmel_ssc_suspend,
747 .resume = atmel_ssc_resume, 774 .resume = atmel_ssc_resume,
748 .playback = { 775 .playback = {
@@ -756,23 +783,43 @@ struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
756 .rates = ATMEL_SSC_RATES, 783 .rates = ATMEL_SSC_RATES,
757 .formats = ATMEL_SSC_FORMATS,}, 784 .formats = ATMEL_SSC_FORMATS,},
758 .ops = &atmel_ssc_dai_ops, 785 .ops = &atmel_ssc_dai_ops,
759 .private_data = &ssc_info[2],
760 }, 786 },
761#endif 787#endif
762}; 788};
763EXPORT_SYMBOL_GPL(atmel_ssc_dai);
764 789
765static int __init atmel_ssc_modinit(void) 790static __devinit int asoc_ssc_probe(struct platform_device *pdev)
791{
792 return snd_soc_register_dais(&pdev->dev, atmel_ssc_dai,
793 ARRAY_SIZE(atmel_ssc_dai));
794}
795
796static int __devexit asoc_ssc_remove(struct platform_device *pdev)
797{
798 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(atmel_ssc_dai));
799 return 0;
800}
801
802static struct platform_driver asoc_ssc_driver = {
803 .driver = {
804 .name = "atmel-ssc-dai",
805 .owner = THIS_MODULE,
806 },
807
808 .probe = asoc_ssc_probe,
809 .remove = __devexit_p(asoc_ssc_remove),
810};
811
812static int __init snd_atmel_ssc_init(void)
766{ 813{
767 return snd_soc_register_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai)); 814 return platform_driver_register(&asoc_ssc_driver);
768} 815}
769module_init(atmel_ssc_modinit); 816module_init(snd_atmel_ssc_init);
770 817
771static void __exit atmel_ssc_modexit(void) 818static void __exit snd_atmel_ssc_exit(void)
772{ 819{
773 snd_soc_unregister_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai)); 820 platform_driver_unregister(&asoc_ssc_driver);
774} 821}
775module_exit(atmel_ssc_modexit); 822module_exit(snd_atmel_ssc_exit);
776 823
777/* Module information */ 824/* Module information */
778MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com"); 825MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h
index 391135f9c6c..392a4695311 100644
--- a/sound/soc/atmel/atmel_ssc_dai.h
+++ b/sound/soc/atmel/atmel_ssc_dai.h
@@ -116,6 +116,5 @@ struct atmel_ssc_info {
116 struct atmel_pcm_dma_params *dma_params[2]; 116 struct atmel_pcm_dma_params *dma_params[2];
117 struct atmel_ssc_state ssc_state; 117 struct atmel_ssc_state ssc_state;
118}; 118};
119extern struct snd_soc_dai atmel_ssc_dai[];
120 119
121#endif /* _AT91_SSC_DAI_H */ 120#endif /* _AT91_SSC_DAI_H */
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 9df4c68ef00..5f4e59f4461 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -83,7 +83,7 @@ static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock(
83 struct snd_pcm_hw_params *params, 83 struct snd_pcm_hw_params *params,
84 struct snd_soc_dai *cpu_dai) 84 struct snd_soc_dai *cpu_dai)
85{ 85{
86 struct at32_ssc_info *ssc_p = cpu_dai->private_data; 86 struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai);
87 struct ssc_device *ssc = ssc_p->ssc; 87 struct ssc_device *ssc = ssc_p->ssc;
88 struct ssc_clock_data cd; 88 struct ssc_clock_data cd;
89 unsigned int rate, width_bits, channels; 89 unsigned int rate, width_bits, channels;
@@ -131,9 +131,9 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream,
131 struct snd_pcm_hw_params *params) 131 struct snd_pcm_hw_params *params)
132{ 132{
133 struct snd_soc_pcm_runtime *rtd = substream->private_data; 133 struct snd_soc_pcm_runtime *rtd = substream->private_data;
134 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 134 struct snd_soc_dai *codec_dai = rtd->codec_dai;
135 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 135 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
136 struct at32_ssc_info *ssc_p = cpu_dai->private_data; 136 struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai);
137 struct ssc_device *ssc = ssc_p->ssc; 137 struct ssc_device *ssc = ssc_p->ssc;
138 unsigned int pll_out = 0, bclk = 0, mclk_div = 0; 138 unsigned int pll_out = 0, bclk = 0, mclk_div = 0;
139 int ret; 139 int ret;
@@ -315,8 +315,9 @@ static const struct snd_soc_dapm_route intercon[] = {
315 315
316 316
317 317
318static int playpaq_wm8510_init(struct snd_soc_codec *codec) 318static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd)
319{ 319{
320 struct snd_soc_codec *codec = rtd->codec;
320 int i; 321 int i;
321 322
322 /* 323 /*
@@ -342,7 +343,7 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec)
342 343
343 344
344 /* Make CSB show PLL rate */ 345 /* Make CSB show PLL rate */
345 snd_soc_dai_set_clkdiv(codec->dai, WM8510_OPCLKDIV, 346 snd_soc_dai_set_clkdiv(rtd->codec_dai, WM8510_OPCLKDIV,
346 WM8510_OPCLKDIV_1 | 4); 347 WM8510_OPCLKDIV_1 | 4);
347 348
348 return 0; 349 return 0;
@@ -353,8 +354,10 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec)
353static struct snd_soc_dai_link playpaq_wm8510_dai = { 354static struct snd_soc_dai_link playpaq_wm8510_dai = {
354 .name = "WM8510", 355 .name = "WM8510",
355 .stream_name = "WM8510 PCM", 356 .stream_name = "WM8510 PCM",
356 .cpu_dai = &at32_ssc_dai[0], 357 .cpu_dai_name= "atmel-ssc-dai.0",
357 .codec_dai = &wm8510_dai, 358 .platform_name = "atmel-pcm-audio",
359 .codec_name = "wm8510-codec.0-0x1a",
360 .codec_dai_name = "wm8510-hifi",
358 .init = playpaq_wm8510_init, 361 .init = playpaq_wm8510_init,
359 .ops = &playpaq_wm8510_ops, 362 .ops = &playpaq_wm8510_ops,
360}; 363};
@@ -363,46 +366,16 @@ static struct snd_soc_dai_link playpaq_wm8510_dai = {
363 366
364static struct snd_soc_card snd_soc_playpaq = { 367static struct snd_soc_card snd_soc_playpaq = {
365 .name = "LRS_PlayPaq_WM8510", 368 .name = "LRS_PlayPaq_WM8510",
366 .platform = &at32_soc_platform,
367 .dai_link = &playpaq_wm8510_dai, 369 .dai_link = &playpaq_wm8510_dai,
368 .num_links = 1, 370 .num_links = 1,
369}; 371};
370 372
371
372
373static struct wm8510_setup_data playpaq_wm8510_setup = {
374 .i2c_bus = 0,
375 .i2c_address = 0x1a,
376};
377
378
379
380static struct snd_soc_device playpaq_wm8510_snd_devdata = {
381 .card = &snd_soc_playpaq,
382 .codec_dev = &soc_codec_dev_wm8510,
383 .codec_data = &playpaq_wm8510_setup,
384};
385
386static struct platform_device *playpaq_snd_device; 373static struct platform_device *playpaq_snd_device;
387 374
388 375
389static int __init playpaq_asoc_init(void) 376static int __init playpaq_asoc_init(void)
390{ 377{
391 int ret = 0; 378 int ret = 0;
392 struct at32_ssc_info *ssc_p = playpaq_wm8510_dai.cpu_dai->private_data;
393 struct ssc_device *ssc = NULL;
394
395
396 /*
397 * Request SSC device
398 */
399 ssc = ssc_request(0);
400 if (IS_ERR(ssc)) {
401 ret = PTR_ERR(ssc);
402 goto err_ssc;
403 }
404 ssc_p->ssc = ssc;
405
406 379
407 /* 380 /*
408 * Configure MCLK for WM8510 381 * Configure MCLK for WM8510
@@ -439,8 +412,7 @@ static int __init playpaq_asoc_init(void)
439 goto err_device_alloc; 412 goto err_device_alloc;
440 } 413 }
441 414
442 platform_set_drvdata(playpaq_snd_device, &playpaq_wm8510_snd_devdata); 415 platform_set_drvdata(playpaq_snd_device, &snd_soc_playpaq);
443 playpaq_wm8510_snd_devdata.dev = &playpaq_snd_device->dev;
444 416
445 ret = platform_device_add(playpaq_snd_device); 417 ret = platform_device_add(playpaq_snd_device);
446 if (ret) { 418 if (ret) {
@@ -468,25 +440,12 @@ err_pll0:
468 clk_put(_gclk0); 440 clk_put(_gclk0);
469 _gclk0 = NULL; 441 _gclk0 = NULL;
470 } 442 }
471err_gclk0:
472 ssc_free(ssc);
473err_ssc:
474 return ret; 443 return ret;
475} 444}
476 445
477 446
478static void __exit playpaq_asoc_exit(void) 447static void __exit playpaq_asoc_exit(void)
479{ 448{
480 struct at32_ssc_info *ssc_p = playpaq_wm8510_dai.cpu_dai->private_data;
481 struct ssc_device *ssc;
482
483 if (ssc_p != NULL) {
484 ssc = ssc_p->ssc;
485 if (ssc != NULL)
486 ssc_free(ssc);
487 ssc_p->ssc = NULL;
488 }
489
490 if (_gclk0 != NULL) { 449 if (_gclk0 != NULL) {
491 clk_put(_gclk0); 450 clk_put(_gclk0);
492 _gclk0 = NULL; 451 _gclk0 = NULL;
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index e028744c32c..66a6f187968 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -69,8 +69,8 @@ static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
69 struct snd_pcm_hw_params *params) 69 struct snd_pcm_hw_params *params)
70{ 70{
71 struct snd_soc_pcm_runtime *rtd = substream->private_data; 71 struct snd_soc_pcm_runtime *rtd = substream->private_data;
72 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 72 struct snd_soc_dai *codec_dai = rtd->codec_dai;
73 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 73 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
74 int ret; 74 int ret;
75 75
76 /* set codec DAI configuration */ 76 /* set codec DAI configuration */
@@ -136,9 +136,10 @@ static const struct snd_soc_dapm_route intercon[] = {
136/* 136/*
137 * Logic for a wm8731 as connected on a at91sam9g20ek board. 137 * Logic for a wm8731 as connected on a at91sam9g20ek board.
138 */ 138 */
139static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec) 139static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
140{ 140{
141 struct snd_soc_dai *codec_dai = &codec->dai[0]; 141 struct snd_soc_codec *codec = rtd->codec;
142 struct snd_soc_dai *codec_dai = rtd->codec_dai;
142 int ret; 143 int ret;
143 144
144 printk(KERN_DEBUG 145 printk(KERN_DEBUG
@@ -179,31 +180,25 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
179static struct snd_soc_dai_link at91sam9g20ek_dai = { 180static struct snd_soc_dai_link at91sam9g20ek_dai = {
180 .name = "WM8731", 181 .name = "WM8731",
181 .stream_name = "WM8731 PCM", 182 .stream_name = "WM8731 PCM",
182 .cpu_dai = &atmel_ssc_dai[0], 183 .cpu_dai_name = "atmel-ssc-dai.0",
183 .codec_dai = &wm8731_dai, 184 .codec_dai_name = "wm8731-hifi",
184 .init = at91sam9g20ek_wm8731_init, 185 .init = at91sam9g20ek_wm8731_init,
186 .platform_name = "atmel_pcm-audio",
187 .codec_name = "wm8731-codec.0-001a",
185 .ops = &at91sam9g20ek_ops, 188 .ops = &at91sam9g20ek_ops,
186}; 189};
187 190
188static struct snd_soc_card snd_soc_at91sam9g20ek = { 191static struct snd_soc_card snd_soc_at91sam9g20ek = {
189 .name = "AT91SAMG20-EK", 192 .name = "AT91SAMG20-EK",
190 .platform = &atmel_soc_platform,
191 .dai_link = &at91sam9g20ek_dai, 193 .dai_link = &at91sam9g20ek_dai,
192 .num_links = 1, 194 .num_links = 1,
193 .set_bias_level = at91sam9g20ek_set_bias_level, 195 .set_bias_level = at91sam9g20ek_set_bias_level,
194}; 196};
195 197
196static struct snd_soc_device at91sam9g20ek_snd_devdata = {
197 .card = &snd_soc_at91sam9g20ek,
198 .codec_dev = &soc_codec_dev_wm8731,
199};
200
201static struct platform_device *at91sam9g20ek_snd_device; 198static struct platform_device *at91sam9g20ek_snd_device;
202 199
203static int __init at91sam9g20ek_init(void) 200static int __init at91sam9g20ek_init(void)
204{ 201{
205 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
206 struct ssc_device *ssc = NULL;
207 struct clk *pllb; 202 struct clk *pllb;
208 int ret; 203 int ret;
209 204
@@ -235,18 +230,6 @@ static int __init at91sam9g20ek_init(void)
235 230
236 clk_set_rate(mclk, MCLK_RATE); 231 clk_set_rate(mclk, MCLK_RATE);
237 232
238 /*
239 * Request SSC device
240 */
241 ssc = ssc_request(0);
242 if (IS_ERR(ssc)) {
243 printk(KERN_ERR "ASoC: Failed to request SSC 0\n");
244 ret = PTR_ERR(ssc);
245 ssc = NULL;
246 goto err_ssc;
247 }
248 ssc_p->ssc = ssc;
249
250 at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1); 233 at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
251 if (!at91sam9g20ek_snd_device) { 234 if (!at91sam9g20ek_snd_device) {
252 printk(KERN_ERR "ASoC: Platform device allocation failed\n"); 235 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
@@ -254,8 +237,7 @@ static int __init at91sam9g20ek_init(void)
254 } 237 }
255 238
256 platform_set_drvdata(at91sam9g20ek_snd_device, 239 platform_set_drvdata(at91sam9g20ek_snd_device,
257 &at91sam9g20ek_snd_devdata); 240 &snd_soc_at91sam9g20ek);
258 at91sam9g20ek_snd_devdata.dev = &at91sam9g20ek_snd_device->dev;
259 241
260 ret = platform_device_add(at91sam9g20ek_snd_device); 242 ret = platform_device_add(at91sam9g20ek_snd_device);
261 if (ret) { 243 if (ret) {
@@ -265,9 +247,6 @@ static int __init at91sam9g20ek_init(void)
265 247
266 return ret; 248 return ret;
267 249
268err_ssc:
269 ssc_free(ssc);
270 ssc_p->ssc = NULL;
271err_mclk: 250err_mclk:
272 clk_put(mclk); 251 clk_put(mclk);
273 mclk = NULL; 252 mclk = NULL;
@@ -277,16 +256,6 @@ err:
277 256
278static void __exit at91sam9g20ek_exit(void) 257static void __exit at91sam9g20ek_exit(void)
279{ 258{
280 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
281 struct ssc_device *ssc;
282
283 if (ssc_p != NULL) {
284 ssc = ssc_p->ssc;
285 if (ssc != NULL)
286 ssc_free(ssc);
287 ssc_p->ssc = NULL;
288 }
289
290 platform_device_unregister(at91sam9g20ek_snd_device); 259 platform_device_unregister(at91sam9g20ek_snd_device);
291 at91sam9g20ek_snd_device = NULL; 260 at91sam9g20ek_snd_device = NULL;
292 clk_put(mclk); 261 clk_put(mclk);
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index 23349de2731..e3d283561c1 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -46,8 +46,8 @@ static int afeb9260_hw_params(struct snd_pcm_substream *substream,
46 struct snd_pcm_hw_params *params) 46 struct snd_pcm_hw_params *params)
47{ 47{
48 struct snd_soc_pcm_runtime *rtd = substream->private_data; 48 struct snd_soc_pcm_runtime *rtd = substream->private_data;
49 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 49 struct snd_soc_dai *codec_dai = rtd->codec_dai;
50 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
51 int err; 51 int err;
52 52
53 /* Set codec DAI configuration */ 53 /* Set codec DAI configuration */
@@ -102,8 +102,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
102 {"MICIN", NULL, "Mic Jack"}, 102 {"MICIN", NULL, "Mic Jack"},
103}; 103};
104 104
105static int afeb9260_tlv320aic23_init(struct snd_soc_codec *codec) 105static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
106{ 106{
107 struct snd_soc_codec *codec = rtd->codec;
107 108
108 /* Add afeb9260 specific widgets */ 109 /* Add afeb9260 specific widgets */
109 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 110 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
@@ -125,8 +126,10 @@ static int afeb9260_tlv320aic23_init(struct snd_soc_codec *codec)
125static struct snd_soc_dai_link afeb9260_dai = { 126static struct snd_soc_dai_link afeb9260_dai = {
126 .name = "TLV320AIC23", 127 .name = "TLV320AIC23",
127 .stream_name = "AIC23", 128 .stream_name = "AIC23",
128 .cpu_dai = &atmel_ssc_dai[0], 129 .cpu_dai_name = "atmel-ssc-dai.0",
129 .codec_dai = &tlv320aic23_dai, 130 .codec_dai_name = "tlv320aic23-hifi",
131 .platform_name = "atmel_pcm-audio",
132 .codec_name = "tlv320aic23-codec.0-0x1a",
130 .init = afeb9260_tlv320aic23_init, 133 .init = afeb9260_tlv320aic23_init,
131 .ops = &afeb9260_ops, 134 .ops = &afeb9260_ops,
132}; 135};
@@ -134,37 +137,20 @@ static struct snd_soc_dai_link afeb9260_dai = {
134/* Audio machine driver */ 137/* Audio machine driver */
135static struct snd_soc_card snd_soc_machine_afeb9260 = { 138static struct snd_soc_card snd_soc_machine_afeb9260 = {
136 .name = "AFEB9260", 139 .name = "AFEB9260",
137 .platform = &atmel_soc_platform,
138 .dai_link = &afeb9260_dai, 140 .dai_link = &afeb9260_dai,
139 .num_links = 1, 141 .num_links = 1,
140}; 142};
141 143
142/* Audio subsystem */
143static struct snd_soc_device afeb9260_snd_devdata = {
144 .card = &snd_soc_machine_afeb9260,
145 .codec_dev = &soc_codec_dev_tlv320aic23,
146};
147
148static struct platform_device *afeb9260_snd_device; 144static struct platform_device *afeb9260_snd_device;
149 145
150static int __init afeb9260_soc_init(void) 146static int __init afeb9260_soc_init(void)
151{ 147{
152 int err; 148 int err;
153 struct device *dev; 149 struct device *dev;
154 struct atmel_ssc_info *ssc_p = afeb9260_dai.cpu_dai->private_data;
155 struct ssc_device *ssc = NULL;
156 150
157 if (!(machine_is_afeb9260())) 151 if (!(machine_is_afeb9260()))
158 return -ENODEV; 152 return -ENODEV;
159 153
160 ssc = ssc_request(0);
161 if (IS_ERR(ssc)) {
162 printk(KERN_ERR "ASoC: Failed to request SSC 0\n");
163 err = PTR_ERR(ssc);
164 ssc = NULL;
165 goto err_ssc;
166 }
167 ssc_p->ssc = ssc;
168 154
169 afeb9260_snd_device = platform_device_alloc("soc-audio", -1); 155 afeb9260_snd_device = platform_device_alloc("soc-audio", -1);
170 if (!afeb9260_snd_device) { 156 if (!afeb9260_snd_device) {
@@ -172,8 +158,7 @@ static int __init afeb9260_soc_init(void)
172 return -ENOMEM; 158 return -ENOMEM;
173 } 159 }
174 160
175 platform_set_drvdata(afeb9260_snd_device, &afeb9260_snd_devdata); 161 platform_set_drvdata(afeb9260_snd_device, &snd_soc_machine_afeb9260);
176 afeb9260_snd_devdata.dev = &afeb9260_snd_device->dev;
177 err = platform_device_add(afeb9260_snd_device); 162 err = platform_device_add(afeb9260_snd_device);
178 if (err) 163 if (err)
179 goto err1; 164 goto err1;
@@ -184,9 +169,7 @@ static int __init afeb9260_soc_init(void)
184err1: 169err1:
185 platform_device_del(afeb9260_snd_device); 170 platform_device_del(afeb9260_snd_device);
186 platform_device_put(afeb9260_snd_device); 171 platform_device_put(afeb9260_snd_device);
187err_ssc:
188 return err; 172 return err;
189
190} 173}
191 174
192static void __exit afeb9260_soc_exit(void) 175static void __exit afeb9260_soc_exit(void)
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index cdf7be1b9b9..8780c90107f 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -19,7 +19,6 @@
19#include <asm/mach-au1x00/au1xxx_dbdma.h> 19#include <asm/mach-au1x00/au1xxx_dbdma.h>
20#include <asm/mach-db1x00/bcsr.h> 20#include <asm/mach-db1x00/bcsr.h>
21 21
22#include "../codecs/ac97.h"
23#include "../codecs/wm8731.h" 22#include "../codecs/wm8731.h"
24#include "psc.h" 23#include "psc.h"
25 24
@@ -28,20 +27,16 @@
28static struct snd_soc_dai_link db1200_ac97_dai = { 27static struct snd_soc_dai_link db1200_ac97_dai = {
29 .name = "AC97", 28 .name = "AC97",
30 .stream_name = "AC97 HiFi", 29 .stream_name = "AC97 HiFi",
31 .cpu_dai = &au1xpsc_ac97_dai, 30 .cpu_dai_name = "au1xpsc-ac97",
32 .codec_dai = &ac97_dai, 31 .codec_dai_name = "ac97-hifi",
32 .platform_name = "au1xpsc-pcm-audio",
33 .codec_name = "ac97-codec",
33}; 34};
34 35
35static struct snd_soc_card db1200_ac97_machine = { 36static struct snd_soc_card db1200_ac97_machine = {
36 .name = "DB1200_AC97", 37 .name = "DB1200_AC97",
37 .dai_link = &db1200_ac97_dai, 38 .dai_link = &db1200_ac97_dai,
38 .num_links = 1, 39 .num_links = 1,
39 .platform = &au1xpsc_soc_platform,
40};
41
42static struct snd_soc_device db1200_ac97_devdata = {
43 .card = &db1200_ac97_machine,
44 .codec_dev = &soc_codec_dev_ac97,
45}; 40};
46 41
47/*------------------------- I2S PART ---------------------------*/ 42/*------------------------- I2S PART ---------------------------*/
@@ -49,8 +44,8 @@ static struct snd_soc_device db1200_ac97_devdata = {
49static int db1200_i2s_startup(struct snd_pcm_substream *substream) 44static int db1200_i2s_startup(struct snd_pcm_substream *substream)
50{ 45{
51 struct snd_soc_pcm_runtime *rtd = substream->private_data; 46 struct snd_soc_pcm_runtime *rtd = substream->private_data;
52 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 47 struct snd_soc_dai *codec_dai = rtd->codec_dai;
53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 48 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
54 int ret; 49 int ret;
55 50
56 /* WM8731 has its own 12MHz crystal */ 51 /* WM8731 has its own 12MHz crystal */
@@ -80,8 +75,10 @@ static struct snd_soc_ops db1200_i2s_wm8731_ops = {
80static struct snd_soc_dai_link db1200_i2s_dai = { 75static struct snd_soc_dai_link db1200_i2s_dai = {
81 .name = "WM8731", 76 .name = "WM8731",
82 .stream_name = "WM8731 PCM", 77 .stream_name = "WM8731 PCM",
83 .cpu_dai = &au1xpsc_i2s_dai, 78 .cpu_dai_name = "au1xpsc",
84 .codec_dai = &wm8731_dai, 79 .codec_dai_name = "wm8731-hifi"
80 .platform_name = "au1xpsc-pcm-audio",
81 .codec_name = "wm8731-codec.0-001a",
85 .ops = &db1200_i2s_wm8731_ops, 82 .ops = &db1200_i2s_wm8731_ops,
86}; 83};
87 84
@@ -89,12 +86,6 @@ static struct snd_soc_card db1200_i2s_machine = {
89 .name = "DB1200_I2S", 86 .name = "DB1200_I2S",
90 .dai_link = &db1200_i2s_dai, 87 .dai_link = &db1200_i2s_dai,
91 .num_links = 1, 88 .num_links = 1,
92 .platform = &au1xpsc_soc_platform,
93};
94
95static struct snd_soc_device db1200_i2s_devdata = {
96 .card = &db1200_i2s_machine,
97 .codec_dev = &soc_codec_dev_wm8731,
98}; 89};
99 90
100/*------------------------- COMMON PART ---------------------------*/ 91/*------------------------- COMMON PART ---------------------------*/
@@ -112,12 +103,10 @@ static int __init db1200_audio_load(void)
112 103
113 /* DB1200 board setup set PSC1MUX to preferred audio device */ 104 /* DB1200 board setup set PSC1MUX to preferred audio device */
114 if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX) 105 if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX)
115 platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_devdata); 106 platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_machine);
116 else 107 else
117 platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_devdata); 108 platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_machine);
118 109
119 db1200_ac97_devdata.dev = &db1200_asoc_dev->dev;
120 db1200_i2s_devdata.dev = &db1200_asoc_dev->dev;
121 ret = platform_device_add(db1200_asoc_dev); 110 ret = platform_device_add(db1200_asoc_dev);
122 111
123 if (ret) { 112 if (ret) {
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 6d9f4c62494..00fdb9cbfc2 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -329,7 +329,7 @@ static int au1xpsc_pcm_new(struct snd_card *card,
329 return 0; 329 return 0;
330} 330}
331 331
332static int au1xpsc_pcm_probe(struct platform_device *pdev) 332static int au1xpsc_pcm_probe(struct snd_soc_platform *platform)
333{ 333{
334 if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX]) 334 if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX])
335 return -ENODEV; 335 return -ENODEV;
@@ -337,17 +337,10 @@ static int au1xpsc_pcm_probe(struct platform_device *pdev)
337 return 0; 337 return 0;
338} 338}
339 339
340static int au1xpsc_pcm_remove(struct platform_device *pdev)
341{
342 return 0;
343}
344
345/* au1xpsc audio platform */ 340/* au1xpsc audio platform */
346struct snd_soc_platform au1xpsc_soc_platform = { 341struct snd_soc_platform_driver au1xpsc_soc_platform = {
347 .name = "au1xpsc-pcm-dbdma",
348 .probe = au1xpsc_pcm_probe, 342 .probe = au1xpsc_pcm_probe,
349 .remove = au1xpsc_pcm_remove, 343 .ops = &au1xpsc_pcm_ops,
350 .pcm_ops = &au1xpsc_pcm_ops,
351 .pcm_new = au1xpsc_pcm_new, 344 .pcm_new = au1xpsc_pcm_new,
352 .pcm_free = au1xpsc_pcm_free_dma_buffers, 345 .pcm_free = au1xpsc_pcm_free_dma_buffers,
353}; 346};
@@ -387,7 +380,7 @@ static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
387 } 380 }
388 (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start; 381 (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start;
389 382
390 ret = snd_soc_register_platform(&au1xpsc_soc_platform); 383 ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
391 if (!ret) 384 if (!ret)
392 return ret; 385 return ret;
393 386
@@ -404,7 +397,7 @@ static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
404{ 397{
405 int i; 398 int i;
406 399
407 snd_soc_unregister_platform(&au1xpsc_soc_platform); 400 snd_soc_unregister_platform(&pdev->dev);
408 401
409 for (i = 0; i < 2; i++) { 402 for (i = 0; i < 2; i++) {
410 if (au1xpsc_audio_pcmdma[i]) { 403 if (au1xpsc_audio_pcmdma[i]) {
@@ -419,7 +412,7 @@ static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
419 412
420static struct platform_driver au1xpsc_pcm_driver = { 413static struct platform_driver au1xpsc_pcm_driver = {
421 .driver = { 414 .driver = {
422 .name = "au1xpsc-pcm", 415 .name = "au1xpsc-pcm-audio",
423 .owner = THIS_MODULE, 416 .owner = THIS_MODULE,
424 }, 417 },
425 .probe = au1xpsc_pcm_drvprobe, 418 .probe = au1xpsc_pcm_drvprobe,
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index d14a5a91a46..6a9516cbe42 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -315,27 +315,19 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
315 return ret; 315 return ret;
316} 316}
317 317
318static int au1xpsc_ac97_probe(struct platform_device *pdev, 318static int au1xpsc_ac97_probe(struct snd_soc_dai *dai)
319 struct snd_soc_dai *dai)
320{ 319{
321 return au1xpsc_ac97_workdata ? 0 : -ENODEV; 320 return au1xpsc_ac97_workdata ? 0 : -ENODEV;
322} 321}
323 322
324static void au1xpsc_ac97_remove(struct platform_device *pdev,
325 struct snd_soc_dai *dai)
326{
327}
328
329static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { 323static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
330 .trigger = au1xpsc_ac97_trigger, 324 .trigger = au1xpsc_ac97_trigger,
331 .hw_params = au1xpsc_ac97_hw_params, 325 .hw_params = au1xpsc_ac97_hw_params,
332}; 326};
333 327
334struct snd_soc_dai au1xpsc_ac97_dai = { 328struct snd_soc_dai_driver au1xpsc_ac97_dai = {
335 .name = "au1xpsc_ac97",
336 .ac97_control = 1, 329 .ac97_control = 1,
337 .probe = au1xpsc_ac97_probe, 330 .probe = au1xpsc_ac97_probe,
338 .remove = au1xpsc_ac97_remove,
339 .playback = { 331 .playback = {
340 .rates = AC97_RATES, 332 .rates = AC97_RATES,
341 .formats = AC97_FMTS, 333 .formats = AC97_FMTS,
@@ -395,7 +387,7 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
395 au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd)); 387 au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd));
396 au_sync(); 388 au_sync();
397 389
398 ret = snd_soc_register_dai(&au1xpsc_ac97_dai); 390 ret = snd_soc_register_dai(&pdev->dev, &au1xpsc_ac97_dai);
399 if (ret) 391 if (ret)
400 goto out1; 392 goto out1;
401 393
@@ -406,7 +398,7 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
406 return 0; 398 return 0;
407 } 399 }
408 400
409 snd_soc_unregister_dai(&au1xpsc_ac97_dai); 401 snd_soc_unregister_dai(&pdev->dev);
410out1: 402out1:
411 release_mem_region(r->start, resource_size(r)); 403 release_mem_region(r->start, resource_size(r));
412out0: 404out0:
@@ -422,7 +414,7 @@ static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
422 if (wd->dmapd) 414 if (wd->dmapd)
423 au1xpsc_pcm_destroy(wd->dmapd); 415 au1xpsc_pcm_destroy(wd->dmapd);
424 416
425 snd_soc_unregister_dai(&au1xpsc_ac97_dai); 417 snd_soc_unregister_dai(&pdev->dev);
426 418
427 /* disable PSC completely */ 419 /* disable PSC completely */
428 au_writel(0, AC97_CFG(wd)); 420 au_writel(0, AC97_CFG(wd));
@@ -485,7 +477,7 @@ static struct dev_pm_ops au1xpscac97_pmops = {
485 477
486static struct platform_driver au1xpsc_ac97_driver = { 478static struct platform_driver au1xpsc_ac97_driver = {
487 .driver = { 479 .driver = {
488 .name = "au1xpsc_ac97", 480 .name = "au1xpsc-ac97",
489 .owner = THIS_MODULE, 481 .owner = THIS_MODULE,
490 .pm = AU1XPSCAC97_PMOPS, 482 .pm = AU1XPSCAC97_PMOPS,
491 }, 483 },
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 6083fe7799f..94e560a8756 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -263,27 +263,19 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
263 return ret; 263 return ret;
264} 264}
265 265
266static int au1xpsc_i2s_probe(struct platform_device *pdev, 266static int au1xpsc_i2s_probe(struct snd_soc_dai *dai)
267 struct snd_soc_dai *dai)
268{ 267{
269 return au1xpsc_i2s_workdata ? 0 : -ENODEV; 268 return au1xpsc_i2s_workdata ? 0 : -ENODEV;
270} 269}
271 270
272static void au1xpsc_i2s_remove(struct platform_device *pdev,
273 struct snd_soc_dai *dai)
274{
275}
276
277static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { 271static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
278 .trigger = au1xpsc_i2s_trigger, 272 .trigger = au1xpsc_i2s_trigger,
279 .hw_params = au1xpsc_i2s_hw_params, 273 .hw_params = au1xpsc_i2s_hw_params,
280 .set_fmt = au1xpsc_i2s_set_fmt, 274 .set_fmt = au1xpsc_i2s_set_fmt,
281}; 275};
282 276
283struct snd_soc_dai au1xpsc_i2s_dai = { 277static struct snd_soc_dai_driver au1xpsc_i2s_dai = {
284 .name = "au1xpsc_i2s",
285 .probe = au1xpsc_i2s_probe, 278 .probe = au1xpsc_i2s_probe,
286 .remove = au1xpsc_i2s_remove,
287 .playback = { 279 .playback = {
288 .rates = AU1XPSC_I2S_RATES, 280 .rates = AU1XPSC_I2S_RATES,
289 .formats = AU1XPSC_I2S_FMTS, 281 .formats = AU1XPSC_I2S_FMTS,
@@ -298,7 +290,6 @@ struct snd_soc_dai au1xpsc_i2s_dai = {
298 }, 290 },
299 .ops = &au1xpsc_i2s_dai_ops, 291 .ops = &au1xpsc_i2s_dai_ops,
300}; 292};
301EXPORT_SYMBOL(au1xpsc_i2s_dai);
302 293
303static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) 294static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
304{ 295{
@@ -346,7 +337,7 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
346 * time out. 337 * time out.
347 */ 338 */
348 339
349 ret = snd_soc_register_dai(&au1xpsc_i2s_dai); 340 ret = snd_soc_register_dai(&pdev->dev, &au1xpsc_i2s_dai);
350 if (ret) 341 if (ret)
351 goto out1; 342 goto out1;
352 343
@@ -358,7 +349,7 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
358 return 0; 349 return 0;
359 } 350 }
360 351
361 snd_soc_unregister_dai(&au1xpsc_i2s_dai); 352 snd_soc_unregister_dai(&pdev->dev);
362out1: 353out1:
363 release_mem_region(r->start, resource_size(r)); 354 release_mem_region(r->start, resource_size(r));
364out0: 355out0:
@@ -374,7 +365,7 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
374 if (wd->dmapd) 365 if (wd->dmapd)
375 au1xpsc_pcm_destroy(wd->dmapd); 366 au1xpsc_pcm_destroy(wd->dmapd);
376 367
377 snd_soc_unregister_dai(&au1xpsc_i2s_dai); 368 snd_soc_unregister_dai(&pdev->dev);
378 369
379 au_writel(0, I2S_CFG(wd)); 370 au_writel(0, I2S_CFG(wd));
380 au_sync(); 371 au_sync();
@@ -436,7 +427,7 @@ static struct dev_pm_ops au1xpsci2s_pmops = {
436 427
437static struct platform_driver au1xpsc_i2s_driver = { 428static struct platform_driver au1xpsc_i2s_driver = {
438 .driver = { 429 .driver = {
439 .name = "au1xpsc_i2s", 430 .name = "au1xpsc",
440 .owner = THIS_MODULE, 431 .owner = THIS_MODULE,
441 .pm = AU1XPSCI2S_PMOPS, 432 .pm = AU1XPSCI2S_PMOPS,
442 }, 433 },
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h
index 093775d4dc3..f281443fd52 100644
--- a/sound/soc/au1x/psc.h
+++ b/sound/soc/au1x/psc.h
@@ -16,9 +16,6 @@
16#ifndef _AU1X_PCM_H 16#ifndef _AU1X_PCM_H
17#define _AU1X_PCM_H 17#define _AU1X_PCM_H
18 18
19extern struct snd_soc_dai au1xpsc_ac97_dai;
20extern struct snd_soc_dai au1xpsc_i2s_dai;
21extern struct snd_soc_platform au1xpsc_soc_platform;
22extern struct snd_ac97_bus_ops soc_ac97_ops; 19extern struct snd_ac97_bus_ops soc_ac97_ops;
23 20
24/* DBDMA helpers */ 21/* DBDMA helpers */
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 5e7aacf3bb5..5a2fd8abaef 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -422,14 +422,14 @@ int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
422 if (!card->dev->coherent_dma_mask) 422 if (!card->dev->coherent_dma_mask)
423 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 423 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
424 424
425 if (dai->playback.channels_min) { 425 if (dai->driver->playback.channels_min) {
426 ret = bf5xx_pcm_preallocate_dma_buffer(pcm, 426 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
427 SNDRV_PCM_STREAM_PLAYBACK); 427 SNDRV_PCM_STREAM_PLAYBACK);
428 if (ret) 428 if (ret)
429 goto out; 429 goto out;
430 } 430 }
431 431
432 if (dai->capture.channels_min) { 432 if (dai->driver->capture.channels_min) {
433 ret = bf5xx_pcm_preallocate_dma_buffer(pcm, 433 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
434 SNDRV_PCM_STREAM_CAPTURE); 434 SNDRV_PCM_STREAM_CAPTURE);
435 if (ret) 435 if (ret)
@@ -439,25 +439,44 @@ int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
439 return ret; 439 return ret;
440} 440}
441 441
442struct snd_soc_platform bf5xx_ac97_soc_platform = { 442static struct snd_soc_platform_driver bf5xx_ac97_soc_platform = {
443 .name = "bf5xx-audio", 443 .ops = &bf5xx_pcm_ac97_ops,
444 .pcm_ops = &bf5xx_pcm_ac97_ops,
445 .pcm_new = bf5xx_pcm_ac97_new, 444 .pcm_new = bf5xx_pcm_ac97_new,
446 .pcm_free = bf5xx_pcm_free_dma_buffers, 445 .pcm_free = bf5xx_pcm_free_dma_buffers,
447}; 446};
448EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform);
449 447
450static int __init bfin_ac97_init(void) 448static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev)
451{ 449{
452 return snd_soc_register_platform(&bf5xx_ac97_soc_platform); 450 return snd_soc_register_platform(&pdev->dev, &bf5xx_ac97_soc_platform);
453} 451}
454module_init(bfin_ac97_init);
455 452
456static void __exit bfin_ac97_exit(void) 453static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
457{ 454{
458 snd_soc_unregister_platform(&bf5xx_ac97_soc_platform); 455 snd_soc_unregister_platform(&pdev->dev);
456 return 0;
457}
458
459static struct platform_driver bf5xx_pcm_driver = {
460 .driver = {
461 .name = "bf5xx-pcm-audio",
462 .owner = THIS_MODULE,
463 },
464
465 .probe = bf5xx_soc_platform_probe,
466 .remove = __devexit_p(bf5xx_soc_platform_remove),
467};
468
469static int __init snd_bf5xx_pcm_init(void)
470{
471 return platform_driver_register(&bf5xx_pcm_driver);
472}
473module_init(snd_bf5xx_pcm_init);
474
475static void __exit snd_bf5xx_pcm_exit(void)
476{
477 platform_driver_unregister(&bf5xx_pcm_driver);
459} 478}
460module_exit(bfin_ac97_exit); 479module_exit(snd_bf5xx_pcm_exit);
461 480
462MODULE_AUTHOR("Cliff Cai"); 481MODULE_AUTHOR("Cliff Cai");
463MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module"); 482MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.h b/sound/soc/blackfin/bf5xx-ac97-pcm.h
index 350125a0ae2..d324d5826a9 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.h
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.h
@@ -23,7 +23,4 @@ struct bf5xx_gpio {
23 u32 frm; 23 u32 frm;
24}; 24};
25 25
26/* platform data */
27extern struct snd_soc_platform bf5xx_ac97_soc_platform;
28
29#endif 26#endif
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index c0eba510998..c5f856ec27c 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -255,7 +255,7 @@ EXPORT_SYMBOL_GPL(soc_ac97_ops);
255#ifdef CONFIG_PM 255#ifdef CONFIG_PM
256static int bf5xx_ac97_suspend(struct snd_soc_dai *dai) 256static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
257{ 257{
258 struct sport_device *sport = dai->private_data; 258 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
259 259
260 pr_debug("%s : sport %d\n", __func__, dai->id); 260 pr_debug("%s : sport %d\n", __func__, dai->id);
261 if (!dai->active) 261 if (!dai->active)
@@ -270,7 +270,7 @@ static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
270static int bf5xx_ac97_resume(struct snd_soc_dai *dai) 270static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
271{ 271{
272 int ret; 272 int ret;
273 struct sport_device *sport = dai->private_data; 273 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
274 274
275 pr_debug("%s : sport %d\n", __func__, dai->id); 275 pr_debug("%s : sport %d\n", __func__, dai->id);
276 if (!dai->active) 276 if (!dai->active)
@@ -306,8 +306,7 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
306#define bf5xx_ac97_resume NULL 306#define bf5xx_ac97_resume NULL
307#endif 307#endif
308 308
309static int bf5xx_ac97_probe(struct platform_device *pdev, 309static int bf5xx_ac97_probe(struct snd_soc_dai *dai)
310 struct snd_soc_dai *dai)
311{ 310{
312 int ret = 0; 311 int ret = 0;
313 cmd_count = (int *)get_zeroed_page(GFP_KERNEL); 312 cmd_count = (int *)get_zeroed_page(GFP_KERNEL);
@@ -379,8 +378,7 @@ peripheral_err:
379 return ret; 378 return ret;
380} 379}
381 380
382static void bf5xx_ac97_remove(struct platform_device *pdev, 381static int bf5xx_ac97_remove(struct snd_soc_dai *dai)
383 struct snd_soc_dai *dai)
384{ 382{
385 free_page((unsigned long)cmd_count); 383 free_page((unsigned long)cmd_count);
386 cmd_count = NULL; 384 cmd_count = NULL;
@@ -388,11 +386,10 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
388#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 386#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
389 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 387 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
390#endif 388#endif
389 return 0;
391} 390}
392 391
393struct snd_soc_dai bfin_ac97_dai = { 392struct snd_soc_dai_driver bfin_ac97_dai = {
394 .name = "bf5xx-ac97",
395 .id = 0,
396 .ac97_control = 1, 393 .ac97_control = 1,
397 .probe = bf5xx_ac97_probe, 394 .probe = bf5xx_ac97_probe,
398 .remove = bf5xx_ac97_remove, 395 .remove = bf5xx_ac97_remove,
@@ -417,18 +414,40 @@ struct snd_soc_dai bfin_ac97_dai = {
417}; 414};
418EXPORT_SYMBOL_GPL(bfin_ac97_dai); 415EXPORT_SYMBOL_GPL(bfin_ac97_dai);
419 416
417static __devinit int asoc_bfin_ac97_probe(struct platform_device *pdev)
418{
419 return snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai);
420}
421
422static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
423{
424 snd_soc_unregister_dai(&pdev->dev);
425 return 0;
426}
427
428static struct platform_driver asoc_bfin_ac97_driver = {
429 .driver = {
430 .name = "bfin-ac97",
431 .owner = THIS_MODULE,
432 },
433
434 .probe = asoc_bfin_ac97_probe,
435 .remove = __devexit_p(asoc_bfin_ac97_remove),
436};
437
420static int __init bfin_ac97_init(void) 438static int __init bfin_ac97_init(void)
421{ 439{
422 return snd_soc_register_dai(&bfin_ac97_dai); 440 return platform_driver_register(&asoc_bfin_ac97_driver);
423} 441}
424module_init(bfin_ac97_init); 442module_init(bfin_ac97_init);
425 443
426static void __exit bfin_ac97_exit(void) 444static void __exit bfin_ac97_exit(void)
427{ 445{
428 snd_soc_unregister_dai(&bfin_ac97_dai); 446 platform_driver_unregister(&asoc_bfin_ac97_driver);
429} 447}
430module_exit(bfin_ac97_exit); 448module_exit(bfin_ac97_exit);
431 449
450
432MODULE_AUTHOR("Roy Huang"); 451MODULE_AUTHOR("Roy Huang");
433MODULE_DESCRIPTION("AC97 driver for ADI Blackfin"); 452MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
434MODULE_LICENSE("GPL"); 453MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.h b/sound/soc/blackfin/bf5xx-ac97.h
index a1f97dd809d..15c635e33f4 100644
--- a/sound/soc/blackfin/bf5xx-ac97.h
+++ b/sound/soc/blackfin/bf5xx-ac97.h
@@ -50,8 +50,6 @@ struct ac97_frame {
50#define TAG_PCM_SR 0x0080 50#define TAG_PCM_SR 0x0080
51#define TAG_PCM_LFE 0x0040 51#define TAG_PCM_LFE 0x0040
52 52
53extern struct snd_soc_dai bfin_ac97_dai;
54
55void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, \ 53void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, \
56 size_t count, unsigned int chan_mask); 54 size_t count, unsigned int chan_mask);
57 55
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 0f45a3f56be..2394bff2b65 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -40,9 +40,9 @@ static struct snd_soc_card bf5xx_ad1836;
40static int bf5xx_ad1836_startup(struct snd_pcm_substream *substream) 40static int bf5xx_ad1836_startup(struct snd_pcm_substream *substream)
41{ 41{
42 struct snd_soc_pcm_runtime *rtd = substream->private_data; 42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 43 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 44
45 cpu_dai->private_data = sport_handle; 45 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
46 return 0; 46 return 0;
47} 47}
48 48
@@ -50,8 +50,8 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
50 struct snd_pcm_hw_params *params) 50 struct snd_pcm_hw_params *params)
51{ 51{
52 struct snd_soc_pcm_runtime *rtd = substream->private_data; 52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 53 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
54 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 54 struct snd_soc_dai *codec_dai = rtd->codec_dai;
55 unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7}; 55 unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
56 int ret = 0; 56 int ret = 0;
57 /* set cpu DAI configuration */ 57 /* set cpu DAI configuration */
@@ -83,23 +83,19 @@ static struct snd_soc_ops bf5xx_ad1836_ops = {
83static struct snd_soc_dai_link bf5xx_ad1836_dai = { 83static struct snd_soc_dai_link bf5xx_ad1836_dai = {
84 .name = "ad1836", 84 .name = "ad1836",
85 .stream_name = "AD1836", 85 .stream_name = "AD1836",
86 .cpu_dai = &bf5xx_tdm_dai, 86 .cpu_dai_name = "bf5xx-tdm",
87 .codec_dai = &ad1836_dai, 87 .codec_dai_name = "ad1836-hifi",
88 .platform_name = "bf5xx-tdm-pcm-audio",
89 .codec_name = "ad1836-codec.0",
88 .ops = &bf5xx_ad1836_ops, 90 .ops = &bf5xx_ad1836_ops,
89}; 91};
90 92
91static struct snd_soc_card bf5xx_ad1836 = { 93static struct snd_soc_card bf5xx_ad1836 = {
92 .name = "bf5xx_ad1836", 94 .name = "bf5xx_ad1836",
93 .platform = &bf5xx_tdm_soc_platform,
94 .dai_link = &bf5xx_ad1836_dai, 95 .dai_link = &bf5xx_ad1836_dai,
95 .num_links = 1, 96 .num_links = 1,
96}; 97};
97 98
98static struct snd_soc_device bf5xx_ad1836_snd_devdata = {
99 .card = &bf5xx_ad1836,
100 .codec_dev = &soc_codec_dev_ad1836,
101};
102
103static struct platform_device *bfxx_ad1836_snd_device; 99static struct platform_device *bfxx_ad1836_snd_device;
104 100
105static int __init bf5xx_ad1836_init(void) 101static int __init bf5xx_ad1836_init(void)
@@ -110,8 +106,7 @@ static int __init bf5xx_ad1836_init(void)
110 if (!bfxx_ad1836_snd_device) 106 if (!bfxx_ad1836_snd_device)
111 return -ENOMEM; 107 return -ENOMEM;
112 108
113 platform_set_drvdata(bfxx_ad1836_snd_device, &bf5xx_ad1836_snd_devdata); 109 platform_set_drvdata(bfxx_ad1836_snd_device, &bf5xx_ad1836);
114 bf5xx_ad1836_snd_devdata.dev = &bfxx_ad1836_snd_device->dev;
115 ret = platform_device_add(bfxx_ad1836_snd_device); 110 ret = platform_device_add(bfxx_ad1836_snd_device);
116 111
117 if (ret) 112 if (ret)
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index b8c9060cfd8..e4a625317a1 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -49,9 +49,9 @@ static struct snd_soc_card bf5xx_ad193x;
49static int bf5xx_ad193x_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->cpu_dai;
53 53
54 cpu_dai->private_data = sport_handle; 54 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
55 return 0; 55 return 0;
56} 56}
57 57
@@ -59,8 +59,8 @@ static 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;
62 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 62 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
63 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 63 struct snd_soc_dai *codec_dai = rtd->codec_dai;
64 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7}; 64 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7};
65 int ret = 0; 65 int ret = 0;
66 /* set cpu DAI configuration */ 66 /* set cpu DAI configuration */
@@ -97,23 +97,19 @@ static struct snd_soc_ops bf5xx_ad193x_ops = {
97static struct snd_soc_dai_link bf5xx_ad193x_dai = { 97static struct snd_soc_dai_link bf5xx_ad193x_dai = {
98 .name = "ad193x", 98 .name = "ad193x",
99 .stream_name = "AD193X", 99 .stream_name = "AD193X",
100 .cpu_dai = &bf5xx_tdm_dai, 100 .cpu_dai_name = "bf5xx-tdm",
101 .codec_dai = &ad193x_dai, 101 .codec_dai_name ="ad193x-hifi",
102 .platform_name = "bf5xx-tdm-pcm-audio",
103 .codec_name = "ad193x-codec.5",
102 .ops = &bf5xx_ad193x_ops, 104 .ops = &bf5xx_ad193x_ops,
103}; 105};
104 106
105static struct snd_soc_card bf5xx_ad193x = { 107static struct snd_soc_card bf5xx_ad193x = {
106 .name = "bf5xx_ad193x", 108 .name = "bf5xx_ad193x",
107 .platform = &bf5xx_tdm_soc_platform,
108 .dai_link = &bf5xx_ad193x_dai, 109 .dai_link = &bf5xx_ad193x_dai,
109 .num_links = 1, 110 .num_links = 1,
110}; 111};
111 112
112static struct snd_soc_device bf5xx_ad193x_snd_devdata = {
113 .card = &bf5xx_ad193x,
114 .codec_dev = &soc_codec_dev_ad193x,
115};
116
117static struct platform_device *bfxx_ad193x_snd_device; 113static struct platform_device *bfxx_ad193x_snd_device;
118 114
119static int __init bf5xx_ad193x_init(void) 115static int __init bf5xx_ad193x_init(void)
@@ -124,8 +120,7 @@ static int __init bf5xx_ad193x_init(void)
124 if (!bfxx_ad193x_snd_device) 120 if (!bfxx_ad193x_snd_device)
125 return -ENOMEM; 121 return -ENOMEM;
126 122
127 platform_set_drvdata(bfxx_ad193x_snd_device, &bf5xx_ad193x_snd_devdata); 123 platform_set_drvdata(bfxx_ad193x_snd_device, &bf5xx_ad193x);
128 bf5xx_ad193x_snd_devdata.dev = &bfxx_ad193x_snd_device->dev;
129 ret = platform_device_add(bfxx_ad193x_snd_device); 124 ret = platform_device_add(bfxx_ad193x_snd_device);
130 125
131 if (ret) 126 if (ret)
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
index d8f59127377..a31bdf656fc 100644
--- a/sound/soc/blackfin/bf5xx-ad1980.c
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -48,10 +48,10 @@ static struct snd_soc_card bf5xx_board;
48static int bf5xx_board_startup(struct snd_pcm_substream *substream) 48static int bf5xx_board_startup(struct snd_pcm_substream *substream)
49{ 49{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data; 50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 51 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
52 52
53 pr_debug("%s enter\n", __func__); 53 pr_debug("%s enter\n", __func__);
54 cpu_dai->private_data = sport_handle; 54 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
55 return 0; 55 return 0;
56} 56}
57 57
@@ -62,23 +62,19 @@ static struct snd_soc_ops bf5xx_board_ops = {
62static struct snd_soc_dai_link bf5xx_board_dai = { 62static struct snd_soc_dai_link bf5xx_board_dai = {
63 .name = "AC97", 63 .name = "AC97",
64 .stream_name = "AC97 HiFi", 64 .stream_name = "AC97 HiFi",
65 .cpu_dai = &bfin_ac97_dai, 65 .cpu_dai_name = "bfin-ac97",
66 .codec_dai = &ad1980_dai, 66 .codec_dai_name = "ad1980-hifi",
67 .platform_name = "bfin-pcm-audio",
68 .codec_name = "ad1980-codec",
67 .ops = &bf5xx_board_ops, 69 .ops = &bf5xx_board_ops,
68}; 70};
69 71
70static struct snd_soc_card bf5xx_board = { 72static struct snd_soc_card bf5xx_board = {
71 .name = "bf5xx-board", 73 .name = "bf5xx-board",
72 .platform = &bf5xx_ac97_soc_platform,
73 .dai_link = &bf5xx_board_dai, 74 .dai_link = &bf5xx_board_dai,
74 .num_links = 1, 75 .num_links = 1,
75}; 76};
76 77
77static struct snd_soc_device bf5xx_board_snd_devdata = {
78 .card = &bf5xx_board,
79 .codec_dev = &soc_codec_dev_ad1980,
80};
81
82static struct platform_device *bf5xx_board_snd_device; 78static struct platform_device *bf5xx_board_snd_device;
83 79
84static int __init bf5xx_board_init(void) 80static int __init bf5xx_board_init(void)
@@ -89,8 +85,7 @@ static int __init bf5xx_board_init(void)
89 if (!bf5xx_board_snd_device) 85 if (!bf5xx_board_snd_device)
90 return -ENOMEM; 86 return -ENOMEM;
91 87
92 platform_set_drvdata(bf5xx_board_snd_device, &bf5xx_board_snd_devdata); 88 platform_set_drvdata(bf5xx_board_snd_device, &bf5xx_board);
93 bf5xx_board_snd_devdata.dev = &bf5xx_board_snd_device->dev;
94 ret = platform_device_add(bf5xx_board_snd_device); 89 ret = platform_device_add(bf5xx_board_snd_device);
95 90
96 if (ret) 91 if (ret)
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 9825b71d0e2..900ced54ac7 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -47,7 +47,6 @@
47#include "../codecs/ad73311.h" 47#include "../codecs/ad73311.h"
48#include "bf5xx-sport.h" 48#include "bf5xx-sport.h"
49#include "bf5xx-i2s-pcm.h" 49#include "bf5xx-i2s-pcm.h"
50#include "bf5xx-i2s.h"
51 50
52#if CONFIG_SND_BF5XX_SPORT_NUM == 0 51#if CONFIG_SND_BF5XX_SPORT_NUM == 0
53#define bfin_write_SPORT_TCR1 bfin_write_SPORT0_TCR1 52#define bfin_write_SPORT_TCR1 bfin_write_SPORT0_TCR1
@@ -150,10 +149,10 @@ static int bf5xx_probe(struct platform_device *pdev)
150static int bf5xx_ad73311_startup(struct snd_pcm_substream *substream) 149static int bf5xx_ad73311_startup(struct snd_pcm_substream *substream)
151{ 150{
152 struct snd_soc_pcm_runtime *rtd = substream->private_data; 151 struct snd_soc_pcm_runtime *rtd = substream->private_data;
153 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 152 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
154 153
155 pr_debug("%s enter\n", __func__); 154 pr_debug("%s enter\n", __func__);
156 cpu_dai->private_data = sport_handle; 155 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
157 return 0; 156 return 0;
158} 157}
159 158
@@ -161,7 +160,7 @@ static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
161 struct snd_pcm_hw_params *params) 160 struct snd_pcm_hw_params *params)
162{ 161{
163 struct snd_soc_pcm_runtime *rtd = substream->private_data; 162 struct snd_soc_pcm_runtime *rtd = substream->private_data;
164 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 163 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
165 int ret = 0; 164 int ret = 0;
166 165
167 pr_debug("%s rate %d format %x\n", __func__, params_rate(params), 166 pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
@@ -185,24 +184,20 @@ static struct snd_soc_ops bf5xx_ad73311_ops = {
185static struct snd_soc_dai_link bf5xx_ad73311_dai = { 184static struct snd_soc_dai_link bf5xx_ad73311_dai = {
186 .name = "ad73311", 185 .name = "ad73311",
187 .stream_name = "AD73311", 186 .stream_name = "AD73311",
188 .cpu_dai = &bf5xx_i2s_dai, 187 .cpu_dai_name = "bf5xx-i2s",
189 .codec_dai = &ad73311_dai, 188 .codec_dai_name = "ad73311-hifi",
189 .platform_name = "bfin-pcm-audio",
190 .codec_name = "ad73311-codec",
190 .ops = &bf5xx_ad73311_ops, 191 .ops = &bf5xx_ad73311_ops,
191}; 192};
192 193
193static struct snd_soc_card bf5xx_ad73311 = { 194static struct snd_soc_card bf5xx_ad73311 = {
194 .name = "bf5xx_ad73311", 195 .name = "bf5xx_ad73311",
195 .platform = &bf5xx_i2s_soc_platform,
196 .probe = bf5xx_probe, 196 .probe = bf5xx_probe,
197 .dai_link = &bf5xx_ad73311_dai, 197 .dai_link = &bf5xx_ad73311_dai,
198 .num_links = 1, 198 .num_links = 1,
199}; 199};
200 200
201static struct snd_soc_device bf5xx_ad73311_snd_devdata = {
202 .card = &bf5xx_ad73311,
203 .codec_dev = &soc_codec_dev_ad73311,
204};
205
206static struct platform_device *bf5xx_ad73311_snd_device; 201static struct platform_device *bf5xx_ad73311_snd_device;
207 202
208static int __init bf5xx_ad73311_init(void) 203static int __init bf5xx_ad73311_init(void)
@@ -214,8 +209,7 @@ static int __init bf5xx_ad73311_init(void)
214 if (!bf5xx_ad73311_snd_device) 209 if (!bf5xx_ad73311_snd_device)
215 return -ENOMEM; 210 return -ENOMEM;
216 211
217 platform_set_drvdata(bf5xx_ad73311_snd_device, &bf5xx_ad73311_snd_devdata); 212 platform_set_drvdata(bf5xx_ad73311_snd_device, &bf5xx_ad73311);
218 bf5xx_ad73311_snd_devdata.dev = &bf5xx_ad73311_snd_device->dev;
219 ret = platform_device_add(bf5xx_ad73311_snd_device); 213 ret = platform_device_add(bf5xx_ad73311_snd_device);
220 214
221 if (ret) 215 if (ret)
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 1d2a1adf257..890a0dccf90 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -40,7 +40,6 @@
40#include <asm/dma.h> 40#include <asm/dma.h>
41 41
42#include "bf5xx-i2s-pcm.h" 42#include "bf5xx-i2s-pcm.h"
43#include "bf5xx-i2s.h"
44#include "bf5xx-sport.h" 43#include "bf5xx-sport.h"
45 44
46static void bf5xx_dma_irq(void *data) 45static void bf5xx_dma_irq(void *data)
@@ -257,14 +256,14 @@ int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
257 if (!card->dev->coherent_dma_mask) 256 if (!card->dev->coherent_dma_mask)
258 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 257 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
259 258
260 if (dai->playback.channels_min) { 259 if (dai->driver->playback.channels_min) {
261 ret = bf5xx_pcm_preallocate_dma_buffer(pcm, 260 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
262 SNDRV_PCM_STREAM_PLAYBACK); 261 SNDRV_PCM_STREAM_PLAYBACK);
263 if (ret) 262 if (ret)
264 goto out; 263 goto out;
265 } 264 }
266 265
267 if (dai->capture.channels_min) { 266 if (dai->driver->capture.channels_min) {
268 ret = bf5xx_pcm_preallocate_dma_buffer(pcm, 267 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
269 SNDRV_PCM_STREAM_CAPTURE); 268 SNDRV_PCM_STREAM_CAPTURE);
270 if (ret) 269 if (ret)
@@ -274,25 +273,44 @@ int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
274 return ret; 273 return ret;
275} 274}
276 275
277struct snd_soc_platform bf5xx_i2s_soc_platform = { 276static struct snd_soc_platform_driver bf5xx_i2s_soc_platform = {
278 .name = "bf5xx-audio", 277 .ops = &bf5xx_pcm_i2s_ops,
279 .pcm_ops = &bf5xx_pcm_i2s_ops,
280 .pcm_new = bf5xx_pcm_i2s_new, 278 .pcm_new = bf5xx_pcm_i2s_new,
281 .pcm_free = bf5xx_pcm_free_dma_buffers, 279 .pcm_free = bf5xx_pcm_free_dma_buffers,
282}; 280};
283EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform);
284 281
285static int __init bfin_i2s_init(void) 282static int __devinit bfin_i2s_soc_platform_probe(struct platform_device *pdev)
286{ 283{
287 return snd_soc_register_platform(&bf5xx_i2s_soc_platform); 284 return snd_soc_register_platform(&pdev->dev, &bf5xx_i2s_soc_platform);
288} 285}
289module_init(bfin_i2s_init);
290 286
291static void __exit bfin_i2s_exit(void) 287static int __devexit bfin_i2s_soc_platform_remove(struct platform_device *pdev)
292{ 288{
293 snd_soc_unregister_platform(&bf5xx_i2s_soc_platform); 289 snd_soc_unregister_platform(&pdev->dev);
290 return 0;
291}
292
293static struct platform_driver bfin_i2s_pcm_driver = {
294 .driver = {
295 .name = "bfin-pcm-audio",
296 .owner = THIS_MODULE,
297 },
298
299 .probe = bfin_i2s_soc_platform_probe,
300 .remove = __devexit_p(bfin_i2s_soc_platform_remove),
301};
302
303static int __init snd_bfin_i2s_pcm_init(void)
304{
305 return platform_driver_register(&bfin_i2s_pcm_driver);
306}
307module_init(snd_bfin_i2s_pcm_init);
308
309static void __exit snd_bfin_i2s_pcm_exit(void)
310{
311 platform_driver_unregister(&bfin_i2s_pcm_driver);
294} 312}
295module_exit(bfin_i2s_exit); 313module_exit(snd_bfin_i2s_pcm_exit);
296 314
297MODULE_AUTHOR("Cliff Cai"); 315MODULE_AUTHOR("Cliff Cai");
298MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module"); 316MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.h b/sound/soc/blackfin/bf5xx-i2s-pcm.h
index 4d4609a97c5..0c2c5a68d4f 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.h
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.h
@@ -23,7 +23,4 @@ struct bf5xx_gpio {
23 u32 frm; 23 u32 frm;
24}; 24};
25 25
26/* platform data */
27extern struct snd_soc_platform bf5xx_i2s_soc_platform;
28
29#endif 26#endif
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 3e6ada0dd1c..d453b1e9d60 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -42,7 +42,6 @@
42#include <linux/gpio.h> 42#include <linux/gpio.h>
43 43
44#include "bf5xx-sport.h" 44#include "bf5xx-sport.h"
45#include "bf5xx-i2s.h"
46 45
47struct bf5xx_i2s_port { 46struct bf5xx_i2s_port {
48 u16 tcr1; 47 u16 tcr1;
@@ -195,8 +194,7 @@ static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
195 bf5xx_i2s.configured = 0; 194 bf5xx_i2s.configured = 0;
196} 195}
197 196
198static int bf5xx_i2s_probe(struct platform_device *pdev, 197static int bf5xx_i2s_probe(struct snd_soc_dai *dai)
199 struct snd_soc_dai *dai)
200{ 198{
201 pr_debug("%s enter\n", __func__); 199 pr_debug("%s enter\n", __func__);
202 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) { 200 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
@@ -215,11 +213,11 @@ static int bf5xx_i2s_probe(struct platform_device *pdev,
215 return 0; 213 return 0;
216} 214}
217 215
218static void bf5xx_i2s_remove(struct platform_device *pdev, 216static int bf5xx_i2s_remove(struct snd_soc_dai *dai)
219 struct snd_soc_dai *dai)
220{ 217{
221 pr_debug("%s enter\n", __func__); 218 pr_debug("%s enter\n", __func__);
222 peripheral_free_list(&sport_req[sport_num][0]); 219 peripheral_free_list(&sport_req[sport_num][0]);
220 return 0;
223} 221}
224 222
225#ifdef CONFIG_PM 223#ifdef CONFIG_PM
@@ -228,9 +226,9 @@ static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
228 226
229 pr_debug("%s : sport %d\n", __func__, dai->id); 227 pr_debug("%s : sport %d\n", __func__, dai->id);
230 228
231 if (dai->capture.active) 229 if (dai->capture_active)
232 sport_rx_stop(sport_handle); 230 sport_rx_stop(sport_handle);
233 if (dai->playback.active) 231 if (dai->playback_active)
234 sport_tx_stop(sport_handle); 232 sport_tx_stop(sport_handle);
235 return 0; 233 return 0;
236} 234}
@@ -277,9 +275,7 @@ static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
277 .set_fmt = bf5xx_i2s_set_dai_fmt, 275 .set_fmt = bf5xx_i2s_set_dai_fmt,
278}; 276};
279 277
280struct snd_soc_dai bf5xx_i2s_dai = { 278static struct snd_soc_dai_driver bf5xx_i2s_dai = {
281 .name = "bf5xx-i2s",
282 .id = 0,
283 .probe = bf5xx_i2s_probe, 279 .probe = bf5xx_i2s_probe,
284 .remove = bf5xx_i2s_remove, 280 .remove = bf5xx_i2s_remove,
285 .suspend = bf5xx_i2s_suspend, 281 .suspend = bf5xx_i2s_suspend,
@@ -296,18 +292,39 @@ struct snd_soc_dai bf5xx_i2s_dai = {
296 .formats = BF5XX_I2S_FORMATS,}, 292 .formats = BF5XX_I2S_FORMATS,},
297 .ops = &bf5xx_i2s_dai_ops, 293 .ops = &bf5xx_i2s_dai_ops,
298}; 294};
299EXPORT_SYMBOL_GPL(bf5xx_i2s_dai); 295
296static int bfin_i2s_drv_probe(struct platform_device *pdev)
297{
298 return snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai);
299}
300
301static int __devexit bfin_i2s_drv_remove(struct platform_device *pdev)
302{
303 snd_soc_unregister_dai(&pdev->dev);
304 return 0;
305}
306
307static struct platform_driver bfin_i2s_driver = {
308 .probe = bfin_i2s_drv_probe,
309 .remove = __devexit_p(bfin_i2s_drv_remove),
310
311 .driver = {
312 .name = "bf5xx-i2s",
313 .owner = THIS_MODULE,
314 },
315};
300 316
301static int __init bfin_i2s_init(void) 317static int __init bfin_i2s_init(void)
302{ 318{
303 return snd_soc_register_dai(&bf5xx_i2s_dai); 319 return platform_driver_register(&bfin_i2s_driver);
304} 320}
305module_init(bfin_i2s_init);
306 321
307static void __exit bfin_i2s_exit(void) 322static void __exit bfin_i2s_exit(void)
308{ 323{
309 snd_soc_unregister_dai(&bf5xx_i2s_dai); 324 platform_driver_unregister(&bfin_i2s_driver);
310} 325}
326
327module_init(bfin_i2s_init);
311module_exit(bfin_i2s_exit); 328module_exit(bfin_i2s_exit);
312 329
313/* Module information */ 330/* Module information */
diff --git a/sound/soc/blackfin/bf5xx-i2s.h b/sound/soc/blackfin/bf5xx-i2s.h
deleted file mode 100644
index 264ecdcba35..00000000000
--- a/sound/soc/blackfin/bf5xx-i2s.h
+++ /dev/null
@@ -1,14 +0,0 @@
1/*
2 * sound/soc/blackfin/bf5xx-i2s.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _BF5XX_I2S_H
10#define _BF5XX_I2S_H
11
12extern struct snd_soc_dai bf5xx_i2s_dai;
13
14#endif
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index 3a00fa4dbe6..36f2769eb91 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -42,17 +42,16 @@
42#include "../codecs/ssm2602.h" 42#include "../codecs/ssm2602.h"
43#include "bf5xx-sport.h" 43#include "bf5xx-sport.h"
44#include "bf5xx-i2s-pcm.h" 44#include "bf5xx-i2s-pcm.h"
45#include "bf5xx-i2s.h"
46 45
47static struct snd_soc_card bf5xx_ssm2602; 46static struct snd_soc_card bf5xx_ssm2602;
48 47
49static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream) 48static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream)
50{ 49{
51 struct snd_soc_pcm_runtime *rtd = substream->private_data; 50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
52 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 51 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
53 52
54 pr_debug("%s enter\n", __func__); 53 pr_debug("%s enter\n", __func__);
55 cpu_dai->private_data = sport_handle; 54 snd_soc_dai_set_drvdata(cpu_dai, sport_handle);
56 return 0; 55 return 0;
57} 56}
58 57
@@ -60,8 +59,8 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
60 struct snd_pcm_hw_params *params) 59 struct snd_pcm_hw_params *params)
61{ 60{
62 struct snd_soc_pcm_runtime *rtd = substream->private_data; 61 struct snd_soc_pcm_runtime *rtd = substream->private_data;
63 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 62 struct snd_soc_dai *codec_dai = rtd->codec_dai;
64 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 63 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
65 unsigned int clk = 0; 64 unsigned int clk = 0;
66 int ret = 0; 65 int ret = 0;
67 66
@@ -118,36 +117,19 @@ static struct snd_soc_ops bf5xx_ssm2602_ops = {
118static struct snd_soc_dai_link bf5xx_ssm2602_dai = { 117static struct snd_soc_dai_link bf5xx_ssm2602_dai = {
119 .name = "ssm2602", 118 .name = "ssm2602",
120 .stream_name = "SSM2602", 119 .stream_name = "SSM2602",
121 .cpu_dai = &bf5xx_i2s_dai, 120 .cpu_dai_name = "bf5xx-i2s",
122 .codec_dai = &ssm2602_dai, 121 .codec_dai_name = "ssm2602-hifi",
122 .platform_name = "bf5xx-pcm-audio",
123 .codec_name = "ssm2602-codec.0-0x1b",
123 .ops = &bf5xx_ssm2602_ops, 124 .ops = &bf5xx_ssm2602_ops,
124}; 125};
125 126
126/*
127 * SSM2602 2 wire address is determined by CSB
128 * state during powerup.
129 * low = 0x1a
130 * high = 0x1b
131 */
132
133static struct ssm2602_setup_data bf5xx_ssm2602_setup = {
134 .i2c_bus = 0,
135 .i2c_address = 0x1b,
136};
137
138static struct snd_soc_card bf5xx_ssm2602 = { 127static struct snd_soc_card bf5xx_ssm2602 = {
139 .name = "bf5xx_ssm2602", 128 .name = "bf5xx_ssm2602",
140 .platform = &bf5xx_i2s_soc_platform,
141 .dai_link = &bf5xx_ssm2602_dai, 129 .dai_link = &bf5xx_ssm2602_dai,
142 .num_links = 1, 130 .num_links = 1,
143}; 131};
144 132
145static struct snd_soc_device bf5xx_ssm2602_snd_devdata = {
146 .card = &bf5xx_ssm2602,
147 .codec_dev = &soc_codec_dev_ssm2602,
148 .codec_data = &bf5xx_ssm2602_setup,
149};
150
151static struct platform_device *bf5xx_ssm2602_snd_device; 133static struct platform_device *bf5xx_ssm2602_snd_device;
152 134
153static int __init bf5xx_ssm2602_init(void) 135static int __init bf5xx_ssm2602_init(void)
@@ -159,9 +141,7 @@ static int __init bf5xx_ssm2602_init(void)
159 if (!bf5xx_ssm2602_snd_device) 141 if (!bf5xx_ssm2602_snd_device)
160 return -ENOMEM; 142 return -ENOMEM;
161 143
162 platform_set_drvdata(bf5xx_ssm2602_snd_device, 144 platform_set_drvdata(bf5xx_ssm2602_snd_device, &bf5xx_ssm2602);
163 &bf5xx_ssm2602_snd_devdata);
164 bf5xx_ssm2602_snd_devdata.dev = &bf5xx_ssm2602_snd_device->dev;
165 ret = platform_device_add(bf5xx_ssm2602_snd_device); 145 ret = platform_device_add(bf5xx_ssm2602_snd_device);
166 146
167 if (ret) 147 if (ret)
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index 6bac1ac1a31..74cf759b78a 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -290,14 +290,14 @@ static int bf5xx_pcm_tdm_new(struct snd_card *card, struct snd_soc_dai *dai,
290 if (!card->dev->coherent_dma_mask) 290 if (!card->dev->coherent_dma_mask)
291 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 291 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
292 292
293 if (dai->playback.channels_min) { 293 if (dai->driver->playback.channels_min) {
294 ret = bf5xx_pcm_preallocate_dma_buffer(pcm, 294 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
295 SNDRV_PCM_STREAM_PLAYBACK); 295 SNDRV_PCM_STREAM_PLAYBACK);
296 if (ret) 296 if (ret)
297 goto out; 297 goto out;
298 } 298 }
299 299
300 if (dai->capture.channels_min) { 300 if (dai->driver->capture.channels_min) {
301 ret = bf5xx_pcm_preallocate_dma_buffer(pcm, 301 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
302 SNDRV_PCM_STREAM_CAPTURE); 302 SNDRV_PCM_STREAM_CAPTURE);
303 if (ret) 303 if (ret)
@@ -307,25 +307,44 @@ out:
307 return ret; 307 return ret;
308} 308}
309 309
310struct snd_soc_platform bf5xx_tdm_soc_platform = { 310static struct snd_soc_platform_driver bf5xx_tdm_soc_platform = {
311 .name = "bf5xx-audio", 311 .ops = &bf5xx_pcm_tdm_ops,
312 .pcm_ops = &bf5xx_pcm_tdm_ops,
313 .pcm_new = bf5xx_pcm_tdm_new, 312 .pcm_new = bf5xx_pcm_tdm_new,
314 .pcm_free = bf5xx_pcm_free_dma_buffers, 313 .pcm_free = bf5xx_pcm_free_dma_buffers,
315}; 314};
316EXPORT_SYMBOL_GPL(bf5xx_tdm_soc_platform);
317 315
318static int __init bfin_pcm_tdm_init(void) 316static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev)
319{ 317{
320 return snd_soc_register_platform(&bf5xx_tdm_soc_platform); 318 return snd_soc_register_platform(&pdev->dev, &bf5xx_tdm_soc_platform);
321} 319}
322module_init(bfin_pcm_tdm_init);
323 320
324static void __exit bfin_pcm_tdm_exit(void) 321static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
325{ 322{
326 snd_soc_unregister_platform(&bf5xx_tdm_soc_platform); 323 snd_soc_unregister_platform(&pdev->dev);
324 return 0;
325}
326
327static struct platform_driver bfin_tdm_driver = {
328 .driver = {
329 .name = "bf5xx-tdm-pcm-audio",
330 .owner = THIS_MODULE,
331 },
332
333 .probe = bf5xx_soc_platform_probe,
334 .remove = __devexit_p(bf5xx_soc_platform_remove),
335};
336
337static int __init snd_bfin_tdm_init(void)
338{
339 return platform_driver_register(&bfin_tdm_driver);
340}
341module_init(snd_bfin_tdm_init);
342
343static void __exit snd_bfin_tdm_exit(void)
344{
345 platform_driver_unregister(&bfin_tdm_driver);
327} 346}
328module_exit(bfin_pcm_tdm_exit); 347module_exit(snd_bfin_tdm_exit);
329 348
330MODULE_AUTHOR("Barry Song"); 349MODULE_AUTHOR("Barry Song");
331MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module"); 350MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module");
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.h b/sound/soc/blackfin/bf5xx-tdm-pcm.h
index ddc5047df88..7f8cc01c447 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.h
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.h
@@ -15,7 +15,4 @@ struct bf5xx_pcm_dma_params {
15 char *name; /* stream identifier */ 15 char *name; /* stream identifier */
16}; 16};
17 17
18/* platform data */
19extern struct snd_soc_platform bf5xx_tdm_soc_platform;
20
21#endif 18#endif
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index 24c14269f4b..125123929f1 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -214,9 +214,9 @@ static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
214 214
215 if (!dai->active) 215 if (!dai->active)
216 return 0; 216 return 0;
217 if (dai->capture.active) 217 if (dai->capture_active)
218 sport_rx_stop(sport); 218 sport_rx_stop(sport);
219 if (dai->playback.active) 219 if (dai->playback_active)
220 sport_tx_stop(sport); 220 sport_tx_stop(sport);
221 return 0; 221 return 0;
222} 222}
@@ -224,7 +224,7 @@ static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
224static int bf5xx_tdm_resume(struct snd_soc_dai *dai) 224static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
225{ 225{
226 int ret; 226 int ret;
227 struct sport_device *sport = dai->private_data; 227 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
228 228
229 if (!dai->active) 229 if (!dai->active)
230 return 0; 230 return 0;
@@ -262,9 +262,7 @@ static struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
262 .set_channel_map = bf5xx_tdm_set_channel_map, 262 .set_channel_map = bf5xx_tdm_set_channel_map,
263}; 263};
264 264
265struct snd_soc_dai bf5xx_tdm_dai = { 265static struct snd_soc_dai_driver bf5xx_tdm_dai = {
266 .name = "bf5xx-tdm",
267 .id = 0,
268 .suspend = bf5xx_tdm_suspend, 266 .suspend = bf5xx_tdm_suspend,
269 .resume = bf5xx_tdm_resume, 267 .resume = bf5xx_tdm_resume,
270 .playback = { 268 .playback = {
@@ -279,7 +277,6 @@ struct snd_soc_dai bf5xx_tdm_dai = {
279 .formats = SNDRV_PCM_FMTBIT_S32_LE,}, 277 .formats = SNDRV_PCM_FMTBIT_S32_LE,},
280 .ops = &bf5xx_tdm_dai_ops, 278 .ops = &bf5xx_tdm_dai_ops,
281}; 279};
282EXPORT_SYMBOL_GPL(bf5xx_tdm_dai);
283 280
284static int __devinit bfin_tdm_probe(struct platform_device *pdev) 281static int __devinit bfin_tdm_probe(struct platform_device *pdev)
285{ 282{
@@ -320,7 +317,7 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
320 goto sport_config_err; 317 goto sport_config_err;
321 } 318 }
322 319
323 ret = snd_soc_register_dai(&bf5xx_tdm_dai); 320 ret = snd_soc_register_dai(&pdev->dev, &bf5xx_tdm_dai);
324 if (ret) { 321 if (ret) {
325 pr_err("Failed to register DAI: %d\n", ret); 322 pr_err("Failed to register DAI: %d\n", ret);
326 goto sport_config_err; 323 goto sport_config_err;
@@ -337,7 +334,7 @@ sport_config_err:
337static int __devexit bfin_tdm_remove(struct platform_device *pdev) 334static int __devexit bfin_tdm_remove(struct platform_device *pdev)
338{ 335{
339 peripheral_free_list(&sport_req[sport_num][0]); 336 peripheral_free_list(&sport_req[sport_num][0]);
340 snd_soc_unregister_dai(&bf5xx_tdm_dai); 337 snd_soc_unregister_dai(&pdev->dev);
341 338
342 return 0; 339 return 0;
343} 340}
diff --git a/sound/soc/blackfin/bf5xx-tdm.h b/sound/soc/blackfin/bf5xx-tdm.h
index 04189a18c1b..e986a3ea331 100644
--- a/sound/soc/blackfin/bf5xx-tdm.h
+++ b/sound/soc/blackfin/bf5xx-tdm.h
@@ -20,6 +20,4 @@ struct bf5xx_tdm_port {
20 int configured; 20 int configured;
21}; 21};
22 22
23extern struct snd_soc_dai bf5xx_tdm_dai;
24
25#endif 23#endif
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 1f5e57a4bb7..12c87d37eba 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -21,7 +21,6 @@
21#include <sound/ac97_codec.h> 21#include <sound/ac97_codec.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include "ac97.h"
25 24
26#define AC97_VERSION "0.6" 25#define AC97_VERSION "0.6"
27 26
@@ -30,8 +29,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
30{ 29{
31 struct snd_pcm_runtime *runtime = substream->runtime; 30 struct snd_pcm_runtime *runtime = substream->runtime;
32 struct snd_soc_pcm_runtime *rtd = substream->private_data; 31 struct snd_soc_pcm_runtime *rtd = substream->private_data;
33 struct snd_soc_device *socdev = rtd->socdev; 32 struct snd_soc_codec *codec = rtd->codec;
34 struct snd_soc_codec *codec = socdev->card->codec;
35 33
36 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 34 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
37 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; 35 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
@@ -46,8 +44,8 @@ static struct snd_soc_dai_ops ac97_dai_ops = {
46 .prepare = ac97_prepare, 44 .prepare = ac97_prepare,
47}; 45};
48 46
49struct snd_soc_dai ac97_dai = { 47static struct snd_soc_dai_driver ac97_dai = {
50 .name = "AC97 HiFi", 48 .name = "ac97-hifi",
51 .ac97_control = 1, 49 .ac97_control = 1,
52 .playback = { 50 .playback = {
53 .stream_name = "AC97 Playback", 51 .stream_name = "AC97 Playback",
@@ -63,7 +61,6 @@ struct snd_soc_dai ac97_dai = {
63 .formats = SND_SOC_STD_AC97_FMTS,}, 61 .formats = SND_SOC_STD_AC97_FMTS,},
64 .ops = &ac97_dai_ops, 62 .ops = &ac97_dai_ops,
65}; 63};
66EXPORT_SYMBOL_GPL(ac97_dai);
67 64
68static unsigned int ac97_read(struct snd_soc_codec *codec, 65static unsigned int ac97_read(struct snd_soc_codec *codec,
69 unsigned int reg) 66 unsigned int reg)
@@ -78,95 +75,49 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
78 return 0; 75 return 0;
79} 76}
80 77
81static int ac97_soc_probe(struct platform_device *pdev) 78static int ac97_soc_probe(struct snd_soc_codec *codec)
82{ 79{
83 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
84 struct snd_soc_card *card = socdev->card;
85 struct snd_soc_codec *codec;
86 struct snd_ac97_bus *ac97_bus; 80 struct snd_ac97_bus *ac97_bus;
87 struct snd_ac97_template ac97_template; 81 struct snd_ac97_template ac97_template;
88 int i; 82 int ret;
89 int ret = 0;
90 83
91 printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); 84 printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
92 85
93 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 86 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
94 if (!socdev->card->codec) 87 if (ret < 0) {
95 return -ENOMEM; 88 printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n");
96 codec = socdev->card->codec; 89 return ret;
97 mutex_init(&codec->mutex); 90 }
98
99 codec->name = "AC97";
100 codec->owner = THIS_MODULE;
101 codec->dai = &ac97_dai;
102 codec->num_dai = 1;
103 codec->write = ac97_write;
104 codec->read = ac97_read;
105 INIT_LIST_HEAD(&codec->dapm_widgets);
106 INIT_LIST_HEAD(&codec->dapm_paths);
107
108 /* register pcms */
109 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
110 if (ret < 0)
111 goto err;
112 91
113 /* add codec as bus device for standard ac97 */ 92 /* add codec as bus device for standard ac97 */
114 ret = snd_ac97_bus(codec->card, 0, &soc_ac97_ops, NULL, &ac97_bus); 93 ret = snd_ac97_bus(codec->card->snd_card, 0, &soc_ac97_ops, NULL, &ac97_bus);
115 if (ret < 0) 94 if (ret < 0)
116 goto bus_err; 95 return ret;
117 96
118 memset(&ac97_template, 0, sizeof(struct snd_ac97_template)); 97 memset(&ac97_template, 0, sizeof(struct snd_ac97_template));
119 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &codec->ac97); 98 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &codec->ac97);
120 if (ret < 0) 99 if (ret < 0)
121 goto bus_err; 100 return ret;
122
123 for (i = 0; i < card->num_links; i++) {
124 if (card->dai_link[i].codec_dai->ac97_control) {
125 snd_ac97_dev_add_pdata(codec->ac97,
126 card->dai_link[i].cpu_dai->ac97_pdata);
127 }
128 }
129 101
130 return 0; 102 return 0;
131
132bus_err:
133 snd_soc_free_pcms(socdev);
134
135err:
136 kfree(socdev->card->codec);
137 socdev->card->codec = NULL;
138 return ret;
139} 103}
140 104
141static int ac97_soc_remove(struct platform_device *pdev) 105static int ac97_soc_remove(struct snd_soc_codec *codec)
142{ 106{
143 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
144 struct snd_soc_codec *codec = socdev->card->codec;
145
146 if (!codec)
147 return 0;
148
149 snd_soc_free_pcms(socdev);
150 kfree(socdev->card->codec);
151
152 return 0; 107 return 0;
153} 108}
154 109
155#ifdef CONFIG_PM 110#ifdef CONFIG_PM
156static int ac97_soc_suspend(struct platform_device *pdev, pm_message_t msg) 111static int ac97_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
157{ 112{
158 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 113 snd_ac97_suspend(codec->ac97);
159
160 snd_ac97_suspend(socdev->card->codec->ac97);
161 114
162 return 0; 115 return 0;
163} 116}
164 117
165static int ac97_soc_resume(struct platform_device *pdev) 118static int ac97_soc_resume(struct snd_soc_codec *codec)
166{ 119{
167 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 120 snd_ac97_resume(codec->ac97);
168
169 snd_ac97_resume(socdev->card->codec->ac97);
170 121
171 return 0; 122 return 0;
172} 123}
@@ -175,13 +126,48 @@ static int ac97_soc_resume(struct platform_device *pdev)
175#define ac97_soc_resume NULL 126#define ac97_soc_resume NULL
176#endif 127#endif
177 128
178struct snd_soc_codec_device soc_codec_dev_ac97 = { 129static struct snd_soc_codec_driver soc_codec_dev_ac97 = {
130 .write = ac97_write,
131 .read = ac97_read,
179 .probe = ac97_soc_probe, 132 .probe = ac97_soc_probe,
180 .remove = ac97_soc_remove, 133 .remove = ac97_soc_remove,
181 .suspend = ac97_soc_suspend, 134 .suspend = ac97_soc_suspend,
182 .resume = ac97_soc_resume, 135 .resume = ac97_soc_resume,
183}; 136};
184EXPORT_SYMBOL_GPL(soc_codec_dev_ac97); 137
138static __devinit int ac97_probe(struct platform_device *pdev)
139{
140 return snd_soc_register_codec(&pdev->dev,
141 &soc_codec_dev_ac97, &ac97_dai, 1);
142}
143
144static int __devexit ac97_remove(struct platform_device *pdev)
145{
146 snd_soc_unregister_codec(&pdev->dev);
147 return 0;
148}
149
150static struct platform_driver ac97_codec_driver = {
151 .driver = {
152 .name = "ac97-codec",
153 .owner = THIS_MODULE,
154 },
155
156 .probe = ac97_probe,
157 .remove = __devexit_p(ac97_remove),
158};
159
160static int __init ac97_init(void)
161{
162 return platform_driver_register(&ac97_codec_driver);
163}
164module_init(ac97_init);
165
166static void __exit ac97_exit(void)
167{
168 platform_driver_unregister(&ac97_codec_driver);
169}
170module_exit(ac97_exit);
185 171
186MODULE_DESCRIPTION("Soc Generic AC97 driver"); 172MODULE_DESCRIPTION("Soc Generic AC97 driver");
187MODULE_AUTHOR("Liam Girdwood"); 173MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/ac97.h b/sound/soc/codecs/ac97.h
deleted file mode 100644
index 281aa42e2bb..00000000000
--- a/sound/soc/codecs/ac97.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * linux/sound/codecs/ac97.h -- ALSA SoC Layer
3 *
4 * Author: Liam Girdwood
5 * Created: Dec 1st 2005
6 * Copyright: Wolfson Microelectronics. PLC.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __LINUX_SND_SOC_AC97_H
14#define __LINUX_SND_SOC_AC97_H
15
16extern struct snd_soc_codec_device soc_codec_dev_ac97;
17extern struct snd_soc_dai ac97_dai;
18
19#endif
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index a01006c8c60..d272534c8f8 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -33,15 +33,10 @@
33 33
34/* codec private data */ 34/* codec private data */
35struct ad1836_priv { 35struct ad1836_priv {
36 struct snd_soc_codec codec; 36 enum snd_soc_control_type control_type;
37 u16 reg_cache[AD1836_NUM_REGS]; 37 void *control_data;
38}; 38};
39 39
40static struct snd_soc_codec *ad1836_codec;
41struct snd_soc_codec_device soc_codec_dev_ad1836;
42static int ad1836_register(struct ad1836_priv *ad1836);
43static void ad1836_unregister(struct ad1836_priv *ad1836);
44
45/* 40/*
46 * AD1836 volume/mute/de-emphasis etc. controls 41 * AD1836 volume/mute/de-emphasis etc. controls
47 */ 42 */
@@ -146,8 +141,7 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
146 int word_len = 0; 141 int word_len = 0;
147 142
148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 143 struct snd_soc_pcm_runtime *rtd = substream->private_data;
149 struct snd_soc_device *socdev = rtd->socdev; 144 struct snd_soc_codec *codec = rtd->codec;
150 struct snd_soc_codec *codec = socdev->card->codec;
151 145
152 /* bit size */ 146 /* bit size */
153 switch (params_format(params)) { 147 switch (params_format(params)) {
@@ -173,12 +167,9 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
173} 167}
174 168
175#ifdef CONFIG_PM 169#ifdef CONFIG_PM
176static int ad1836_soc_suspend(struct platform_device *pdev, 170static int ad1836_soc_suspend(struct snd_soc_codec *codec,
177 pm_message_t state) 171 pm_message_t state)
178{ 172{
179 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
180 struct snd_soc_codec *codec = socdev->card->codec;
181
182 /* reset clock control mode */ 173 /* reset clock control mode */
183 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); 174 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
184 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK; 175 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
@@ -186,11 +177,8 @@ static int ad1836_soc_suspend(struct platform_device *pdev,
186 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2); 177 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
187} 178}
188 179
189static int ad1836_soc_resume(struct platform_device *pdev) 180static int ad1836_soc_resume(struct snd_soc_codec *codec)
190{ 181{
191 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
192 struct snd_soc_codec *codec = socdev->card->codec;
193
194 /* restore clock control mode */ 182 /* restore clock control mode */
195 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); 183 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
196 adc_ctrl2 |= AD1836_ADC_AUX; 184 adc_ctrl2 |= AD1836_ADC_AUX;
@@ -202,49 +190,14 @@ static int ad1836_soc_resume(struct platform_device *pdev)
202#define ad1836_soc_resume NULL 190#define ad1836_soc_resume NULL
203#endif 191#endif
204 192
205static int __devinit ad1836_spi_probe(struct spi_device *spi)
206{
207 struct snd_soc_codec *codec;
208 struct ad1836_priv *ad1836;
209
210 ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
211 if (ad1836 == NULL)
212 return -ENOMEM;
213
214 codec = &ad1836->codec;
215 codec->control_data = spi;
216 codec->dev = &spi->dev;
217
218 dev_set_drvdata(&spi->dev, ad1836);
219
220 return ad1836_register(ad1836);
221}
222
223static int __devexit ad1836_spi_remove(struct spi_device *spi)
224{
225 struct ad1836_priv *ad1836 = dev_get_drvdata(&spi->dev);
226
227 ad1836_unregister(ad1836);
228 return 0;
229}
230
231static struct spi_driver ad1836_spi_driver = {
232 .driver = {
233 .name = "ad1836",
234 .owner = THIS_MODULE,
235 },
236 .probe = ad1836_spi_probe,
237 .remove = __devexit_p(ad1836_spi_remove),
238};
239
240static struct snd_soc_dai_ops ad1836_dai_ops = { 193static struct snd_soc_dai_ops ad1836_dai_ops = {
241 .hw_params = ad1836_hw_params, 194 .hw_params = ad1836_hw_params,
242 .set_fmt = ad1836_set_dai_fmt, 195 .set_fmt = ad1836_set_dai_fmt,
243}; 196};
244 197
245/* codec DAI instance */ 198/* codec DAI instance */
246struct snd_soc_dai ad1836_dai = { 199static struct snd_soc_dai_driver ad1836_dai = {
247 .name = "AD1836", 200 .name = "ad1836-hifi",
248 .playback = { 201 .playback = {
249 .stream_name = "Playback", 202 .stream_name = "Playback",
250 .channels_min = 2, 203 .channels_min = 2,
@@ -263,35 +216,13 @@ struct snd_soc_dai ad1836_dai = {
263 }, 216 },
264 .ops = &ad1836_dai_ops, 217 .ops = &ad1836_dai_ops,
265}; 218};
266EXPORT_SYMBOL_GPL(ad1836_dai);
267 219
268static int ad1836_register(struct ad1836_priv *ad1836) 220static int ad1836_probe(struct snd_soc_codec *codec)
269{ 221{
270 int ret; 222 struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
271 struct snd_soc_codec *codec = &ad1836->codec; 223 int ret = 0;
272
273 if (ad1836_codec) {
274 dev_err(codec->dev, "Another ad1836 is registered\n");
275 kfree(ad1836);
276 return -EINVAL;
277 }
278
279 mutex_init(&codec->mutex);
280 INIT_LIST_HEAD(&codec->dapm_widgets);
281 INIT_LIST_HEAD(&codec->dapm_paths);
282 snd_soc_codec_set_drvdata(codec, ad1836);
283 codec->reg_cache = ad1836->reg_cache;
284 codec->reg_cache_size = AD1836_NUM_REGS;
285 codec->name = "AD1836";
286 codec->owner = THIS_MODULE;
287 codec->dai = &ad1836_dai;
288 codec->num_dai = 1;
289 INIT_LIST_HEAD(&codec->dapm_widgets);
290 INIT_LIST_HEAD(&codec->dapm_paths);
291
292 ad1836_dai.dev = codec->dev;
293 ad1836_codec = codec;
294 224
225 codec->control_data = ad1836->control_data;
295 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI); 226 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
296 if (ret < 0) { 227 if (ret < 0) {
297 dev_err(codec->dev, "failed to set cache I/O: %d\n", 228 dev_err(codec->dev, "failed to set cache I/O: %d\n",
@@ -319,81 +250,69 @@ static int ad1836_register(struct ad1836_priv *ad1836)
319 snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF); 250 snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
320 snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF); 251 snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
321 252
322 ret = snd_soc_register_codec(codec);
323 if (ret != 0) {
324 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
325 kfree(ad1836);
326 return ret;
327 }
328
329 ret = snd_soc_register_dai(&ad1836_dai);
330 if (ret != 0) {
331 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
332 snd_soc_unregister_codec(codec);
333 kfree(ad1836);
334 return ret;
335 }
336
337 return 0;
338}
339
340static void ad1836_unregister(struct ad1836_priv *ad1836)
341{
342 snd_soc_unregister_dai(&ad1836_dai);
343 snd_soc_unregister_codec(&ad1836->codec);
344 kfree(ad1836);
345 ad1836_codec = NULL;
346}
347
348static int ad1836_probe(struct platform_device *pdev)
349{
350 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
351 struct snd_soc_codec *codec;
352 int ret = 0;
353
354 if (ad1836_codec == NULL) {
355 dev_err(&pdev->dev, "Codec device not registered\n");
356 return -ENODEV;
357 }
358
359 socdev->card->codec = ad1836_codec;
360 codec = ad1836_codec;
361
362 /* register pcms */
363 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
364 if (ret < 0) {
365 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
366 goto pcm_err;
367 }
368
369 snd_soc_add_controls(codec, ad1836_snd_controls, 253 snd_soc_add_controls(codec, ad1836_snd_controls,
370 ARRAY_SIZE(ad1836_snd_controls)); 254 ARRAY_SIZE(ad1836_snd_controls));
371 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets, 255 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
372 ARRAY_SIZE(ad1836_dapm_widgets)); 256 ARRAY_SIZE(ad1836_dapm_widgets));
373 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 257 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
374 258
375pcm_err:
376 return ret; 259 return ret;
377} 260}
378 261
379/* power down chip */ 262/* power down chip */
380static int ad1836_remove(struct platform_device *pdev) 263static int ad1836_remove(struct snd_soc_codec *codec)
381{ 264{
382 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 265 /* reset clock control mode */
383 266 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
384 snd_soc_free_pcms(socdev); 267 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
385 snd_soc_dapm_free(socdev);
386 268
387 return 0; 269 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
388} 270}
389 271
390struct snd_soc_codec_device soc_codec_dev_ad1836 = { 272static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
391 .probe = ad1836_probe, 273 .probe = ad1836_probe,
392 .remove = ad1836_remove, 274 .remove = ad1836_remove,
393 .suspend = ad1836_soc_suspend, 275 .suspend = ad1836_soc_suspend,
394 .resume = ad1836_soc_resume, 276 .resume = ad1836_soc_resume,
277 .reg_cache_size = AD1836_NUM_REGS,
278 .reg_word_size = sizeof(u16),
279};
280
281static int __devinit ad1836_spi_probe(struct spi_device *spi)
282{
283 struct ad1836_priv *ad1836;
284 int ret;
285
286 ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
287 if (ad1836 == NULL)
288 return -ENOMEM;
289
290 spi_set_drvdata(spi, ad1836);
291 ad1836->control_data = spi;
292 ad1836->control_type = SND_SOC_SPI;
293
294 ret = snd_soc_register_codec(&spi->dev,
295 &soc_codec_dev_ad1836, &ad1836_dai, 1);
296 if (ret < 0)
297 kfree(ad1836);
298 return ret;
299}
300
301static int __devexit ad1836_spi_remove(struct spi_device *spi)
302{
303 snd_soc_unregister_codec(&spi->dev);
304 kfree(spi_get_drvdata(spi));
305 return 0;
306}
307
308static struct spi_driver ad1836_spi_driver = {
309 .driver = {
310 .name = "ad1836-codec",
311 .owner = THIS_MODULE,
312 },
313 .probe = ad1836_spi_probe,
314 .remove = __devexit_p(ad1836_spi_remove),
395}; 315};
396EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
397 316
398static int __init ad1836_init(void) 317static int __init ad1836_init(void)
399{ 318{
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
index e9d90d3951c..845596717fd 100644
--- a/sound/soc/codecs/ad1836.h
+++ b/sound/soc/codecs/ad1836.h
@@ -60,6 +60,4 @@
60 60
61#define AD1836_NUM_REGS 16 61#define AD1836_NUM_REGS 16
62 62
63extern struct snd_soc_dai ad1836_dai;
64extern struct snd_soc_codec_device soc_codec_dev_ad1836;
65#endif 63#endif
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 1def75e4862..fa2834c91b9 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -24,9 +24,10 @@
24 24
25/* codec private data */ 25/* codec private data */
26struct ad193x_priv { 26struct ad193x_priv {
27 unsigned int sysclk;
28 struct snd_soc_codec codec;
29 u8 reg_cache[AD193X_NUM_REGS]; 27 u8 reg_cache[AD193X_NUM_REGS];
28 enum snd_soc_control_type bus_type;
29 void *control_data;
30 int sysclk;
30}; 31};
31 32
32/* ad193x register cache & default register settings */ 33/* ad193x register cache & default register settings */
@@ -34,9 +35,6 @@ static const u8 ad193x_reg[AD193X_NUM_REGS] = {
34 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 35 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
35}; 36};
36 37
37static struct snd_soc_codec *ad193x_codec;
38struct snd_soc_codec_device soc_codec_dev_ad193x;
39
40/* 38/*
41 * AD193X volume/mute/de-emphasis etc. controls 39 * AD193X volume/mute/de-emphasis etc. controls
42 */ 40 */
@@ -275,8 +273,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
275 int word_len = 0, reg = 0, master_rate = 0; 273 int word_len = 0, reg = 0, master_rate = 0;
276 274
277 struct snd_soc_pcm_runtime *rtd = substream->private_data; 275 struct snd_soc_pcm_runtime *rtd = substream->private_data;
278 struct snd_soc_device *socdev = rtd->socdev; 276 struct snd_soc_codec *codec = rtd->codec;
279 struct snd_soc_codec *codec = socdev->card->codec;
280 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 277 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
281 278
282 /* bit size */ 279 /* bit size */
@@ -323,100 +320,6 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
323 return 0; 320 return 0;
324} 321}
325 322
326static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
327{
328 struct snd_soc_codec *codec;
329 struct ad193x_priv *ad193x;
330 int ret;
331
332 if (ad193x_codec) {
333 dev_err(dev, "Another ad193x is registered\n");
334 return -EINVAL;
335 }
336
337 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
338 if (ad193x == NULL)
339 return -ENOMEM;
340
341 dev_set_drvdata(dev, ad193x);
342
343 codec = &ad193x->codec;
344 mutex_init(&codec->mutex);
345 codec->control_data = ctrl_data;
346 codec->dev = dev;
347 snd_soc_codec_set_drvdata(codec, ad193x);
348 codec->reg_cache = ad193x->reg_cache;
349 codec->reg_cache_size = AD193X_NUM_REGS;
350 codec->name = "AD193X";
351 codec->owner = THIS_MODULE;
352 codec->dai = &ad193x_dai;
353 codec->num_dai = 1;
354 INIT_LIST_HEAD(&codec->dapm_widgets);
355 INIT_LIST_HEAD(&codec->dapm_paths);
356
357 ad193x_dai.dev = codec->dev;
358 ad193x_codec = codec;
359
360 memcpy(codec->reg_cache, ad193x_reg, AD193X_NUM_REGS);
361
362 if (bus_type == SND_SOC_I2C)
363 ret = snd_soc_codec_set_cache_io(codec, 8, 8, bus_type);
364 else
365 ret = snd_soc_codec_set_cache_io(codec, 16, 8, bus_type);
366 if (ret < 0) {
367 dev_err(codec->dev, "failed to set cache I/O: %d\n",
368 ret);
369 kfree(ad193x);
370 return ret;
371 }
372
373 /* default setting for ad193x */
374
375 /* unmute dac channels */
376 snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
377 /* de-emphasis: 48kHz, powedown dac */
378 snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
379 /* powerdown dac, dac in tdm mode */
380 snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
381 /* high-pass filter enable */
382 snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
383 /* sata delay=1, adc aux mode */
384 snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
385 /* pll input: mclki/xi */
386 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
387 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
388 ad193x->sysclk = 12288000;
389
390 ret = snd_soc_register_codec(codec);
391 if (ret != 0) {
392 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
393 kfree(ad193x);
394 return ret;
395 }
396
397 ret = snd_soc_register_dai(&ad193x_dai);
398 if (ret != 0) {
399 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
400 snd_soc_unregister_codec(codec);
401 kfree(ad193x);
402 return ret;
403 }
404
405 return 0;
406}
407
408static int ad193x_bus_remove(struct device *dev)
409{
410 struct ad193x_priv *ad193x = dev_get_drvdata(dev);
411
412 snd_soc_unregister_dai(&ad193x_dai);
413 snd_soc_unregister_codec(&ad193x->codec);
414 kfree(ad193x);
415 ad193x_codec = NULL;
416
417 return 0;
418}
419
420static struct snd_soc_dai_ops ad193x_dai_ops = { 323static struct snd_soc_dai_ops ad193x_dai_ops = {
421 .hw_params = ad193x_hw_params, 324 .hw_params = ad193x_hw_params,
422 .digital_mute = ad193x_mute, 325 .digital_mute = ad193x_mute,
@@ -426,8 +329,8 @@ static struct snd_soc_dai_ops ad193x_dai_ops = {
426}; 329};
427 330
428/* codec DAI instance */ 331/* codec DAI instance */
429struct snd_soc_dai ad193x_dai = { 332static struct snd_soc_dai_driver ad193x_dai = {
430 .name = "AD193X", 333 .name = "ad193x-hifi",
431 .playback = { 334 .playback = {
432 .stream_name = "Playback", 335 .stream_name = "Playback",
433 .channels_min = 2, 336 .channels_min = 2,
@@ -446,28 +349,39 @@ struct snd_soc_dai ad193x_dai = {
446 }, 349 },
447 .ops = &ad193x_dai_ops, 350 .ops = &ad193x_dai_ops,
448}; 351};
449EXPORT_SYMBOL_GPL(ad193x_dai);
450 352
451static int ad193x_probe(struct platform_device *pdev) 353static int ad193x_probe(struct snd_soc_codec *codec)
452{ 354{
453 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 355 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
454 struct snd_soc_codec *codec; 356 int ret;
455 int ret = 0;
456 357
457 if (ad193x_codec == NULL) { 358 codec->control_data = ad193x->control_data;
458 dev_err(&pdev->dev, "Codec device not registered\n"); 359 if (ad193x->bus_type == SND_SOC_I2C)
459 return -ENODEV; 360 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->bus_type);
361 else
362 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->bus_type);
363 if (ret < 0) {
364 dev_err(codec->dev, "failed to set cache I/O: %d\n",
365 ret);
366 kfree(ad193x);
367 return ret;
460 } 368 }
461 369
462 socdev->card->codec = ad193x_codec; 370 /* default setting for ad193x */
463 codec = ad193x_codec;
464 371
465 /* register pcms */ 372 /* unmute dac channels */
466 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 373 snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
467 if (ret < 0) { 374 /* de-emphasis: 48kHz, powedown dac */
468 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 375 snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
469 goto pcm_err; 376 /* powerdown dac, dac in tdm mode */
470 } 377 snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
378 /* high-pass filter enable */
379 snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
380 /* sata delay=1, adc aux mode */
381 snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
382 /* pll input: mclki/xi */
383 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
384 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
471 385
472 snd_soc_add_controls(codec, ad193x_snd_controls, 386 snd_soc_add_controls(codec, ad193x_snd_controls,
473 ARRAY_SIZE(ad193x_snd_controls)); 387 ARRAY_SIZE(ad193x_snd_controls));
@@ -475,41 +389,47 @@ static int ad193x_probe(struct platform_device *pdev)
475 ARRAY_SIZE(ad193x_dapm_widgets)); 389 ARRAY_SIZE(ad193x_dapm_widgets));
476 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 390 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
477 391
478pcm_err:
479 return ret; 392 return ret;
480} 393}
481 394
482/* power down chip */ 395static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
483static int ad193x_remove(struct platform_device *pdev)
484{
485 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
486
487 snd_soc_free_pcms(socdev);
488 snd_soc_dapm_free(socdev);
489
490 return 0;
491}
492
493struct snd_soc_codec_device soc_codec_dev_ad193x = {
494 .probe = ad193x_probe, 396 .probe = ad193x_probe,
495 .remove = ad193x_remove, 397 .reg_cache_default = ad193x_reg,
398 .reg_cache_size = AD193X_NUM_REGS,
399 .reg_word_size = sizeof(u16),
496}; 400};
497EXPORT_SYMBOL_GPL(soc_codec_dev_ad193x);
498 401
499#if defined(CONFIG_SPI_MASTER) 402#if defined(CONFIG_SPI_MASTER)
500static int __devinit ad193x_spi_probe(struct spi_device *spi) 403static int __devinit ad193x_spi_probe(struct spi_device *spi)
501{ 404{
502 return ad193x_bus_probe(&spi->dev, spi, SND_SOC_SPI); 405 struct ad193x_priv *ad193x;
406 int ret;
407
408 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
409 if (ad193x == NULL)
410 return -ENOMEM;
411
412 spi_set_drvdata(spi, ad193x);
413 ad193x->control_data = spi;
414 ad193x->bus_type = SND_SOC_SPI;
415
416 ret = snd_soc_register_codec(&spi->dev,
417 &soc_codec_dev_ad193x, &ad193x_dai, 1);
418 if (ret < 0)
419 kfree(ad193x);
420 return ret;
503} 421}
504 422
505static int __devexit ad193x_spi_remove(struct spi_device *spi) 423static int __devexit ad193x_spi_remove(struct spi_device *spi)
506{ 424{
507 return ad193x_bus_remove(&spi->dev); 425 snd_soc_unregister_codec(&spi->dev);
426 kfree(spi_get_drvdata(spi));
427 return 0;
508} 428}
509 429
510static struct spi_driver ad193x_spi_driver = { 430static struct spi_driver ad193x_spi_driver = {
511 .driver = { 431 .driver = {
512 .name = "ad193x", 432 .name = "ad193x-codec",
513 .owner = THIS_MODULE, 433 .owner = THIS_MODULE,
514 }, 434 },
515 .probe = ad193x_spi_probe, 435 .probe = ad193x_spi_probe,
@@ -528,17 +448,34 @@ MODULE_DEVICE_TABLE(i2c, ad193x_id);
528static int __devinit ad193x_i2c_probe(struct i2c_client *client, 448static int __devinit ad193x_i2c_probe(struct i2c_client *client,
529 const struct i2c_device_id *id) 449 const struct i2c_device_id *id)
530{ 450{
531 return ad193x_bus_probe(&client->dev, client, SND_SOC_I2C); 451 struct ad193x_priv *ad193x;
452 int ret;
453
454 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
455 if (ad193x == NULL)
456 return -ENOMEM;
457
458 i2c_set_clientdata(client, ad193x);
459 ad193x->control_data = client;
460 ad193x->bus_type = SND_SOC_I2C;
461
462 ret = snd_soc_register_codec(&client->dev,
463 &soc_codec_dev_ad193x, &ad193x_dai, 1);
464 if (ret < 0)
465 kfree(ad193x);
466 return ret;
532} 467}
533 468
534static int __devexit ad193x_i2c_remove(struct i2c_client *client) 469static int __devexit ad193x_i2c_remove(struct i2c_client *client)
535{ 470{
536 return ad193x_bus_remove(&client->dev); 471 snd_soc_unregister_codec(&client->dev);
472 kfree(i2c_get_clientdata(client));
473 return 0;
537} 474}
538 475
539static struct i2c_driver ad193x_i2c_driver = { 476static struct i2c_driver ad193x_i2c_driver = {
540 .driver = { 477 .driver = {
541 .name = "ad193x", 478 .name = "ad193x-codec",
542 }, 479 },
543 .probe = ad193x_i2c_probe, 480 .probe = ad193x_i2c_probe,
544 .remove = __devexit_p(ad193x_i2c_remove), 481 .remove = __devexit_p(ad193x_i2c_remove),
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index 654ba64ae04..9747b549787 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -80,7 +80,4 @@
80 80
81#define AD193X_NUM_REGS 17 81#define AD193X_NUM_REGS 17
82 82
83extern struct snd_soc_dai ad193x_dai;
84extern struct snd_soc_codec_device soc_codec_dev_ad193x;
85
86#endif 83#endif
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 042072738cd..1371afac657 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -130,8 +130,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
130 return 0; 130 return 0;
131} 131}
132 132
133struct snd_soc_dai ad1980_dai = { 133struct snd_soc_dai_driver ad1980_dai = {
134 .name = "AC97", 134 .name = "ad1980-hifi",
135 .ac97_control = 1, 135 .ac97_control = 1,
136 .playback = { 136 .playback = {
137 .stream_name = "Playback", 137 .stream_name = "Playback",
@@ -177,53 +177,20 @@ err:
177 return -EIO; 177 return -EIO;
178} 178}
179 179
180static int ad1980_soc_probe(struct platform_device *pdev) 180static int ad1980_soc_probe(struct snd_soc_codec *codec)
181{ 181{
182 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 182 int ret;
183 struct snd_soc_codec *codec;
184 int ret = 0;
185 u16 vendor_id2; 183 u16 vendor_id2;
186 u16 ext_status; 184 u16 ext_status;
187 185
188 printk(KERN_INFO "AD1980 SoC Audio Codec\n"); 186 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
189 187
190 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
191 if (socdev->card->codec == NULL)
192 return -ENOMEM;
193 codec = socdev->card->codec;
194 mutex_init(&codec->mutex);
195
196 codec->reg_cache =
197 kzalloc(sizeof(u16) * ARRAY_SIZE(ad1980_reg), GFP_KERNEL);
198 if (codec->reg_cache == NULL) {
199 ret = -ENOMEM;
200 goto cache_err;
201 }
202 memcpy(codec->reg_cache, ad1980_reg, sizeof(u16) * \
203 ARRAY_SIZE(ad1980_reg));
204 codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(ad1980_reg);
205 codec->reg_cache_step = 2;
206 codec->name = "AD1980";
207 codec->owner = THIS_MODULE;
208 codec->dai = &ad1980_dai;
209 codec->num_dai = 1;
210 codec->write = ac97_write;
211 codec->read = ac97_read;
212 INIT_LIST_HEAD(&codec->dapm_widgets);
213 INIT_LIST_HEAD(&codec->dapm_paths);
214
215 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 188 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
216 if (ret < 0) { 189 if (ret < 0) {
217 printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); 190 printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
218 goto codec_err; 191 return ret;
219 } 192 }
220 193
221 /* register pcms */
222 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
223 if (ret < 0)
224 goto pcm_err;
225
226
227 ret = ad1980_reset(codec, 0); 194 ret = ad1980_reset(codec, 0);
228 if (ret < 0) { 195 if (ret < 0) {
229 printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n"); 196 printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n");
@@ -262,41 +229,59 @@ static int ad1980_soc_probe(struct platform_device *pdev)
262 return 0; 229 return 0;
263 230
264reset_err: 231reset_err:
265 snd_soc_free_pcms(socdev);
266
267pcm_err:
268 snd_soc_free_ac97_codec(codec); 232 snd_soc_free_ac97_codec(codec);
269
270codec_err:
271 kfree(codec->reg_cache);
272
273cache_err:
274 kfree(socdev->card->codec);
275 socdev->card->codec = NULL;
276 return ret; 233 return ret;
277} 234}
278 235
279static int ad1980_soc_remove(struct platform_device *pdev) 236static int ad1980_soc_remove(struct snd_soc_codec *codec)
280{ 237{
281 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
282 struct snd_soc_codec *codec = socdev->card->codec;
283
284 if (codec == NULL)
285 return 0;
286
287 snd_soc_dapm_free(socdev);
288 snd_soc_free_pcms(socdev);
289 snd_soc_free_ac97_codec(codec); 238 snd_soc_free_ac97_codec(codec);
290 kfree(codec->reg_cache);
291 kfree(codec);
292 return 0; 239 return 0;
293} 240}
294 241
295struct snd_soc_codec_device soc_codec_dev_ad1980 = { 242static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
296 .probe = ad1980_soc_probe, 243 .probe = ad1980_soc_probe,
297 .remove = ad1980_soc_remove, 244 .remove = ad1980_soc_remove,
245 .reg_cache_size = ARRAY_SIZE(ad1980_reg),
246 .reg_word_size = sizeof(u16),
247 .reg_cache_step = 2,
248 .write = ac97_write,
249 .read = ac97_read,
298}; 250};
299EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980); 251
252static __devinit int ad1980_probe(struct platform_device *pdev)
253{
254 return snd_soc_register_codec(&pdev->dev,
255 &soc_codec_dev_ad1980, &ad1980_dai, 1);
256}
257
258static int __devexit ad1980_remove(struct platform_device *pdev)
259{
260 snd_soc_unregister_codec(&pdev->dev);
261 return 0;
262}
263
264static struct platform_driver ad1980_codec_driver = {
265 .driver = {
266 .name = "ad1980-codec",
267 .owner = THIS_MODULE,
268 },
269
270 .probe = ad1980_probe,
271 .remove = __devexit_p(ad1980_remove),
272};
273
274static int __init ad1980_init(void)
275{
276 return platform_driver_register(&ad1980_codec_driver);
277}
278module_init(ad1980_init);
279
280static void __exit ad1980_exit(void)
281{
282 platform_driver_unregister(&ad1980_codec_driver);
283}
284module_exit(ad1980_exit);
300 285
301MODULE_DESCRIPTION("ASoC ad1980 driver"); 286MODULE_DESCRIPTION("ASoC ad1980 driver");
302MODULE_AUTHOR("Roy Huang, Cliff Cai"); 287MODULE_AUTHOR("Roy Huang, Cliff Cai");
diff --git a/sound/soc/codecs/ad1980.h b/sound/soc/codecs/ad1980.h
index db6c8500d66..29b5a875092 100644
--- a/sound/soc/codecs/ad1980.h
+++ b/sound/soc/codecs/ad1980.h
@@ -17,7 +17,4 @@
17#define PR5 0x2000 17#define PR5 0x2000
18#define PR6 0x4000 18#define PR6 0x4000
19 19
20extern struct snd_soc_dai ad1980_dai;
21extern struct snd_soc_codec_device soc_codec_dev_ad1980;
22
23#endif 20#endif
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index 475807bea2c..c53955fe17b 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -23,8 +23,8 @@
23 23
24#include "ad73311.h" 24#include "ad73311.h"
25 25
26struct snd_soc_dai ad73311_dai = { 26static struct snd_soc_dai_driver ad73311_dai = {
27 .name = "AD73311", 27 .name = "ad73311-hifi",
28 .playback = { 28 .playback = {
29 .stream_name = "Playback", 29 .stream_name = "Playback",
30 .channels_min = 1, 30 .channels_min = 1,
@@ -38,68 +38,40 @@ struct snd_soc_dai ad73311_dai = {
38 .rates = SNDRV_PCM_RATE_8000, 38 .rates = SNDRV_PCM_RATE_8000,
39 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 39 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
40}; 40};
41EXPORT_SYMBOL_GPL(ad73311_dai);
42 41
43static int ad73311_soc_probe(struct platform_device *pdev) 42static struct snd_soc_codec_driver soc_codec_dev_ad73311;
44{
45 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
46 struct snd_soc_codec *codec;
47 int ret = 0;
48
49 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
50 if (codec == NULL)
51 return -ENOMEM;
52 mutex_init(&codec->mutex);
53 codec->name = "AD73311";
54 codec->owner = THIS_MODULE;
55 codec->dai = &ad73311_dai;
56 codec->num_dai = 1;
57 socdev->card->codec = codec;
58 INIT_LIST_HEAD(&codec->dapm_widgets);
59 INIT_LIST_HEAD(&codec->dapm_paths);
60
61 /* register pcms */
62 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
63 if (ret < 0) {
64 printk(KERN_ERR "ad73311: failed to create pcms\n");
65 goto pcm_err;
66 }
67
68 return ret;
69 43
70pcm_err: 44static int ad73311_probe(struct platform_device *pdev)
71 kfree(socdev->card->codec); 45{
72 socdev->card->codec = NULL; 46 return snd_soc_register_codec(&pdev->dev,
73 return ret; 47 &soc_codec_dev_ad73311, &ad73311_dai, 1);
74} 48}
75 49
76static int ad73311_soc_remove(struct platform_device *pdev) 50static int ad73311_remove(struct platform_device *pdev)
77{ 51{
78 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 52 snd_soc_unregister_codec(&pdev->dev);
79 struct snd_soc_codec *codec = socdev->card->codec;
80
81 if (codec == NULL)
82 return 0;
83 snd_soc_free_pcms(socdev);
84 kfree(codec);
85 return 0; 53 return 0;
86} 54}
87 55
88struct snd_soc_codec_device soc_codec_dev_ad73311 = { 56static struct platform_driver ad73311_codec_driver = {
89 .probe = ad73311_soc_probe, 57 .driver = {
90 .remove = ad73311_soc_remove, 58 .name = "ad73311-codec",
59 .owner = THIS_MODULE,
60 },
61
62 .probe = ad73311_probe,
63 .remove = __devexit_p(ad73311_remove),
91}; 64};
92EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
93 65
94static int __init ad73311_init(void) 66static int __init ad73311_init(void)
95{ 67{
96 return snd_soc_register_dai(&ad73311_dai); 68 return platform_driver_register(&ad73311_codec_driver);
97} 69}
98module_init(ad73311_init); 70module_init(ad73311_init);
99 71
100static void __exit ad73311_exit(void) 72static void __exit ad73311_exit(void)
101{ 73{
102 snd_soc_unregister_dai(&ad73311_dai); 74 platform_driver_unregister(&ad73311_codec_driver);
103} 75}
104module_exit(ad73311_exit); 76module_exit(ad73311_exit);
105 77
diff --git a/sound/soc/codecs/ad73311.h b/sound/soc/codecs/ad73311.h
index 569573d2d4d..4b353eefc0b 100644
--- a/sound/soc/codecs/ad73311.h
+++ b/sound/soc/codecs/ad73311.h
@@ -85,6 +85,4 @@
85#define REGF_INV (1 << 6) 85#define REGF_INV (1 << 6)
86#define REGF_ALB (1 << 7) 86#define REGF_ALB (1 << 7)
87 87
88extern struct snd_soc_dai ad73311_dai;
89extern struct snd_soc_codec_device soc_codec_dev_ad73311;
90#endif 88#endif
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
index f8e75edb27b..8402854ec15 100644
--- a/sound/soc/codecs/ads117x.c
+++ b/sound/soc/codecs/ads117x.c
@@ -19,16 +19,12 @@
19#include <sound/initval.h> 19#include <sound/initval.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21 21
22#include "ads117x.h"
23
24#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000) 22#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
25
26#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) 23#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
27 24
28struct snd_soc_dai ads117x_dai = { 25static struct snd_soc_dai_driver ads117x_dai = {
29/* ADC */ 26/* ADC */
30 .name = "ADS117X ADC", 27 .name = "ads117x-hifi",
31 .id = 1,
32 .capture = { 28 .capture = {
33 .stream_name = "Capture", 29 .stream_name = "Capture",
34 .channels_min = 1, 30 .channels_min = 1,
@@ -36,75 +32,29 @@ struct snd_soc_dai ads117x_dai = {
36 .rates = ADS117X_RATES, 32 .rates = ADS117X_RATES,
37 .formats = ADS117X_FORMATS,}, 33 .formats = ADS117X_FORMATS,},
38}; 34};
39EXPORT_SYMBOL_GPL(ads117x_dai);
40
41static int ads117x_probe(struct platform_device *pdev)
42{
43 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
44 struct snd_soc_codec *codec;
45 int ret;
46
47 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
48 if (codec == NULL)
49 return -ENOMEM;
50 35
51 socdev->card->codec = codec; 36static struct snd_soc_codec_driver soc_codec_dev_ads117x;
52 mutex_init(&codec->mutex);
53 INIT_LIST_HEAD(&codec->dapm_widgets);
54 INIT_LIST_HEAD(&codec->dapm_paths);
55 codec->name = "ADS117X";
56 codec->owner = THIS_MODULE;
57 codec->dai = &ads117x_dai;
58 codec->num_dai = 1;
59
60 /* register pcms */
61 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
62 if (ret < 0) {
63 printk(KERN_ERR "ads117x: failed to create pcms\n");
64 kfree(codec);
65 return ret;
66 }
67
68 return 0;
69}
70
71static int ads117x_remove(struct platform_device *pdev)
72{
73 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
74 struct snd_soc_codec *codec = socdev->card->codec;
75
76 snd_soc_free_pcms(socdev);
77 kfree(codec);
78
79 return 0;
80}
81
82struct snd_soc_codec_device soc_codec_dev_ads117x = {
83 .probe = ads117x_probe,
84 .remove = ads117x_remove,
85};
86EXPORT_SYMBOL_GPL(soc_codec_dev_ads117x);
87 37
88static __devinit int ads117x_platform_probe(struct platform_device *pdev) 38static __devinit int ads117x_probe(struct platform_device *pdev)
89{ 39{
90 ads117x_dai.dev = &pdev->dev; 40 return snd_soc_register_codec(&pdev->dev,
91 return snd_soc_register_dai(&ads117x_dai); 41 &soc_codec_dev_ads117x, &ads117x_dai, 1);
92} 42}
93 43
94static int __devexit ads117x_platform_remove(struct platform_device *pdev) 44static int __devexit ads117x_remove(struct platform_device *pdev)
95{ 45{
96 snd_soc_unregister_dai(&ads117x_dai); 46 snd_soc_unregister_codec(&pdev->dev);
97 return 0; 47 return 0;
98} 48}
99 49
100static struct platform_driver ads117x_codec_driver = { 50static struct platform_driver ads117x_codec_driver = {
101 .driver = { 51 .driver = {
102 .name = "ads117x", 52 .name = "ads117x-codec",
103 .owner = THIS_MODULE, 53 .owner = THIS_MODULE,
104 }, 54 },
105 55
106 .probe = ads117x_platform_probe, 56 .probe = ads117x_probe,
107 .remove = __devexit_p(ads117x_platform_remove), 57 .remove = __devexit_p(ads117x_remove),
108}; 58};
109 59
110static int __init ads117x_init(void) 60static int __init ads117x_init(void)
diff --git a/sound/soc/codecs/ads117x.h b/sound/soc/codecs/ads117x.h
index dbcf50ec9bd..3ce02861400 100644
--- a/sound/soc/codecs/ads117x.h
+++ b/sound/soc/codecs/ads117x.h
@@ -9,5 +9,5 @@
9 * Free Software Foundation; either version 2 of the License, or (at your 9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. 10 * option) any later version.
11 */ 11 */
12extern struct snd_soc_dai ads117x_dai; 12extern struct snd_soc_dai_driver ads117x_dai;
13extern struct snd_soc_codec_device soc_codec_dev_ads117x; 13extern struct snd_soc_codec_driver soc_codec_dev_ads117x;
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 192aebda302..c27f8f59dc6 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -17,8 +17,6 @@
17#include <linux/spi/spi.h> 17#include <linux/spi/spi.h>
18#include <sound/asoundef.h> 18#include <sound/asoundef.h>
19 19
20#include "ak4104.h"
21
22/* AK4104 registers addresses */ 20/* AK4104 registers addresses */
23#define AK4104_REG_CONTROL1 0x00 21#define AK4104_REG_CONTROL1 0x00
24#define AK4104_REG_RESERVED 0x01 22#define AK4104_REG_RESERVED 0x01
@@ -45,11 +43,11 @@
45#define AK4104_TX_TXE (1 << 0) 43#define AK4104_TX_TXE (1 << 0)
46#define AK4104_TX_V (1 << 1) 44#define AK4104_TX_V (1 << 1)
47 45
48#define DRV_NAME "ak4104" 46#define DRV_NAME "ak4104-codec"
49 47
50struct ak4104_private { 48struct ak4104_private {
51 struct snd_soc_codec codec; 49 enum snd_soc_control_type control_type;
52 u8 reg_cache[AK4104_NUM_REGS]; 50 void *control_data;
53}; 51};
54 52
55static int ak4104_fill_cache(struct snd_soc_codec *codec) 53static int ak4104_fill_cache(struct snd_soc_codec *codec)
@@ -58,7 +56,7 @@ static int ak4104_fill_cache(struct snd_soc_codec *codec)
58 u8 *reg_cache = codec->reg_cache; 56 u8 *reg_cache = codec->reg_cache;
59 struct spi_device *spi = codec->control_data; 57 struct spi_device *spi = codec->control_data;
60 58
61 for (i = 0; i < codec->reg_cache_size; i++) { 59 for (i = 0; i < codec->driver->reg_cache_size; i++) {
62 int ret = spi_w8r8(spi, i | AK4104_READ); 60 int ret = spi_w8r8(spi, i | AK4104_READ);
63 if (ret < 0) { 61 if (ret < 0) {
64 dev_err(&spi->dev, "SPI write failure\n"); 62 dev_err(&spi->dev, "SPI write failure\n");
@@ -76,7 +74,7 @@ static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec,
76{ 74{
77 u8 *reg_cache = codec->reg_cache; 75 u8 *reg_cache = codec->reg_cache;
78 76
79 if (reg >= codec->reg_cache_size) 77 if (reg >= codec->driver->reg_cache_size)
80 return -EINVAL; 78 return -EINVAL;
81 79
82 return reg_cache[reg]; 80 return reg_cache[reg];
@@ -88,7 +86,7 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
88 u8 *cache = codec->reg_cache; 86 u8 *cache = codec->reg_cache;
89 struct spi_device *spi = codec->control_data; 87 struct spi_device *spi = codec->control_data;
90 88
91 if (reg >= codec->reg_cache_size) 89 if (reg >= codec->driver->reg_cache_size)
92 return -EINVAL; 90 return -EINVAL;
93 91
94 /* only write to the hardware if value has changed */ 92 /* only write to the hardware if value has changed */
@@ -145,8 +143,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
145 struct snd_soc_dai *dai) 143 struct snd_soc_dai *dai)
146{ 144{
147 struct snd_soc_pcm_runtime *rtd = substream->private_data; 145 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct snd_soc_device *socdev = rtd->socdev; 146 struct snd_soc_codec *codec = rtd->codec;
149 struct snd_soc_codec *codec = socdev->card->codec;
150 int val = 0; 147 int val = 0;
151 148
152 /* set the IEC958 bits: consumer mode, no copyright bit */ 149 /* set the IEC958 bits: consumer mode, no copyright bit */
@@ -178,8 +175,8 @@ static struct snd_soc_dai_ops ak4101_dai_ops = {
178 .set_fmt = ak4104_set_dai_fmt, 175 .set_fmt = ak4104_set_dai_fmt,
179}; 176};
180 177
181struct snd_soc_dai ak4104_dai = { 178static struct snd_soc_dai_driver ak4104_dai = {
182 .name = DRV_NAME, 179 .name = "ak4104-hifi",
183 .playback = { 180 .playback = {
184 .stream_name = "Playback", 181 .stream_name = "Playback",
185 .channels_min = 2, 182 .channels_min = 2,
@@ -192,45 +189,17 @@ struct snd_soc_dai ak4104_dai = {
192 .ops = &ak4101_dai_ops, 189 .ops = &ak4101_dai_ops,
193}; 190};
194 191
195static struct snd_soc_codec *ak4104_codec; 192static int ak4104_probe(struct snd_soc_codec *codec)
196
197static int ak4104_spi_probe(struct spi_device *spi)
198{ 193{
199 struct snd_soc_codec *codec; 194 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
200 struct ak4104_private *ak4104;
201 int ret, val; 195 int ret, val;
202 196
203 spi->bits_per_word = 8; 197 codec->control_data = ak4104->control_data;
204 spi->mode = SPI_MODE_0;
205 ret = spi_setup(spi);
206 if (ret < 0)
207 return ret;
208
209 ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
210 if (!ak4104) {
211 dev_err(&spi->dev, "could not allocate codec\n");
212 return -ENOMEM;
213 }
214
215 codec = &ak4104->codec;
216 mutex_init(&codec->mutex);
217 INIT_LIST_HEAD(&codec->dapm_widgets);
218 INIT_LIST_HEAD(&codec->dapm_paths);
219
220 codec->dev = &spi->dev;
221 codec->name = DRV_NAME;
222 codec->owner = THIS_MODULE;
223 codec->dai = &ak4104_dai;
224 codec->num_dai = 1;
225 snd_soc_codec_set_drvdata(codec, ak4104);
226 codec->control_data = spi;
227 codec->reg_cache = ak4104->reg_cache;
228 codec->reg_cache_size = AK4104_NUM_REGS;
229 198
230 /* read all regs and fill the cache */ 199 /* read all regs and fill the cache */
231 ret = ak4104_fill_cache(codec); 200 ret = ak4104_fill_cache(codec);
232 if (ret < 0) { 201 if (ret < 0) {
233 dev_err(&spi->dev, "failed to fill register cache\n"); 202 dev_err(codec->dev, "failed to fill register cache\n");
234 return ret; 203 return ret;
235 } 204 }
236 205
@@ -238,93 +207,81 @@ static int ak4104_spi_probe(struct spi_device *spi)
238 * should contain 0x5b. Not a good way to verify the presence of 207 * should contain 0x5b. Not a good way to verify the presence of
239 * the device, but there is no hardware ID register. */ 208 * the device, but there is no hardware ID register. */
240 if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) != 209 if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) !=
241 AK4104_RESERVED_VAL) { 210 AK4104_RESERVED_VAL)
242 ret = -ENODEV; 211 return -ENODEV;
243 goto error_free_codec;
244 }
245 212
246 /* set power-up and non-reset bits */ 213 /* set power-up and non-reset bits */
247 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); 214 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
248 val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN; 215 val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN;
249 ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); 216 ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
250 if (ret < 0) 217 if (ret < 0)
251 goto error_free_codec; 218 return ret;
252 219
253 /* enable transmitter */ 220 /* enable transmitter */
254 val = ak4104_read_reg_cache(codec, AK4104_REG_TX); 221 val = ak4104_read_reg_cache(codec, AK4104_REG_TX);
255 val |= AK4104_TX_TXE; 222 val |= AK4104_TX_TXE;
256 ret = ak4104_spi_write(codec, AK4104_REG_TX, val); 223 ret = ak4104_spi_write(codec, AK4104_REG_TX, val);
257 if (ret < 0) 224 if (ret < 0)
258 goto error_free_codec; 225 return ret;
259
260 ak4104_codec = codec;
261 ret = snd_soc_register_dai(&ak4104_dai);
262 if (ret < 0) {
263 dev_err(&spi->dev, "failed to register DAI\n");
264 goto error_free_codec;
265 }
266 226
267 spi_set_drvdata(spi, ak4104); 227 dev_info(codec->dev, "SPI device initialized\n");
268 dev_info(&spi->dev, "SPI device initialized\n");
269 return 0; 228 return 0;
270
271error_free_codec:
272 kfree(ak4104);
273 ak4104_dai.dev = NULL;
274 return ret;
275} 229}
276 230
277static int __devexit ak4104_spi_remove(struct spi_device *spi) 231static int ak4104_remove(struct snd_soc_codec *codec)
278{ 232{
279 int ret, val; 233 int val, ret;
280 struct ak4104_private *ak4104 = spi_get_drvdata(spi);
281 234
282 val = ak4104_read_reg_cache(&ak4104->codec, AK4104_REG_CONTROL1); 235 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
283 if (val < 0) 236 if (val < 0)
284 return val; 237 return val;
285 238
286 /* clear power-up and non-reset bits */ 239 /* clear power-up and non-reset bits */
287 val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); 240 val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
288 ret = ak4104_spi_write(&ak4104->codec, AK4104_REG_CONTROL1, val); 241 ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
289 if (ret < 0)
290 return ret;
291 242
292 ak4104_codec = NULL; 243 return ret;
293 kfree(ak4104);
294 return 0;
295} 244}
296 245
297static int ak4104_probe(struct platform_device *pdev) 246static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
247 .probe = ak4104_probe,
248 .remove = ak4104_remove,
249 .reg_cache_size = AK4104_NUM_REGS,
250 .reg_word_size = sizeof(u16),
251};
252
253static int ak4104_spi_probe(struct spi_device *spi)
298{ 254{
299 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 255 struct ak4104_private *ak4104;
300 struct snd_soc_codec *codec = ak4104_codec;
301 int ret; 256 int ret;
302 257
303 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ 258 spi->bits_per_word = 8;
304 socdev->card->codec = codec; 259 spi->mode = SPI_MODE_0;
305 260 ret = spi_setup(spi);
306 /* Register PCMs */ 261 if (ret < 0)
307 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
308 if (ret < 0) {
309 dev_err(codec->dev, "failed to create pcms\n");
310 return ret; 262 return ret;
311 }
312 263
313 return 0; 264 ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
265 if (ak4104 == NULL)
266 return -ENOMEM;
267
268 ak4104->control_data = spi;
269 ak4104->control_type = SND_SOC_SPI;
270 spi_set_drvdata(spi, ak4104);
271
272 ret = snd_soc_register_codec(&spi->dev,
273 &soc_codec_device_ak4104, &ak4104_dai, 1);
274 if (ret < 0)
275 kfree(ak4104);
276 return ret;
314} 277}
315 278
316static int ak4104_remove(struct platform_device *pdev) 279static int __devexit ak4104_spi_remove(struct spi_device *spi)
317{ 280{
318 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 281 snd_soc_unregister_codec(&spi->dev);
319 snd_soc_free_pcms(socdev); 282 kfree(spi_get_drvdata(spi));
320 return 0; 283 return 0;
321}; 284}
322
323struct snd_soc_codec_device soc_codec_device_ak4104 = {
324 .probe = ak4104_probe,
325 .remove = ak4104_remove
326};
327EXPORT_SYMBOL_GPL(soc_codec_device_ak4104);
328 285
329static struct spi_driver ak4104_spi_driver = { 286static struct spi_driver ak4104_spi_driver = {
330 .driver = { 287 .driver = {
diff --git a/sound/soc/codecs/ak4104.h b/sound/soc/codecs/ak4104.h
deleted file mode 100644
index eb88fe7e4de..00000000000
--- a/sound/soc/codecs/ak4104.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef _AK4104_H
2#define _AK4104_H
3
4extern struct snd_soc_dai ak4104_dai;
5extern struct snd_soc_codec_device soc_codec_device_ak4104;
6
7#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index d4253675b2d..cd88c8f32a3 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -31,11 +31,11 @@
31 31
32#define AK4535_VERSION "0.3" 32#define AK4535_VERSION "0.3"
33 33
34struct snd_soc_codec_device soc_codec_dev_ak4535;
35
36/* codec private data */ 34/* codec private data */
37struct ak4535_priv { 35struct ak4535_priv {
38 unsigned int sysclk; 36 unsigned int sysclk;
37 enum snd_soc_control_type control_type;
38 void *control_data;
39}; 39};
40 40
41/* 41/*
@@ -313,8 +313,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
313 struct snd_soc_dai *dai) 313 struct snd_soc_dai *dai)
314{ 314{
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_codec *codec = rtd->codec;
317 struct snd_soc_codec *codec = socdev->card->codec;
318 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 317 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
319 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); 318 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5);
320 int rate = params_rate(params), fs = 256; 319 int rate = params_rate(params), fs = 256;
@@ -378,14 +377,16 @@ static int ak4535_mute(struct snd_soc_dai *dai, int mute)
378static int ak4535_set_bias_level(struct snd_soc_codec *codec, 377static int ak4535_set_bias_level(struct snd_soc_codec *codec,
379 enum snd_soc_bias_level level) 378 enum snd_soc_bias_level level)
380{ 379{
381 u16 i; 380 u16 i, mute_reg;
382 381
383 switch (level) { 382 switch (level) {
384 case SND_SOC_BIAS_ON: 383 case SND_SOC_BIAS_ON:
385 ak4535_mute(codec->dai, 0); 384 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
385 ak4535_write(codec, AK4535_DAC, mute_reg);
386 break; 386 break;
387 case SND_SOC_BIAS_PREPARE: 387 case SND_SOC_BIAS_PREPARE:
388 ak4535_mute(codec->dai, 1); 388 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
389 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
389 break; 390 break;
390 case SND_SOC_BIAS_STANDBY: 391 case SND_SOC_BIAS_STANDBY:
391 i = ak4535_read_reg_cache(codec, AK4535_PM1); 392 i = ak4535_read_reg_cache(codec, AK4535_PM1);
@@ -413,8 +414,8 @@ static struct snd_soc_dai_ops ak4535_dai_ops = {
413 .set_sysclk = ak4535_set_dai_sysclk, 414 .set_sysclk = ak4535_set_dai_sysclk,
414}; 415};
415 416
416struct snd_soc_dai ak4535_dai = { 417static struct snd_soc_dai_driver ak4535_dai = {
417 .name = "AK4535", 418 .name = "ak4535-hifi",
418 .playback = { 419 .playback = {
419 .stream_name = "Playback", 420 .stream_name = "Playback",
420 .channels_min = 1, 421 .channels_min = 1,
@@ -429,54 +430,27 @@ struct snd_soc_dai ak4535_dai = {
429 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 430 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
430 .ops = &ak4535_dai_ops, 431 .ops = &ak4535_dai_ops,
431}; 432};
432EXPORT_SYMBOL_GPL(ak4535_dai);
433 433
434static int ak4535_suspend(struct platform_device *pdev, pm_message_t state) 434static int ak4535_suspend(struct snd_soc_codec *codec, pm_message_t state)
435{ 435{
436 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
437 struct snd_soc_codec *codec = socdev->card->codec;
438
439 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); 436 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
440 return 0; 437 return 0;
441} 438}
442 439
443static int ak4535_resume(struct platform_device *pdev) 440static int ak4535_resume(struct snd_soc_codec *codec)
444{ 441{
445 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
446 struct snd_soc_codec *codec = socdev->card->codec;
447 ak4535_sync(codec); 442 ak4535_sync(codec);
448 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 443 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
449 return 0; 444 return 0;
450} 445}
451 446
452/* 447static int ak4535_probe(struct snd_soc_codec *codec)
453 * initialise the AK4535 driver
454 * register the mixer and dsp interfaces with the kernel
455 */
456static int ak4535_init(struct snd_soc_device *socdev)
457{ 448{
458 struct snd_soc_codec *codec = socdev->card->codec; 449 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
459 int ret = 0;
460 450
461 codec->name = "AK4535"; 451 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
462 codec->owner = THIS_MODULE;
463 codec->read = ak4535_read_reg_cache;
464 codec->write = ak4535_write;
465 codec->set_bias_level = ak4535_set_bias_level;
466 codec->dai = &ak4535_dai;
467 codec->num_dai = 1;
468 codec->reg_cache_size = ARRAY_SIZE(ak4535_reg);
469 codec->reg_cache = kmemdup(ak4535_reg, sizeof(ak4535_reg), GFP_KERNEL);
470
471 if (codec->reg_cache == NULL)
472 return -ENOMEM;
473 452
474 /* register pcms */ 453 codec->control_data = ak4535->control_data;
475 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
476 if (ret < 0) {
477 printk(KERN_ERR "ak4535: failed to create pcms\n");
478 goto pcm_err;
479 }
480 454
481 /* power on device */ 455 /* power on device */
482 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 456 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -485,39 +459,55 @@ static int ak4535_init(struct snd_soc_device *socdev)
485 ARRAY_SIZE(ak4535_snd_controls)); 459 ARRAY_SIZE(ak4535_snd_controls));
486 ak4535_add_widgets(codec); 460 ak4535_add_widgets(codec);
487 461
488 return ret; 462 return 0;
489 463}
490pcm_err:
491 kfree(codec->reg_cache);
492 464
493 return ret; 465/* power down chip */
466static int ak4535_remove(struct snd_soc_codec *codec)
467{
468 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
469 return 0;
494} 470}
495 471
496static struct snd_soc_device *ak4535_socdev; 472static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
473 .probe = ak4535_probe,
474 .remove = ak4535_remove,
475 .suspend = ak4535_suspend,
476 .resume = ak4535_resume,
477 .read = ak4535_read_reg_cache,
478 .write = ak4535_write,
479 .set_bias_level = ak4535_set_bias_level,
480 .reg_cache_size = ARRAY_SIZE(ak4535_reg),
481 .reg_word_size = sizeof(u8),
482 .reg_cache_default = ak4535_reg,
483};
497 484
498#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 485#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
499 486static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
500static int ak4535_i2c_probe(struct i2c_client *i2c, 487 const struct i2c_device_id *id)
501 const struct i2c_device_id *id)
502{ 488{
503 struct snd_soc_device *socdev = ak4535_socdev; 489 struct ak4535_priv *ak4535;
504 struct snd_soc_codec *codec = socdev->card->codec;
505 int ret; 490 int ret;
506 491
507 i2c_set_clientdata(i2c, codec); 492 ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
508 codec->control_data = i2c; 493 if (ak4535 == NULL)
494 return -ENOMEM;
509 495
510 ret = ak4535_init(socdev); 496 i2c_set_clientdata(i2c, ak4535);
511 if (ret < 0) 497 ak4535->control_data = i2c;
512 printk(KERN_ERR "failed to initialise AK4535\n"); 498 ak4535->control_type = SND_SOC_I2C;
513 499
500 ret = snd_soc_register_codec(&i2c->dev,
501 &soc_codec_dev_ak4535, &ak4535_dai, 1);
502 if (ret < 0)
503 kfree(ak4535);
514 return ret; 504 return ret;
515} 505}
516 506
517static int ak4535_i2c_remove(struct i2c_client *client) 507static __devexit int ak4535_i2c_remove(struct i2c_client *client)
518{ 508{
519 struct snd_soc_codec *codec = i2c_get_clientdata(client); 509 snd_soc_unregister_codec(&client->dev);
520 kfree(codec->reg_cache); 510 kfree(i2c_get_clientdata(client));
521 return 0; 511 return 0;
522} 512}
523 513
@@ -529,138 +519,34 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
529 519
530static struct i2c_driver ak4535_i2c_driver = { 520static struct i2c_driver ak4535_i2c_driver = {
531 .driver = { 521 .driver = {
532 .name = "AK4535 I2C Codec", 522 .name = "ak4535-codec",
533 .owner = THIS_MODULE, 523 .owner = THIS_MODULE,
534 }, 524 },
535 .probe = ak4535_i2c_probe, 525 .probe = ak4535_i2c_probe,
536 .remove = ak4535_i2c_remove, 526 .remove = __devexit_p(ak4535_i2c_remove),
537 .id_table = ak4535_i2c_id, 527 .id_table = ak4535_i2c_id,
538}; 528};
539
540static int ak4535_add_i2c_device(struct platform_device *pdev,
541 const struct ak4535_setup_data *setup)
542{
543 struct i2c_board_info info;
544 struct i2c_adapter *adapter;
545 struct i2c_client *client;
546 int ret;
547
548 ret = i2c_add_driver(&ak4535_i2c_driver);
549 if (ret != 0) {
550 dev_err(&pdev->dev, "can't add i2c driver\n");
551 return ret;
552 }
553
554 memset(&info, 0, sizeof(struct i2c_board_info));
555 info.addr = setup->i2c_address;
556 strlcpy(info.type, "ak4535", I2C_NAME_SIZE);
557
558 adapter = i2c_get_adapter(setup->i2c_bus);
559 if (!adapter) {
560 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
561 setup->i2c_bus);
562 goto err_driver;
563 }
564
565 client = i2c_new_device(adapter, &info);
566 i2c_put_adapter(adapter);
567 if (!client) {
568 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
569 (unsigned int)info.addr);
570 goto err_driver;
571 }
572
573 return 0;
574
575err_driver:
576 i2c_del_driver(&ak4535_i2c_driver);
577 return -ENODEV;
578}
579#endif 529#endif
580 530
581static int ak4535_probe(struct platform_device *pdev) 531static int __init ak4535_modinit(void)
582{ 532{
583 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 533 int ret = 0;
584 struct ak4535_setup_data *setup;
585 struct snd_soc_codec *codec;
586 struct ak4535_priv *ak4535;
587 int ret;
588
589 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
590
591 setup = socdev->codec_data;
592 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
593 if (codec == NULL)
594 return -ENOMEM;
595
596 ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
597 if (ak4535 == NULL) {
598 kfree(codec);
599 return -ENOMEM;
600 }
601
602 snd_soc_codec_set_drvdata(codec, ak4535);
603 socdev->card->codec = codec;
604 mutex_init(&codec->mutex);
605 INIT_LIST_HEAD(&codec->dapm_widgets);
606 INIT_LIST_HEAD(&codec->dapm_paths);
607
608 ak4535_socdev = socdev;
609 ret = -ENODEV;
610
611#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 534#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
612 if (setup->i2c_address) { 535 ret = i2c_add_driver(&ak4535_i2c_driver);
613 codec->hw_write = (hw_write_t)i2c_master_send;
614 ret = ak4535_add_i2c_device(pdev, setup);
615 }
616#endif
617
618 if (ret != 0) { 536 if (ret != 0) {
619 kfree(snd_soc_codec_get_drvdata(codec)); 537 printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n",
620 kfree(codec); 538 ret);
621 } 539 }
540#endif
622 return ret; 541 return ret;
623} 542}
543module_init(ak4535_modinit);
624 544
625/* power down chip */ 545static void __exit ak4535_exit(void)
626static int ak4535_remove(struct platform_device *pdev)
627{ 546{
628 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
629 struct snd_soc_codec *codec = socdev->card->codec;
630
631 if (codec->control_data)
632 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
633
634 snd_soc_free_pcms(socdev);
635 snd_soc_dapm_free(socdev);
636#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 547#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
637 if (codec->control_data)
638 i2c_unregister_device(codec->control_data);
639 i2c_del_driver(&ak4535_i2c_driver); 548 i2c_del_driver(&ak4535_i2c_driver);
640#endif 549#endif
641 kfree(snd_soc_codec_get_drvdata(codec));
642 kfree(codec);
643
644 return 0;
645}
646
647struct snd_soc_codec_device soc_codec_dev_ak4535 = {
648 .probe = ak4535_probe,
649 .remove = ak4535_remove,
650 .suspend = ak4535_suspend,
651 .resume = ak4535_resume,
652};
653EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535);
654
655static int __init ak4535_modinit(void)
656{
657 return snd_soc_register_dai(&ak4535_dai);
658}
659module_init(ak4535_modinit);
660
661static void __exit ak4535_exit(void)
662{
663 snd_soc_unregister_dai(&ak4535_dai);
664} 550}
665module_exit(ak4535_exit); 551module_exit(ak4535_exit);
666 552
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h
index c7a58703ea3..0431e5f634a 100644
--- a/sound/soc/codecs/ak4535.h
+++ b/sound/soc/codecs/ak4535.h
@@ -36,12 +36,4 @@
36 36
37#define AK4535_CACHEREGNUM 0x10 37#define AK4535_CACHEREGNUM 0x10
38 38
39struct ak4535_setup_data {
40 int i2c_bus;
41 unsigned short i2c_address;
42};
43
44extern struct snd_soc_dai ak4535_dai;
45extern struct snd_soc_codec_device soc_codec_dev_ak4535;
46
47#endif 39#endif
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 3d7dc55305e..31b35e96739 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -30,8 +30,6 @@
30#include <sound/initval.h> 30#include <sound/initval.h>
31#include <sound/tlv.h> 31#include <sound/tlv.h>
32 32
33#include "ak4642.h"
34
35#define AK4642_VERSION "0.0.1" 33#define AK4642_VERSION "0.0.1"
36 34
37#define PW_MGMT1 0x00 35#define PW_MGMT1 0x00
@@ -102,7 +100,6 @@
102#define FS3 (1 << 5) 100#define FS3 (1 << 5)
103#define FS_MASK (FS0 | FS1 | FS2 | FS3) 101#define FS_MASK (FS0 | FS1 | FS2 | FS3)
104 102
105struct snd_soc_codec_device soc_codec_dev_ak4642;
106 103
107/* 104/*
108 * Playback Volume (table 39) 105 * Playback Volume (table 39)
@@ -123,11 +120,11 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
123 120
124/* codec private data */ 121/* codec private data */
125struct ak4642_priv { 122struct ak4642_priv {
126 struct snd_soc_codec codec; 123 unsigned int sysclk;
124 enum snd_soc_control_type control_type;
125 void *control_data;
127}; 126};
128 127
129static struct snd_soc_codec *ak4642_codec;
130
131/* 128/*
132 * ak4642 register cache 129 * ak4642 register cache
133 */ 130 */
@@ -393,8 +390,8 @@ static struct snd_soc_dai_ops ak4642_dai_ops = {
393 .hw_params = ak4642_dai_hw_params, 390 .hw_params = ak4642_dai_hw_params,
394}; 391};
395 392
396struct snd_soc_dai ak4642_dai = { 393static struct snd_soc_dai_driver ak4642_dai = {
397 .name = "AK4642", 394 .name = "ak4642-hifi",
398 .playback = { 395 .playback = {
399 .stream_name = "Playback", 396 .stream_name = "Playback",
400 .channels_min = 1, 397 .channels_min = 1,
@@ -410,112 +407,63 @@ struct snd_soc_dai ak4642_dai = {
410 .ops = &ak4642_dai_ops, 407 .ops = &ak4642_dai_ops,
411 .symmetric_rates = 1, 408 .symmetric_rates = 1,
412}; 409};
413EXPORT_SYMBOL_GPL(ak4642_dai);
414 410
415static int ak4642_resume(struct platform_device *pdev) 411static int ak4642_resume(struct snd_soc_codec *codec)
416{ 412{
417 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
418 struct snd_soc_codec *codec = socdev->card->codec;
419
420 ak4642_sync(codec); 413 ak4642_sync(codec);
421 return 0; 414 return 0;
422} 415}
423 416
424/* 417
425 * initialise the AK4642 driver 418static int ak4642_probe(struct snd_soc_codec *codec)
426 * register the mixer and dsp interfaces with the kernel
427 */
428static int ak4642_init(struct ak4642_priv *ak4642)
429{ 419{
430 struct snd_soc_codec *codec = &ak4642->codec; 420 struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
431 int ret = 0;
432 421
433 if (ak4642_codec) { 422 dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
434 dev_err(codec->dev, "Another ak4642 is registered\n");
435 return -EINVAL;
436 }
437 423
438 mutex_init(&codec->mutex);
439 INIT_LIST_HEAD(&codec->dapm_widgets);
440 INIT_LIST_HEAD(&codec->dapm_paths);
441
442 snd_soc_codec_set_drvdata(codec, ak4642);
443 codec->name = "AK4642";
444 codec->owner = THIS_MODULE;
445 codec->read = ak4642_read_reg_cache;
446 codec->write = ak4642_write;
447 codec->dai = &ak4642_dai;
448 codec->num_dai = 1;
449 codec->hw_write = (hw_write_t)i2c_master_send; 424 codec->hw_write = (hw_write_t)i2c_master_send;
450 codec->reg_cache_size = ARRAY_SIZE(ak4642_reg); 425 codec->control_data = ak4642->control_data;
451 codec->reg_cache = kmemdup(ak4642_reg,
452 sizeof(ak4642_reg), GFP_KERNEL);
453
454 if (!codec->reg_cache)
455 return -ENOMEM;
456
457 ak4642_dai.dev = codec->dev;
458 ak4642_codec = codec;
459
460 ret = snd_soc_register_codec(codec);
461 if (ret) {
462 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
463 goto reg_cache_err;
464 }
465 426
466 ret = snd_soc_register_dai(&ak4642_dai);
467 if (ret) {
468 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
469 snd_soc_unregister_codec(codec);
470 goto reg_cache_err;
471 }
472
473 return ret;
474
475reg_cache_err:
476 kfree(codec->reg_cache);
477 codec->reg_cache = NULL;
478 427
479 return ret; 428 return 0;
480} 429}
481 430
431static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
432 .probe = ak4642_probe,
433 .resume = ak4642_resume,
434 .read = ak4642_read_reg_cache,
435 .write = ak4642_write,
436 .reg_cache_size = ARRAY_SIZE(ak4642_reg),
437 .reg_word_size = sizeof(u8),
438 .reg_cache_default = ak4642_reg,
439};
440
482#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 441#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
483static int ak4642_i2c_probe(struct i2c_client *i2c, 442static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
484 const struct i2c_device_id *id) 443 const struct i2c_device_id *id)
485{ 444{
486 struct ak4642_priv *ak4642; 445 struct ak4642_priv *ak4642;
487 struct snd_soc_codec *codec;
488 int ret; 446 int ret;
489 447
490 ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL); 448 ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL);
491 if (!ak4642) 449 if (ak4642 == NULL)
492 return -ENOMEM; 450 return -ENOMEM;
493 451
494 codec = &ak4642->codec;
495 codec->dev = &i2c->dev;
496
497 i2c_set_clientdata(i2c, ak4642); 452 i2c_set_clientdata(i2c, ak4642);
498 codec->control_data = i2c; 453 ak4642->control_data = i2c;
454 ak4642->control_type = SND_SOC_I2C;
499 455
500 ret = ak4642_init(ak4642); 456 ret = snd_soc_register_codec(&i2c->dev,
501 if (ret < 0) { 457 &soc_codec_dev_ak4642, &ak4642_dai, 1);
502 printk(KERN_ERR "failed to initialise AK4642\n"); 458 if (ret < 0)
503 kfree(ak4642); 459 kfree(ak4642);
504 }
505
506 return ret; 460 return ret;
507} 461}
508 462
509static int ak4642_i2c_remove(struct i2c_client *client) 463static __devexit int ak4642_i2c_remove(struct i2c_client *client)
510{ 464{
511 struct ak4642_priv *ak4642 = i2c_get_clientdata(client); 465 snd_soc_unregister_codec(&client->dev);
512 466 kfree(i2c_get_clientdata(client));
513 snd_soc_unregister_dai(&ak4642_dai);
514 snd_soc_unregister_codec(&ak4642->codec);
515 kfree(ak4642->codec.reg_cache);
516 kfree(ak4642);
517 ak4642_codec = NULL;
518
519 return 0; 467 return 0;
520} 468}
521 469
@@ -528,64 +476,15 @@ MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
528 476
529static struct i2c_driver ak4642_i2c_driver = { 477static struct i2c_driver ak4642_i2c_driver = {
530 .driver = { 478 .driver = {
531 .name = "AK4642 I2C Codec", 479 .name = "ak4642-codec",
532 .owner = THIS_MODULE, 480 .owner = THIS_MODULE,
533 }, 481 },
534 .probe = ak4642_i2c_probe, 482 .probe = ak4642_i2c_probe,
535 .remove = ak4642_i2c_remove, 483 .remove = __devexit_p(ak4642_i2c_remove),
536 .id_table = ak4642_i2c_id, 484 .id_table = ak4642_i2c_id,
537}; 485};
538
539#endif 486#endif
540 487
541static int ak4642_probe(struct platform_device *pdev)
542{
543 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
544 int ret;
545
546 if (!ak4642_codec) {
547 dev_err(&pdev->dev, "Codec device not registered\n");
548 return -ENODEV;
549 }
550
551 socdev->card->codec = ak4642_codec;
552
553 /* register pcms */
554 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
555 if (ret < 0) {
556 printk(KERN_ERR "ak4642: failed to create pcms\n");
557 goto pcm_err;
558 }
559
560 snd_soc_add_controls(ak4642_codec, ak4642_snd_controls,
561 ARRAY_SIZE(ak4642_snd_controls));
562
563 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
564 return ret;
565
566pcm_err:
567 return ret;
568
569}
570
571/* power down chip */
572static int ak4642_remove(struct platform_device *pdev)
573{
574 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
575
576 snd_soc_free_pcms(socdev);
577 snd_soc_dapm_free(socdev);
578
579 return 0;
580}
581
582struct snd_soc_codec_device soc_codec_dev_ak4642 = {
583 .probe = ak4642_probe,
584 .remove = ak4642_remove,
585 .resume = ak4642_resume,
586};
587EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642);
588
589static int __init ak4642_modinit(void) 488static int __init ak4642_modinit(void)
590{ 489{
591 int ret = 0; 490 int ret = 0;
diff --git a/sound/soc/codecs/ak4642.h b/sound/soc/codecs/ak4642.h
deleted file mode 100644
index e476833d314..00000000000
--- a/sound/soc/codecs/ak4642.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * ak4642.h -- AK4642 Soc Audio driver
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * Based on ak4535.c
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#ifndef _AK4642_H
15#define _AK4642_H
16
17extern struct snd_soc_dai ak4642_dai;
18extern struct snd_soc_codec_device soc_codec_dev_ak4642;
19
20#endif
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 87566932a3b..239f0562003 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -23,11 +23,11 @@
23 23
24#include "ak4671.h" 24#include "ak4671.h"
25 25
26static struct snd_soc_codec *ak4671_codec;
27 26
28/* codec private data */ 27/* codec private data */
29struct ak4671_priv { 28struct ak4671_priv {
30 struct snd_soc_codec codec; 29 enum snd_soc_control_type control_type;
30 void *control_data;
31 u8 reg_cache[AK4671_CACHEREGNUM]; 31 u8 reg_cache[AK4671_CACHEREGNUM];
32}; 32};
33 33
@@ -619,8 +619,8 @@ static struct snd_soc_dai_ops ak4671_dai_ops = {
619 .set_fmt = ak4671_set_dai_fmt, 619 .set_fmt = ak4671_set_dai_fmt,
620}; 620};
621 621
622struct snd_soc_dai ak4671_dai = { 622static struct snd_soc_dai_driver ak4671_dai = {
623 .name = "AK4671", 623 .name = "ak4671-hifi",
624 .playback = { 624 .playback = {
625 .stream_name = "Playback", 625 .stream_name = "Playback",
626 .channels_min = 1, 626 .channels_min = 1,
@@ -635,27 +635,19 @@ struct snd_soc_dai ak4671_dai = {
635 .formats = AK4671_FORMATS,}, 635 .formats = AK4671_FORMATS,},
636 .ops = &ak4671_dai_ops, 636 .ops = &ak4671_dai_ops,
637}; 637};
638EXPORT_SYMBOL_GPL(ak4671_dai);
639 638
640static int ak4671_probe(struct platform_device *pdev) 639static int ak4671_probe(struct snd_soc_codec *codec)
641{ 640{
642 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 641 struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
643 struct snd_soc_codec *codec; 642 int ret;
644 int ret = 0;
645
646 if (ak4671_codec == NULL) {
647 dev_err(&pdev->dev, "Codec device not registered\n");
648 return -ENODEV;
649 }
650 643
651 socdev->card->codec = ak4671_codec; 644 codec->hw_write = (hw_write_t)i2c_master_send;
652 codec = ak4671_codec; 645 codec->bias_level = SND_SOC_BIAS_OFF;
653 646
654 /* register pcms */ 647 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
655 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
656 if (ret < 0) { 648 if (ret < 0) {
657 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 649 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
658 goto pcm_err; 650 return ret;
659 } 651 }
660 652
661 snd_soc_add_controls(codec, ak4671_snd_controls, 653 snd_soc_add_controls(codec, ak4671_snd_controls,
@@ -665,121 +657,48 @@ static int ak4671_probe(struct platform_device *pdev)
665 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 657 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
666 658
667 return ret; 659 return ret;
668
669pcm_err:
670 return ret;
671} 660}
672 661
673static int ak4671_remove(struct platform_device *pdev) 662static int ak4671_remove(struct snd_soc_codec *codec)
674{ 663{
675 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 664 ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF);
676
677 snd_soc_free_pcms(socdev);
678 snd_soc_dapm_free(socdev);
679
680 return 0; 665 return 0;
681} 666}
682 667
683struct snd_soc_codec_device soc_codec_dev_ak4671 = { 668static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
684 .probe = ak4671_probe, 669 .probe = ak4671_probe,
685 .remove = ak4671_remove, 670 .remove = ak4671_remove,
671 .set_bias_level = ak4671_set_bias_level,
672 .reg_cache_size = AK4671_CACHEREGNUM,
673 .reg_word_size = sizeof(u8),
674 .reg_cache_default = ak4671_reg,
686}; 675};
687EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671);
688
689static int ak4671_register(struct ak4671_priv *ak4671,
690 enum snd_soc_control_type control)
691{
692 int ret;
693 struct snd_soc_codec *codec = &ak4671->codec;
694
695 if (ak4671_codec) {
696 dev_err(codec->dev, "Another AK4671 is registered\n");
697 ret = -EINVAL;
698 goto err;
699 }
700
701 mutex_init(&codec->mutex);
702 INIT_LIST_HEAD(&codec->dapm_widgets);
703 INIT_LIST_HEAD(&codec->dapm_paths);
704
705 snd_soc_codec_set_drvdata(codec, ak4671);
706 codec->name = "AK4671";
707 codec->owner = THIS_MODULE;
708 codec->bias_level = SND_SOC_BIAS_OFF;
709 codec->set_bias_level = ak4671_set_bias_level;
710 codec->dai = &ak4671_dai;
711 codec->num_dai = 1;
712 codec->reg_cache_size = AK4671_CACHEREGNUM;
713 codec->reg_cache = &ak4671->reg_cache;
714
715 memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg));
716
717 ret = snd_soc_codec_set_cache_io(codec, 8, 8, control);
718 if (ret < 0) {
719 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
720 goto err;
721 }
722
723 ak4671_dai.dev = codec->dev;
724 ak4671_codec = codec;
725
726 ret = snd_soc_register_codec(codec);
727 if (ret != 0) {
728 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
729 goto err;
730 }
731
732 ret = snd_soc_register_dai(&ak4671_dai);
733 if (ret != 0) {
734 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
735 goto err_codec;
736 }
737
738 return 0;
739
740err_codec:
741 snd_soc_unregister_codec(codec);
742err:
743 kfree(ak4671);
744 return ret;
745}
746
747static void ak4671_unregister(struct ak4671_priv *ak4671)
748{
749 ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
750 snd_soc_unregister_dai(&ak4671_dai);
751 snd_soc_unregister_codec(&ak4671->codec);
752 kfree(ak4671);
753 ak4671_codec = NULL;
754}
755 676
756static int __devinit ak4671_i2c_probe(struct i2c_client *client, 677static int __devinit ak4671_i2c_probe(struct i2c_client *client,
757 const struct i2c_device_id *id) 678 const struct i2c_device_id *id)
758{ 679{
759 struct ak4671_priv *ak4671; 680 struct ak4671_priv *ak4671;
760 struct snd_soc_codec *codec; 681 int ret;
761 682
762 ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL); 683 ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
763 if (ak4671 == NULL) 684 if (ak4671 == NULL)
764 return -ENOMEM; 685 return -ENOMEM;
765 686
766 codec = &ak4671->codec;
767 codec->hw_write = (hw_write_t)i2c_master_send;
768
769 i2c_set_clientdata(client, ak4671); 687 i2c_set_clientdata(client, ak4671);
770 codec->control_data = client; 688 ak4671->control_data = client;
771 689 ak4671->control_type = SND_SOC_I2C;
772 codec->dev = &client->dev;
773 690
774 return ak4671_register(ak4671, SND_SOC_I2C); 691 ret = snd_soc_register_codec(&client->dev,
692 &soc_codec_dev_ak4671, &ak4671_dai, 1);
693 if (ret < 0)
694 kfree(ak4671);
695 return ret;
775} 696}
776 697
777static __devexit int ak4671_i2c_remove(struct i2c_client *client) 698static __devexit int ak4671_i2c_remove(struct i2c_client *client)
778{ 699{
779 struct ak4671_priv *ak4671 = i2c_get_clientdata(client); 700 snd_soc_unregister_codec(&client->dev);
780 701 kfree(i2c_get_clientdata(client));
781 ak4671_unregister(ak4671);
782
783 return 0; 702 return 0;
784} 703}
785 704
@@ -791,7 +710,7 @@ MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
791 710
792static struct i2c_driver ak4671_i2c_driver = { 711static struct i2c_driver ak4671_i2c_driver = {
793 .driver = { 712 .driver = {
794 .name = "ak4671", 713 .name = "ak4671-codec",
795 .owner = THIS_MODULE, 714 .owner = THIS_MODULE,
796 }, 715 },
797 .probe = ak4671_i2c_probe, 716 .probe = ak4671_i2c_probe,
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h
index e2fad964e88..61cb7ab7552 100644
--- a/sound/soc/codecs/ak4671.h
+++ b/sound/soc/codecs/ak4671.h
@@ -150,7 +150,4 @@
150/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */ 150/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */
151#define AK4671_MUTEN 0x04 151#define AK4671_MUTEN 0x04
152 152
153extern struct snd_soc_dai ak4671_dai;
154extern struct snd_soc_codec_device soc_codec_dev_ak4671;
155
156#endif 153#endif
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index a320fb5a0e2..823643932dd 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -30,6 +30,7 @@
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/clk.h> 31#include <linux/clk.h>
32#include <linux/mfd/davinci_voicecodec.h> 32#include <linux/mfd/davinci_voicecodec.h>
33#include <linux/spi/spi.h>
33 34
34#include <sound/core.h> 35#include <sound/core.h>
35#include <sound/pcm.h> 36#include <sound/pcm.h>
@@ -41,8 +42,6 @@
41 42
42#include <mach/dm365.h> 43#include <mach/dm365.h>
43 44
44#include "cq93vc.h"
45
46static inline unsigned int cq93vc_read(struct snd_soc_codec *codec, 45static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
47 unsigned int reg) 46 unsigned int reg)
48{ 47{
@@ -130,8 +129,8 @@ static struct snd_soc_dai_ops cq93vc_dai_ops = {
130 .set_sysclk = cq93vc_set_dai_sysclk, 129 .set_sysclk = cq93vc_set_dai_sysclk,
131}; 130};
132 131
133struct snd_soc_dai cq93vc_dai = { 132static struct snd_soc_dai_driver cq93vc_dai = {
134 .name = "CQ93VC", 133 .name = "cq93vc-hifi",
135 .playback = { 134 .playback = {
136 .stream_name = "Playback", 135 .stream_name = "Playback",
137 .channels_min = 1, 136 .channels_min = 1,
@@ -146,36 +145,20 @@ struct snd_soc_dai cq93vc_dai = {
146 .formats = CQ93VC_FORMATS,}, 145 .formats = CQ93VC_FORMATS,},
147 .ops = &cq93vc_dai_ops, 146 .ops = &cq93vc_dai_ops,
148}; 147};
149EXPORT_SYMBOL_GPL(cq93vc_dai);
150 148
151static int cq93vc_resume(struct platform_device *pdev) 149static int cq93vc_resume(struct snd_soc_codec *codec)
152{ 150{
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); 151 cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
157 152
158 return 0; 153 return 0;
159} 154}
160 155
161static struct snd_soc_codec *cq93vc_codec; 156static int cq93vc_probe(struct snd_soc_codec *codec)
162
163static int cq93vc_probe(struct platform_device *pdev)
164{ 157{
165 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 158 struct davinci_vc *davinci_vc = codec->dev->platform_data;
166 struct device *dev = &pdev->dev; 159
167 struct snd_soc_codec *codec; 160 davinci_vc->cq93vc.codec = codec;
168 int ret; 161 codec->control_data = davinci_vc;
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 162
180 /* Set controls */ 163 /* Set controls */
181 snd_soc_add_controls(codec, cq93vc_snd_controls, 164 snd_soc_add_controls(codec, cq93vc_snd_controls,
@@ -187,108 +170,51 @@ static int cq93vc_probe(struct platform_device *pdev)
187 return 0; 170 return 0;
188} 171}
189 172
190static int cq93vc_remove(struct platform_device *pdev) 173static int cq93vc_remove(struct snd_soc_codec *codec)
191{ 174{
192 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 175 cq93vc_set_bias_level(codec, SND_SOC_BIAS_OFF);
193
194 snd_soc_free_pcms(socdev);
195 snd_soc_dapm_free(socdev);
196 176
197 return 0; 177 return 0;
198} 178}
199 179
200struct snd_soc_codec_device soc_codec_dev_cq93vc = { 180static struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
181 .read = cq93vc_read,
182 .write = cq93vc_write,
183 .set_bias_level = cq93vc_set_bias_level,
201 .probe = cq93vc_probe, 184 .probe = cq93vc_probe,
202 .remove = cq93vc_remove, 185 .remove = cq93vc_remove,
203 .resume = cq93vc_resume, 186 .resume = cq93vc_resume,
204}; 187};
205EXPORT_SYMBOL_GPL(soc_codec_dev_cq93vc);
206 188
207static __init int cq93vc_codec_probe(struct platform_device *pdev) 189static int cq93vc_platform_probe(struct platform_device *pdev)
208{ 190{
209 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev); 191 return snd_soc_register_codec(&pdev->dev,
210 struct snd_soc_codec *codec; 192 &soc_codec_dev_cq93vc, &cq93vc_dai, 1);
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} 193}
261 194
262static int __devexit cq93vc_codec_remove(struct platform_device *pdev) 195static int cq93vc_platform_remove(struct platform_device *pdev)
263{ 196{
264 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 197 snd_soc_unregister_codec(&pdev->dev);
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; 198 return 0;
274} 199}
275 200
276static struct platform_driver cq93vc_codec_driver = { 201static struct platform_driver cq93vc_codec_driver = {
277 .driver = { 202 .driver = {
278 .name = "cq93vc", 203 .name = "cq93vc-codec",
279 .owner = THIS_MODULE, 204 .owner = THIS_MODULE,
280 }, 205 },
281 .probe = cq93vc_codec_probe, 206
282 .remove = __devexit_p(cq93vc_codec_remove), 207 .probe = cq93vc_platform_probe,
208 .remove = __devexit_p(cq93vc_platform_remove),
283}; 209};
284 210
285static __init int cq93vc_init(void) 211static int __init cq93vc_init(void)
286{ 212{
287 return platform_driver_probe(&cq93vc_codec_driver, cq93vc_codec_probe); 213 return platform_driver_register(&cq93vc_codec_driver);
288} 214}
289module_init(cq93vc_init); 215module_init(cq93vc_init);
290 216
291static __exit void cq93vc_exit(void) 217static void __exit cq93vc_exit(void)
292{ 218{
293 platform_driver_unregister(&cq93vc_codec_driver); 219 platform_driver_unregister(&cq93vc_codec_driver);
294} 220}
diff --git a/sound/soc/codecs/cq93vc.h b/sound/soc/codecs/cq93vc.h
deleted file mode 100644
index 845b1968ef9..00000000000
--- a/sound/soc/codecs/cq93vc.h
+++ /dev/null
@@ -1,29 +0,0 @@
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 30d949239de..6542dc03895 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -31,8 +31,6 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/regulator/consumer.h> 32#include <linux/regulator/consumer.h>
33 33
34#include "cs4270.h"
35
36/* 34/*
37 * The codec isn't really big-endian or little-endian, since the I2S 35 * The codec isn't really big-endian or little-endian, since the I2S
38 * interface requires data to be sent serially with the MSbit first. 36 * interface requires data to be sent serially with the MSbit first.
@@ -114,7 +112,8 @@ static const char *supply_names[] = {
114 112
115/* Private data for the CS4270 */ 113/* Private data for the CS4270 */
116struct cs4270_private { 114struct cs4270_private {
117 struct snd_soc_codec codec; 115 enum snd_soc_control_type control_type;
116 void *control_data;
118 u8 reg_cache[CS4270_NUMREGS]; 117 u8 reg_cache[CS4270_NUMREGS];
119 unsigned int mclk; /* Input frequency of the MCLK pin */ 118 unsigned int mclk; /* Input frequency of the MCLK pin */
120 unsigned int mode; /* The mode (I2S or left-justified) */ 119 unsigned int mode; /* The mode (I2S or left-justified) */
@@ -212,44 +211,8 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
212{ 211{
213 struct snd_soc_codec *codec = codec_dai->codec; 212 struct snd_soc_codec *codec = codec_dai->codec;
214 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 213 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
215 unsigned int rates = 0;
216 unsigned int rate_min = -1;
217 unsigned int rate_max = 0;
218 unsigned int i;
219 214
220 cs4270->mclk = freq; 215 cs4270->mclk = freq;
221
222 if (cs4270->mclk) {
223 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
224 unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
225 rates |= snd_pcm_rate_to_rate_bit(rate);
226 if (rate < rate_min)
227 rate_min = rate;
228 if (rate > rate_max)
229 rate_max = rate;
230 }
231 /* FIXME: soc should support a rate list */
232 rates &= ~SNDRV_PCM_RATE_KNOT;
233
234 if (!rates) {
235 dev_err(codec->dev, "could not find a valid sample rate\n");
236 return -EINVAL;
237 }
238 } else {
239 /* enable all possible rates */
240 rates = SNDRV_PCM_RATE_8000_192000;
241 rate_min = 8000;
242 rate_max = 192000;
243 }
244
245 codec_dai->playback.rates = rates;
246 codec_dai->playback.rate_min = rate_min;
247 codec_dai->playback.rate_max = rate_max;
248
249 codec_dai->capture.rates = rates;
250 codec_dai->capture.rate_min = rate_min;
251 codec_dai->capture.rate_max = rate_max;
252
253 return 0; 216 return 0;
254} 217}
255 218
@@ -410,8 +373,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
410 struct snd_soc_dai *dai) 373 struct snd_soc_dai *dai)
411{ 374{
412 struct snd_soc_pcm_runtime *rtd = substream->private_data; 375 struct snd_soc_pcm_runtime *rtd = substream->private_data;
413 struct snd_soc_device *socdev = rtd->socdev; 376 struct snd_soc_codec *codec = rtd->codec;
414 struct snd_soc_codec *codec = socdev->card->codec;
415 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 377 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
416 int ret; 378 int ret;
417 unsigned int i; 379 unsigned int i;
@@ -549,19 +511,6 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
549 snd_soc_get_volsw, cs4270_soc_put_mute), 511 snd_soc_get_volsw, cs4270_soc_put_mute),
550}; 512};
551 513
552/*
553 * cs4270_codec - global variable to store codec for the ASoC probe function
554 *
555 * If struct i2c_driver had a private_data field, we wouldn't need to use
556 * cs4270_codec. This is the only way to pass the codec structure from
557 * cs4270_i2c_probe() to cs4270_probe(). Unfortunately, there is no good
558 * way to synchronize these two functions. cs4270_i2c_probe() can be called
559 * multiple times before cs4270_probe() is called even once. So for now, we
560 * also only allow cs4270_i2c_probe() to be run once. That means that we do
561 * not support more than one cs4270 device in the system, at least for now.
562 */
563static struct snd_soc_codec *cs4270_codec;
564
565static struct snd_soc_dai_ops cs4270_dai_ops = { 514static struct snd_soc_dai_ops cs4270_dai_ops = {
566 .hw_params = cs4270_hw_params, 515 .hw_params = cs4270_hw_params,
567 .set_sysclk = cs4270_set_dai_sysclk, 516 .set_sysclk = cs4270_set_dai_sysclk,
@@ -569,20 +518,24 @@ static struct snd_soc_dai_ops cs4270_dai_ops = {
569 .digital_mute = cs4270_dai_mute, 518 .digital_mute = cs4270_dai_mute,
570}; 519};
571 520
572struct snd_soc_dai cs4270_dai = { 521struct snd_soc_dai_driver cs4270_dai = {
573 .name = "cs4270", 522 .name = "cs4270-hifi",
574 .playback = { 523 .playback = {
575 .stream_name = "Playback", 524 .stream_name = "Playback",
576 .channels_min = 1, 525 .channels_min = 1,
577 .channels_max = 2, 526 .channels_max = 2,
578 .rates = 0, 527 .rates = SNDRV_PCM_RATE_CONTINUOUS,
528 .rate_min = 4000,
529 .rate_max = 216000,
579 .formats = CS4270_FORMATS, 530 .formats = CS4270_FORMATS,
580 }, 531 },
581 .capture = { 532 .capture = {
582 .stream_name = "Capture", 533 .stream_name = "Capture",
583 .channels_min = 1, 534 .channels_min = 1,
584 .channels_max = 2, 535 .channels_max = 2,
585 .rates = 0, 536 .rates = SNDRV_PCM_RATE_CONTINUOUS,
537 .rate_min = 4000,
538 .rate_max = 216000,
586 .formats = CS4270_FORMATS, 539 .formats = CS4270_FORMATS,
587 }, 540 },
588 .ops = &cs4270_dai_ops, 541 .ops = &cs4270_dai_ops,
@@ -596,153 +549,19 @@ EXPORT_SYMBOL_GPL(cs4270_dai);
596 * This function is called when ASoC has all the pieces it needs to 549 * This function is called when ASoC has all the pieces it needs to
597 * instantiate a sound driver. 550 * instantiate a sound driver.
598 */ 551 */
599static int cs4270_probe(struct platform_device *pdev) 552static int cs4270_probe(struct snd_soc_codec *codec)
600{
601 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
602 struct snd_soc_codec *codec = cs4270_codec;
603 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
604 int i, ret;
605
606 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
607 socdev->card->codec = codec;
608
609 /* Register PCMs */
610 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
611 if (ret < 0) {
612 dev_err(codec->dev, "failed to create pcms\n");
613 return ret;
614 }
615
616 /* Add the non-DAPM controls */
617 ret = snd_soc_add_controls(codec, cs4270_snd_controls,
618 ARRAY_SIZE(cs4270_snd_controls));
619 if (ret < 0) {
620 dev_err(codec->dev, "failed to add controls\n");
621 goto error_free_pcms;
622 }
623
624 /* get the power supply regulators */
625 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
626 cs4270->supplies[i].supply = supply_names[i];
627
628 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
629 cs4270->supplies);
630 if (ret < 0)
631 goto error_free_pcms;
632
633 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
634 cs4270->supplies);
635 if (ret < 0)
636 goto error_free_regulators;
637
638 return 0;
639
640error_free_regulators:
641 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
642 cs4270->supplies);
643
644error_free_pcms:
645 snd_soc_free_pcms(socdev);
646
647 return ret;
648}
649
650/**
651 * cs4270_remove - ASoC remove function
652 * @pdev: platform device
653 *
654 * This function is the counterpart to cs4270_probe().
655 */
656static int cs4270_remove(struct platform_device *pdev)
657{ 553{
658 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
659 struct snd_soc_codec *codec = cs4270_codec;
660 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 554 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
555 int i, ret, reg;
661 556
662 snd_soc_free_pcms(socdev); 557 codec->control_data = cs4270->control_data;
663 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
664 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
665
666 return 0;
667};
668
669/**
670 * cs4270_i2c_probe - initialize the I2C interface of the CS4270
671 * @i2c_client: the I2C client object
672 * @id: the I2C device ID (ignored)
673 *
674 * This function is called whenever the I2C subsystem finds a device that
675 * matches the device ID given via a prior call to i2c_add_driver().
676 */
677static int cs4270_i2c_probe(struct i2c_client *i2c_client,
678 const struct i2c_device_id *id)
679{
680 struct snd_soc_codec *codec;
681 struct cs4270_private *cs4270;
682 unsigned int reg;
683 int ret;
684
685 /* For now, we only support one cs4270 device in the system. See the
686 * comment for cs4270_codec.
687 */
688 if (cs4270_codec) {
689 dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n",
690 i2c_client->addr);
691 dev_err(&i2c_client->dev, "only one per board allowed\n");
692 /* Should we return something other than ENODEV here? */
693 return -ENODEV;
694 }
695
696 /* Verify that we have a CS4270 */
697
698 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
699 if (ret < 0) {
700 dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
701 i2c_client->addr);
702 return ret;
703 }
704 /* The top four bits of the chip ID should be 1100. */
705 if ((ret & 0xF0) != 0xC0) {
706 dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
707 i2c_client->addr);
708 return -ENODEV;
709 }
710
711 dev_info(&i2c_client->dev, "found device at i2c address %X\n",
712 i2c_client->addr);
713 dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
714
715 /* Allocate enough space for the snd_soc_codec structure
716 and our private data together. */
717 cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
718 if (!cs4270) {
719 dev_err(&i2c_client->dev, "could not allocate codec\n");
720 return -ENOMEM;
721 }
722 codec = &cs4270->codec;
723
724 mutex_init(&codec->mutex);
725 INIT_LIST_HEAD(&codec->dapm_widgets);
726 INIT_LIST_HEAD(&codec->dapm_paths);
727
728 codec->dev = &i2c_client->dev;
729 codec->name = "CS4270";
730 codec->owner = THIS_MODULE;
731 codec->dai = &cs4270_dai;
732 codec->num_dai = 1;
733 snd_soc_codec_set_drvdata(codec, cs4270);
734 codec->control_data = i2c_client;
735 codec->read = cs4270_read_reg_cache;
736 codec->write = cs4270_i2c_write;
737 codec->reg_cache = cs4270->reg_cache;
738 codec->reg_cache_size = CS4270_NUMREGS;
739 558
740 /* The I2C interface is set up, so pre-fill our register cache */ 559 /* The I2C interface is set up, so pre-fill our register cache */
741 560
742 ret = cs4270_fill_cache(codec); 561 ret = cs4270_fill_cache(codec);
743 if (ret < 0) { 562 if (ret < 0) {
744 dev_err(&i2c_client->dev, "failed to fill register cache\n"); 563 dev_err(codec->dev, "failed to fill register cache\n");
745 goto error_free_codec; 564 return ret;
746 } 565 }
747 566
748 /* Disable auto-mute. This feature appears to be buggy. In some 567 /* Disable auto-mute. This feature appears to be buggy. In some
@@ -755,7 +574,7 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
755 reg &= ~CS4270_MUTE_AUTO; 574 reg &= ~CS4270_MUTE_AUTO;
756 ret = cs4270_i2c_write(codec, CS4270_MUTE, reg); 575 ret = cs4270_i2c_write(codec, CS4270_MUTE, reg);
757 if (ret < 0) { 576 if (ret < 0) {
758 dev_err(&i2c_client->dev, "i2c write failed\n"); 577 dev_err(codec->dev, "i2c write failed\n");
759 return ret; 578 return ret;
760 } 579 }
761 580
@@ -769,65 +588,56 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
769 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO); 588 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
770 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg); 589 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
771 if (ret < 0) { 590 if (ret < 0) {
772 dev_err(&i2c_client->dev, "i2c write failed\n"); 591 dev_err(codec->dev, "i2c write failed\n");
773 return ret; 592 return ret;
774 } 593 }
775 594
776 /* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI 595 /* Add the non-DAPM controls */
777 * structure for each CS4270 device, but the machine driver needs to 596 ret = snd_soc_add_controls(codec, cs4270_snd_controls,
778 * have a pointer to the DAI structure, so for now it must be a global 597 ARRAY_SIZE(cs4270_snd_controls));
779 * variable.
780 */
781 cs4270_dai.dev = &i2c_client->dev;
782
783 /* Register the DAI. If all the other ASoC driver have already
784 * registered, then this will call our probe function, so
785 * cs4270_codec needs to be ready.
786 */
787 cs4270_codec = codec;
788 ret = snd_soc_register_dai(&cs4270_dai);
789 if (ret < 0) { 598 if (ret < 0) {
790 dev_err(&i2c_client->dev, "failed to register DAIe\n"); 599 dev_err(codec->dev, "failed to add controls\n");
791 goto error_free_codec; 600 return ret;
792 } 601 }
793 602
794 i2c_set_clientdata(i2c_client, cs4270); 603 /* get the power supply regulators */
604 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
605 cs4270->supplies[i].supply = supply_names[i];
606
607 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
608 cs4270->supplies);
609 if (ret < 0)
610 return ret;
611
612 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
613 cs4270->supplies);
614 if (ret < 0)
615 goto error_free_regulators;
795 616
796 return 0; 617 return 0;
797 618
798error_free_codec: 619error_free_regulators:
799 kfree(cs4270); 620 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
800 cs4270_codec = NULL; 621 cs4270->supplies);
801 cs4270_dai.dev = NULL;
802 622
803 return ret; 623 return ret;
804} 624}
805 625
806/** 626/**
807 * cs4270_i2c_remove - remove an I2C device 627 * cs4270_remove - ASoC remove function
808 * @i2c_client: the I2C client object 628 * @pdev: platform device
809 * 629 *
810 * This function is the counterpart to cs4270_i2c_probe(). 630 * This function is the counterpart to cs4270_probe().
811 */ 631 */
812static int cs4270_i2c_remove(struct i2c_client *i2c_client) 632static int cs4270_remove(struct snd_soc_codec *codec)
813{ 633{
814 struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client); 634 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
815 635
816 kfree(cs4270); 636 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
817 cs4270_codec = NULL; 637 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
818 cs4270_dai.dev = NULL;
819 638
820 return 0; 639 return 0;
821}
822
823/*
824 * cs4270_id - I2C device IDs supported by this driver
825 */
826static struct i2c_device_id cs4270_id[] = {
827 {"cs4270", 0},
828 {}
829}; 640};
830MODULE_DEVICE_TABLE(i2c, cs4270_id);
831 641
832#ifdef CONFIG_PM 642#ifdef CONFIG_PM
833 643
@@ -840,9 +650,8 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
840 * and all registers are written back to the hardware when resuming. 650 * and all registers are written back to the hardware when resuming.
841 */ 651 */
842 652
843static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 653static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
844{ 654{
845 struct snd_soc_codec *codec = cs4270_codec;
846 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 655 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
847 int reg, ret; 656 int reg, ret;
848 657
@@ -860,9 +669,8 @@ static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
860 return 0; 669 return 0;
861} 670}
862 671
863static int cs4270_soc_resume(struct platform_device *pdev) 672static int cs4270_soc_resume(struct snd_soc_codec *codec)
864{ 673{
865 struct snd_soc_codec *codec = cs4270_codec;
866 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 674 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
867 struct i2c_client *i2c_client = codec->control_data; 675 struct i2c_client *i2c_client = codec->control_data;
868 int reg; 676 int reg;
@@ -896,6 +704,95 @@ static int cs4270_soc_resume(struct platform_device *pdev)
896#endif /* CONFIG_PM */ 704#endif /* CONFIG_PM */
897 705
898/* 706/*
707 * ASoC codec device structure
708 *
709 * Assign this variable to the codec_dev field of the machine driver's
710 * snd_soc_device structure.
711 */
712static struct snd_soc_codec_driver soc_codec_device_cs4270 = {
713 .probe = cs4270_probe,
714 .remove = cs4270_remove,
715 .suspend = cs4270_soc_suspend,
716 .resume = cs4270_soc_resume,
717 .read = cs4270_read_reg_cache,
718 .write = cs4270_i2c_write,
719 .reg_cache_size = CS4270_NUMREGS,
720 .reg_word_size = sizeof(u8),
721};
722
723/**
724 * cs4270_i2c_probe - initialize the I2C interface of the CS4270
725 * @i2c_client: the I2C client object
726 * @id: the I2C device ID (ignored)
727 *
728 * This function is called whenever the I2C subsystem finds a device that
729 * matches the device ID given via a prior call to i2c_add_driver().
730 */
731static int cs4270_i2c_probe(struct i2c_client *i2c_client,
732 const struct i2c_device_id *id)
733{
734 struct cs4270_private *cs4270;
735 int ret;
736
737 /* Verify that we have a CS4270 */
738
739 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
740 if (ret < 0) {
741 dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
742 i2c_client->addr);
743 return ret;
744 }
745 /* The top four bits of the chip ID should be 1100. */
746 if ((ret & 0xF0) != 0xC0) {
747 dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
748 i2c_client->addr);
749 return -ENODEV;
750 }
751
752 dev_info(&i2c_client->dev, "found device at i2c address %X\n",
753 i2c_client->addr);
754 dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
755
756 cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
757 if (!cs4270) {
758 dev_err(&i2c_client->dev, "could not allocate codec\n");
759 return -ENOMEM;
760 }
761
762 i2c_set_clientdata(i2c_client, cs4270);
763 cs4270->control_data = i2c_client;
764 cs4270->control_type = SND_SOC_I2C;
765
766 ret = snd_soc_register_codec(&i2c_client->dev,
767 &soc_codec_device_cs4270, &cs4270_dai, 1);
768 if (ret < 0)
769 kfree(cs4270);
770 return ret;
771}
772
773/**
774 * cs4270_i2c_remove - remove an I2C device
775 * @i2c_client: the I2C client object
776 *
777 * This function is the counterpart to cs4270_i2c_probe().
778 */
779static int cs4270_i2c_remove(struct i2c_client *i2c_client)
780{
781 snd_soc_unregister_codec(&i2c_client->dev);
782 kfree(i2c_get_clientdata(i2c_client));
783 return 0;
784}
785
786/*
787 * cs4270_id - I2C device IDs supported by this driver
788 */
789static struct i2c_device_id cs4270_id[] = {
790 {"cs4270", 0},
791 {}
792};
793MODULE_DEVICE_TABLE(i2c, cs4270_id);
794
795/*
899 * cs4270_i2c_driver - I2C device identification 796 * cs4270_i2c_driver - I2C device identification
900 * 797 *
901 * This structure tells the I2C subsystem how to identify and support a 798 * This structure tells the I2C subsystem how to identify and support a
@@ -903,7 +800,7 @@ static int cs4270_soc_resume(struct platform_device *pdev)
903 */ 800 */
904static struct i2c_driver cs4270_i2c_driver = { 801static struct i2c_driver cs4270_i2c_driver = {
905 .driver = { 802 .driver = {
906 .name = "cs4270", 803 .name = "cs4270-codec",
907 .owner = THIS_MODULE, 804 .owner = THIS_MODULE,
908 }, 805 },
909 .id_table = cs4270_id, 806 .id_table = cs4270_id,
@@ -911,20 +808,6 @@ static struct i2c_driver cs4270_i2c_driver = {
911 .remove = cs4270_i2c_remove, 808 .remove = cs4270_i2c_remove,
912}; 809};
913 810
914/*
915 * ASoC codec device structure
916 *
917 * Assign this variable to the codec_dev field of the machine driver's
918 * snd_soc_device structure.
919 */
920struct snd_soc_codec_device soc_codec_device_cs4270 = {
921 .probe = cs4270_probe,
922 .remove = cs4270_remove,
923 .suspend = cs4270_soc_suspend,
924 .resume = cs4270_soc_resume,
925};
926EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
927
928static int __init cs4270_init(void) 811static int __init cs4270_init(void)
929{ 812{
930 pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n"); 813 pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
diff --git a/sound/soc/codecs/cs4270.h b/sound/soc/codecs/cs4270.h
deleted file mode 100644
index adc6cd9667d..00000000000
--- a/sound/soc/codecs/cs4270.h
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * Cirrus Logic CS4270 ALSA SoC Codec Driver
3 *
4 * Author: Timur Tabi <timur@freescale.com>
5 *
6 * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11
12#ifndef _CS4270_H
13#define _CS4270_H
14
15/*
16 * The ASoC codec DAI structure for the CS4270. Assign this structure to
17 * the .codec_dai field of your machine driver's snd_soc_dai_link structure.
18 */
19extern struct snd_soc_dai cs4270_dai;
20
21/*
22 * The ASoC codec device structure for the CS4270. Assign this structure
23 * to the .codec_dev field of your machine driver's snd_soc_device
24 * structure.
25 */
26extern struct snd_soc_codec_device soc_codec_device_cs4270;
27
28#endif
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index dd9b8550c40..8a25743870c 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -42,15 +42,14 @@ enum master_slave_mode {
42}; 42};
43 43
44struct cs42l51_private { 44struct cs42l51_private {
45 enum snd_soc_control_type control_type;
46 void *control_data;
45 unsigned int mclk; 47 unsigned int mclk;
46 unsigned int audio_mode; /* The mode (I2S or left-justified) */ 48 unsigned int audio_mode; /* The mode (I2S or left-justified) */
47 enum master_slave_mode func; 49 enum master_slave_mode func;
48 struct snd_soc_codec codec;
49 u8 reg_cache[CS42L51_NUMREGS]; 50 u8 reg_cache[CS42L51_NUMREGS];
50}; 51};
51 52
52static struct snd_soc_codec *cs42l51_codec;
53
54#define CS42L51_FORMATS ( \ 53#define CS42L51_FORMATS ( \
55 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ 54 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
56 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ 55 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
@@ -75,134 +74,6 @@ static int cs42l51_fill_cache(struct snd_soc_codec *codec)
75 return 0; 74 return 0;
76} 75}
77 76
78static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
79 const struct i2c_device_id *id)
80{
81 struct snd_soc_codec *codec;
82 struct cs42l51_private *cs42l51;
83 int ret = 0;
84 int reg;
85
86 if (cs42l51_codec)
87 return -EBUSY;
88
89 /* Verify that we have a CS42L51 */
90 ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
91 if (ret < 0) {
92 dev_err(&i2c_client->dev, "failed to read I2C\n");
93 goto error;
94 }
95
96 if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
97 (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
98 dev_err(&i2c_client->dev, "Invalid chip id\n");
99 ret = -ENODEV;
100 goto error;
101 }
102
103 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
104 ret & 7);
105
106 cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
107 if (!cs42l51) {
108 dev_err(&i2c_client->dev, "could not allocate codec\n");
109 return -ENOMEM;
110 }
111 codec = &cs42l51->codec;
112
113 mutex_init(&codec->mutex);
114 INIT_LIST_HEAD(&codec->dapm_widgets);
115 INIT_LIST_HEAD(&codec->dapm_paths);
116
117 codec->dev = &i2c_client->dev;
118 codec->name = "CS42L51";
119 codec->owner = THIS_MODULE;
120 codec->dai = &cs42l51_dai;
121 codec->num_dai = 1;
122 snd_soc_codec_set_drvdata(codec, cs42l51);
123
124 codec->control_data = i2c_client;
125 codec->reg_cache = cs42l51->reg_cache;
126 codec->reg_cache_size = CS42L51_NUMREGS;
127 i2c_set_clientdata(i2c_client, codec);
128
129 ret = cs42l51_fill_cache(codec);
130 if (ret < 0) {
131 dev_err(&i2c_client->dev, "failed to fill register cache\n");
132 goto error_alloc;
133 }
134
135 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
136 if (ret < 0) {
137 dev_err(&i2c_client->dev, "Failed to set cache I/O: %d\n", ret);
138 goto error_alloc;
139 }
140
141 /*
142 * DAC configuration
143 * - Use signal processor
144 * - auto mute
145 * - vol changes immediate
146 * - no de-emphasize
147 */
148 reg = CS42L51_DAC_CTL_DATA_SEL(1)
149 | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
150 ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
151 if (ret < 0)
152 goto error_alloc;
153
154 cs42l51_dai.dev = codec->dev;
155 cs42l51_codec = codec;
156
157 ret = snd_soc_register_codec(codec);
158 if (ret != 0) {
159 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
160 goto error_alloc;
161 }
162
163 ret = snd_soc_register_dai(&cs42l51_dai);
164 if (ret < 0) {
165 dev_err(&i2c_client->dev, "failed to register DAIe\n");
166 goto error_reg;
167 }
168
169 return 0;
170
171error_reg:
172 snd_soc_unregister_codec(codec);
173error_alloc:
174 kfree(cs42l51);
175error:
176 return ret;
177}
178
179static int cs42l51_i2c_remove(struct i2c_client *client)
180{
181 struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
182 snd_soc_unregister_dai(&cs42l51_dai);
183 snd_soc_unregister_codec(cs42l51_codec);
184 cs42l51_codec = NULL;
185 kfree(cs42l51);
186 return 0;
187}
188
189
190static const struct i2c_device_id cs42l51_id[] = {
191 {"cs42l51", 0},
192 {}
193};
194MODULE_DEVICE_TABLE(i2c, cs42l51_id);
195
196static struct i2c_driver cs42l51_i2c_driver = {
197 .driver = {
198 .name = "CS42L51 I2C",
199 .owner = THIS_MODULE,
200 },
201 .id_table = cs42l51_id,
202 .probe = cs42l51_i2c_probe,
203 .remove = cs42l51_i2c_remove,
204};
205
206static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, 77static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol) 78 struct snd_ctl_elem_value *ucontrol)
208{ 79{
@@ -484,51 +355,8 @@ static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
484{ 355{
485 struct snd_soc_codec *codec = codec_dai->codec; 356 struct snd_soc_codec *codec = codec_dai->codec;
486 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 357 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
487 struct cs42l51_ratios *ratios = NULL;
488 int nr_ratios = 0;
489 unsigned int rates = 0;
490 unsigned int rate_min = -1;
491 unsigned int rate_max = 0;
492 int i;
493 358
494 cs42l51->mclk = freq; 359 cs42l51->mclk = freq;
495
496 switch (cs42l51->func) {
497 case MODE_MASTER:
498 return -EINVAL;
499 case MODE_SLAVE:
500 ratios = slave_ratios;
501 nr_ratios = ARRAY_SIZE(slave_ratios);
502 break;
503 case MODE_SLAVE_AUTO:
504 ratios = slave_auto_ratios;
505 nr_ratios = ARRAY_SIZE(slave_auto_ratios);
506 break;
507 }
508
509 for (i = 0; i < nr_ratios; i++) {
510 unsigned int rate = freq / ratios[i].ratio;
511 rates |= snd_pcm_rate_to_rate_bit(rate);
512 if (rate < rate_min)
513 rate_min = rate;
514 if (rate > rate_max)
515 rate_max = rate;
516 }
517 rates &= ~SNDRV_PCM_RATE_KNOT;
518
519 if (!rates) {
520 dev_err(codec->dev, "could not find a valid sample rate\n");
521 return -EINVAL;
522 }
523
524 codec_dai->playback.rates = rates;
525 codec_dai->playback.rate_min = rate_min;
526 codec_dai->playback.rate_max = rate_max;
527
528 codec_dai->capture.rates = rates;
529 codec_dai->capture.rate_min = rate_min;
530 codec_dai->capture.rate_max = rate_max;
531
532 return 0; 360 return 0;
533} 361}
534 362
@@ -537,8 +365,7 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
537 struct snd_soc_dai *dai) 365 struct snd_soc_dai *dai)
538{ 366{
539 struct snd_soc_pcm_runtime *rtd = substream->private_data; 367 struct snd_soc_pcm_runtime *rtd = substream->private_data;
540 struct snd_soc_device *socdev = rtd->socdev; 368 struct snd_soc_codec *codec = rtd->codec;
541 struct snd_soc_codec *codec = socdev->card->codec;
542 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 369 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
543 int ret; 370 int ret;
544 unsigned int i; 371 unsigned int i;
@@ -670,8 +497,8 @@ static struct snd_soc_dai_ops cs42l51_dai_ops = {
670 .digital_mute = cs42l51_dai_mute, 497 .digital_mute = cs42l51_dai_mute,
671}; 498};
672 499
673struct snd_soc_dai cs42l51_dai = { 500static struct snd_soc_dai_driver cs42l51_dai = {
674 .name = "CS42L51 HiFi", 501 .name = "cs42l51-hifi",
675 .playback = { 502 .playback = {
676 .stream_name = "Playback", 503 .stream_name = "Playback",
677 .channels_min = 1, 504 .channels_min = 1,
@@ -688,30 +515,39 @@ struct snd_soc_dai cs42l51_dai = {
688 }, 515 },
689 .ops = &cs42l51_dai_ops, 516 .ops = &cs42l51_dai_ops,
690}; 517};
691EXPORT_SYMBOL_GPL(cs42l51_dai);
692
693 518
694static int cs42l51_probe(struct platform_device *pdev) 519static int cs42l51_probe(struct snd_soc_codec *codec)
695{ 520{
696 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 521 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
697 struct snd_soc_codec *codec; 522 int ret, reg;
698 int ret = 0;
699 523
700 if (!cs42l51_codec) { 524 codec->control_data = cs42l51->control_data;
701 dev_err(&pdev->dev, "CS42L51 codec not yet registered\n");
702 return -EINVAL;
703 }
704 525
705 socdev->card->codec = cs42l51_codec; 526 ret = cs42l51_fill_cache(codec);
706 codec = socdev->card->codec; 527 if (ret < 0) {
528 dev_err(codec->dev, "failed to fill register cache\n");
529 return ret;
530 }
707 531
708 /* Register PCMs */ 532 ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
709 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
710 if (ret < 0) { 533 if (ret < 0) {
711 dev_err(&pdev->dev, "failed to create PCMs\n"); 534 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
712 return ret; 535 return ret;
713 } 536 }
714 537
538 /*
539 * DAC configuration
540 * - Use signal processor
541 * - auto mute
542 * - vol changes immediate
543 * - no de-emphasize
544 */
545 reg = CS42L51_DAC_CTL_DATA_SEL(1)
546 | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
547 ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
548 if (ret < 0)
549 return ret;
550
715 snd_soc_add_controls(codec, cs42l51_snd_controls, 551 snd_soc_add_controls(codec, cs42l51_snd_controls,
716 ARRAY_SIZE(cs42l51_snd_controls)); 552 ARRAY_SIZE(cs42l51_snd_controls));
717 snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets, 553 snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,
@@ -722,22 +558,77 @@ static int cs42l51_probe(struct platform_device *pdev)
722 return 0; 558 return 0;
723} 559}
724 560
561static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
562 .probe = cs42l51_probe,
563 .reg_cache_size = CS42L51_NUMREGS,
564 .reg_word_size = sizeof(u8),
565};
725 566
726static int cs42l51_remove(struct platform_device *pdev) 567static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
568 const struct i2c_device_id *id)
727{ 569{
728 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 570 struct cs42l51_private *cs42l51;
571 int ret;
729 572
730 snd_soc_free_pcms(socdev); 573 /* Verify that we have a CS42L51 */
731 snd_soc_dapm_free(socdev); 574 ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
575 if (ret < 0) {
576 dev_err(&i2c_client->dev, "failed to read I2C\n");
577 goto error;
578 }
579
580 if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
581 (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
582 dev_err(&i2c_client->dev, "Invalid chip id\n");
583 ret = -ENODEV;
584 goto error;
585 }
586
587 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
588 ret & 7);
589
590 cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
591 if (!cs42l51) {
592 dev_err(&i2c_client->dev, "could not allocate codec\n");
593 return -ENOMEM;
594 }
595
596 i2c_set_clientdata(i2c_client, cs42l51);
597 cs42l51->control_data = i2c_client;
598 cs42l51->control_type = SND_SOC_I2C;
732 599
600 ret = snd_soc_register_codec(&i2c_client->dev,
601 &soc_codec_device_cs42l51, &cs42l51_dai, 1);
602 if (ret < 0)
603 kfree(cs42l51);
604error:
605 return ret;
606}
607
608static int cs42l51_i2c_remove(struct i2c_client *client)
609{
610 struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
611
612 snd_soc_unregister_codec(&client->dev);
613 kfree(cs42l51);
733 return 0; 614 return 0;
734} 615}
735 616
736struct snd_soc_codec_device soc_codec_device_cs42l51 = { 617static const struct i2c_device_id cs42l51_id[] = {
737 .probe = cs42l51_probe, 618 {"cs42l51", 0},
738 .remove = cs42l51_remove 619 {}
620};
621MODULE_DEVICE_TABLE(i2c, cs42l51_id);
622
623static struct i2c_driver cs42l51_i2c_driver = {
624 .driver = {
625 .name = "cs42L51-codec",
626 .owner = THIS_MODULE,
627 },
628 .id_table = cs42l51_id,
629 .probe = cs42l51_i2c_probe,
630 .remove = cs42l51_i2c_remove,
739}; 631};
740EXPORT_SYMBOL_GPL(soc_codec_device_cs42l51);
741 632
742static int __init cs42l51_init(void) 633static int __init cs42l51_init(void)
743{ 634{
diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h
index 8f0bd9786ad..2beeb171db4 100644
--- a/sound/soc/codecs/cs42l51.h
+++ b/sound/soc/codecs/cs42l51.h
@@ -158,6 +158,4 @@
158#define CS42L51_LASTREG 0x20 158#define CS42L51_LASTREG 0x20
159#define CS42L51_NUMREGS (CS42L51_LASTREG - CS42L51_FIRSTREG + 1) 159#define CS42L51_NUMREGS (CS42L51_LASTREG - CS42L51_FIRSTREG + 1)
160 160
161extern struct snd_soc_dai cs42l51_dai;
162extern struct snd_soc_codec_device soc_codec_device_cs42l51;
163#endif 161#endif
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index f07a415c753..cf4323dbf9c 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -24,7 +24,8 @@
24 24
25 25
26struct cx20442_priv { 26struct cx20442_priv {
27 struct snd_soc_codec codec; 27 enum snd_soc_control_type control_type;
28 void *control_data;
28 u8 reg_cache[1]; 29 u8 reg_cache[1];
29}; 30};
30 31
@@ -102,7 +103,7 @@ static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
102{ 103{
103 u8 *reg_cache = codec->reg_cache; 104 u8 *reg_cache = codec->reg_cache;
104 105
105 if (reg >= codec->reg_cache_size) 106 if (reg >= codec->driver->reg_cache_size)
106 return -EINVAL; 107 return -EINVAL;
107 108
108 return reg_cache[reg]; 109 return reg_cache[reg];
@@ -164,16 +165,17 @@ static int cx20442_pm_to_v253_vsp(u8 value)
164static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg, 165static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
165 unsigned int value) 166 unsigned int value)
166{ 167{
168 struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
167 u8 *reg_cache = codec->reg_cache; 169 u8 *reg_cache = codec->reg_cache;
168 int vls, vsp, old, len; 170 int vls, vsp, old, len;
169 char buf[18]; 171 char buf[18];
170 172
171 if (reg >= codec->reg_cache_size) 173 if (reg >= codec->driver->reg_cache_size)
172 return -EINVAL; 174 return -EINVAL;
173 175
174 /* hw_write and control_data pointers required for talking to the modem 176 /* hw_write and control_data pointers required for talking to the modem
175 * are expected to be set by the line discipline initialization code */ 177 * are expected to be set by the line discipline initialization code */
176 if (!codec->hw_write || !codec->control_data) 178 if (!codec->hw_write || !cx20442->control_data)
177 return -EIO; 179 return -EIO;
178 180
179 old = reg_cache[reg]; 181 old = reg_cache[reg];
@@ -202,17 +204,13 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
202 return -ENOMEM; 204 return -ENOMEM;
203 205
204 dev_dbg(codec->dev, "%s: %s\n", __func__, buf); 206 dev_dbg(codec->dev, "%s: %s\n", __func__, buf);
205 if (codec->hw_write(codec->control_data, buf, len) != len) 207 if (codec->hw_write(cx20442->control_data, buf, len) != len)
206 return -EIO; 208 return -EIO;
207 209
208 return 0; 210 return 0;
209} 211}
210 212
211 213
212/* Moved up here as line discipline referres it during initialization */
213static struct snd_soc_codec *cx20442_codec;
214
215
216/* 214/*
217 * Line discpline related code 215 * Line discpline related code
218 * 216 *
@@ -228,15 +226,15 @@ static const char *v253_init = "ate0m0q0+fclass=8\r";
228/* Line discipline .open() */ 226/* Line discipline .open() */
229static int v253_open(struct tty_struct *tty) 227static int v253_open(struct tty_struct *tty)
230{ 228{
231 struct snd_soc_codec *codec = cx20442_codec;
232 int ret, len = strlen(v253_init); 229 int ret, len = strlen(v253_init);
233 230
234 /* Doesn't make sense without write callback */ 231 /* Doesn't make sense without write callback */
235 if (!tty->ops->write) 232 if (!tty->ops->write)
236 return -EINVAL; 233 return -EINVAL;
237 234
238 /* Pass the codec structure address for use by other ldisc callbacks */ 235 /* Won't work if no codec pointer has been passed by a card driver */
239 tty->disc_data = codec; 236 if (!tty->disc_data)
237 return -ENODEV;
240 238
241 if (tty->ops->write(tty, v253_init, len) != len) { 239 if (tty->ops->write(tty, v253_init, len) != len) {
242 ret = -EIO; 240 ret = -EIO;
@@ -253,15 +251,18 @@ err:
253static void v253_close(struct tty_struct *tty) 251static void v253_close(struct tty_struct *tty)
254{ 252{
255 struct snd_soc_codec *codec = tty->disc_data; 253 struct snd_soc_codec *codec = tty->disc_data;
254 struct cx20442_priv *cx20442;
256 255
257 tty->disc_data = NULL; 256 tty->disc_data = NULL;
258 257
259 if (!codec) 258 if (!codec)
260 return; 259 return;
261 260
261 cx20442 = snd_soc_codec_get_drvdata(codec);
262
262 /* Prevent the codec driver from further accessing the modem */ 263 /* Prevent the codec driver from further accessing the modem */
263 codec->hw_write = NULL; 264 codec->hw_write = NULL;
264 codec->control_data = NULL; 265 cx20442->control_data = NULL;
265 codec->pop_time = 0; 266 codec->pop_time = 0;
266} 267}
267 268
@@ -277,15 +278,18 @@ static void v253_receive(struct tty_struct *tty,
277 const unsigned char *cp, char *fp, int count) 278 const unsigned char *cp, char *fp, int count)
278{ 279{
279 struct snd_soc_codec *codec = tty->disc_data; 280 struct snd_soc_codec *codec = tty->disc_data;
281 struct cx20442_priv *cx20442;
280 282
281 if (!codec) 283 if (!codec)
282 return; 284 return;
283 285
284 if (!codec->control_data) { 286 cx20442 = snd_soc_codec_get_drvdata(codec);
287
288 if (!cx20442->control_data) {
285 /* First modem response, complete setup procedure */ 289 /* First modem response, complete setup procedure */
286 290
287 /* Set up codec driver access to modem controls */ 291 /* Set up codec driver access to modem controls */
288 codec->control_data = tty; 292 cx20442->control_data = tty;
289 codec->hw_write = (hw_write_t)tty->ops->write; 293 codec->hw_write = (hw_write_t)tty->ops->write;
290 codec->pop_time = 1; 294 codec->pop_time = 1;
291 } 295 }
@@ -313,8 +317,8 @@ EXPORT_SYMBOL_GPL(v253_ops);
313 * Codec DAI 317 * Codec DAI
314 */ 318 */
315 319
316struct snd_soc_dai cx20442_dai = { 320static struct snd_soc_dai_driver cx20442_dai = {
317 .name = "CX20442", 321 .name = "cx20442-hifi",
318 .playback = { 322 .playback = {
319 .stream_name = "Playback", 323 .stream_name = "Playback",
320 .channels_min = 1, 324 .channels_min = 1,
@@ -330,142 +334,63 @@ struct snd_soc_dai cx20442_dai = {
330 .formats = SNDRV_PCM_FMTBIT_S16_LE, 334 .formats = SNDRV_PCM_FMTBIT_S16_LE,
331 }, 335 },
332}; 336};
333EXPORT_SYMBOL_GPL(cx20442_dai);
334 337
335static int cx20442_codec_probe(struct platform_device *pdev) 338static int cx20442_codec_probe(struct snd_soc_codec *codec)
336{ 339{
337 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 340 struct cx20442_priv *cx20442;
338 struct snd_soc_codec *codec;
339 int ret;
340
341 if (!cx20442_codec) {
342 dev_err(&pdev->dev, "cx20442 not yet discovered\n");
343 return -ENODEV;
344 }
345 codec = cx20442_codec;
346
347 socdev->card->codec = codec;
348 341
349 /* register pcms */ 342 cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
350 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 343 if (cx20442 == NULL)
351 if (ret < 0) { 344 return -ENOMEM;
352 dev_err(&pdev->dev, "failed to create pcms\n"); 345 snd_soc_codec_set_drvdata(codec, cx20442);
353 goto pcm_err;
354 }
355 346
356 cx20442_add_widgets(codec); 347 cx20442_add_widgets(codec);
357 348
358pcm_err: 349 cx20442->control_data = NULL;
359 return ret; 350 codec->hw_write = NULL;
351 codec->pop_time = 0;
352
353 return 0;
360} 354}
361 355
362/* power down chip */ 356/* power down chip */
363static int cx20442_codec_remove(struct platform_device *pdev) 357static int cx20442_codec_remove(struct snd_soc_codec *codec)
364{ 358{
365 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 359 struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
366 360
367 snd_soc_free_pcms(socdev); 361 if (cx20442->control_data) {
368 snd_soc_dapm_free(socdev); 362 struct tty_struct *tty = cx20442->control_data;
363 tty_hangup(tty);
364 }
369 365
366 kfree(cx20442);
370 return 0; 367 return 0;
371} 368}
372 369
373struct snd_soc_codec_device cx20442_codec_dev = { 370static struct snd_soc_codec_driver cx20442_codec_dev = {
374 .probe = cx20442_codec_probe, 371 .probe = cx20442_codec_probe,
375 .remove = cx20442_codec_remove, 372 .remove = cx20442_codec_remove,
373 .reg_cache_size = 1,
374 .reg_word_size = sizeof(u8),
375 .read = cx20442_read_reg_cache,
376 .write = cx20442_write,
376}; 377};
377EXPORT_SYMBOL_GPL(cx20442_codec_dev);
378
379static int cx20442_register(struct cx20442_priv *cx20442)
380{
381 struct snd_soc_codec *codec = &cx20442->codec;
382 int ret;
383
384 mutex_init(&codec->mutex);
385 INIT_LIST_HEAD(&codec->dapm_widgets);
386 INIT_LIST_HEAD(&codec->dapm_paths);
387
388 codec->name = "CX20442";
389 codec->owner = THIS_MODULE;
390 snd_soc_codec_set_drvdata(codec, cx20442);
391
392 codec->dai = &cx20442_dai;
393 codec->num_dai = 1;
394
395 codec->reg_cache = &cx20442->reg_cache;
396 codec->reg_cache_size = ARRAY_SIZE(cx20442->reg_cache);
397 codec->read = cx20442_read_reg_cache;
398 codec->write = cx20442_write;
399
400 codec->bias_level = SND_SOC_BIAS_OFF;
401
402 cx20442_dai.dev = codec->dev;
403
404 cx20442_codec = codec;
405
406 ret = snd_soc_register_codec(codec);
407 if (ret != 0) {
408 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
409 goto err;
410 }
411
412 ret = snd_soc_register_dai(&cx20442_dai);
413 if (ret != 0) {
414 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
415 goto err_codec;
416 }
417
418 return 0;
419
420err_codec:
421 snd_soc_unregister_codec(codec);
422err:
423 cx20442_codec = NULL;
424 kfree(cx20442);
425 return ret;
426}
427
428static void cx20442_unregister(struct cx20442_priv *cx20442)
429{
430 snd_soc_unregister_dai(&cx20442_dai);
431 snd_soc_unregister_codec(&cx20442->codec);
432
433 cx20442_codec = NULL;
434 kfree(cx20442);
435}
436 378
437static int cx20442_platform_probe(struct platform_device *pdev) 379static int cx20442_platform_probe(struct platform_device *pdev)
438{ 380{
439 struct cx20442_priv *cx20442; 381 return snd_soc_register_codec(&pdev->dev,
440 struct snd_soc_codec *codec; 382 &cx20442_codec_dev, &cx20442_dai, 1);
441
442 cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
443 if (cx20442 == NULL)
444 return -ENOMEM;
445
446 codec = &cx20442->codec;
447
448 codec->control_data = NULL;
449 codec->hw_write = NULL;
450 codec->pop_time = 0;
451
452 codec->dev = &pdev->dev;
453 platform_set_drvdata(pdev, cx20442);
454
455 return cx20442_register(cx20442);
456} 383}
457 384
458static int __exit cx20442_platform_remove(struct platform_device *pdev) 385static int __exit cx20442_platform_remove(struct platform_device *pdev)
459{ 386{
460 struct cx20442_priv *cx20442 = platform_get_drvdata(pdev); 387 snd_soc_unregister_codec(&pdev->dev);
461
462 cx20442_unregister(cx20442);
463 return 0; 388 return 0;
464} 389}
465 390
466static struct platform_driver cx20442_platform_driver = { 391static struct platform_driver cx20442_platform_driver = {
467 .driver = { 392 .driver = {
468 .name = "cx20442", 393 .name = "cx20442-codec",
469 .owner = THIS_MODULE, 394 .owner = THIS_MODULE,
470 }, 395 },
471 .probe = cx20442_platform_probe, 396 .probe = cx20442_platform_probe,
@@ -487,4 +412,4 @@ module_exit(cx20442_exit);
487MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver"); 412MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver");
488MODULE_AUTHOR("Janusz Krzysztofik"); 413MODULE_AUTHOR("Janusz Krzysztofik");
489MODULE_LICENSE("GPL"); 414MODULE_LICENSE("GPL");
490MODULE_ALIAS("platform:cx20442"); 415MODULE_ALIAS("platform:cx20442-codec");
diff --git a/sound/soc/codecs/cx20442.h b/sound/soc/codecs/cx20442.h
index 688a5eb62e1..c7a7c79ef0c 100644
--- a/sound/soc/codecs/cx20442.h
+++ b/sound/soc/codecs/cx20442.h
@@ -13,8 +13,6 @@
13#ifndef _CX20442_CODEC_H 13#ifndef _CX20442_CODEC_H
14#define _CX20442_CODEC_H 14#define _CX20442_CODEC_H
15 15
16extern struct snd_soc_dai cx20442_dai;
17extern struct snd_soc_codec_device cx20442_codec_dev;
18extern struct tty_ldisc_ops v253_ops; 16extern struct tty_ldisc_ops v253_ops;
19 17
20#endif 18#endif
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 3c51d6a5752..eabf3c06250 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -25,8 +25,6 @@
25#include <sound/initval.h> 25#include <sound/initval.h>
26#include <sound/tlv.h> 26#include <sound/tlv.h>
27 27
28#include "da7210.h"
29
30/* DA7210 register space */ 28/* DA7210 register space */
31#define DA7210_STATUS 0x02 29#define DA7210_STATUS 0x02
32#define DA7210_STARTUP1 0x03 30#define DA7210_STARTUP1 0x03
@@ -162,11 +160,10 @@ static const struct snd_kcontrol_new da7210_snd_controls[] = {
162 160
163/* Codec private data */ 161/* Codec private data */
164struct da7210_priv { 162struct da7210_priv {
165 struct snd_soc_codec codec; 163 enum snd_soc_control_type control_type;
164 void *control_data;
166}; 165};
167 166
168static struct snd_soc_codec *da7210_codec;
169
170/* 167/*
171 * Register cache 168 * Register cache
172 */ 169 */
@@ -209,12 +206,12 @@ static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
209 u8 *cache = codec->reg_cache; 206 u8 *cache = codec->reg_cache;
210 u8 data[2]; 207 u8 data[2];
211 208
212 BUG_ON(codec->volatile_register); 209 BUG_ON(codec->driver->volatile_register);
213 210
214 data[0] = reg & 0xff; 211 data[0] = reg & 0xff;
215 data[1] = value & 0xff; 212 data[1] = value & 0xff;
216 213
217 if (reg >= codec->reg_cache_size) 214 if (reg >= codec->driver->reg_cache_size)
218 return -EIO; 215 return -EIO;
219 216
220 if (2 != codec->hw_write(codec->control_data, data, 2)) 217 if (2 != codec->hw_write(codec->control_data, data, 2))
@@ -267,8 +264,7 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
267 struct snd_soc_dai *dai) 264 struct snd_soc_dai *dai)
268{ 265{
269 struct snd_soc_pcm_runtime *rtd = substream->private_data; 266 struct snd_soc_pcm_runtime *rtd = substream->private_data;
270 struct snd_soc_device *socdev = rtd->socdev; 267 struct snd_soc_codec *codec = rtd->codec;
271 struct snd_soc_codec *codec = socdev->card->codec;
272 u32 dai_cfg1; 268 u32 dai_cfg1;
273 u32 hpf_reg, hpf_mask, hpf_value; 269 u32 hpf_reg, hpf_mask, hpf_value;
274 u32 fs, bypass; 270 u32 fs, bypass;
@@ -430,9 +426,8 @@ static struct snd_soc_dai_ops da7210_dai_ops = {
430 .set_fmt = da7210_set_dai_fmt, 426 .set_fmt = da7210_set_dai_fmt,
431}; 427};
432 428
433struct snd_soc_dai da7210_dai = { 429static struct snd_soc_dai_driver da7210_dai = {
434 .name = "DA7210 IIS", 430 .name = "da7210-hifi",
435 .id = 0,
436 /* playback capabilities */ 431 /* playback capabilities */
437 .playback = { 432 .playback = {
438 .stream_name = "Playback", 433 .stream_name = "Playback",
@@ -452,55 +447,15 @@ struct snd_soc_dai da7210_dai = {
452 .ops = &da7210_dai_ops, 447 .ops = &da7210_dai_ops,
453 .symmetric_rates = 1, 448 .symmetric_rates = 1,
454}; 449};
455EXPORT_SYMBOL_GPL(da7210_dai);
456 450
457/* 451static int da7210_probe(struct snd_soc_codec *codec)
458 * Initialize the DA7210 driver
459 * register the mixer and dsp interfaces with the kernel
460 */
461static int da7210_init(struct da7210_priv *da7210)
462{ 452{
463 struct snd_soc_codec *codec = &da7210->codec; 453 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
464 int ret = 0;
465 454
466 if (da7210_codec) { 455 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
467 dev_err(codec->dev, "Another da7210 is registered\n");
468 return -EINVAL;
469 }
470 456
471 mutex_init(&codec->mutex); 457 codec->control_data = da7210->control_data;
472 INIT_LIST_HEAD(&codec->dapm_widgets);
473 INIT_LIST_HEAD(&codec->dapm_paths);
474
475 snd_soc_codec_set_drvdata(codec, da7210);
476 codec->name = "DA7210";
477 codec->owner = THIS_MODULE;
478 codec->read = da7210_read;
479 codec->write = da7210_write;
480 codec->dai = &da7210_dai;
481 codec->num_dai = 1;
482 codec->hw_write = (hw_write_t)i2c_master_send; 458 codec->hw_write = (hw_write_t)i2c_master_send;
483 codec->reg_cache_size = ARRAY_SIZE(da7210_reg);
484 codec->reg_cache = kmemdup(da7210_reg,
485 sizeof(da7210_reg), GFP_KERNEL);
486
487 if (!codec->reg_cache)
488 return -ENOMEM;
489
490 da7210_dai.dev = codec->dev;
491 da7210_codec = codec;
492
493 ret = snd_soc_register_codec(codec);
494 if (ret) {
495 dev_err(codec->dev, "Failed to register CODEC: %d\n", ret);
496 goto init_err;
497 }
498
499 ret = snd_soc_register_dai(&da7210_dai);
500 if (ret) {
501 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
502 goto codec_err;
503 }
504 459
505 /* FIXME 460 /* FIXME
506 * 461 *
@@ -583,54 +538,50 @@ static int da7210_init(struct da7210_priv *da7210)
583 /* Activate all enabled subsystem */ 538 /* Activate all enabled subsystem */
584 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 539 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
585 540
586 return ret; 541 snd_soc_add_controls(codec, da7210_snd_controls,
587 542 ARRAY_SIZE(da7210_snd_controls));
588codec_err:
589 snd_soc_unregister_codec(codec);
590init_err:
591 kfree(codec->reg_cache);
592 codec->reg_cache = NULL;
593 543
594 return ret; 544 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
595 545
546 return 0;
596} 547}
597 548
549static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
550 .probe = da7210_probe,
551 .read = da7210_read,
552 .write = da7210_write,
553 .reg_cache_size = ARRAY_SIZE(da7210_reg),
554 .reg_word_size = sizeof(u8),
555 .reg_cache_default = da7210_reg,
556};
557
598#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 558#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
599static int __devinit da7210_i2c_probe(struct i2c_client *i2c, 559static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
600 const struct i2c_device_id *id) 560 const struct i2c_device_id *id)
601{ 561{
602 struct da7210_priv *da7210; 562 struct da7210_priv *da7210;
603 struct snd_soc_codec *codec;
604 int ret; 563 int ret;
605 564
606 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL); 565 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
607 if (!da7210) 566 if (!da7210)
608 return -ENOMEM; 567 return -ENOMEM;
609 568
610 codec = &da7210->codec;
611 codec->dev = &i2c->dev;
612
613 i2c_set_clientdata(i2c, da7210); 569 i2c_set_clientdata(i2c, da7210);
614 codec->control_data = i2c; 570 da7210->control_data = i2c;
571 da7210->control_type = SND_SOC_I2C;
615 572
616 ret = da7210_init(da7210); 573 ret = snd_soc_register_codec(&i2c->dev,
617 if (ret < 0) { 574 &soc_codec_dev_da7210, &da7210_dai, 1);
618 pr_err("Failed to initialise da7210 audio codec\n"); 575 if (ret < 0)
619 kfree(da7210); 576 kfree(da7210);
620 }
621 577
622 return ret; 578 return ret;
623} 579}
624 580
625static int __devexit da7210_i2c_remove(struct i2c_client *client) 581static int __devexit da7210_i2c_remove(struct i2c_client *client)
626{ 582{
627 struct da7210_priv *da7210 = i2c_get_clientdata(client); 583 snd_soc_unregister_codec(&client->dev);
628 584 kfree(i2c_get_clientdata(client));
629 snd_soc_unregister_dai(&da7210_dai);
630 kfree(da7210->codec.reg_cache);
631 kfree(da7210);
632 da7210_codec = NULL;
633
634 return 0; 585 return 0;
635} 586}
636 587
@@ -643,7 +594,7 @@ MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
643/* I2C codec control layer */ 594/* I2C codec control layer */
644static struct i2c_driver da7210_i2c_driver = { 595static struct i2c_driver da7210_i2c_driver = {
645 .driver = { 596 .driver = {
646 .name = "DA7210 I2C Codec", 597 .name = "da7210-codec",
647 .owner = THIS_MODULE, 598 .owner = THIS_MODULE,
648 }, 599 },
649 .probe = da7210_i2c_probe, 600 .probe = da7210_i2c_probe,
@@ -652,50 +603,6 @@ static struct i2c_driver da7210_i2c_driver = {
652}; 603};
653#endif 604#endif
654 605
655static int da7210_probe(struct platform_device *pdev)
656{
657 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
658 struct snd_soc_codec *codec;
659 int ret;
660
661 if (!da7210_codec) {
662 dev_err(&pdev->dev, "Codec device not registered\n");
663 return -ENODEV;
664 }
665
666 socdev->card->codec = da7210_codec;
667 codec = da7210_codec;
668
669 /* Register pcms */
670 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
671 if (ret < 0)
672 goto pcm_err;
673
674 snd_soc_add_controls(da7210_codec, da7210_snd_controls,
675 ARRAY_SIZE(da7210_snd_controls));
676
677 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
678
679pcm_err:
680 return ret;
681}
682
683static int da7210_remove(struct platform_device *pdev)
684{
685 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
686
687 snd_soc_free_pcms(socdev);
688 snd_soc_dapm_free(socdev);
689
690 return 0;
691}
692
693struct snd_soc_codec_device soc_codec_dev_da7210 = {
694 .probe = da7210_probe,
695 .remove = da7210_remove,
696};
697EXPORT_SYMBOL_GPL(soc_codec_dev_da7210);
698
699static int __init da7210_modinit(void) 606static int __init da7210_modinit(void)
700{ 607{
701 int ret = 0; 608 int ret = 0;
diff --git a/sound/soc/codecs/da7210.h b/sound/soc/codecs/da7210.h
deleted file mode 100644
index 390d621eb74..00000000000
--- a/sound/soc/codecs/da7210.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * da7210.h -- audio driver for da7210
3 *
4 * Copyright (c) 2009 Dialog Semiconductor
5 * Written by David Chen <Dajun.chen@diasemi.com>
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef _DA7210_H
18#define _DA7210_H
19
20extern struct snd_soc_dai da7210_dai;
21extern struct snd_soc_codec_device soc_codec_dev_da7210;
22
23#endif
24
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 66557de1e4f..16253ec9b02 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -74,29 +74,22 @@ static const uint32_t jz4740_codec_regs[] = {
74struct jz4740_codec { 74struct jz4740_codec {
75 void __iomem *base; 75 void __iomem *base;
76 struct resource *mem; 76 struct resource *mem;
77
78 uint32_t reg_cache[2];
79 struct snd_soc_codec codec;
80}; 77};
81 78
82static inline struct jz4740_codec *codec_to_jz4740(struct snd_soc_codec *codec)
83{
84 return container_of(codec, struct jz4740_codec, codec);
85}
86
87static unsigned int jz4740_codec_read(struct snd_soc_codec *codec, 79static unsigned int jz4740_codec_read(struct snd_soc_codec *codec,
88 unsigned int reg) 80 unsigned int reg)
89{ 81{
90 struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec); 82 struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
91 return readl(jz4740_codec->base + (reg << 2)); 83 return readl(jz4740_codec->base + (reg << 2));
92} 84}
93 85
94static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg, 86static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg,
95 unsigned int val) 87 unsigned int val)
96{ 88{
97 struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec); 89 struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
90 u32 *cache = codec->reg_cache;
98 91
99 jz4740_codec->reg_cache[reg] = val; 92 cache[reg] = val;
100 writel(val, jz4740_codec->base + (reg << 2)); 93 writel(val, jz4740_codec->base + (reg << 2));
101 94
102 return 0; 95 return 0;
@@ -172,8 +165,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
172{ 165{
173 uint32_t val; 166 uint32_t val;
174 struct snd_soc_pcm_runtime *rtd = substream->private_data; 167 struct snd_soc_pcm_runtime *rtd = substream->private_data;
175 struct snd_soc_device *socdev = rtd->socdev; 168 struct snd_soc_codec *codec =rtd->codec;
176 struct snd_soc_codec *codec = socdev->card->codec;
177 169
178 switch (params_rate(params)) { 170 switch (params_rate(params)) {
179 case 8000: 171 case 8000:
@@ -219,8 +211,8 @@ static struct snd_soc_dai_ops jz4740_codec_dai_ops = {
219 .hw_params = jz4740_codec_hw_params, 211 .hw_params = jz4740_codec_hw_params,
220}; 212};
221 213
222struct snd_soc_dai jz4740_codec_dai = { 214static struct snd_soc_dai_driver jz4740_codec_dai = {
223 .name = "jz4740", 215 .name = "jz4740-hifi",
224 .playback = { 216 .playback = {
225 .stream_name = "Playback", 217 .stream_name = "Playback",
226 .channels_min = 2, 218 .channels_min = 2,
@@ -238,7 +230,6 @@ struct snd_soc_dai jz4740_codec_dai = {
238 .ops = &jz4740_codec_dai_ops, 230 .ops = &jz4740_codec_dai_ops,
239 .symmetric_rates = 1, 231 .symmetric_rates = 1,
240}; 232};
241EXPORT_SYMBOL_GPL(jz4740_codec_dai);
242 233
243static void jz4740_codec_wakeup(struct snd_soc_codec *codec) 234static void jz4740_codec_wakeup(struct snd_soc_codec *codec)
244{ 235{
@@ -302,23 +293,10 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
302 return 0; 293 return 0;
303} 294}
304 295
305static struct snd_soc_codec *jz4740_codec_codec; 296static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
306
307static int jz4740_codec_dev_probe(struct platform_device *pdev)
308{ 297{
309 int ret; 298 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
310 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 299 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
311 struct snd_soc_codec *codec = jz4740_codec_codec;
312
313 BUG_ON(!codec);
314
315 socdev->card->codec = codec;
316
317 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
318 if (ret) {
319 dev_err(&pdev->dev, "Failed to create pcms: %d\n", ret);
320 return ret;
321 }
322 300
323 snd_soc_add_controls(codec, jz4740_codec_controls, 301 snd_soc_add_controls(codec, jz4740_codec_controls,
324 ARRAY_SIZE(jz4740_codec_controls)); 302 ARRAY_SIZE(jz4740_codec_controls));
@@ -331,34 +309,27 @@ static int jz4740_codec_dev_probe(struct platform_device *pdev)
331 309
332 snd_soc_dapm_new_widgets(codec); 310 snd_soc_dapm_new_widgets(codec);
333 311
312 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
313
334 return 0; 314 return 0;
335} 315}
336 316
337static int jz4740_codec_dev_remove(struct platform_device *pdev) 317static int jz4740_codec_dev_remove(struct snd_soc_codec *codec)
338{ 318{
339 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 319 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
340
341 snd_soc_free_pcms(socdev);
342 snd_soc_dapm_free(socdev);
343 320
344 return 0; 321 return 0;
345} 322}
346 323
347#ifdef CONFIG_PM_SLEEP 324#ifdef CONFIG_PM_SLEEP
348 325
349static int jz4740_codec_suspend(struct platform_device *pdev, pm_message_t state) 326static int jz4740_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
350{ 327{
351 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
352 struct snd_soc_codec *codec = socdev->card->codec;
353
354 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); 328 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
355} 329}
356 330
357static int jz4740_codec_resume(struct platform_device *pdev) 331static int jz4740_codec_resume(struct snd_soc_codec *codec)
358{ 332{
359 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
360 struct snd_soc_codec *codec = socdev->card->codec;
361
362 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 333 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
363} 334}
364 335
@@ -367,19 +338,23 @@ static int jz4740_codec_resume(struct platform_device *pdev)
367#define jz4740_codec_resume NULL 338#define jz4740_codec_resume NULL
368#endif 339#endif
369 340
370struct snd_soc_codec_device soc_codec_dev_jz4740_codec = { 341static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
371 .probe = jz4740_codec_dev_probe, 342 .probe = jz4740_codec_dev_probe,
372 .remove = jz4740_codec_dev_remove, 343 .remove = jz4740_codec_dev_remove,
373 .suspend = jz4740_codec_suspend, 344 .suspend = jz4740_codec_suspend,
374 .resume = jz4740_codec_resume, 345 .resume = jz4740_codec_resume,
346 .read = jz4740_codec_read,
347 .write = jz4740_codec_write,
348 .set_bias_level = jz4740_codec_set_bias_level,
349 .reg_cache_default = jz4740_codec_regs,
350 .reg_word_size = sizeof(u32),
351 .reg_cache_size = 2,
375}; 352};
376EXPORT_SYMBOL_GPL(soc_codec_dev_jz4740_codec);
377 353
378static int __devinit jz4740_codec_probe(struct platform_device *pdev) 354static int __devinit jz4740_codec_probe(struct platform_device *pdev)
379{ 355{
380 int ret; 356 int ret;
381 struct jz4740_codec *jz4740_codec; 357 struct jz4740_codec *jz4740_codec;
382 struct snd_soc_codec *codec;
383 struct resource *mem; 358 struct resource *mem;
384 359
385 jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL); 360 jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL);
@@ -408,55 +383,17 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev)
408 } 383 }
409 jz4740_codec->mem = mem; 384 jz4740_codec->mem = mem;
410 385
411 jz4740_codec_dai.dev = &pdev->dev;
412
413 codec = &jz4740_codec->codec;
414
415 codec->dev = &pdev->dev;
416 codec->name = "jz4740";
417 codec->owner = THIS_MODULE;
418
419 codec->read = jz4740_codec_read;
420 codec->write = jz4740_codec_write;
421 codec->set_bias_level = jz4740_codec_set_bias_level;
422 codec->bias_level = SND_SOC_BIAS_OFF;
423
424 codec->dai = &jz4740_codec_dai;
425 codec->num_dai = 1;
426
427 codec->reg_cache = jz4740_codec->reg_cache;
428 codec->reg_cache_size = 2;
429 memcpy(codec->reg_cache, jz4740_codec_regs, sizeof(jz4740_codec_regs));
430
431 mutex_init(&codec->mutex);
432 INIT_LIST_HEAD(&codec->dapm_widgets);
433 INIT_LIST_HEAD(&codec->dapm_paths);
434
435 jz4740_codec_codec = codec;
436
437 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
438 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
439
440 platform_set_drvdata(pdev, jz4740_codec); 386 platform_set_drvdata(pdev, jz4740_codec);
441 387
442 ret = snd_soc_register_codec(codec); 388 ret = snd_soc_register_codec(&pdev->dev,
389 &soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1);
443 if (ret) { 390 if (ret) {
444 dev_err(&pdev->dev, "Failed to register codec\n"); 391 dev_err(&pdev->dev, "Failed to register codec\n");
445 goto err_iounmap; 392 goto err_iounmap;
446 } 393 }
447 394
448 ret = snd_soc_register_dai(&jz4740_codec_dai);
449 if (ret) {
450 dev_err(&pdev->dev, "Failed to register codec dai\n");
451 goto err_unregister_codec;
452 }
453
454 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
455
456 return 0; 395 return 0;
457 396
458err_unregister_codec:
459 snd_soc_unregister_codec(codec);
460err_iounmap: 397err_iounmap:
461 iounmap(jz4740_codec->base); 398 iounmap(jz4740_codec->base);
462err_release_mem_region: 399err_release_mem_region:
@@ -472,8 +409,7 @@ static int __devexit jz4740_codec_remove(struct platform_device *pdev)
472 struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev); 409 struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev);
473 struct resource *mem = jz4740_codec->mem; 410 struct resource *mem = jz4740_codec->mem;
474 411
475 snd_soc_unregister_dai(&jz4740_codec_dai); 412 snd_soc_unregister_codec(&pdev->dev);
476 snd_soc_unregister_codec(&jz4740_codec->codec);
477 413
478 iounmap(jz4740_codec->base); 414 iounmap(jz4740_codec->base);
479 release_mem_region(mem->start, resource_size(mem)); 415 release_mem_region(mem->start, resource_size(mem));
diff --git a/sound/soc/codecs/jz4740.h b/sound/soc/codecs/jz4740.h
deleted file mode 100644
index b5a0691be76..00000000000
--- a/sound/soc/codecs/jz4740.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
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 * You should have received a copy of the GNU General Public License along
9 * with this program; if not, write to the Free Software Foundation, Inc.,
10 * 675 Mass Ave, Cambridge, MA 02139, USA.
11 *
12 */
13
14#ifndef __SND_SOC_CODECS_JZ4740_CODEC_H__
15#define __SND_SOC_CODECS_JZ4740_CODEC_H__
16
17extern struct snd_soc_dai jz4740_codec_dai;
18extern struct snd_soc_codec_device soc_codec_dev_jz4740_codec;
19
20#endif
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 5a5f187a265..bd8f26e4160 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -32,8 +32,8 @@
32#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 32#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
33 SNDRV_PCM_RATE_48000) 33 SNDRV_PCM_RATE_48000)
34 34
35struct snd_soc_dai pcm3008_dai = { 35static struct snd_soc_dai_driver pcm3008_dai = {
36 .name = "PCM3008 HiFi", 36 .name = "pcm3008-hifi",
37 .playback = { 37 .playback = {
38 .stream_name = "PCM3008 Playback", 38 .stream_name = "PCM3008 Playback",
39 .channels_min = 1, 39 .channels_min = 1,
@@ -49,7 +49,6 @@ struct snd_soc_dai pcm3008_dai = {
49 .formats = SNDRV_PCM_FMTBIT_S16_LE, 49 .formats = SNDRV_PCM_FMTBIT_S16_LE,
50 }, 50 },
51}; 51};
52EXPORT_SYMBOL_GPL(pcm3008_dai);
53 52
54static void pcm3008_gpio_free(struct pcm3008_setup_data *setup) 53static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
55{ 54{
@@ -59,38 +58,13 @@ static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
59 gpio_free(setup->pdda_pin); 58 gpio_free(setup->pdda_pin);
60} 59}
61 60
62static int pcm3008_soc_probe(struct platform_device *pdev) 61static int pcm3008_soc_probe(struct snd_soc_codec *codec)
63{ 62{
64 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 63 struct pcm3008_setup_data *setup = codec->dev->platform_data;
65 struct snd_soc_codec *codec;
66 struct pcm3008_setup_data *setup = socdev->codec_data;
67 int ret = 0; 64 int ret = 0;
68 65
69 printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION); 66 printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION);
70 67
71 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
72 if (!socdev->card->codec)
73 return -ENOMEM;
74
75 codec = socdev->card->codec;
76 mutex_init(&codec->mutex);
77
78 codec->name = "PCM3008";
79 codec->owner = THIS_MODULE;
80 codec->dai = &pcm3008_dai;
81 codec->num_dai = 1;
82 codec->write = NULL;
83 codec->read = NULL;
84 INIT_LIST_HEAD(&codec->dapm_widgets);
85 INIT_LIST_HEAD(&codec->dapm_paths);
86
87 /* Register PCMs. */
88 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
89 if (ret < 0) {
90 printk(KERN_ERR "pcm3008: failed to create pcms\n");
91 goto pcm_err;
92 }
93
94 /* DEM1 DEM0 DE-EMPHASIS_MODE 68 /* DEM1 DEM0 DE-EMPHASIS_MODE
95 * Low Low De-emphasis 44.1 kHz ON 69 * Low Low De-emphasis 44.1 kHz ON
96 * Low High De-emphasis OFF 70 * Low High De-emphasis OFF
@@ -130,33 +104,22 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
130 104
131gpio_err: 105gpio_err:
132 pcm3008_gpio_free(setup); 106 pcm3008_gpio_free(setup);
133pcm_err:
134 kfree(socdev->card->codec);
135 107
136 return ret; 108 return ret;
137} 109}
138 110
139static int pcm3008_soc_remove(struct platform_device *pdev) 111static int pcm3008_soc_remove(struct snd_soc_codec *codec)
140{ 112{
141 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 113 struct pcm3008_setup_data *setup = codec->dev->platform_data;
142 struct snd_soc_codec *codec = socdev->card->codec;
143 struct pcm3008_setup_data *setup = socdev->codec_data;
144
145 if (!codec)
146 return 0;
147 114
148 pcm3008_gpio_free(setup); 115 pcm3008_gpio_free(setup);
149 snd_soc_free_pcms(socdev);
150 kfree(socdev->card->codec);
151
152 return 0; 116 return 0;
153} 117}
154 118
155#ifdef CONFIG_PM 119#ifdef CONFIG_PM
156static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg) 120static int pcm3008_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
157{ 121{
158 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 122 struct pcm3008_setup_data *setup = codec->dev->platform_data;
159 struct pcm3008_setup_data *setup = socdev->codec_data;
160 123
161 gpio_set_value(setup->pdad_pin, 0); 124 gpio_set_value(setup->pdad_pin, 0);
162 gpio_set_value(setup->pdda_pin, 0); 125 gpio_set_value(setup->pdda_pin, 0);
@@ -164,10 +127,9 @@ static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
164 return 0; 127 return 0;
165} 128}
166 129
167static int pcm3008_soc_resume(struct platform_device *pdev) 130static int pcm3008_soc_resume(struct snd_soc_codec *codec)
168{ 131{
169 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 132 struct pcm3008_setup_data *setup = codec->dev->platform_data;
170 struct pcm3008_setup_data *setup = socdev->codec_data;
171 133
172 gpio_set_value(setup->pdad_pin, 1); 134 gpio_set_value(setup->pdad_pin, 1);
173 gpio_set_value(setup->pdda_pin, 1); 135 gpio_set_value(setup->pdda_pin, 1);
@@ -179,23 +141,45 @@ static int pcm3008_soc_resume(struct platform_device *pdev)
179#define pcm3008_soc_resume NULL 141#define pcm3008_soc_resume NULL
180#endif 142#endif
181 143
182struct snd_soc_codec_device soc_codec_dev_pcm3008 = { 144static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
183 .probe = pcm3008_soc_probe, 145 .probe = pcm3008_soc_probe,
184 .remove = pcm3008_soc_remove, 146 .remove = pcm3008_soc_remove,
185 .suspend = pcm3008_soc_suspend, 147 .suspend = pcm3008_soc_suspend,
186 .resume = pcm3008_soc_resume, 148 .resume = pcm3008_soc_resume,
187}; 149};
188EXPORT_SYMBOL_GPL(soc_codec_dev_pcm3008);
189 150
190static int __init pcm3008_init(void) 151static int __devinit pcm3008_codec_probe(struct platform_device *pdev)
152{
153 return snd_soc_register_codec(&pdev->dev,
154 &soc_codec_dev_pcm3008, &pcm3008_dai, 1);
155}
156
157static int __devexit pcm3008_codec_remove(struct platform_device *pdev)
158{
159 snd_soc_unregister_codec(&pdev->dev);
160 return 0;
161}
162
163MODULE_ALIAS("platform:pcm3008-codec");
164
165static struct platform_driver pcm3008_codec_driver = {
166 .probe = pcm3008_codec_probe,
167 .remove = __devexit_p(pcm3008_codec_remove),
168 .driver = {
169 .name = "pcm3008-codec",
170 .owner = THIS_MODULE,
171 },
172};
173
174static int __init pcm3008_modinit(void)
191{ 175{
192 return snd_soc_register_dai(&pcm3008_dai); 176 return platform_driver_register(&pcm3008_codec_driver);
193} 177}
194module_init(pcm3008_init); 178module_init(pcm3008_modinit);
195 179
196static void __exit pcm3008_exit(void) 180static void __exit pcm3008_exit(void)
197{ 181{
198 snd_soc_unregister_dai(&pcm3008_dai); 182 platform_driver_unregister(&pcm3008_codec_driver);
199} 183}
200module_exit(pcm3008_exit); 184module_exit(pcm3008_exit);
201 185
diff --git a/sound/soc/codecs/pcm3008.h b/sound/soc/codecs/pcm3008.h
index d04e87d3c06..7e5489ab481 100644
--- a/sound/soc/codecs/pcm3008.h
+++ b/sound/soc/codecs/pcm3008.h
@@ -19,7 +19,4 @@ struct pcm3008_setup_data {
19 unsigned pdda_pin; 19 unsigned pdda_pin;
20}; 20};
21 21
22extern struct snd_soc_codec_device soc_codec_dev_pcm3008;
23extern struct snd_soc_dai pcm3008_dai;
24
25#endif 22#endif
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c
index 9119836051a..4c32b54913a 100644
--- a/sound/soc/codecs/spdif_transciever.c
+++ b/sound/soc/codecs/spdif_transciever.c
@@ -21,57 +21,16 @@
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23 23
24#include "spdif_transciever.h"
25
26MODULE_LICENSE("GPL"); 24MODULE_LICENSE("GPL");
27 25
28#define STUB_RATES SNDRV_PCM_RATE_8000_96000 26#define STUB_RATES SNDRV_PCM_RATE_8000_96000
29#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE 27#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
30 28
31static struct snd_soc_codec *spdif_dit_codec;
32
33static int spdif_dit_codec_probe(struct platform_device *pdev)
34{
35 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
36 struct snd_soc_codec *codec;
37 int ret;
38
39 if (spdif_dit_codec == NULL) {
40 dev_err(&pdev->dev, "Codec device not registered\n");
41 return -ENODEV;
42 }
43
44 socdev->card->codec = spdif_dit_codec;
45 codec = spdif_dit_codec;
46
47 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
48 if (ret < 0) {
49 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
50 goto err_create_pcms;
51 }
52
53 return 0;
54
55err_create_pcms:
56 return ret;
57}
58
59static int spdif_dit_codec_remove(struct platform_device *pdev)
60{
61 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
62
63 snd_soc_free_pcms(socdev);
64
65 return 0;
66}
67 29
68struct snd_soc_codec_device soc_codec_dev_spdif_dit = { 30static struct snd_soc_codec_driver soc_codec_spdif_dit;
69 .probe = spdif_dit_codec_probe,
70 .remove = spdif_dit_codec_remove,
71}; EXPORT_SYMBOL_GPL(soc_codec_dev_spdif_dit);
72 31
73struct snd_soc_dai dit_stub_dai = { 32static struct snd_soc_dai_driver dit_stub_dai = {
74 .name = "DIT", 33 .name = "dit-hifi",
75 .playback = { 34 .playback = {
76 .stream_name = "Playback", 35 .stream_name = "Playback",
77 .channels_min = 1, 36 .channels_min = 1,
@@ -80,65 +39,16 @@ struct snd_soc_dai dit_stub_dai = {
80 .formats = STUB_FORMATS, 39 .formats = STUB_FORMATS,
81 }, 40 },
82}; 41};
83EXPORT_SYMBOL_GPL(dit_stub_dai);
84 42
85static int spdif_dit_probe(struct platform_device *pdev) 43static int spdif_dit_probe(struct platform_device *pdev)
86{ 44{
87 struct snd_soc_codec *codec; 45 return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dit,
88 int ret; 46 &dit_stub_dai, 1);
89
90 if (spdif_dit_codec) {
91 dev_err(&pdev->dev, "Another Codec is registered\n");
92 ret = -EINVAL;
93 goto err_reg_codec;
94 }
95
96 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
97 if (codec == NULL)
98 return -ENOMEM;
99
100 codec->dev = &pdev->dev;
101
102 mutex_init(&codec->mutex);
103
104 INIT_LIST_HEAD(&codec->dapm_widgets);
105 INIT_LIST_HEAD(&codec->dapm_paths);
106
107 codec->name = "spdif-dit";
108 codec->owner = THIS_MODULE;
109 codec->dai = &dit_stub_dai;
110 codec->num_dai = 1;
111
112 spdif_dit_codec = codec;
113
114 ret = snd_soc_register_codec(codec);
115 if (ret < 0) {
116 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
117 goto err_reg_codec;
118 }
119
120 dit_stub_dai.dev = &pdev->dev;
121 ret = snd_soc_register_dai(&dit_stub_dai);
122 if (ret < 0) {
123 dev_err(codec->dev, "Failed to register dai: %d\n", ret);
124 goto err_reg_dai;
125 }
126
127 return 0;
128
129err_reg_dai:
130 snd_soc_unregister_codec(codec);
131err_reg_codec:
132 kfree(spdif_dit_codec);
133 return ret;
134} 47}
135 48
136static int spdif_dit_remove(struct platform_device *pdev) 49static int spdif_dit_remove(struct platform_device *pdev)
137{ 50{
138 snd_soc_unregister_dai(&dit_stub_dai); 51 snd_soc_unregister_codec(&pdev->dev);
139 snd_soc_unregister_codec(spdif_dit_codec);
140 kfree(spdif_dit_codec);
141 spdif_dit_codec = NULL;
142 return 0; 52 return 0;
143} 53}
144 54
diff --git a/sound/soc/codecs/spdif_transciever.h b/sound/soc/codecs/spdif_transciever.h
deleted file mode 100644
index 1e102124f54..00000000000
--- a/sound/soc/codecs/spdif_transciever.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * ALSA SoC DIT/DIR driver header
3 *
4 * Author: Steve Chen, <schen@mvista.com>
5 * Copyright: (C) 2008 MontaVista Software, Inc., <source@mvista.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#ifndef CODEC_STUBS_H
13#define CODEC_STUBS_H
14
15extern struct snd_soc_codec_device soc_codec_dev_spdif_dit;
16extern struct snd_soc_dai dit_stub_dai;
17
18#endif /* CODEC_STUBS_H */
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index b47ed4f6ab2..67d8c044ca0 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -45,11 +45,11 @@
45 45
46#define SSM2602_VERSION "0.1" 46#define SSM2602_VERSION "0.1"
47 47
48struct snd_soc_codec_device soc_codec_dev_ssm2602;
49
50/* codec private data */ 48/* codec private data */
51struct ssm2602_priv { 49struct ssm2602_priv {
52 unsigned int sysclk; 50 unsigned int sysclk;
51 enum snd_soc_control_type control_type;
52 void *control_data;
53 struct snd_pcm_substream *master_substream; 53 struct snd_pcm_substream *master_substream;
54 struct snd_pcm_substream *slave_substream; 54 struct snd_pcm_substream *slave_substream;
55}; 55};
@@ -276,8 +276,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
276{ 276{
277 u16 srate; 277 u16 srate;
278 struct snd_soc_pcm_runtime *rtd = substream->private_data; 278 struct snd_soc_pcm_runtime *rtd = substream->private_data;
279 struct snd_soc_device *socdev = rtd->socdev; 279 struct snd_soc_codec *codec = rtd->codec;
280 struct snd_soc_codec *codec = socdev->card->codec;
281 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 280 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
282 struct i2c_client *i2c = codec->control_data; 281 struct i2c_client *i2c = codec->control_data;
283 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; 282 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
@@ -321,8 +320,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
321 struct snd_soc_dai *dai) 320 struct snd_soc_dai *dai)
322{ 321{
323 struct snd_soc_pcm_runtime *rtd = substream->private_data; 322 struct snd_soc_pcm_runtime *rtd = substream->private_data;
324 struct snd_soc_device *socdev = rtd->socdev; 323 struct snd_soc_codec *codec = rtd->codec;
325 struct snd_soc_codec *codec = socdev->card->codec;
326 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 324 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
327 struct i2c_client *i2c = codec->control_data; 325 struct i2c_client *i2c = codec->control_data;
328 struct snd_pcm_runtime *master_runtime; 326 struct snd_pcm_runtime *master_runtime;
@@ -360,8 +358,7 @@ static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream,
360 struct snd_soc_dai *dai) 358 struct snd_soc_dai *dai)
361{ 359{
362 struct snd_soc_pcm_runtime *rtd = substream->private_data; 360 struct snd_soc_pcm_runtime *rtd = substream->private_data;
363 struct snd_soc_device *socdev = rtd->socdev; 361 struct snd_soc_codec *codec = rtd->codec;
364 struct snd_soc_codec *codec = socdev->card->codec;
365 /* set active */ 362 /* set active */
366 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC); 363 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
367 364
@@ -372,8 +369,7 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
372 struct snd_soc_dai *dai) 369 struct snd_soc_dai *dai)
373{ 370{
374 struct snd_soc_pcm_runtime *rtd = substream->private_data; 371 struct snd_soc_pcm_runtime *rtd = substream->private_data;
375 struct snd_soc_device *socdev = rtd->socdev; 372 struct snd_soc_codec *codec = rtd->codec;
376 struct snd_soc_codec *codec = socdev->card->codec;
377 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 373 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
378 374
379 /* deactivate */ 375 /* deactivate */
@@ -518,8 +514,8 @@ static struct snd_soc_dai_ops ssm2602_dai_ops = {
518 .set_fmt = ssm2602_set_dai_fmt, 514 .set_fmt = ssm2602_set_dai_fmt,
519}; 515};
520 516
521struct snd_soc_dai ssm2602_dai = { 517static struct snd_soc_dai_driver ssm2602_dai = {
522 .name = "SSM2602", 518 .name = "ssm2602-hifi",
523 .playback = { 519 .playback = {
524 .stream_name = "Playback", 520 .stream_name = "Playback",
525 .channels_min = 2, 521 .channels_min = 2,
@@ -534,21 +530,15 @@ struct snd_soc_dai ssm2602_dai = {
534 .formats = SSM2602_FORMATS,}, 530 .formats = SSM2602_FORMATS,},
535 .ops = &ssm2602_dai_ops, 531 .ops = &ssm2602_dai_ops,
536}; 532};
537EXPORT_SYMBOL_GPL(ssm2602_dai);
538 533
539static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state) 534static int ssm2602_suspend(struct snd_soc_codec *codec, pm_message_t state)
540{ 535{
541 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
542 struct snd_soc_codec *codec = socdev->card->codec;
543
544 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); 536 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
545 return 0; 537 return 0;
546} 538}
547 539
548static int ssm2602_resume(struct platform_device *pdev) 540static int ssm2602_resume(struct snd_soc_codec *codec)
549{ 541{
550 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
551 struct snd_soc_codec *codec = socdev->card->codec;
552 int i; 542 int i;
553 u8 data[2]; 543 u8 data[2];
554 u16 *cache = codec->reg_cache; 544 u16 *cache = codec->reg_cache;
@@ -563,36 +553,18 @@ static int ssm2602_resume(struct platform_device *pdev)
563 return 0; 553 return 0;
564} 554}
565 555
566/* 556static int ssm2602_probe(struct snd_soc_codec *codec)
567 * initialise the ssm2602 driver
568 * register the mixer and dsp interfaces with the kernel
569 */
570static int ssm2602_init(struct snd_soc_device *socdev)
571{ 557{
572 struct snd_soc_codec *codec = socdev->card->codec; 558 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
573 int reg, ret = 0; 559 int ret = 0, reg;
574 560
575 codec->name = "SSM2602"; 561 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
576 codec->owner = THIS_MODULE; 562
577 codec->read = ssm2602_read_reg_cache; 563 codec->bias_level = SND_SOC_BIAS_OFF,
578 codec->write = ssm2602_write; 564 codec->control_data = ssm2602->control_data;
579 codec->set_bias_level = ssm2602_set_bias_level;
580 codec->dai = &ssm2602_dai;
581 codec->num_dai = 1;
582 codec->reg_cache_size = sizeof(ssm2602_reg);
583 codec->reg_cache = kmemdup(ssm2602_reg, sizeof(ssm2602_reg),
584 GFP_KERNEL);
585 if (codec->reg_cache == NULL)
586 return -ENOMEM;
587 565
588 ssm2602_reset(codec); 566 ssm2602_reset(codec);
589 567
590 /* register pcms */
591 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
592 if (ret < 0) {
593 pr_err("ssm2602: failed to create pcms\n");
594 goto pcm_err;
595 }
596 /*power on device*/ 568 /*power on device*/
597 ssm2602_write(codec, SSM2602_ACTIVE, 0); 569 ssm2602_write(codec, SSM2602_ACTIVE, 0);
598 /* set the update bits */ 570 /* set the update bits */
@@ -614,13 +586,27 @@ static int ssm2602_init(struct snd_soc_device *socdev)
614 ssm2602_add_widgets(codec); 586 ssm2602_add_widgets(codec);
615 587
616 return ret; 588 return ret;
589}
617 590
618pcm_err: 591/* remove everything here */
619 kfree(codec->reg_cache); 592static int ssm2602_remove(struct snd_soc_codec *codec)
620 return ret; 593{
594 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
595 return 0;
621} 596}
622 597
623static struct snd_soc_device *ssm2602_socdev; 598static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
599 .probe = ssm2602_probe,
600 .remove = ssm2602_remove,
601 .suspend = ssm2602_suspend,
602 .resume = ssm2602_resume,
603 .read = ssm2602_read_reg_cache,
604 .write = ssm2602_write,
605 .set_bias_level = ssm2602_set_bias_level,
606 .reg_cache_size = sizeof(ssm2602_reg),
607 .reg_word_size = sizeof(u16),
608 .reg_cache_default = ssm2602_reg,
609};
624 610
625#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 611#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
626/* 612/*
@@ -632,24 +618,28 @@ static struct snd_soc_device *ssm2602_socdev;
632static int ssm2602_i2c_probe(struct i2c_client *i2c, 618static int ssm2602_i2c_probe(struct i2c_client *i2c,
633 const struct i2c_device_id *id) 619 const struct i2c_device_id *id)
634{ 620{
635 struct snd_soc_device *socdev = ssm2602_socdev; 621 struct ssm2602_priv *ssm2602;
636 struct snd_soc_codec *codec = socdev->card->codec;
637 int ret; 622 int ret;
638 623
639 i2c_set_clientdata(i2c, codec); 624 ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
640 codec->control_data = i2c; 625 if (ssm2602 == NULL)
626 return -ENOMEM;
641 627
642 ret = ssm2602_init(socdev); 628 i2c_set_clientdata(i2c, ssm2602);
643 if (ret < 0) 629 ssm2602->control_data = i2c;
644 pr_err("failed to initialise SSM2602\n"); 630 ssm2602->control_type = SND_SOC_I2C;
645 631
632 ret = snd_soc_register_codec(&i2c->dev,
633 &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
634 if (ret < 0)
635 kfree(ssm2602);
646 return ret; 636 return ret;
647} 637}
648 638
649static int ssm2602_i2c_remove(struct i2c_client *client) 639static int ssm2602_i2c_remove(struct i2c_client *client)
650{ 640{
651 struct snd_soc_codec *codec = i2c_get_clientdata(client); 641 snd_soc_unregister_codec(&client->dev);
652 kfree(codec->reg_cache); 642 kfree(i2c_get_clientdata(client));
653 return 0; 643 return 0;
654} 644}
655 645
@@ -658,130 +648,39 @@ static const struct i2c_device_id ssm2602_i2c_id[] = {
658 { } 648 { }
659}; 649};
660MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); 650MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
651
661/* corgi i2c codec control layer */ 652/* corgi i2c codec control layer */
662static struct i2c_driver ssm2602_i2c_driver = { 653static struct i2c_driver ssm2602_i2c_driver = {
663 .driver = { 654 .driver = {
664 .name = "SSM2602 I2C Codec", 655 .name = "ssm2602-codec",
665 .owner = THIS_MODULE, 656 .owner = THIS_MODULE,
666 }, 657 },
667 .probe = ssm2602_i2c_probe, 658 .probe = ssm2602_i2c_probe,
668 .remove = ssm2602_i2c_remove, 659 .remove = ssm2602_i2c_remove,
669 .id_table = ssm2602_i2c_id, 660 .id_table = ssm2602_i2c_id,
670}; 661};
671
672static int ssm2602_add_i2c_device(struct platform_device *pdev,
673 const struct ssm2602_setup_data *setup)
674{
675 struct i2c_board_info info;
676 struct i2c_adapter *adapter;
677 struct i2c_client *client;
678 int ret;
679
680 ret = i2c_add_driver(&ssm2602_i2c_driver);
681 if (ret != 0) {
682 dev_err(&pdev->dev, "can't add i2c driver\n");
683 return ret;
684 }
685 memset(&info, 0, sizeof(struct i2c_board_info));
686 info.addr = setup->i2c_address;
687 strlcpy(info.type, "ssm2602", I2C_NAME_SIZE);
688 adapter = i2c_get_adapter(setup->i2c_bus);
689 if (!adapter) {
690 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
691 setup->i2c_bus);
692 goto err_driver;
693 }
694 client = i2c_new_device(adapter, &info);
695 i2c_put_adapter(adapter);
696 if (!client) {
697 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
698 (unsigned int)info.addr);
699 goto err_driver;
700 }
701 return 0;
702err_driver:
703 i2c_del_driver(&ssm2602_i2c_driver);
704 return -ENODEV;
705}
706#endif 662#endif
707 663
708static int ssm2602_probe(struct platform_device *pdev) 664
665static int __init ssm2602_modinit(void)
709{ 666{
710 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
711 struct ssm2602_setup_data *setup;
712 struct snd_soc_codec *codec;
713 struct ssm2602_priv *ssm2602;
714 int ret = 0; 667 int ret = 0;
715
716 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
717
718 setup = socdev->codec_data;
719 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
720 if (codec == NULL)
721 return -ENOMEM;
722
723 ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
724 if (ssm2602 == NULL) {
725 kfree(codec);
726 return -ENOMEM;
727 }
728
729 snd_soc_codec_set_drvdata(codec, ssm2602);
730 socdev->card->codec = codec;
731 mutex_init(&codec->mutex);
732 INIT_LIST_HEAD(&codec->dapm_widgets);
733 INIT_LIST_HEAD(&codec->dapm_paths);
734
735 ssm2602_socdev = socdev;
736#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 668#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
737 if (setup->i2c_address) { 669 ret = i2c_add_driver(&ssm2602_i2c_driver);
738 codec->hw_write = (hw_write_t)i2c_master_send; 670 if (ret != 0) {
739 ret = ssm2602_add_i2c_device(pdev, setup); 671 printk(KERN_ERR "Failed to register SSM2602 I2C driver: %d\n",
672 ret);
740 } 673 }
741#else
742 /* other interfaces */
743#endif 674#endif
744 return ret; 675 return ret;
745} 676}
677module_init(ssm2602_modinit);
746 678
747/* remove everything here */ 679static void __exit ssm2602_exit(void)
748static int ssm2602_remove(struct platform_device *pdev)
749{ 680{
750 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
751 struct snd_soc_codec *codec = socdev->card->codec;
752
753 if (codec->control_data)
754 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
755
756 snd_soc_free_pcms(socdev);
757 snd_soc_dapm_free(socdev);
758#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 681#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
759 i2c_unregister_device(codec->control_data);
760 i2c_del_driver(&ssm2602_i2c_driver); 682 i2c_del_driver(&ssm2602_i2c_driver);
761#endif 683#endif
762 kfree(snd_soc_codec_get_drvdata(codec));
763 kfree(codec);
764
765 return 0;
766}
767
768struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
769 .probe = ssm2602_probe,
770 .remove = ssm2602_remove,
771 .suspend = ssm2602_suspend,
772 .resume = ssm2602_resume,
773};
774EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
775
776static int __init ssm2602_modinit(void)
777{
778 return snd_soc_register_dai(&ssm2602_dai);
779}
780module_init(ssm2602_modinit);
781
782static void __exit ssm2602_exit(void)
783{
784 snd_soc_unregister_dai(&ssm2602_dai);
785} 684}
786module_exit(ssm2602_exit); 685module_exit(ssm2602_exit);
787 686
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h
index f344e6d76e3..42a47d0f8e2 100644
--- a/sound/soc/codecs/ssm2602.h
+++ b/sound/soc/codecs/ssm2602.h
@@ -124,7 +124,4 @@ struct ssm2602_setup_data {
124 unsigned short i2c_address; 124 unsigned short i2c_address;
125}; 125};
126 126
127extern struct snd_soc_dai ssm2602_dai;
128extern struct snd_soc_codec_device soc_codec_dev_ssm2602;
129
130#endif 127#endif
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index ee86568545c..00d67cc8e20 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -25,7 +25,6 @@
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/tlv.h> 27#include <sound/tlv.h>
28#include <sound/soc-of-simple.h>
29 28
30#include "stac9766.h" 29#include "stac9766.h"
31 30
@@ -257,20 +256,15 @@ static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
257 return 0; 256 return 0;
258} 257}
259 258
260static int stac9766_codec_suspend(struct platform_device *pdev, 259static int stac9766_codec_suspend(struct snd_soc_codec *codec,
261 pm_message_t state) 260 pm_message_t state)
262{ 261{
263 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
264 struct snd_soc_codec *codec = socdev->card->codec;
265
266 stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF); 262 stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF);
267 return 0; 263 return 0;
268} 264}
269 265
270static int stac9766_codec_resume(struct platform_device *pdev) 266static int stac9766_codec_resume(struct snd_soc_codec *codec)
271{ 267{
272 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
273 struct snd_soc_codec *codec = socdev->card->codec;
274 u16 id, reset; 268 u16 id, reset;
275 269
276 reset = 0; 270 reset = 0;
@@ -300,10 +294,9 @@ static struct snd_soc_dai_ops stac9766_dai_ops_digital = {
300 .prepare = ac97_digital_prepare, 294 .prepare = ac97_digital_prepare,
301}; 295};
302 296
303struct snd_soc_dai stac9766_dai[] = { 297static struct snd_soc_dai_driver stac9766_dai[] = {
304{ 298{
305 .name = "stac9766 analog", 299 .name = "stac9766-hifi-analog",
306 .id = 0,
307 .ac97_control = 1, 300 .ac97_control = 1,
308 301
309 /* stream cababilities */ 302 /* stream cababilities */
@@ -325,8 +318,7 @@ struct snd_soc_dai stac9766_dai[] = {
325 .ops = &stac9766_dai_ops_analog, 318 .ops = &stac9766_dai_ops_analog,
326}, 319},
327{ 320{
328 .name = "stac9766 IEC958", 321 .name = "stac9766-hifi-IEC958",
329 .id = 1,
330 .ac97_control = 1, 322 .ac97_control = 1,
331 323
332 /* stream cababilities */ 324 /* stream cababilities */
@@ -342,57 +334,24 @@ struct snd_soc_dai stac9766_dai[] = {
342 .ops = &stac9766_dai_ops_digital, 334 .ops = &stac9766_dai_ops_digital,
343} 335}
344}; 336};
345EXPORT_SYMBOL_GPL(stac9766_dai);
346 337
347static int stac9766_codec_probe(struct platform_device *pdev) 338static int stac9766_codec_probe(struct snd_soc_codec *codec)
348{ 339{
349 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
350 struct snd_soc_codec *codec;
351 int ret = 0; 340 int ret = 0;
352 341
353 printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); 342 printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION);
354 343
355 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
356 if (socdev->card->codec == NULL)
357 return -ENOMEM;
358 codec = socdev->card->codec;
359 mutex_init(&codec->mutex);
360
361 codec->reg_cache = kmemdup(stac9766_reg, sizeof(stac9766_reg),
362 GFP_KERNEL);
363 if (codec->reg_cache == NULL) {
364 ret = -ENOMEM;
365 goto cache_err;
366 }
367 codec->reg_cache_size = sizeof(stac9766_reg);
368 codec->reg_cache_step = 2;
369
370 codec->name = "STAC9766";
371 codec->owner = THIS_MODULE;
372 codec->dai = stac9766_dai;
373 codec->num_dai = ARRAY_SIZE(stac9766_dai);
374 codec->write = stac9766_ac97_write;
375 codec->read = stac9766_ac97_read;
376 codec->set_bias_level = stac9766_set_bias_level;
377 INIT_LIST_HEAD(&codec->dapm_widgets);
378 INIT_LIST_HEAD(&codec->dapm_paths);
379
380 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 344 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
381 if (ret < 0) 345 if (ret < 0)
382 goto codec_err; 346 goto codec_err;
383 347
384 /* register pcms */
385 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
386 if (ret < 0)
387 goto pcm_err;
388
389 /* do a cold reset for the controller and then try 348 /* do a cold reset for the controller and then try
390 * a warm reset followed by an optional cold reset for codec */ 349 * a warm reset followed by an optional cold reset for codec */
391 stac9766_reset(codec, 0); 350 stac9766_reset(codec, 0);
392 ret = stac9766_reset(codec, 1); 351 ret = stac9766_reset(codec, 1);
393 if (ret < 0) { 352 if (ret < 0) {
394 printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n"); 353 printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n");
395 goto reset_err; 354 goto codec_err;
396 } 355 }
397 356
398 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 357 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -402,40 +361,63 @@ static int stac9766_codec_probe(struct platform_device *pdev)
402 361
403 return 0; 362 return 0;
404 363
405reset_err:
406 snd_soc_free_pcms(socdev);
407pcm_err:
408 snd_soc_free_ac97_codec(codec);
409codec_err: 364codec_err:
410 kfree(snd_soc_codec_get_drvdata(codec)); 365 snd_soc_free_ac97_codec(codec);
411cache_err:
412 kfree(socdev->card->codec);
413 socdev->card->codec = NULL;
414 return ret; 366 return ret;
415} 367}
416 368
417static int stac9766_codec_remove(struct platform_device *pdev) 369static int stac9766_codec_remove(struct snd_soc_codec *codec)
418{ 370{
419 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
420 struct snd_soc_codec *codec = socdev->card->codec;
421
422 if (codec == NULL)
423 return 0;
424
425 snd_soc_free_pcms(socdev);
426 snd_soc_free_ac97_codec(codec); 371 snd_soc_free_ac97_codec(codec);
427 kfree(codec->reg_cache);
428 kfree(codec);
429 return 0; 372 return 0;
430} 373}
431 374
432struct snd_soc_codec_device soc_codec_dev_stac9766 = { 375static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
376 .write = stac9766_ac97_write,
377 .read = stac9766_ac97_read,
378 .set_bias_level = stac9766_set_bias_level,
433 .probe = stac9766_codec_probe, 379 .probe = stac9766_codec_probe,
434 .remove = stac9766_codec_remove, 380 .remove = stac9766_codec_remove,
435 .suspend = stac9766_codec_suspend, 381 .suspend = stac9766_codec_suspend,
436 .resume = stac9766_codec_resume, 382 .resume = stac9766_codec_resume,
383 .reg_cache_size = sizeof(stac9766_reg),
384 .reg_word_size = sizeof(u16),
385 .reg_cache_step = 2,
386};
387
388static __devinit int stac9766_probe(struct platform_device *pdev)
389{
390 return snd_soc_register_codec(&pdev->dev,
391 &soc_codec_dev_stac9766, stac9766_dai, ARRAY_SIZE(stac9766_dai));
392}
393
394static int __devexit stac9766_remove(struct platform_device *pdev)
395{
396 snd_soc_unregister_codec(&pdev->dev);
397 return 0;
398}
399
400static struct platform_driver stac9766_codec_driver = {
401 .driver = {
402 .name = "stac9766-codec",
403 .owner = THIS_MODULE,
404 },
405
406 .probe = stac9766_probe,
407 .remove = __devexit_p(stac9766_remove),
437}; 408};
438EXPORT_SYMBOL_GPL(soc_codec_dev_stac9766); 409
410static int __init stac9766_init(void)
411{
412 return platform_driver_register(&stac9766_codec_driver);
413}
414module_init(stac9766_init);
415
416static void __exit stac9766_exit(void)
417{
418 platform_driver_unregister(&stac9766_codec_driver);
419}
420module_exit(stac9766_exit);
439 421
440MODULE_DESCRIPTION("ASoC stac9766 driver"); 422MODULE_DESCRIPTION("ASoC stac9766 driver");
441MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>"); 423MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
diff --git a/sound/soc/codecs/stac9766.h b/sound/soc/codecs/stac9766.h
index 65642eb8393..c726f907e2c 100644
--- a/sound/soc/codecs/stac9766.h
+++ b/sound/soc/codecs/stac9766.h
@@ -14,8 +14,4 @@
14#define STAC9766_DAI_AC97_ANALOG 0 14#define STAC9766_DAI_AC97_ANALOG 0
15#define STAC9766_DAI_AC97_DIGITAL 1 15#define STAC9766_DAI_AC97_DIGITAL 1
16 16
17extern struct snd_soc_dai stac9766_dai[];
18extern struct snd_soc_codec_device soc_codec_dev_stac9766;
19
20
21#endif 17#endif
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 0a4b0fef335..e8652b1ae32 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -240,7 +240,8 @@ static const struct snd_soc_dapm_route intercon[] = {
240 240
241/* AIC23 driver data */ 241/* AIC23 driver data */
242struct aic23 { 242struct aic23 {
243 struct snd_soc_codec codec; 243 enum snd_soc_control_type control_type;
244 void *control_data;
244 int mclk; 245 int mclk;
245 int requested_adc; 246 int requested_adc;
246 int requested_dac; 247 int requested_dac;
@@ -404,11 +405,10 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
404 struct snd_soc_dai *dai) 405 struct snd_soc_dai *dai)
405{ 406{
406 struct snd_soc_pcm_runtime *rtd = substream->private_data; 407 struct snd_soc_pcm_runtime *rtd = substream->private_data;
407 struct snd_soc_device *socdev = rtd->socdev; 408 struct snd_soc_codec *codec = rtd->codec;
408 struct snd_soc_codec *codec = socdev->card->codec;
409 u16 iface_reg; 409 u16 iface_reg;
410 int ret; 410 int ret;
411 struct aic23 *aic23 = container_of(codec, struct aic23, codec); 411 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
412 u32 sample_rate_adc = aic23->requested_adc; 412 u32 sample_rate_adc = aic23->requested_adc;
413 u32 sample_rate_dac = aic23->requested_dac; 413 u32 sample_rate_dac = aic23->requested_dac;
414 u32 sample_rate = params_rate(params); 414 u32 sample_rate = params_rate(params);
@@ -452,8 +452,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
452 struct snd_soc_dai *dai) 452 struct snd_soc_dai *dai)
453{ 453{
454 struct snd_soc_pcm_runtime *rtd = substream->private_data; 454 struct snd_soc_pcm_runtime *rtd = substream->private_data;
455 struct snd_soc_device *socdev = rtd->socdev; 455 struct snd_soc_codec *codec = rtd->codec;
456 struct snd_soc_codec *codec = socdev->card->codec;
457 456
458 /* set active */ 457 /* set active */
459 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001); 458 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001);
@@ -465,9 +464,8 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
465 struct snd_soc_dai *dai) 464 struct snd_soc_dai *dai)
466{ 465{
467 struct snd_soc_pcm_runtime *rtd = substream->private_data; 466 struct snd_soc_pcm_runtime *rtd = substream->private_data;
468 struct snd_soc_device *socdev = rtd->socdev; 467 struct snd_soc_codec *codec = rtd->codec;
469 struct snd_soc_codec *codec = socdev->card->codec; 468 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
470 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
471 469
472 /* deactivate */ 470 /* deactivate */
473 if (!codec->active) { 471 if (!codec->active) {
@@ -546,8 +544,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
546static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai, 544static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
547 int clk_id, unsigned int freq, int dir) 545 int clk_id, unsigned int freq, int dir)
548{ 546{
549 struct snd_soc_codec *codec = codec_dai->codec; 547 struct aic23 *aic23 = snd_soc_dai_get_drvdata(codec_dai);
550 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
551 aic23->mclk = freq; 548 aic23->mclk = freq;
552 return 0; 549 return 0;
553} 550}
@@ -594,8 +591,8 @@ static struct snd_soc_dai_ops tlv320aic23_dai_ops = {
594 .set_sysclk = tlv320aic23_set_dai_sysclk, 591 .set_sysclk = tlv320aic23_set_dai_sysclk,
595}; 592};
596 593
597struct snd_soc_dai tlv320aic23_dai = { 594static struct snd_soc_dai_driver tlv320aic23_dai = {
598 .name = "tlv320aic23", 595 .name = "tlv320aic23-hifi",
599 .playback = { 596 .playback = {
600 .stream_name = "Playback", 597 .stream_name = "Playback",
601 .channels_min = 2, 598 .channels_min = 2,
@@ -610,23 +607,17 @@ struct snd_soc_dai tlv320aic23_dai = {
610 .formats = AIC23_FORMATS,}, 607 .formats = AIC23_FORMATS,},
611 .ops = &tlv320aic23_dai_ops, 608 .ops = &tlv320aic23_dai_ops,
612}; 609};
613EXPORT_SYMBOL_GPL(tlv320aic23_dai);
614 610
615static int tlv320aic23_suspend(struct platform_device *pdev, 611static int tlv320aic23_suspend(struct snd_soc_codec *codec,
616 pm_message_t state) 612 pm_message_t state)
617{ 613{
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
619 struct snd_soc_codec *codec = socdev->card->codec;
620
621 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); 614 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
622 615
623 return 0; 616 return 0;
624} 617}
625 618
626static int tlv320aic23_resume(struct platform_device *pdev) 619static int tlv320aic23_resume(struct snd_soc_codec *codec)
627{ 620{
628 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
629 struct snd_soc_codec *codec = socdev->card->codec;
630 u16 reg; 621 u16 reg;
631 622
632 /* Sync reg_cache with the hardware */ 623 /* Sync reg_cache with the hardware */
@@ -639,39 +630,19 @@ static int tlv320aic23_resume(struct platform_device *pdev)
639 return 0; 630 return 0;
640} 631}
641 632
642/* 633static int tlv320aic23_probe(struct snd_soc_codec *codec)
643 * initialise the AIC23 driver
644 * register the mixer and dsp interfaces with the kernel
645 */
646static int tlv320aic23_init(struct snd_soc_device *socdev)
647{ 634{
648 struct snd_soc_codec *codec = socdev->card->codec; 635 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
649 int ret = 0; 636 int reg;
650 u16 reg;
651 637
652 codec->name = "tlv320aic23"; 638 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
653 codec->owner = THIS_MODULE; 639 codec->control_data = aic23->control_data;
654 codec->read = tlv320aic23_read_reg_cache; 640 codec->hw_write = (hw_write_t)i2c_master_send;
655 codec->write = tlv320aic23_write; 641 codec->hw_read = NULL;
656 codec->set_bias_level = tlv320aic23_set_bias_level;
657 codec->dai = &tlv320aic23_dai;
658 codec->num_dai = 1;
659 codec->reg_cache_size = ARRAY_SIZE(tlv320aic23_reg);
660 codec->reg_cache =
661 kmemdup(tlv320aic23_reg, sizeof(tlv320aic23_reg), GFP_KERNEL);
662 if (codec->reg_cache == NULL)
663 return -ENOMEM;
664 642
665 /* Reset codec */ 643 /* Reset codec */
666 tlv320aic23_write(codec, TLV320AIC23_RESET, 0); 644 tlv320aic23_write(codec, TLV320AIC23_RESET, 0);
667 645
668 /* register pcms */
669 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
670 if (ret < 0) {
671 printk(KERN_ERR "tlv320aic23: failed to create pcms\n");
672 goto pcm_err;
673 }
674
675 /* power on device */ 646 /* power on device */
676 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 647 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
677 648
@@ -707,13 +678,27 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
707 ARRAY_SIZE(tlv320aic23_snd_controls)); 678 ARRAY_SIZE(tlv320aic23_snd_controls));
708 tlv320aic23_add_widgets(codec); 679 tlv320aic23_add_widgets(codec);
709 680
710 return ret; 681 return 0;
682}
711 683
712pcm_err: 684static int tlv320aic23_remove(struct snd_soc_codec *codec)
713 kfree(codec->reg_cache); 685{
714 return ret; 686 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
687 return 0;
715} 688}
716static struct snd_soc_device *tlv320aic23_socdev; 689
690static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
691 .reg_cache_size = ARRAY_SIZE(tlv320aic23_reg),
692 .reg_word_size = sizeof(u16),
693 .reg_cache_default = tlv320aic23_reg,
694 .probe = tlv320aic23_probe,
695 .remove = tlv320aic23_remove,
696 .suspend = tlv320aic23_suspend,
697 .resume = tlv320aic23_resume,
698 .read = tlv320aic23_read_reg_cache,
699 .write = tlv320aic23_write,
700 .set_bias_level = tlv320aic23_set_bias_level,
701};
717 702
718#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 703#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
719/* 704/*
@@ -723,31 +708,30 @@ static struct snd_soc_device *tlv320aic23_socdev;
723static int tlv320aic23_codec_probe(struct i2c_client *i2c, 708static int tlv320aic23_codec_probe(struct i2c_client *i2c,
724 const struct i2c_device_id *i2c_id) 709 const struct i2c_device_id *i2c_id)
725{ 710{
726 struct snd_soc_device *socdev = tlv320aic23_socdev; 711 struct aic23 *aic23;
727 struct snd_soc_codec *codec = socdev->card->codec;
728 int ret; 712 int ret;
729 713
730 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 714 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
731 return -EINVAL; 715 return -EINVAL;
732 716
733 i2c_set_clientdata(i2c, codec); 717 aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL);
734 codec->control_data = i2c; 718 if (aic23 == NULL)
719 return -ENOMEM;
735 720
736 ret = tlv320aic23_init(socdev); 721 i2c_set_clientdata(i2c, aic23);
737 if (ret < 0) { 722 aic23->control_data = i2c;
738 printk(KERN_ERR "tlv320aic23: failed to initialise AIC23\n"); 723 aic23->control_type = SND_SOC_I2C;
739 goto err;
740 }
741 return ret;
742 724
743err: 725 ret = snd_soc_register_codec(&i2c->dev,
744 kfree(codec); 726 &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1);
745 kfree(i2c); 727 if (ret < 0)
728 kfree(aic23);
746 return ret; 729 return ret;
747} 730}
748static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c) 731static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
749{ 732{
750 put_device(&i2c->dev); 733 snd_soc_unregister_codec(&i2c->dev);
734 kfree(i2c_get_clientdata(i2c));
751 return 0; 735 return 0;
752} 736}
753 737
@@ -760,7 +744,7 @@ MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
760 744
761static struct i2c_driver tlv320aic23_i2c_driver = { 745static struct i2c_driver tlv320aic23_i2c_driver = {
762 .driver = { 746 .driver = {
763 .name = "tlv320aic23", 747 .name = "tlv320aic23-codec",
764 }, 748 },
765 .probe = tlv320aic23_codec_probe, 749 .probe = tlv320aic23_codec_probe,
766 .remove = __exit_p(tlv320aic23_i2c_remove), 750 .remove = __exit_p(tlv320aic23_i2c_remove),
@@ -769,71 +753,25 @@ static struct i2c_driver tlv320aic23_i2c_driver = {
769 753
770#endif 754#endif
771 755
772static int tlv320aic23_probe(struct platform_device *pdev) 756static int __init tlv320aic23_modinit(void)
773{ 757{
774 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 758 int ret;
775 struct snd_soc_codec *codec;
776 struct aic23 *aic23;
777 int ret = 0;
778
779 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
780
781 aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL);
782 if (aic23 == NULL)
783 return -ENOMEM;
784 codec = &aic23->codec;
785 socdev->card->codec = codec;
786 mutex_init(&codec->mutex);
787 INIT_LIST_HEAD(&codec->dapm_widgets);
788 INIT_LIST_HEAD(&codec->dapm_paths);
789
790 tlv320aic23_socdev = socdev;
791#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 759#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
792 codec->hw_write = (hw_write_t) i2c_master_send;
793 codec->hw_read = NULL;
794 ret = i2c_add_driver(&tlv320aic23_i2c_driver); 760 ret = i2c_add_driver(&tlv320aic23_i2c_driver);
795 if (ret != 0) 761 if (ret != 0) {
796 printk(KERN_ERR "can't add i2c driver"); 762 printk(KERN_ERR "Failed to register TLV320AIC23 I2C driver: %d\n",
763 ret);
764 }
797#endif 765#endif
798 return ret; 766 return ret;
799} 767}
768module_init(tlv320aic23_modinit);
800 769
801static int tlv320aic23_remove(struct platform_device *pdev) 770static void __exit tlv320aic23_exit(void)
802{ 771{
803 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
804 struct snd_soc_codec *codec = socdev->card->codec;
805 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
806
807 if (codec->control_data)
808 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
809
810 snd_soc_free_pcms(socdev);
811 snd_soc_dapm_free(socdev);
812#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 772#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
813 i2c_del_driver(&tlv320aic23_i2c_driver); 773 i2c_del_driver(&tlv320aic23_i2c_driver);
814#endif 774#endif
815 kfree(codec->reg_cache);
816 kfree(aic23);
817
818 return 0;
819}
820struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
821 .probe = tlv320aic23_probe,
822 .remove = tlv320aic23_remove,
823 .suspend = tlv320aic23_suspend,
824 .resume = tlv320aic23_resume,
825};
826EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
827
828static int __init tlv320aic23_modinit(void)
829{
830 return snd_soc_register_dai(&tlv320aic23_dai);
831}
832module_init(tlv320aic23_modinit);
833
834static void __exit tlv320aic23_exit(void)
835{
836 snd_soc_unregister_dai(&tlv320aic23_dai);
837} 775}
838module_exit(tlv320aic23_exit); 776module_exit(tlv320aic23_exit);
839 777
diff --git a/sound/soc/codecs/tlv320aic23.h b/sound/soc/codecs/tlv320aic23.h
index 79d1faf8e57..e804120bd3d 100644
--- a/sound/soc/codecs/tlv320aic23.h
+++ b/sound/soc/codecs/tlv320aic23.h
@@ -116,7 +116,4 @@
116#define TLV320AIC23_SIDETONE_12 0x080 116#define TLV320AIC23_SIDETONE_12 0x080
117#define TLV320AIC23_SIDETONE_18 0x0c0 117#define TLV320AIC23_SIDETONE_18 0x0c0
118 118
119extern struct snd_soc_dai tlv320aic23_dai;
120extern struct snd_soc_codec_device soc_codec_dev_tlv320aic23;
121
122#endif /* _TLV320AIC23_H */ 119#endif /* _TLV320AIC23_H */
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index f0e00fd4b43..6b7d71ec000 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -19,7 +19,6 @@
19#include <sound/pcm_params.h> 19#include <sound/pcm_params.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/soc-dapm.h> 21#include <sound/soc-dapm.h>
22#include <sound/soc-of-simple.h>
23#include <sound/initval.h> 22#include <sound/initval.h>
24 23
25#include "tlv320aic26.h" 24#include "tlv320aic26.h"
@@ -130,8 +129,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
130 struct snd_soc_dai *dai) 129 struct snd_soc_dai *dai)
131{ 130{
132 struct snd_soc_pcm_runtime *rtd = substream->private_data; 131 struct snd_soc_pcm_runtime *rtd = substream->private_data;
133 struct snd_soc_device *socdev = rtd->socdev; 132 struct snd_soc_codec *codec = rtd->codec;
134 struct snd_soc_codec *codec = socdev->card->codec;
135 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec); 133 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
136 int fsref, divisor, wlen, pval, jval, dval, qval; 134 int fsref, divisor, wlen, pval, jval, dval, qval;
137 u16 reg; 135 u16 reg;
@@ -278,8 +276,8 @@ static struct snd_soc_dai_ops aic26_dai_ops = {
278 .set_fmt = aic26_set_fmt, 276 .set_fmt = aic26_set_fmt,
279}; 277};
280 278
281struct snd_soc_dai aic26_dai = { 279static struct snd_soc_dai_driver aic26_dai = {
282 .name = "tlv320aic26", 280 .name = "tlv320aic26-hifi",
283 .playback = { 281 .playback = {
284 .stream_name = "Playback", 282 .stream_name = "Playback",
285 .channels_min = 2, 283 .channels_min = 2,
@@ -296,7 +294,6 @@ struct snd_soc_dai aic26_dai = {
296 }, 294 },
297 .ops = &aic26_dai_ops, 295 .ops = &aic26_dai_ops,
298}; 296};
299EXPORT_SYMBOL_GPL(aic26_dai);
300 297
301/* --------------------------------------------------------------------- 298/* ---------------------------------------------------------------------
302 * ALSA controls 299 * ALSA controls
@@ -319,61 +316,6 @@ static const struct snd_kcontrol_new aic26_snd_controls[] = {
319}; 316};
320 317
321/* --------------------------------------------------------------------- 318/* ---------------------------------------------------------------------
322 * SoC CODEC portion of driver: probe and release routines
323 */
324static int aic26_probe(struct platform_device *pdev)
325{
326 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
327 struct snd_soc_codec *codec;
328 struct aic26 *aic26;
329 int ret, err;
330
331 dev_info(&pdev->dev, "Probing AIC26 SoC CODEC driver\n");
332 dev_dbg(&pdev->dev, "socdev=%p\n", socdev);
333 dev_dbg(&pdev->dev, "codec_data=%p\n", socdev->codec_data);
334
335 /* Fetch the relevant aic26 private data here (it's already been
336 * stored in the .codec pointer) */
337 aic26 = socdev->codec_data;
338 if (aic26 == NULL) {
339 dev_err(&pdev->dev, "aic26: missing codec pointer\n");
340 return -ENODEV;
341 }
342 codec = &aic26->codec;
343 socdev->card->codec = codec;
344
345 dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n",
346 &pdev->dev, socdev->dev);
347 /* register pcms */
348 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
349 if (ret < 0) {
350 dev_err(&pdev->dev, "aic26: failed to create pcms\n");
351 return -ENODEV;
352 }
353
354 /* register controls */
355 dev_dbg(&pdev->dev, "Registering controls\n");
356 err = snd_soc_add_controls(codec, aic26_snd_controls,
357 ARRAY_SIZE(aic26_snd_controls));
358 WARN_ON(err < 0);
359
360 return 0;
361}
362
363static int aic26_remove(struct platform_device *pdev)
364{
365 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
366 snd_soc_free_pcms(socdev);
367 return 0;
368}
369
370struct snd_soc_codec_device aic26_soc_codec_dev = {
371 .probe = aic26_probe,
372 .remove = aic26_remove,
373};
374EXPORT_SYMBOL_GPL(aic26_soc_codec_dev);
375
376/* ---------------------------------------------------------------------
377 * SPI device portion of driver: sysfs files for debugging 319 * SPI device portion of driver: sysfs files for debugging
378 */ 320 */
379 321
@@ -409,95 +351,95 @@ static ssize_t aic26_keyclick_set(struct device *dev,
409static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set); 351static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
410 352
411/* --------------------------------------------------------------------- 353/* ---------------------------------------------------------------------
412 * SPI device portion of driver: probe and release routines and SPI 354 * SoC CODEC portion of driver: probe and release routines
413 * driver registration.
414 */ 355 */
415static int aic26_spi_probe(struct spi_device *spi) 356static int aic26_probe(struct snd_soc_codec *codec)
416{ 357{
417 struct aic26 *aic26; 358 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
418 int ret, i, reg; 359 int ret, err, i, reg;
419
420 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
421
422 /* Allocate driver data */
423 aic26 = kzalloc(sizeof *aic26, GFP_KERNEL);
424 if (!aic26)
425 return -ENOMEM;
426
427 /* Initialize the driver data */
428 aic26->spi = spi;
429 dev_set_drvdata(&spi->dev, aic26);
430 360
431 /* Setup what we can in the codec structure so that the register 361 dev_info(codec->dev, "Probing AIC26 SoC CODEC driver\n");
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 */
434 snd_soc_codec_set_drvdata(&aic26->codec, aic26);
435 aic26->codec.name = "aic26";
436 aic26->codec.owner = THIS_MODULE;
437 aic26->codec.dai = &aic26_dai;
438 aic26->codec.num_dai = 1;
439 aic26->codec.read = aic26_reg_read;
440 aic26->codec.write = aic26_reg_write;
441 aic26->master = 1;
442 mutex_init(&aic26->codec.mutex);
443 INIT_LIST_HEAD(&aic26->codec.dapm_widgets);
444 INIT_LIST_HEAD(&aic26->codec.dapm_paths);
445 aic26->codec.reg_cache_size = AIC26_NUM_REGS;
446 aic26->codec.reg_cache = aic26->reg_cache;
447
448 aic26_dai.dev = &spi->dev;
449 ret = snd_soc_register_dai(&aic26_dai);
450 if (ret != 0) {
451 dev_err(&spi->dev, "Failed to register DAI: %d\n", ret);
452 kfree(aic26);
453 return ret;
454 }
455 362
456 /* Reset the codec to power on defaults */ 363 /* Reset the codec to power on defaults */
457 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00); 364 aic26_reg_write(codec, AIC26_REG_RESET, 0xBB00);
458 365
459 /* Power up CODEC */ 366 /* Power up CODEC */
460 aic26_reg_write(&aic26->codec, AIC26_REG_POWER_CTRL, 0); 367 aic26_reg_write(codec, AIC26_REG_POWER_CTRL, 0);
461 368
462 /* Audio Control 3 (master mode, fsref rate) */ 369 /* Audio Control 3 (master mode, fsref rate) */
463 reg = aic26_reg_read(&aic26->codec, AIC26_REG_AUDIO_CTRL3); 370 reg = aic26_reg_read(codec, AIC26_REG_AUDIO_CTRL3);
464 reg &= ~0xf800; 371 reg &= ~0xf800;
465 reg |= 0x0800; /* set master mode */ 372 reg |= 0x0800; /* set master mode */
466 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL3, reg); 373 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
467 374
468 /* Fill register cache */ 375 /* Fill register cache */
469 for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++) 376 for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++)
470 aic26_reg_read(&aic26->codec, i); 377 aic26_reg_read(codec, i);
471 378
472 /* Register the sysfs files for debugging */ 379 /* Register the sysfs files for debugging */
473 /* Create SysFS files */ 380 /* Create SysFS files */
474 ret = device_create_file(&spi->dev, &dev_attr_keyclick); 381 ret = device_create_file(codec->dev, &dev_attr_keyclick);
475 if (ret) 382 if (ret)
476 dev_info(&spi->dev, "error creating sysfs files\n"); 383 dev_info(codec->dev, "error creating sysfs files\n");
477 384
478#if defined(CONFIG_SND_SOC_OF_SIMPLE) 385 /* register controls */
479 /* Tell the of_soc helper about this codec */ 386 dev_dbg(codec->dev, "Registering controls\n");
480 of_snd_soc_register_codec(&aic26_soc_codec_dev, aic26, &aic26_dai, 387 err = snd_soc_add_controls(codec, aic26_snd_controls,
481 spi->dev.archdata.of_node); 388 ARRAY_SIZE(aic26_snd_controls));
482#endif 389 WARN_ON(err < 0);
483 390
484 dev_dbg(&spi->dev, "SPI device initialized\n");
485 return 0; 391 return 0;
486} 392}
487 393
488static int aic26_spi_remove(struct spi_device *spi) 394static struct snd_soc_codec_driver aic26_soc_codec_dev = {
395 .probe = aic26_probe,
396 .read = aic26_reg_read,
397 .write = aic26_reg_write,
398 .reg_cache_size = AIC26_NUM_REGS,
399 .reg_word_size = sizeof(u16),
400};
401
402/* ---------------------------------------------------------------------
403 * SPI device portion of driver: probe and release routines and SPI
404 * driver registration.
405 */
406static int aic26_spi_probe(struct spi_device *spi)
489{ 407{
490 struct aic26 *aic26 = dev_get_drvdata(&spi->dev); 408 struct aic26 *aic26;
409 int ret;
491 410
492 snd_soc_unregister_dai(&aic26_dai); 411 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
493 kfree(aic26); 412
413 /* Allocate driver data */
414 aic26 = kzalloc(sizeof *aic26, GFP_KERNEL);
415 if (!aic26)
416 return -ENOMEM;
494 417
418 /* Initialize the driver data */
419 aic26->spi = spi;
420 dev_set_drvdata(&spi->dev, aic26);
421 aic26->master = 1;
422
423 ret = snd_soc_register_codec(&spi->dev,
424 &aic26_soc_codec_dev, &aic26_dai, 1);
425 if (ret < 0)
426 kfree(aic26);
427 return ret;
428
429 dev_dbg(&spi->dev, "SPI device initialized\n");
430 return 0;
431}
432
433static int aic26_spi_remove(struct spi_device *spi)
434{
435 snd_soc_unregister_codec(&spi->dev);
436 kfree(spi_get_drvdata(spi));
495 return 0; 437 return 0;
496} 438}
497 439
498static struct spi_driver aic26_spi = { 440static struct spi_driver aic26_spi = {
499 .driver = { 441 .driver = {
500 .name = "tlv320aic26", 442 .name = "tlv320aic26-codec",
501 .owner = THIS_MODULE, 443 .owner = THIS_MODULE,
502 }, 444 },
503 .probe = aic26_spi_probe, 445 .probe = aic26_spi_probe,
diff --git a/sound/soc/codecs/tlv320aic26.h b/sound/soc/codecs/tlv320aic26.h
index 786ba16c945..62b1f226142 100644
--- a/sound/soc/codecs/tlv320aic26.h
+++ b/sound/soc/codecs/tlv320aic26.h
@@ -90,7 +90,4 @@ enum aic26_wlen {
90 AIC26_WLEN_32 = 3 << 10, 90 AIC26_WLEN_32 = 3 << 10,
91}; 91};
92 92
93extern struct snd_soc_dai aic26_dai;
94extern struct snd_soc_codec_device aic26_soc_codec_dev;
95
96#endif /* _TLV320AIC16_H_ */ 93#endif /* _TLV320AIC16_H_ */
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 71a69908ccf..43fd9c17174 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -63,8 +63,10 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
63 63
64/* codec private data */ 64/* codec private data */
65struct aic3x_priv { 65struct aic3x_priv {
66 struct snd_soc_codec codec;
67 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES]; 66 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
67 enum snd_soc_control_type control_type;
68 struct aic3x_setup_data *setup;
69 void *control_data;
68 unsigned int sysclk; 70 unsigned int sysclk;
69 int master; 71 int master;
70 int gpio_reset; 72 int gpio_reset;
@@ -773,8 +775,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
773 struct snd_soc_dai *dai) 775 struct snd_soc_dai *dai)
774{ 776{
775 struct snd_soc_pcm_runtime *rtd = substream->private_data; 777 struct snd_soc_pcm_runtime *rtd = substream->private_data;
776 struct snd_soc_device *socdev = rtd->socdev; 778 struct snd_soc_codec *codec =rtd->codec;
777 struct snd_soc_codec *codec = socdev->card->codec;
778 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 779 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
779 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 780 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
780 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 781 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
@@ -1101,8 +1102,8 @@ static struct snd_soc_dai_ops aic3x_dai_ops = {
1101 .set_fmt = aic3x_set_dai_fmt, 1102 .set_fmt = aic3x_set_dai_fmt,
1102}; 1103};
1103 1104
1104struct snd_soc_dai aic3x_dai = { 1105static struct snd_soc_dai_driver aic3x_dai = {
1105 .name = "tlv320aic3x", 1106 .name = "tlv320aic3x-hifi",
1106 .playback = { 1107 .playback = {
1107 .stream_name = "Playback", 1108 .stream_name = "Playback",
1108 .channels_min = 1, 1109 .channels_min = 1,
@@ -1117,22 +1118,16 @@ struct snd_soc_dai aic3x_dai = {
1117 .formats = AIC3X_FORMATS,}, 1118 .formats = AIC3X_FORMATS,},
1118 .ops = &aic3x_dai_ops, 1119 .ops = &aic3x_dai_ops,
1119}; 1120};
1120EXPORT_SYMBOL_GPL(aic3x_dai);
1121 1121
1122static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) 1122static int aic3x_suspend(struct snd_soc_codec *codec, pm_message_t state)
1123{ 1123{
1124 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1125 struct snd_soc_codec *codec = socdev->card->codec;
1126
1127 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); 1124 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1128 1125
1129 return 0; 1126 return 0;
1130} 1127}
1131 1128
1132static int aic3x_resume(struct platform_device *pdev) 1129static int aic3x_resume(struct snd_soc_codec *codec)
1133{ 1130{
1134 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1135 struct snd_soc_codec *codec = socdev->card->codec;
1136 int i; 1131 int i;
1137 u8 data[2]; 1132 u8 data[2];
1138 u8 *cache = codec->reg_cache; 1133 u8 *cache = codec->reg_cache;
@@ -1157,22 +1152,6 @@ static int aic3x_init(struct snd_soc_codec *codec)
1157{ 1152{
1158 int reg; 1153 int reg;
1159 1154
1160 mutex_init(&codec->mutex);
1161 INIT_LIST_HEAD(&codec->dapm_widgets);
1162 INIT_LIST_HEAD(&codec->dapm_paths);
1163
1164 codec->name = "tlv320aic3x";
1165 codec->owner = THIS_MODULE;
1166 codec->read = aic3x_read_reg_cache;
1167 codec->write = aic3x_write;
1168 codec->set_bias_level = aic3x_set_bias_level;
1169 codec->dai = &aic3x_dai;
1170 codec->num_dai = 1;
1171 codec->reg_cache_size = ARRAY_SIZE(aic3x_reg);
1172 codec->reg_cache = kmemdup(aic3x_reg, sizeof(aic3x_reg), GFP_KERNEL);
1173 if (codec->reg_cache == NULL)
1174 return -ENOMEM;
1175
1176 aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT); 1155 aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
1177 aic3x_write(codec, AIC3X_RESET, SOFT_RESET); 1156 aic3x_write(codec, AIC3X_RESET, SOFT_RESET);
1178 1157
@@ -1245,56 +1224,50 @@ static int aic3x_init(struct snd_soc_codec *codec)
1245 return 0; 1224 return 0;
1246} 1225}
1247 1226
1248static struct snd_soc_codec *aic3x_codec; 1227static int aic3x_probe(struct snd_soc_codec *codec)
1249
1250static int aic3x_register(struct snd_soc_codec *codec)
1251{ 1228{
1252 int ret; 1229 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1230
1231 codec->hw_write = (hw_write_t) i2c_master_send;
1232 codec->control_data = aic3x->control_data;
1253 1233
1254 ret = aic3x_init(codec); 1234 if (aic3x->setup) {
1255 if (ret < 0) { 1235 /* setup GPIO functions */
1256 dev_err(codec->dev, "Failed to initialise device\n"); 1236 aic3x_write(codec, AIC3X_GPIO1_REG,
1257 return ret; 1237 (aic3x->setup->gpio_func[0] & 0xf) << 4);
1238 aic3x_write(codec, AIC3X_GPIO2_REG,
1239 (aic3x->setup->gpio_func[1] & 0xf) << 4);
1258 } 1240 }
1259 1241
1260 aic3x_codec = codec; 1242 aic3x_init(codec);
1261 1243
1262 ret = snd_soc_register_codec(codec); 1244 snd_soc_add_controls(codec, aic3x_snd_controls,
1263 if (ret) { 1245 ARRAY_SIZE(aic3x_snd_controls));
1264 dev_err(codec->dev, "Failed to register codec\n");
1265 return ret;
1266 }
1267 1246
1268 ret = snd_soc_register_dai(&aic3x_dai); 1247 aic3x_add_widgets(codec);
1269 if (ret) {
1270 dev_err(codec->dev, "Failed to register dai\n");
1271 snd_soc_unregister_codec(codec);
1272 return ret;
1273 }
1274 1248
1275 return 0; 1249 return 0;
1276} 1250}
1277 1251
1278static int aic3x_unregister(struct aic3x_priv *aic3x) 1252static int aic3x_remove(struct snd_soc_codec *codec)
1279{ 1253{
1280 aic3x_set_bias_level(&aic3x->codec, SND_SOC_BIAS_OFF); 1254 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1281
1282 snd_soc_unregister_dai(&aic3x_dai);
1283 snd_soc_unregister_codec(&aic3x->codec);
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
1292 kfree(aic3x);
1293 aic3x_codec = NULL;
1294
1295 return 0; 1255 return 0;
1296} 1256}
1297 1257
1258static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
1259 .read = aic3x_read_reg_cache,
1260 .write = aic3x_write,
1261 .set_bias_level = aic3x_set_bias_level,
1262 .reg_cache_size = ARRAY_SIZE(aic3x_reg),
1263 .reg_word_size = sizeof(u8),
1264 .reg_cache_default = aic3x_reg,
1265 .probe = aic3x_probe,
1266 .remove = aic3x_remove,
1267 .suspend = aic3x_suspend,
1268 .resume = aic3x_resume,
1269};
1270
1298#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1271#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1299/* 1272/*
1300 * AIC3X 2 wire address can be up to 4 devices with device addresses 1273 * AIC3X 2 wire address can be up to 4 devices with device addresses
@@ -1308,9 +1281,9 @@ static int aic3x_unregister(struct aic3x_priv *aic3x)
1308static int aic3x_i2c_probe(struct i2c_client *i2c, 1281static int aic3x_i2c_probe(struct i2c_client *i2c,
1309 const struct i2c_device_id *id) 1282 const struct i2c_device_id *id)
1310{ 1283{
1311 struct snd_soc_codec *codec;
1312 struct aic3x_priv *aic3x;
1313 struct aic3x_pdata *pdata = i2c->dev.platform_data; 1284 struct aic3x_pdata *pdata = i2c->dev.platform_data;
1285 struct aic3x_setup_data *setup = pdata->setup;
1286 struct aic3x_priv *aic3x;
1314 int ret, i; 1287 int ret, i;
1315 1288
1316 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); 1289 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
@@ -1319,12 +1292,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1319 return -ENOMEM; 1292 return -ENOMEM;
1320 } 1293 }
1321 1294
1322 codec = &aic3x->codec; 1295 aic3x->control_data = i2c;
1323 codec->dev = &i2c->dev; 1296 aic3x->setup = setup;
1324 snd_soc_codec_set_drvdata(codec, aic3x);
1325 codec->control_data = i2c;
1326 codec->hw_write = (hw_write_t) i2c_master_send;
1327
1328 i2c_set_clientdata(i2c, aic3x); 1297 i2c_set_clientdata(i2c, aic3x);
1329 1298
1330 aic3x->gpio_reset = -1; 1299 aic3x->gpio_reset = -1;
@@ -1339,17 +1308,17 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1339 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) 1308 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1340 aic3x->supplies[i].supply = aic3x_supply_names[i]; 1309 aic3x->supplies[i].supply = aic3x_supply_names[i];
1341 1310
1342 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies), 1311 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(aic3x->supplies),
1343 aic3x->supplies); 1312 aic3x->supplies);
1344 if (ret != 0) { 1313 if (ret != 0) {
1345 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 1314 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
1346 goto err_get; 1315 goto err_get;
1347 } 1316 }
1348 1317
1349 ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies), 1318 ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies),
1350 aic3x->supplies); 1319 aic3x->supplies);
1351 if (ret != 0) { 1320 if (ret != 0) {
1352 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 1321 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
1353 goto err_enable; 1322 goto err_enable;
1354 } 1323 }
1355 1324
@@ -1358,7 +1327,11 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1358 gpio_set_value(aic3x->gpio_reset, 1); 1327 gpio_set_value(aic3x->gpio_reset, 1);
1359 } 1328 }
1360 1329
1361 return aic3x_register(codec); 1330 ret = snd_soc_register_codec(&i2c->dev,
1331 &soc_codec_dev_aic3x, &aic3x_dai, 1);
1332 if (ret < 0)
1333 goto err_enable;
1334 return ret;
1362 1335
1363err_enable: 1336err_enable:
1364 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1337 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
@@ -1374,7 +1347,16 @@ static int aic3x_i2c_remove(struct i2c_client *client)
1374{ 1347{
1375 struct aic3x_priv *aic3x = i2c_get_clientdata(client); 1348 struct aic3x_priv *aic3x = i2c_get_clientdata(client);
1376 1349
1377 return aic3x_unregister(aic3x); 1350 if (aic3x->gpio_reset >= 0) {
1351 gpio_set_value(aic3x->gpio_reset, 0);
1352 gpio_free(aic3x->gpio_reset);
1353 }
1354 regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1355 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1356
1357 snd_soc_unregister_codec(&client->dev);
1358 kfree(i2c_get_clientdata(client));
1359 return 0;
1378} 1360}
1379 1361
1380static const struct i2c_device_id aic3x_i2c_id[] = { 1362static const struct i2c_device_id aic3x_i2c_id[] = {
@@ -1387,7 +1369,7 @@ MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
1387/* machine i2c codec control layer */ 1369/* machine i2c codec control layer */
1388static struct i2c_driver aic3x_i2c_driver = { 1370static struct i2c_driver aic3x_i2c_driver = {
1389 .driver = { 1371 .driver = {
1390 .name = "aic3x I2C Codec", 1372 .name = "tlv320aic3x-codec",
1391 .owner = THIS_MODULE, 1373 .owner = THIS_MODULE,
1392 }, 1374 },
1393 .probe = aic3x_i2c_probe, 1375 .probe = aic3x_i2c_probe,
@@ -1409,90 +1391,27 @@ static inline void aic3x_i2c_exit(void)
1409{ 1391{
1410 i2c_del_driver(&aic3x_i2c_driver); 1392 i2c_del_driver(&aic3x_i2c_driver);
1411} 1393}
1412#else
1413static inline void aic3x_i2c_init(void) { }
1414static inline void aic3x_i2c_exit(void) { }
1415#endif 1394#endif
1416 1395
1417static int aic3x_probe(struct platform_device *pdev) 1396static int __init aic3x_modinit(void)
1418{ 1397{
1419 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1420 struct aic3x_setup_data *setup;
1421 struct snd_soc_codec *codec;
1422 int ret = 0; 1398 int ret = 0;
1423 1399#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1424 codec = aic3x_codec; 1400 ret = i2c_add_driver(&aic3x_i2c_driver);
1425 if (!codec) { 1401 if (ret != 0) {
1426 dev_err(&pdev->dev, "Codec not registered\n"); 1402 printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n",
1427 return -ENODEV; 1403 ret);
1428 }
1429
1430 socdev->card->codec = codec;
1431 setup = socdev->codec_data;
1432
1433 if (setup) {
1434 /* setup GPIO functions */
1435 aic3x_write(codec, AIC3X_GPIO1_REG,
1436 (setup->gpio_func[0] & 0xf) << 4);
1437 aic3x_write(codec, AIC3X_GPIO2_REG,
1438 (setup->gpio_func[1] & 0xf) << 4);
1439 }
1440
1441 /* register pcms */
1442 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1443 if (ret < 0) {
1444 printk(KERN_ERR "aic3x: failed to create pcms\n");
1445 goto pcm_err;
1446 } 1404 }
1447 1405#endif
1448 snd_soc_add_controls(codec, aic3x_snd_controls,
1449 ARRAY_SIZE(aic3x_snd_controls));
1450
1451 aic3x_add_widgets(codec);
1452
1453 return ret;
1454
1455pcm_err:
1456 kfree(codec->reg_cache);
1457 return ret; 1406 return ret;
1458} 1407}
1459
1460static int aic3x_remove(struct platform_device *pdev)
1461{
1462 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1463 struct snd_soc_codec *codec = socdev->card->codec;
1464
1465 /* power down chip */
1466 if (codec->control_data)
1467 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1468
1469 snd_soc_free_pcms(socdev);
1470 snd_soc_dapm_free(socdev);
1471
1472 kfree(codec->reg_cache);
1473
1474 return 0;
1475}
1476
1477struct snd_soc_codec_device soc_codec_dev_aic3x = {
1478 .probe = aic3x_probe,
1479 .remove = aic3x_remove,
1480 .suspend = aic3x_suspend,
1481 .resume = aic3x_resume,
1482};
1483EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
1484
1485static int __init aic3x_modinit(void)
1486{
1487 aic3x_i2c_init();
1488
1489 return 0;
1490}
1491module_init(aic3x_modinit); 1408module_init(aic3x_modinit);
1492 1409
1493static void __exit aic3x_exit(void) 1410static void __exit aic3x_exit(void)
1494{ 1411{
1495 aic3x_i2c_exit(); 1412#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1413 i2c_del_driver(&aic3x_i2c_driver);
1414#endif
1496} 1415}
1497module_exit(aic3x_exit); 1416module_exit(aic3x_exit);
1498 1417
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 9af1c886213..f6e3d9b42da 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -199,42 +199,6 @@
199/* Default input volume */ 199/* Default input volume */
200#define DEFAULT_GAIN 0x20 200#define DEFAULT_GAIN 0x20
201 201
202/* GPIO API */
203enum {
204 AIC3X_GPIO1_FUNC_DISABLED = 0,
205 AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1,
206 AIC3X_GPIO1_FUNC_CLOCK_MUX = 2,
207 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3,
208 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4,
209 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5,
210 AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6,
211 AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7,
212 AIC3X_GPIO1_FUNC_INPUT = 8,
213 AIC3X_GPIO1_FUNC_OUTPUT = 9,
214 AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10,
215 AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11,
216 AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12,
217 AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13,
218 AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14,
219 AIC3X_GPIO1_FUNC_ALL_IRQ = 16
220};
221
222enum {
223 AIC3X_GPIO2_FUNC_DISABLED = 0,
224 AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2,
225 AIC3X_GPIO2_FUNC_INPUT = 3,
226 AIC3X_GPIO2_FUNC_OUTPUT = 4,
227 AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5,
228 AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8,
229 AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9,
230 AIC3X_GPIO2_FUNC_ALL_IRQ = 10,
231 AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11,
232 AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12,
233 AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13,
234 AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14,
235 AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15
236};
237
238void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state); 202void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
239int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio); 203int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
240 204
@@ -281,11 +245,4 @@ void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
281int aic3x_headset_detected(struct snd_soc_codec *codec); 245int aic3x_headset_detected(struct snd_soc_codec *codec);
282int aic3x_button_pressed(struct snd_soc_codec *codec); 246int aic3x_button_pressed(struct snd_soc_codec *codec);
283 247
284struct aic3x_setup_data {
285 unsigned int gpio_func[2];
286};
287
288extern struct snd_soc_dai aic3x_dai;
289extern struct snd_soc_codec_device soc_codec_dev_aic3x;
290
291#endif /* _AIC3X_H */ 248#endif /* _AIC3X_H */
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 8651b01ed22..a3c5b521da6 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -66,8 +66,6 @@
66static void dac33_calculate_times(struct snd_pcm_substream *substream); 66static void dac33_calculate_times(struct snd_pcm_substream *substream);
67static int dac33_prepare_chip(struct snd_pcm_substream *substream); 67static int dac33_prepare_chip(struct snd_pcm_substream *substream);
68 68
69static struct snd_soc_codec *tlv320dac33_codec;
70
71enum dac33_state { 69enum dac33_state {
72 DAC33_IDLE = 0, 70 DAC33_IDLE = 0,
73 DAC33_PREFILL, 71 DAC33_PREFILL,
@@ -93,7 +91,7 @@ struct tlv320dac33_priv {
93 struct mutex mutex; 91 struct mutex mutex;
94 struct workqueue_struct *dac33_wq; 92 struct workqueue_struct *dac33_wq;
95 struct work_struct work; 93 struct work_struct work;
96 struct snd_soc_codec codec; 94 struct snd_soc_codec *codec;
97 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES]; 95 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
98 struct snd_pcm_substream *substream; 96 struct snd_pcm_substream *substream;
99 int power_gpio; 97 int power_gpio;
@@ -128,6 +126,8 @@ struct tlv320dac33_priv {
128 unsigned int uthr; 126 unsigned int uthr;
129 127
130 enum dac33_state state; 128 enum dac33_state state;
129 enum snd_soc_control_type control_type;
130 void *control_data;
131}; 131};
132 132
133static const u8 dac33_reg[DAC33_CACHEREGNUM] = { 133static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
@@ -650,9 +650,7 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
650 650
651static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33) 651static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
652{ 652{
653 struct snd_soc_codec *codec; 653 struct snd_soc_codec *codec = dac33->codec;
654
655 codec = &dac33->codec;
656 654
657 switch (dac33->fifo_mode) { 655 switch (dac33->fifo_mode) {
658 case DAC33_FIFO_MODE1: 656 case DAC33_FIFO_MODE1:
@@ -695,9 +693,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
695 693
696static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33) 694static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
697{ 695{
698 struct snd_soc_codec *codec; 696 struct snd_soc_codec *codec = dac33->codec;
699
700 codec = &dac33->codec;
701 697
702 switch (dac33->fifo_mode) { 698 switch (dac33->fifo_mode) {
703 case DAC33_FIFO_MODE1: 699 case DAC33_FIFO_MODE1:
@@ -726,7 +722,7 @@ static void dac33_work(struct work_struct *work)
726 u8 reg; 722 u8 reg;
727 723
728 dac33 = container_of(work, struct tlv320dac33_priv, work); 724 dac33 = container_of(work, struct tlv320dac33_priv, work);
729 codec = &dac33->codec; 725 codec = dac33->codec;
730 726
731 mutex_lock(&dac33->mutex); 727 mutex_lock(&dac33->mutex);
732 switch (dac33->state) { 728 switch (dac33->state) {
@@ -787,8 +783,7 @@ static int dac33_startup(struct snd_pcm_substream *substream,
787 struct snd_soc_dai *dai) 783 struct snd_soc_dai *dai)
788{ 784{
789 struct snd_soc_pcm_runtime *rtd = substream->private_data; 785 struct snd_soc_pcm_runtime *rtd = substream->private_data;
790 struct snd_soc_device *socdev = rtd->socdev; 786 struct snd_soc_codec *codec = rtd->codec;
791 struct snd_soc_codec *codec = socdev->card->codec;
792 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 787 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
793 788
794 /* Stream started, save the substream pointer */ 789 /* Stream started, save the substream pointer */
@@ -801,8 +796,7 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
801 struct snd_soc_dai *dai) 796 struct snd_soc_dai *dai)
802{ 797{
803 struct snd_soc_pcm_runtime *rtd = substream->private_data; 798 struct snd_soc_pcm_runtime *rtd = substream->private_data;
804 struct snd_soc_device *socdev = rtd->socdev; 799 struct snd_soc_codec *codec = rtd->codec;
805 struct snd_soc_codec *codec = socdev->card->codec;
806 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 800 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
807 801
808 dac33->substream = NULL; 802 dac33->substream = NULL;
@@ -817,8 +811,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
817 struct snd_soc_dai *dai) 811 struct snd_soc_dai *dai)
818{ 812{
819 struct snd_soc_pcm_runtime *rtd = substream->private_data; 813 struct snd_soc_pcm_runtime *rtd = substream->private_data;
820 struct snd_soc_device *socdev = rtd->socdev; 814 struct snd_soc_codec *codec = rtd->codec;
821 struct snd_soc_codec *codec = socdev->card->codec;
822 815
823 /* Check parameters for validity */ 816 /* Check parameters for validity */
824 switch (params_rate(params)) { 817 switch (params_rate(params)) {
@@ -856,8 +849,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
856static int dac33_prepare_chip(struct snd_pcm_substream *substream) 849static int dac33_prepare_chip(struct snd_pcm_substream *substream)
857{ 850{
858 struct snd_soc_pcm_runtime *rtd = substream->private_data; 851 struct snd_soc_pcm_runtime *rtd = substream->private_data;
859 struct snd_soc_device *socdev = rtd->socdev; 852 struct snd_soc_codec *codec = rtd->codec;
860 struct snd_soc_codec *codec = socdev->card->codec;
861 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 853 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
862 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp; 854 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
863 u8 aictrl_a, aictrl_b, fifoctrl_a; 855 u8 aictrl_a, aictrl_b, fifoctrl_a;
@@ -1049,8 +1041,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
1049static void dac33_calculate_times(struct snd_pcm_substream *substream) 1041static void dac33_calculate_times(struct snd_pcm_substream *substream)
1050{ 1042{
1051 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1043 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1052 struct snd_soc_device *socdev = rtd->socdev; 1044 struct snd_soc_codec *codec = rtd->codec;
1053 struct snd_soc_codec *codec = socdev->card->codec;
1054 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1045 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1055 unsigned int period_size = substream->runtime->period_size; 1046 unsigned int period_size = substream->runtime->period_size;
1056 unsigned int rate = substream->runtime->rate; 1047 unsigned int rate = substream->runtime->rate;
@@ -1129,8 +1120,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
1129 struct snd_soc_dai *dai) 1120 struct snd_soc_dai *dai)
1130{ 1121{
1131 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1122 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1132 struct snd_soc_device *socdev = rtd->socdev; 1123 struct snd_soc_codec *codec = rtd->codec;
1133 struct snd_soc_codec *codec = socdev->card->codec;
1134 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1124 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1135 int ret = 0; 1125 int ret = 0;
1136 1126
@@ -1163,8 +1153,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1163 struct snd_soc_dai *dai) 1153 struct snd_soc_dai *dai)
1164{ 1154{
1165 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1155 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1166 struct snd_soc_device *socdev = rtd->socdev; 1156 struct snd_soc_codec *codec = rtd->codec;
1167 struct snd_soc_codec *codec = socdev->card->codec;
1168 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1157 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1169 unsigned long long t0, t1, t_now; 1158 unsigned long long t0, t1, t_now;
1170 unsigned int time_delta, uthr; 1159 unsigned int time_delta, uthr;
@@ -1389,24 +1378,47 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
1389 return 0; 1378 return 0;
1390} 1379}
1391 1380
1392static int dac33_soc_probe(struct platform_device *pdev) 1381static int dac33_soc_probe(struct snd_soc_codec *codec)
1393{ 1382{
1394 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1383 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1395 struct snd_soc_codec *codec;
1396 struct tlv320dac33_priv *dac33;
1397 int ret = 0; 1384 int ret = 0;
1398 1385
1399 BUG_ON(!tlv320dac33_codec); 1386 codec->control_data = dac33->control_data;
1387 codec->hw_write = (hw_write_t) i2c_master_send;
1388 codec->bias_level = SND_SOC_BIAS_OFF;
1389 codec->idle_bias_off = 1;
1390 dac33->codec = codec;
1400 1391
1401 codec = tlv320dac33_codec; 1392 /* Read the tlv320dac33 ID registers */
1402 socdev->card->codec = codec; 1393 ret = dac33_hard_power(codec, 1);
1403 dac33 = snd_soc_codec_get_drvdata(codec); 1394 if (ret != 0) {
1395 dev_err(codec->dev, "Failed to power up codec: %d\n", ret);
1396 goto err_power;
1397 }
1398 dac33_read_id(codec);
1399 dac33_hard_power(codec, 0);
1404 1400
1405 /* register pcms */ 1401 /* Check if the IRQ number is valid and request it */
1406 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1402 if (dac33->irq >= 0) {
1407 if (ret < 0) { 1403 ret = request_irq(dac33->irq, dac33_interrupt_handler,
1408 dev_err(codec->dev, "failed to create pcms\n"); 1404 IRQF_TRIGGER_RISING | IRQF_DISABLED,
1409 goto pcm_err; 1405 codec->name, codec);
1406 if (ret < 0) {
1407 dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
1408 dac33->irq, ret);
1409 dac33->irq = -1;
1410 }
1411 if (dac33->irq != -1) {
1412 /* Setup work queue */
1413 dac33->dac33_wq =
1414 create_singlethread_workqueue("tlv320dac33");
1415 if (dac33->dac33_wq == NULL) {
1416 free_irq(dac33->irq, codec);
1417 return -ENOMEM;
1418 }
1419
1420 INIT_WORK(&dac33->work, dac33_work);
1421 }
1410 } 1422 }
1411 1423
1412 snd_soc_add_controls(codec, dac33_snd_controls, 1424 snd_soc_add_controls(codec, dac33_snd_controls,
@@ -1420,56 +1432,51 @@ static int dac33_soc_probe(struct platform_device *pdev)
1420 snd_soc_add_controls(codec, dac33_fifo_snd_controls, 1432 snd_soc_add_controls(codec, dac33_fifo_snd_controls,
1421 ARRAY_SIZE(dac33_fifo_snd_controls)); 1433 ARRAY_SIZE(dac33_fifo_snd_controls));
1422 } 1434 }
1423
1424 dac33_add_widgets(codec); 1435 dac33_add_widgets(codec);
1425 1436
1426 return 0; 1437err_power:
1427
1428pcm_err:
1429 dac33_hard_power(codec, 0);
1430 return ret; 1438 return ret;
1431} 1439}
1432 1440
1433static int dac33_soc_remove(struct platform_device *pdev) 1441static int dac33_soc_remove(struct snd_soc_codec *codec)
1434{ 1442{
1435 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1443 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1436 struct snd_soc_codec *codec = socdev->card->codec;
1437 1444
1438 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF); 1445 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
1439 1446
1440 snd_soc_free_pcms(socdev); 1447 if (dac33->irq >= 0) {
1441 snd_soc_dapm_free(socdev); 1448 free_irq(dac33->irq, dac33->codec);
1442 1449 destroy_workqueue(dac33->dac33_wq);
1450 }
1443 return 0; 1451 return 0;
1444} 1452}
1445 1453
1446static int dac33_soc_suspend(struct platform_device *pdev, pm_message_t state) 1454static int dac33_soc_suspend(struct snd_soc_codec *codec, pm_message_t state)
1447{ 1455{
1448 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1449 struct snd_soc_codec *codec = socdev->card->codec;
1450
1451 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF); 1456 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
1452 1457
1453 return 0; 1458 return 0;
1454} 1459}
1455 1460
1456static int dac33_soc_resume(struct platform_device *pdev) 1461static int dac33_soc_resume(struct snd_soc_codec *codec)
1457{ 1462{
1458 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1459 struct snd_soc_codec *codec = socdev->card->codec;
1460
1461 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1463 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1462 1464
1463 return 0; 1465 return 0;
1464} 1466}
1465 1467
1466struct snd_soc_codec_device soc_codec_dev_tlv320dac33 = { 1468static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
1469 .read = dac33_read_reg_cache,
1470 .write = dac33_write_locked,
1471 .set_bias_level = dac33_set_bias_level,
1472 .reg_cache_size = ARRAY_SIZE(dac33_reg),
1473 .reg_word_size = sizeof(u8),
1474 .reg_cache_default = dac33_reg,
1467 .probe = dac33_soc_probe, 1475 .probe = dac33_soc_probe,
1468 .remove = dac33_soc_remove, 1476 .remove = dac33_soc_remove,
1469 .suspend = dac33_soc_suspend, 1477 .suspend = dac33_soc_suspend,
1470 .resume = dac33_soc_resume, 1478 .resume = dac33_soc_resume,
1471}; 1479};
1472EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320dac33);
1473 1480
1474#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ 1481#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
1475 SNDRV_PCM_RATE_48000) 1482 SNDRV_PCM_RATE_48000)
@@ -1485,8 +1492,8 @@ static struct snd_soc_dai_ops dac33_dai_ops = {
1485 .set_fmt = dac33_set_dai_fmt, 1492 .set_fmt = dac33_set_dai_fmt,
1486}; 1493};
1487 1494
1488struct snd_soc_dai dac33_dai = { 1495static struct snd_soc_dai_driver dac33_dai = {
1489 .name = "tlv320dac33", 1496 .name = "tlv320dac33-hifi",
1490 .playback = { 1497 .playback = {
1491 .stream_name = "Playback", 1498 .stream_name = "Playback",
1492 .channels_min = 2, 1499 .channels_min = 2,
@@ -1495,14 +1502,12 @@ struct snd_soc_dai dac33_dai = {
1495 .formats = DAC33_FORMATS,}, 1502 .formats = DAC33_FORMATS,},
1496 .ops = &dac33_dai_ops, 1503 .ops = &dac33_dai_ops,
1497}; 1504};
1498EXPORT_SYMBOL_GPL(dac33_dai);
1499 1505
1500static int __devinit dac33_i2c_probe(struct i2c_client *client, 1506static int __devinit dac33_i2c_probe(struct i2c_client *client,
1501 const struct i2c_device_id *id) 1507 const struct i2c_device_id *id)
1502{ 1508{
1503 struct tlv320dac33_platform_data *pdata; 1509 struct tlv320dac33_platform_data *pdata;
1504 struct tlv320dac33_priv *dac33; 1510 struct tlv320dac33_priv *dac33;
1505 struct snd_soc_codec *codec;
1506 int ret, i; 1511 int ret, i;
1507 1512
1508 if (client->dev.platform_data == NULL) { 1513 if (client->dev.platform_data == NULL) {
@@ -1515,33 +1520,9 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1515 if (dac33 == NULL) 1520 if (dac33 == NULL)
1516 return -ENOMEM; 1521 return -ENOMEM;
1517 1522
1518 codec = &dac33->codec; 1523 dac33->control_data = client;
1519 snd_soc_codec_set_drvdata(codec, dac33);
1520 codec->control_data = client;
1521
1522 mutex_init(&codec->mutex);
1523 mutex_init(&dac33->mutex); 1524 mutex_init(&dac33->mutex);
1524 spin_lock_init(&dac33->lock); 1525 spin_lock_init(&dac33->lock);
1525 INIT_LIST_HEAD(&codec->dapm_widgets);
1526 INIT_LIST_HEAD(&codec->dapm_paths);
1527
1528 codec->name = "tlv320dac33";
1529 codec->owner = THIS_MODULE;
1530 codec->read = dac33_read_reg_cache;
1531 codec->write = dac33_write_locked;
1532 codec->hw_write = (hw_write_t) i2c_master_send;
1533 codec->bias_level = SND_SOC_BIAS_OFF;
1534 codec->set_bias_level = dac33_set_bias_level;
1535 codec->idle_bias_off = 1;
1536 codec->dai = &dac33_dai;
1537 codec->num_dai = 1;
1538 codec->reg_cache_size = ARRAY_SIZE(dac33_reg);
1539 codec->reg_cache = kmemdup(dac33_reg, ARRAY_SIZE(dac33_reg),
1540 GFP_KERNEL);
1541 if (codec->reg_cache == NULL) {
1542 ret = -ENOMEM;
1543 goto error_reg;
1544 }
1545 1526
1546 i2c_set_clientdata(client, dac33); 1527 i2c_set_clientdata(client, dac33);
1547 1528
@@ -1561,125 +1542,59 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1561 /* Disable FIFO use by default */ 1542 /* Disable FIFO use by default */
1562 dac33->fifo_mode = DAC33_FIFO_BYPASS; 1543 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1563 1544
1564 tlv320dac33_codec = codec;
1565
1566 codec->dev = &client->dev;
1567 dac33_dai.dev = codec->dev;
1568
1569 /* Check if the reset GPIO number is valid and request it */ 1545 /* Check if the reset GPIO number is valid and request it */
1570 if (dac33->power_gpio >= 0) { 1546 if (dac33->power_gpio >= 0) {
1571 ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset"); 1547 ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset");
1572 if (ret < 0) { 1548 if (ret < 0) {
1573 dev_err(codec->dev, 1549 dev_err(&client->dev,
1574 "Failed to request reset GPIO (%d)\n", 1550 "Failed to request reset GPIO (%d)\n",
1575 dac33->power_gpio); 1551 dac33->power_gpio);
1576 snd_soc_unregister_dai(&dac33_dai); 1552 goto err_gpio;
1577 snd_soc_unregister_codec(codec);
1578 goto error_gpio;
1579 } 1553 }
1580 gpio_direction_output(dac33->power_gpio, 0); 1554 gpio_direction_output(dac33->power_gpio, 0);
1581 } 1555 }
1582 1556
1583 /* Check if the IRQ number is valid and request it */
1584 if (dac33->irq >= 0) {
1585 ret = request_irq(dac33->irq, dac33_interrupt_handler,
1586 IRQF_TRIGGER_RISING | IRQF_DISABLED,
1587 codec->name, codec);
1588 if (ret < 0) {
1589 dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
1590 dac33->irq, ret);
1591 dac33->irq = -1;
1592 }
1593 if (dac33->irq != -1) {
1594 /* Setup work queue */
1595 dac33->dac33_wq =
1596 create_singlethread_workqueue("tlv320dac33");
1597 if (dac33->dac33_wq == NULL) {
1598 free_irq(dac33->irq, &dac33->codec);
1599 ret = -ENOMEM;
1600 goto error_wq;
1601 }
1602
1603 INIT_WORK(&dac33->work, dac33_work);
1604 }
1605 }
1606
1607 for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++) 1557 for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
1608 dac33->supplies[i].supply = dac33_supply_names[i]; 1558 dac33->supplies[i].supply = dac33_supply_names[i];
1609 1559
1610 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(dac33->supplies), 1560 ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(dac33->supplies),
1611 dac33->supplies); 1561 dac33->supplies);
1612 1562
1613 if (ret != 0) { 1563 if (ret != 0) {
1614 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 1564 dev_err(&client->dev, "Failed to request supplies: %d\n", ret);
1615 goto err_get; 1565 goto err_get;
1616 } 1566 }
1617 1567
1618 /* Read the tlv320dac33 ID registers */ 1568 ret = snd_soc_register_codec(&client->dev,
1619 ret = dac33_hard_power(codec, 1); 1569 &soc_codec_dev_tlv320dac33, &dac33_dai, 1);
1620 if (ret != 0) { 1570 if (ret < 0)
1621 dev_err(codec->dev, "Failed to power up codec: %d\n", ret); 1571 goto err_register;
1622 goto error_codec;
1623 }
1624 dac33_read_id(codec);
1625 dac33_hard_power(codec, 0);
1626
1627 ret = snd_soc_register_codec(codec);
1628 if (ret != 0) {
1629 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1630 goto error_codec;
1631 }
1632
1633 ret = snd_soc_register_dai(&dac33_dai);
1634 if (ret != 0) {
1635 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1636 snd_soc_unregister_codec(codec);
1637 goto error_codec;
1638 }
1639 1572
1640 return ret; 1573 return ret;
1641 1574err_register:
1642error_codec:
1643 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies); 1575 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1644err_get: 1576err_get:
1645 if (dac33->irq >= 0) {
1646 free_irq(dac33->irq, &dac33->codec);
1647 destroy_workqueue(dac33->dac33_wq);
1648 }
1649error_wq:
1650 if (dac33->power_gpio >= 0) 1577 if (dac33->power_gpio >= 0)
1651 gpio_free(dac33->power_gpio); 1578 gpio_free(dac33->power_gpio);
1652error_gpio: 1579err_gpio:
1653 kfree(codec->reg_cache);
1654error_reg:
1655 tlv320dac33_codec = NULL;
1656 kfree(dac33); 1580 kfree(dac33);
1657
1658 return ret; 1581 return ret;
1659} 1582}
1660 1583
1661static int __devexit dac33_i2c_remove(struct i2c_client *client) 1584static int __devexit dac33_i2c_remove(struct i2c_client *client)
1662{ 1585{
1663 struct tlv320dac33_priv *dac33; 1586 struct tlv320dac33_priv *dac33 = i2c_get_clientdata(client);
1664
1665 dac33 = i2c_get_clientdata(client);
1666 1587
1667 if (unlikely(dac33->chip_power)) 1588 if (unlikely(dac33->chip_power))
1668 dac33_hard_power(&dac33->codec, 0); 1589 dac33_hard_power(dac33->codec, 0);
1669 1590
1670 if (dac33->power_gpio >= 0) 1591 if (dac33->power_gpio >= 0)
1671 gpio_free(dac33->power_gpio); 1592 gpio_free(dac33->power_gpio);
1672 if (dac33->irq >= 0)
1673 free_irq(dac33->irq, &dac33->codec);
1674 1593
1675 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies); 1594 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1676 1595
1677 destroy_workqueue(dac33->dac33_wq); 1596 snd_soc_unregister_codec(&client->dev);
1678 snd_soc_unregister_dai(&dac33_dai);
1679 snd_soc_unregister_codec(&dac33->codec);
1680 kfree(dac33->codec.reg_cache);
1681 kfree(dac33); 1597 kfree(dac33);
1682 tlv320dac33_codec = NULL;
1683 1598
1684 return 0; 1599 return 0;
1685} 1600}
@@ -1694,7 +1609,7 @@ static const struct i2c_device_id tlv320dac33_i2c_id[] = {
1694 1609
1695static struct i2c_driver tlv320dac33_i2c_driver = { 1610static struct i2c_driver tlv320dac33_i2c_driver = {
1696 .driver = { 1611 .driver = {
1697 .name = "tlv320dac33", 1612 .name = "tlv320dac33-codec",
1698 .owner = THIS_MODULE, 1613 .owner = THIS_MODULE,
1699 }, 1614 },
1700 .probe = dac33_i2c_probe, 1615 .probe = dac33_i2c_probe,
diff --git a/sound/soc/codecs/tlv320dac33.h b/sound/soc/codecs/tlv320dac33.h
index eb8ae07f0bd..7c318b5da43 100644
--- a/sound/soc/codecs/tlv320dac33.h
+++ b/sound/soc/codecs/tlv320dac33.h
@@ -261,7 +261,4 @@
261#define TLV320DAC33_MCLK 0 261#define TLV320DAC33_MCLK 0
262#define TLV320DAC33_SLEEPCLK 1 262#define TLV320DAC33_SLEEPCLK 1
263 263
264extern struct snd_soc_dai dac33_dai;
265extern struct snd_soc_codec_device soc_codec_dev_tlv320dac33;
266
267#endif /* __TLV320DAC33_H */ 264#endif /* __TLV320DAC33_H */
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 7b618bbff88..898430f44f9 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -36,7 +36,16 @@
36#include <sound/initval.h> 36#include <sound/initval.h>
37#include <sound/tlv.h> 37#include <sound/tlv.h>
38 38
39#include "twl4030.h" 39/* Register descriptions are here */
40#include <linux/mfd/twl4030-codec.h>
41
42/* Shadow register used by the audio driver */
43#define TWL4030_REG_SW_SHADOW 0x4A
44#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
45
46/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
47#define TWL4030_HFL_EN 0x01
48#define TWL4030_HFR_EN 0x02
40 49
41/* 50/*
42 * twl4030 register cache & default register settings 51 * twl4030 register cache & default register settings
@@ -277,21 +286,19 @@ static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
277 286
278} 287}
279 288
280static void twl4030_init_chip(struct platform_device *pdev) 289static void twl4030_init_chip(struct snd_soc_codec *codec)
281{ 290{
282 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 291 struct twl4030_codec_audio_data *pdata = dev_get_platdata(codec->dev);
283 struct twl4030_setup_data *setup = socdev->codec_data;
284 struct snd_soc_codec *codec = socdev->card->codec;
285 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 292 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
286 u8 reg, byte; 293 u8 reg, byte;
287 int i = 0; 294 int i = 0;
288 295
289 /* Check defaults, if instructed before anything else */ 296 /* Check defaults, if instructed before anything else */
290 if (setup && setup->check_defaults) 297 if (pdata && pdata->check_defaults)
291 twl4030_check_defaults(codec); 298 twl4030_check_defaults(codec);
292 299
293 /* Reset registers, if no setup data or if instructed to do so */ 300 /* Reset registers, if no setup data or if instructed to do so */
294 if (!setup || (setup && setup->reset_registers)) 301 if (!pdata || (pdata && pdata->reset_registers))
295 twl4030_reset_registers(codec); 302 twl4030_reset_registers(codec);
296 303
297 /* Refresh APLL_CTL register from HW */ 304 /* Refresh APLL_CTL register from HW */
@@ -312,20 +319,14 @@ static void twl4030_init_chip(struct platform_device *pdev)
312 twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32); 319 twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
313 320
314 /* Machine dependent setup */ 321 /* Machine dependent setup */
315 if (!setup) 322 if (!pdata)
316 return; 323 return;
317 324
318 twl4030->digimic_delay = setup->digimic_delay; 325 twl4030->digimic_delay = pdata->digimic_delay;
319
320 /* Configuration for headset ramp delay from setup data */
321 if (setup->sysclk != twl4030->sysclk)
322 dev_warn(codec->dev,
323 "Mismatch in APLL mclk: %u (configured: %u)\n",
324 setup->sysclk, twl4030->sysclk);
325 326
326 reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 327 reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
327 reg &= ~TWL4030_RAMP_DELAY; 328 reg &= ~TWL4030_RAMP_DELAY;
328 reg |= (setup->ramp_delay_value << 2); 329 reg |= (pdata->ramp_delay_value << 2);
329 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg); 330 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg);
330 331
331 /* initiate offset cancellation */ 332 /* initiate offset cancellation */
@@ -333,7 +334,7 @@ static void twl4030_init_chip(struct platform_device *pdev)
333 334
334 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL); 335 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
335 reg &= ~TWL4030_OFFSET_CNCL_SEL; 336 reg &= ~TWL4030_OFFSET_CNCL_SEL;
336 reg |= setup->offset_cncl_path; 337 reg |= pdata->offset_cncl_path;
337 twl4030_write(codec, TWL4030_REG_ANAMICL, 338 twl4030_write(codec, TWL4030_REG_ANAMICL,
338 reg | TWL4030_CNCL_OFFSET_START); 339 reg | TWL4030_CNCL_OFFSET_START);
339 340
@@ -718,9 +719,7 @@ static int aif_event(struct snd_soc_dapm_widget *w,
718 719
719static void headset_ramp(struct snd_soc_codec *codec, int ramp) 720static void headset_ramp(struct snd_soc_codec *codec, int ramp)
720{ 721{
721 struct snd_soc_device *socdev = codec->socdev; 722 struct twl4030_codec_audio_data *pdata = codec->dev->platform_data;
722 struct twl4030_setup_data *setup = socdev->codec_data;
723
724 unsigned char hs_gain, hs_pop; 723 unsigned char hs_gain, hs_pop;
725 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 724 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
726 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 725 /* Base values for ramp delay calculation: 2^19 - 2^26 */
@@ -732,9 +731,9 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
732 731
733 /* Enable external mute control, this dramatically reduces 732 /* Enable external mute control, this dramatically reduces
734 * the pop-noise */ 733 * the pop-noise */
735 if (setup && setup->hs_extmute) { 734 if (pdata && pdata->hs_extmute) {
736 if (setup->set_hs_extmute) { 735 if (pdata->set_hs_extmute) {
737 setup->set_hs_extmute(1); 736 pdata->set_hs_extmute(1);
738 } else { 737 } else {
739 hs_pop |= TWL4030_EXTMUTE; 738 hs_pop |= TWL4030_EXTMUTE;
740 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 739 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -772,9 +771,9 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
772 } 771 }
773 772
774 /* Disable external mute */ 773 /* Disable external mute */
775 if (setup && setup->hs_extmute) { 774 if (pdata && pdata->hs_extmute) {
776 if (setup->set_hs_extmute) { 775 if (pdata->set_hs_extmute) {
777 setup->set_hs_extmute(0); 776 pdata->set_hs_extmute(0);
778 } else { 777 } else {
779 hs_pop &= ~TWL4030_EXTMUTE; 778 hs_pop &= ~TWL4030_EXTMUTE;
780 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 779 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -1707,8 +1706,7 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
1707 struct snd_soc_dai *dai) 1706 struct snd_soc_dai *dai)
1708{ 1707{
1709 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1708 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1710 struct snd_soc_device *socdev = rtd->socdev; 1709 struct snd_soc_codec *codec = rtd->codec;
1711 struct snd_soc_codec *codec = socdev->card->codec;
1712 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1710 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1713 1711
1714 if (twl4030->master_substream) { 1712 if (twl4030->master_substream) {
@@ -1738,8 +1736,7 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream,
1738 struct snd_soc_dai *dai) 1736 struct snd_soc_dai *dai)
1739{ 1737{
1740 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1738 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1741 struct snd_soc_device *socdev = rtd->socdev; 1739 struct snd_soc_codec *codec = rtd->codec;
1742 struct snd_soc_codec *codec = socdev->card->codec;
1743 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1740 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1744 1741
1745 if (twl4030->master_substream == substream) 1742 if (twl4030->master_substream == substream)
@@ -1764,8 +1761,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1764 struct snd_soc_dai *dai) 1761 struct snd_soc_dai *dai)
1765{ 1762{
1766 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1763 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1767 struct snd_soc_device *socdev = rtd->socdev; 1764 struct snd_soc_codec *codec = rtd->codec;
1768 struct snd_soc_codec *codec = socdev->card->codec;
1769 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1765 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1770 u8 mode, old_mode, format, old_format; 1766 u8 mode, old_mode, format, old_format;
1771 1767
@@ -1999,8 +1995,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1999 struct snd_soc_dai *dai) 1995 struct snd_soc_dai *dai)
2000{ 1996{
2001 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1997 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2002 struct snd_soc_device *socdev = rtd->socdev; 1998 struct snd_soc_codec *codec = rtd->codec;
2003 struct snd_soc_codec *codec = socdev->card->codec;
2004 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1999 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2005 u8 mode; 2000 u8 mode;
2006 2001
@@ -2033,8 +2028,7 @@ static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
2033 struct snd_soc_dai *dai) 2028 struct snd_soc_dai *dai)
2034{ 2029{
2035 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2030 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2036 struct snd_soc_device *socdev = rtd->socdev; 2031 struct snd_soc_codec *codec = rtd->codec;
2037 struct snd_soc_codec *codec = socdev->card->codec;
2038 2032
2039 /* Enable voice digital filters */ 2033 /* Enable voice digital filters */
2040 twl4030_voice_enable(codec, substream->stream, 0); 2034 twl4030_voice_enable(codec, substream->stream, 0);
@@ -2044,8 +2038,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2044 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 2038 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
2045{ 2039{
2046 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2040 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2047 struct snd_soc_device *socdev = rtd->socdev; 2041 struct snd_soc_codec *codec = rtd->codec;
2048 struct snd_soc_codec *codec = socdev->card->codec;
2049 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2042 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2050 u8 old_mode, mode; 2043 u8 old_mode, mode;
2051 2044
@@ -2175,7 +2168,7 @@ static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
2175#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) 2168#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
2176#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) 2169#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
2177 2170
2178static struct snd_soc_dai_ops twl4030_dai_ops = { 2171static struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
2179 .startup = twl4030_startup, 2172 .startup = twl4030_startup,
2180 .shutdown = twl4030_shutdown, 2173 .shutdown = twl4030_shutdown,
2181 .hw_params = twl4030_hw_params, 2174 .hw_params = twl4030_hw_params,
@@ -2193,9 +2186,9 @@ static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
2193 .set_tristate = twl4030_voice_set_tristate, 2186 .set_tristate = twl4030_voice_set_tristate,
2194}; 2187};
2195 2188
2196struct snd_soc_dai twl4030_dai[] = { 2189static struct snd_soc_dai_driver twl4030_dai[] = {
2197{ 2190{
2198 .name = "twl4030", 2191 .name = "twl4030-hifi",
2199 .playback = { 2192 .playback = {
2200 .stream_name = "HiFi Playback", 2193 .stream_name = "HiFi Playback",
2201 .channels_min = 2, 2194 .channels_min = 2,
@@ -2208,10 +2201,10 @@ struct snd_soc_dai twl4030_dai[] = {
2208 .channels_max = 4, 2201 .channels_max = 4,
2209 .rates = TWL4030_RATES, 2202 .rates = TWL4030_RATES,
2210 .formats = TWL4030_FORMATS,}, 2203 .formats = TWL4030_FORMATS,},
2211 .ops = &twl4030_dai_ops, 2204 .ops = &twl4030_dai_hifi_ops,
2212}, 2205},
2213{ 2206{
2214 .name = "twl4030 Voice", 2207 .name = "twl4030-voice",
2215 .playback = { 2208 .playback = {
2216 .stream_name = "Voice Playback", 2209 .stream_name = "Voice Playback",
2217 .channels_min = 1, 2210 .channels_min = 1,
@@ -2227,164 +2220,90 @@ struct snd_soc_dai twl4030_dai[] = {
2227 .ops = &twl4030_dai_voice_ops, 2220 .ops = &twl4030_dai_voice_ops,
2228}, 2221},
2229}; 2222};
2230EXPORT_SYMBOL_GPL(twl4030_dai);
2231 2223
2232static int twl4030_soc_suspend(struct platform_device *pdev, pm_message_t state) 2224static int twl4030_soc_suspend(struct snd_soc_codec *codec, pm_message_t state)
2233{ 2225{
2234 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2235 struct snd_soc_codec *codec = socdev->card->codec;
2236
2237 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2226 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2238
2239 return 0; 2227 return 0;
2240} 2228}
2241 2229
2242static int twl4030_soc_resume(struct platform_device *pdev) 2230static int twl4030_soc_resume(struct snd_soc_codec *codec)
2243{ 2231{
2244 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2245 struct snd_soc_codec *codec = socdev->card->codec;
2246
2247 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2232 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2248 return 0; 2233 return 0;
2249} 2234}
2250 2235
2251static struct snd_soc_codec *twl4030_codec; 2236static int twl4030_soc_probe(struct snd_soc_codec *codec)
2252
2253static int twl4030_soc_probe(struct platform_device *pdev)
2254{ 2237{
2255 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2238 struct twl4030_priv *twl4030;
2256 struct snd_soc_codec *codec;
2257 int ret;
2258
2259 BUG_ON(!twl4030_codec);
2260
2261 codec = twl4030_codec;
2262 socdev->card->codec = codec;
2263
2264 twl4030_init_chip(pdev);
2265 2239
2266 /* register pcms */ 2240 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
2267 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 2241 if (twl4030 == NULL) {
2268 if (ret < 0) { 2242 printk("Can not allocate memroy\n");
2269 dev_err(&pdev->dev, "failed to create pcms\n"); 2243 return -ENOMEM;
2270 return ret;
2271 } 2244 }
2245 snd_soc_codec_set_drvdata(codec, twl4030);
2246 /* Set the defaults, and power up the codec */
2247 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2248 codec->bias_level = SND_SOC_BIAS_OFF;
2249 codec->idle_bias_off = 1;
2250
2251 twl4030_init_chip(codec);
2272 2252
2273 snd_soc_add_controls(codec, twl4030_snd_controls, 2253 snd_soc_add_controls(codec, twl4030_snd_controls,
2274 ARRAY_SIZE(twl4030_snd_controls)); 2254 ARRAY_SIZE(twl4030_snd_controls));
2275 twl4030_add_widgets(codec); 2255 twl4030_add_widgets(codec);
2276
2277 return 0; 2256 return 0;
2278} 2257}
2279 2258
2280static int twl4030_soc_remove(struct platform_device *pdev) 2259static int twl4030_soc_remove(struct snd_soc_codec *codec)
2281{ 2260{
2282 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2283 struct snd_soc_codec *codec = socdev->card->codec;
2284
2285 /* Reset registers to their chip default before leaving */
2286 twl4030_reset_registers(codec);
2287 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2261 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2288 snd_soc_free_pcms(socdev);
2289 snd_soc_dapm_free(socdev);
2290
2291 return 0; 2262 return 0;
2292} 2263}
2293 2264
2265static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2266 .probe = twl4030_soc_probe,
2267 .remove = twl4030_soc_remove,
2268 .suspend = twl4030_soc_suspend,
2269 .resume = twl4030_soc_resume,
2270 .read = twl4030_read_reg_cache,
2271 .write = twl4030_write,
2272 .set_bias_level = twl4030_set_bias_level,
2273 .reg_cache_size = sizeof(twl4030_reg),
2274 .reg_word_size = sizeof(u8),
2275 .reg_cache_default = twl4030_reg,
2276};
2277
2294static int __devinit twl4030_codec_probe(struct platform_device *pdev) 2278static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2295{ 2279{
2296 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data; 2280 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
2297 struct snd_soc_codec *codec;
2298 struct twl4030_priv *twl4030;
2299 int ret;
2300 2281
2301 if (!pdata) { 2282 if (!pdata) {
2302 dev_err(&pdev->dev, "platform_data is missing\n"); 2283 dev_err(&pdev->dev, "platform_data is missing\n");
2303 return -EINVAL; 2284 return -EINVAL;
2304 } 2285 }
2305 2286
2306 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); 2287 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
2307 if (twl4030 == NULL) { 2288 twl4030_dai, ARRAY_SIZE(twl4030_dai));
2308 dev_err(&pdev->dev, "Can not allocate memroy\n");
2309 return -ENOMEM;
2310 }
2311
2312 codec = &twl4030->codec;
2313 snd_soc_codec_set_drvdata(codec, twl4030);
2314 codec->dev = &pdev->dev;
2315 twl4030_dai[0].dev = &pdev->dev;
2316 twl4030_dai[1].dev = &pdev->dev;
2317
2318 mutex_init(&codec->mutex);
2319 INIT_LIST_HEAD(&codec->dapm_widgets);
2320 INIT_LIST_HEAD(&codec->dapm_paths);
2321
2322 codec->name = "twl4030";
2323 codec->owner = THIS_MODULE;
2324 codec->read = twl4030_read_reg_cache;
2325 codec->write = twl4030_write;
2326 codec->set_bias_level = twl4030_set_bias_level;
2327 codec->idle_bias_off = 1;
2328 codec->dai = twl4030_dai;
2329 codec->num_dai = ARRAY_SIZE(twl4030_dai);
2330 codec->reg_cache_size = sizeof(twl4030_reg);
2331 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2332 GFP_KERNEL);
2333 if (codec->reg_cache == NULL) {
2334 ret = -ENOMEM;
2335 goto error_cache;
2336 }
2337
2338 platform_set_drvdata(pdev, twl4030);
2339 twl4030_codec = codec;
2340
2341 /* Set the defaults, and power up the codec */
2342 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2343 codec->bias_level = SND_SOC_BIAS_OFF;
2344
2345 ret = snd_soc_register_codec(codec);
2346 if (ret != 0) {
2347 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2348 goto error_codec;
2349 }
2350
2351 ret = snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2352 if (ret != 0) {
2353 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
2354 snd_soc_unregister_codec(codec);
2355 goto error_codec;
2356 }
2357
2358 return 0;
2359
2360error_codec:
2361 twl4030_codec_enable(codec, 0);
2362 kfree(codec->reg_cache);
2363error_cache:
2364 kfree(twl4030);
2365 return ret;
2366} 2289}
2367 2290
2368static int __devexit twl4030_codec_remove(struct platform_device *pdev) 2291static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2369{ 2292{
2370 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev); 2293 struct twl4030_priv *twl4030 = dev_get_drvdata(&pdev->dev);
2371 2294
2372 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); 2295 snd_soc_unregister_codec(&pdev->dev);
2373 snd_soc_unregister_codec(&twl4030->codec);
2374 kfree(twl4030->codec.reg_cache);
2375 kfree(twl4030); 2296 kfree(twl4030);
2376
2377 twl4030_codec = NULL;
2378 return 0; 2297 return 0;
2379} 2298}
2380 2299
2381MODULE_ALIAS("platform:twl4030_codec_audio"); 2300MODULE_ALIAS("platform:twl4030-codec");
2382 2301
2383static struct platform_driver twl4030_codec_driver = { 2302static struct platform_driver twl4030_codec_driver = {
2384 .probe = twl4030_codec_probe, 2303 .probe = twl4030_codec_probe,
2385 .remove = __devexit_p(twl4030_codec_remove), 2304 .remove = __devexit_p(twl4030_codec_remove),
2386 .driver = { 2305 .driver = {
2387 .name = "twl4030_codec_audio", 2306 .name = "twl4030-codec",
2388 .owner = THIS_MODULE, 2307 .owner = THIS_MODULE,
2389 }, 2308 },
2390}; 2309};
@@ -2401,14 +2320,6 @@ static void __exit twl4030_exit(void)
2401} 2320}
2402module_exit(twl4030_exit); 2321module_exit(twl4030_exit);
2403 2322
2404struct snd_soc_codec_device soc_codec_dev_twl4030 = {
2405 .probe = twl4030_soc_probe,
2406 .remove = twl4030_soc_remove,
2407 .suspend = twl4030_soc_suspend,
2408 .resume = twl4030_soc_resume,
2409};
2410EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2411
2412MODULE_DESCRIPTION("ASoC TWL4030 codec driver"); 2323MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
2413MODULE_AUTHOR("Steve Sakoman"); 2324MODULE_AUTHOR("Steve Sakoman");
2414MODULE_LICENSE("GPL"); 2325MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
deleted file mode 100644
index 6c57430f6e2..00000000000
--- a/sound/soc/codecs/twl4030.h
+++ /dev/null
@@ -1,55 +0,0 @@
1/*
2 * ALSA SoC TWL4030 codec driver
3 *
4 * Author: Steve Sakoman <steve@sakoman.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 __TWL4030_AUDIO_H__
23#define __TWL4030_AUDIO_H__
24
25/* Register descriptions are here */
26#include <linux/mfd/twl4030-codec.h>
27
28/* Shadow register used by the audio driver */
29#define TWL4030_REG_SW_SHADOW 0x4A
30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
31
32/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
33#define TWL4030_HFL_EN 0x01
34#define TWL4030_HFR_EN 0x02
35
36#define TWL4030_DAI_HIFI 0
37#define TWL4030_DAI_VOICE 1
38
39extern struct snd_soc_dai twl4030_dai[2];
40extern struct snd_soc_codec_device soc_codec_dev_twl4030;
41
42struct twl4030_setup_data {
43 unsigned int ramp_delay_value;
44 unsigned int digimic_delay; /* in ms */
45 unsigned int sysclk;
46 unsigned int offset_cncl_path;
47 unsigned int check_defaults:1;
48 unsigned int reset_registers:1;
49 unsigned int hs_extmute:1;
50 void (*set_hs_extmute)(int mute);
51};
52
53#endif /* End of __TWL4030_AUDIO_H__ */
54
55
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 64a807f1a8a..10f6e521451 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -45,7 +45,6 @@
45 45
46/* codec private data */ 46/* codec private data */
47struct twl6040_data { 47struct twl6040_data {
48 struct snd_soc_codec codec;
49 int audpwron; 48 int audpwron;
50 int naudint; 49 int naudint;
51 int codec_powered; 50 int codec_powered;
@@ -770,8 +769,7 @@ static int twl6040_startup(struct snd_pcm_substream *substream,
770 struct snd_soc_dai *dai) 769 struct snd_soc_dai *dai)
771{ 770{
772 struct snd_soc_pcm_runtime *rtd = substream->private_data; 771 struct snd_soc_pcm_runtime *rtd = substream->private_data;
773 struct snd_soc_device *socdev = rtd->socdev; 772 struct snd_soc_codec *codec = rtd->codec;
774 struct snd_soc_codec *codec = socdev->card->codec;
775 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 773 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
776 774
777 if (!priv->sysclk) { 775 if (!priv->sysclk) {
@@ -803,8 +801,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
803 struct snd_soc_dai *dai) 801 struct snd_soc_dai *dai)
804{ 802{
805 struct snd_soc_pcm_runtime *rtd = substream->private_data; 803 struct snd_soc_pcm_runtime *rtd = substream->private_data;
806 struct snd_soc_device *socdev = rtd->socdev; 804 struct snd_soc_codec *codec = rtd->codec;
807 struct snd_soc_codec *codec = socdev->card->codec;
808 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 805 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
809 u8 lppllctl; 806 u8 lppllctl;
810 int rate; 807 int rate;
@@ -839,8 +836,7 @@ static int twl6040_trigger(struct snd_pcm_substream *substream,
839 int cmd, struct snd_soc_dai *dai) 836 int cmd, struct snd_soc_dai *dai)
840{ 837{
841 struct snd_soc_pcm_runtime *rtd = substream->private_data; 838 struct snd_soc_pcm_runtime *rtd = substream->private_data;
842 struct snd_soc_device *socdev = rtd->socdev; 839 struct snd_soc_codec *codec = rtd->codec;
843 struct snd_soc_codec *codec = socdev->card->codec;
844 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 840 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
845 841
846 switch (cmd) { 842 switch (cmd) {
@@ -978,8 +974,8 @@ static struct snd_soc_dai_ops twl6040_dai_ops = {
978 .set_sysclk = twl6040_set_dai_sysclk, 974 .set_sysclk = twl6040_set_dai_sysclk,
979}; 975};
980 976
981struct snd_soc_dai twl6040_dai = { 977static struct snd_soc_dai_driver twl6040_dai = {
982 .name = "twl6040", 978 .name = "twl6040-hifi",
983 .playback = { 979 .playback = {
984 .stream_name = "Playback", 980 .stream_name = "Playback",
985 .channels_min = 1, 981 .channels_min = 1,
@@ -996,24 +992,17 @@ struct snd_soc_dai twl6040_dai = {
996 }, 992 },
997 .ops = &twl6040_dai_ops, 993 .ops = &twl6040_dai_ops,
998}; 994};
999EXPORT_SYMBOL_GPL(twl6040_dai);
1000 995
1001#ifdef CONFIG_PM 996#ifdef CONFIG_PM
1002static int twl6040_suspend(struct platform_device *pdev, pm_message_t state) 997static int twl6040_suspend(struct snd_soc_codec *codec, pm_message_t state)
1003{ 998{
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); 999 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1008 1000
1009 return 0; 1001 return 0;
1010} 1002}
1011 1003
1012static int twl6040_resume(struct platform_device *pdev) 1004static int twl6040_resume(struct snd_soc_codec *codec)
1013{ 1005{
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); 1006 twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1018 1007
1019 return 0; 1008 return 0;
@@ -1023,68 +1012,9 @@ static int twl6040_resume(struct platform_device *pdev)
1023#define twl6040_resume NULL 1012#define twl6040_resume NULL
1024#endif 1013#endif
1025 1014
1026static struct snd_soc_codec *twl6040_codec; 1015static int twl6040_probe(struct snd_soc_codec *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{ 1016{
1086 struct twl4030_codec_data *twl_codec = pdev->dev.platform_data; 1017 struct twl4030_codec_data *twl_codec = codec->dev->platform_data;
1087 struct snd_soc_codec *codec;
1088 struct twl6040_data *priv; 1018 struct twl6040_data *priv;
1089 int audpwron, naudint; 1019 int audpwron, naudint;
1090 int ret = 0; 1020 int ret = 0;
@@ -1092,6 +1022,7 @@ static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1092 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); 1022 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
1093 if (priv == NULL) 1023 if (priv == NULL)
1094 return -ENOMEM; 1024 return -ENOMEM;
1025 snd_soc_codec_set_drvdata(codec, priv);
1095 1026
1096 if (twl_codec) { 1027 if (twl_codec) {
1097 audpwron = twl_codec->audpwron_gpio; 1028 audpwron = twl_codec->audpwron_gpio;
@@ -1104,29 +1035,6 @@ static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1104 priv->audpwron = audpwron; 1035 priv->audpwron = audpwron;
1105 priv->naudint = naudint; 1036 priv->naudint = naudint;
1106 1037
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); 1038 init_completion(&priv->ready);
1131 1039
1132 if (gpio_is_valid(audpwron)) { 1040 if (gpio_is_valid(audpwron)) {
@@ -1169,23 +1077,12 @@ static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1169 if (ret) 1077 if (ret)
1170 goto irq_err; 1078 goto irq_err;
1171 1079
1172 ret = snd_soc_register_codec(codec); 1080 snd_soc_add_controls(codec, twl6040_snd_controls,
1173 if (ret) 1081 ARRAY_SIZE(twl6040_snd_controls));
1174 goto reg_err; 1082 twl6040_add_widgets(codec);
1175
1176 twl6040_codec = codec;
1177
1178 ret = snd_soc_register_dai(&twl6040_dai);
1179 if (ret)
1180 goto dai_err;
1181 1083
1182 return 0; 1084 return 0;
1183 1085
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: 1086irq_err:
1190 if (naudint) 1087 if (naudint)
1191 free_irq(naudint, codec); 1088 free_irq(naudint, codec);
@@ -1193,36 +1090,57 @@ gpio2_err:
1193 if (gpio_is_valid(audpwron)) 1090 if (gpio_is_valid(audpwron))
1194 gpio_free(audpwron); 1091 gpio_free(audpwron);
1195gpio1_err: 1092gpio1_err:
1196 kfree(codec->reg_cache);
1197cache_err:
1198 kfree(priv); 1093 kfree(priv);
1199 return ret; 1094 return ret;
1200} 1095}
1201 1096
1202static int __devexit twl6040_codec_remove(struct platform_device *pdev) 1097static int twl6040_remove(struct snd_soc_codec *codec)
1203{ 1098{
1204 struct twl6040_data *priv = snd_soc_codec_get_drvdata(twl6040_codec); 1099 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1205 int audpwron = priv->audpwron; 1100 int audpwron = priv->audpwron;
1206 int naudint = priv->naudint; 1101 int naudint = priv->naudint;
1207 1102
1103 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1104
1208 if (gpio_is_valid(audpwron)) 1105 if (gpio_is_valid(audpwron))
1209 gpio_free(audpwron); 1106 gpio_free(audpwron);
1210 1107
1211 if (naudint) 1108 if (naudint)
1212 free_irq(naudint, twl6040_codec); 1109 free_irq(naudint, codec);
1213 1110
1214 snd_soc_unregister_dai(&twl6040_dai); 1111 kfree(priv);
1215 snd_soc_unregister_codec(twl6040_codec);
1216 1112
1217 kfree(twl6040_codec); 1113 return 0;
1218 twl6040_codec = NULL; 1114}
1219 1115
1116static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
1117 .probe = twl6040_probe,
1118 .remove = twl6040_remove,
1119 .suspend = twl6040_suspend,
1120 .resume = twl6040_resume,
1121 .read = twl6040_read_reg_cache,
1122 .write = twl6040_write,
1123 .set_bias_level = twl6040_set_bias_level,
1124 .reg_cache_size = ARRAY_SIZE(twl6040_reg),
1125 .reg_word_size = sizeof(u8),
1126 .reg_cache_default = twl6040_reg,
1127};
1128
1129static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1130{
1131 return snd_soc_register_codec(&pdev->dev,
1132 &soc_codec_dev_twl6040, &twl6040_dai, 1);
1133}
1134
1135static int __devexit twl6040_codec_remove(struct platform_device *pdev)
1136{
1137 snd_soc_unregister_codec(&pdev->dev);
1220 return 0; 1138 return 0;
1221} 1139}
1222 1140
1223static struct platform_driver twl6040_codec_driver = { 1141static struct platform_driver twl6040_codec_driver = {
1224 .driver = { 1142 .driver = {
1225 .name = "twl6040_codec", 1143 .name = "twl6040-codec",
1226 .owner = THIS_MODULE, 1144 .owner = THIS_MODULE,
1227 }, 1145 },
1228 .probe = twl6040_codec_probe, 1146 .probe = twl6040_codec_probe,
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index c472070a1da..f7c77fa58a3 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -135,7 +135,4 @@
135#define TWL6040_HPPLL_ID 1 135#define TWL6040_HPPLL_ID 1
136#define TWL6040_LPPLL_ID 2 136#define TWL6040_LPPLL_ID 2
137 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__ */ 138#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index f3b4c1d6a82..7540a509a6f 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -161,8 +161,7 @@ static int uda134x_startup(struct snd_pcm_substream *substream,
161 struct snd_soc_dai *dai) 161 struct snd_soc_dai *dai)
162{ 162{
163 struct snd_soc_pcm_runtime *rtd = substream->private_data; 163 struct snd_soc_pcm_runtime *rtd = substream->private_data;
164 struct snd_soc_device *socdev = rtd->socdev; 164 struct snd_soc_codec *codec =rtd->codec;
165 struct snd_soc_codec *codec = socdev->card->codec;
166 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); 165 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
167 struct snd_pcm_runtime *master_runtime; 166 struct snd_pcm_runtime *master_runtime;
168 167
@@ -194,8 +193,7 @@ static void uda134x_shutdown(struct snd_pcm_substream *substream,
194 struct snd_soc_dai *dai) 193 struct snd_soc_dai *dai)
195{ 194{
196 struct snd_soc_pcm_runtime *rtd = substream->private_data; 195 struct snd_soc_pcm_runtime *rtd = substream->private_data;
197 struct snd_soc_device *socdev = rtd->socdev; 196 struct snd_soc_codec *codec = rtd->codec;
198 struct snd_soc_codec *codec = socdev->card->codec;
199 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); 197 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
200 198
201 if (uda134x->master_substream == substream) 199 if (uda134x->master_substream == substream)
@@ -209,8 +207,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream,
209 struct snd_soc_dai *dai) 207 struct snd_soc_dai *dai)
210{ 208{
211 struct snd_soc_pcm_runtime *rtd = substream->private_data; 209 struct snd_soc_pcm_runtime *rtd = substream->private_data;
212 struct snd_soc_device *socdev = rtd->socdev; 210 struct snd_soc_codec *codec = rtd->codec;
213 struct snd_soc_codec *codec = socdev->card->codec;
214 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); 211 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
215 u8 hw_params; 212 u8 hw_params;
216 213
@@ -364,7 +361,7 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
364 pd->power(1); 361 pd->power(1);
365 /* Sync reg_cache with the hardware */ 362 /* Sync reg_cache with the hardware */
366 for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++) 363 for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++)
367 codec->write(codec, i, *cache++); 364 codec->driver->write(codec, i, *cache++);
368 } 365 }
369 break; 366 break;
370 case SND_SOC_BIAS_STANDBY: 367 case SND_SOC_BIAS_STANDBY:
@@ -465,8 +462,8 @@ static struct snd_soc_dai_ops uda134x_dai_ops = {
465 .set_fmt = uda134x_set_dai_fmt, 462 .set_fmt = uda134x_set_dai_fmt,
466}; 463};
467 464
468struct snd_soc_dai uda134x_dai = { 465static struct snd_soc_dai_driver uda134x_dai = {
469 .name = "UDA134X", 466 .name = "uda134x-hifi",
470 /* playback capabilities */ 467 /* playback capabilities */
471 .playback = { 468 .playback = {
472 .stream_name = "Playback", 469 .stream_name = "Playback",
@@ -486,27 +483,21 @@ struct snd_soc_dai uda134x_dai = {
486 /* pcm operations */ 483 /* pcm operations */
487 .ops = &uda134x_dai_ops, 484 .ops = &uda134x_dai_ops,
488}; 485};
489EXPORT_SYMBOL(uda134x_dai);
490 486
491 487static int uda134x_soc_probe(struct snd_soc_codec *codec)
492static int uda134x_soc_probe(struct platform_device *pdev)
493{ 488{
494 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
495 struct snd_soc_codec *codec;
496 struct uda134x_priv *uda134x; 489 struct uda134x_priv *uda134x;
497 void *codec_setup_data = socdev->codec_data; 490 struct uda134x_platform_data *pd = dev_get_drvdata(codec->card->dev);
498 int ret = -ENOMEM; 491 int ret;
499 struct uda134x_platform_data *pd;
500 492
501 printk(KERN_INFO "UDA134X SoC Audio Codec\n"); 493 printk(KERN_INFO "UDA134X SoC Audio Codec\n");
502 494
503 if (!codec_setup_data) { 495 if (!pd) {
504 printk(KERN_ERR "UDA134X SoC codec: " 496 printk(KERN_ERR "UDA134X SoC codec: "
505 "missing L3 bitbang function\n"); 497 "missing L3 bitbang function\n");
506 return -ENODEV; 498 return -ENODEV;
507 } 499 }
508 500
509 pd = codec_setup_data;
510 switch (pd->model) { 501 switch (pd->model) {
511 case UDA134X_UDA1340: 502 case UDA134X_UDA1340:
512 case UDA134X_UDA1341: 503 case UDA134X_UDA1341:
@@ -520,58 +511,22 @@ static int uda134x_soc_probe(struct platform_device *pdev)
520 return -EINVAL; 511 return -EINVAL;
521 } 512 }
522 513
523 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
524 if (socdev->card->codec == NULL)
525 return ret;
526
527 codec = socdev->card->codec;
528
529 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); 514 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
530 if (uda134x == NULL) 515 if (uda134x == NULL)
531 goto priv_err; 516 return -ENOMEM;
532 snd_soc_codec_set_drvdata(codec, uda134x); 517 snd_soc_codec_set_drvdata(codec, uda134x);
533 518
534 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg), 519 codec->control_data = pd;
535 GFP_KERNEL);
536 if (codec->reg_cache == NULL)
537 goto reg_err;
538
539 mutex_init(&codec->mutex);
540
541 codec->reg_cache_size = sizeof(uda134x_reg);
542 codec->reg_cache_step = 1;
543
544 codec->name = "UDA134X";
545 codec->owner = THIS_MODULE;
546 codec->dai = &uda134x_dai;
547 codec->num_dai = 1;
548 codec->read = uda134x_read_reg_cache;
549 codec->write = uda134x_write;
550
551 INIT_LIST_HEAD(&codec->dapm_widgets);
552 INIT_LIST_HEAD(&codec->dapm_paths);
553
554 codec->control_data = codec_setup_data;
555 520
556 if (pd->power) 521 if (pd->power)
557 pd->power(1); 522 pd->power(1);
558 523
559 uda134x_reset(codec); 524 uda134x_reset(codec);
560 525
561 if (pd->is_powered_on_standby) { 526 if (pd->is_powered_on_standby)
562 codec->set_bias_level = NULL;
563 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); 527 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
564 } else { 528 else
565 codec->set_bias_level = uda134x_set_bias_level;
566 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 529 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
567 }
568
569 /* register pcms */
570 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
571 if (ret < 0) {
572 printk(KERN_ERR "UDA134X: failed to register pcms\n");
573 goto pcm_err;
574 }
575 530
576 switch (pd->model) { 531 switch (pd->model) {
577 case UDA134X_UDA1340: 532 case UDA134X_UDA1340:
@@ -590,61 +545,42 @@ static int uda134x_soc_probe(struct platform_device *pdev)
590 default: 545 default:
591 printk(KERN_ERR "%s unknown codec type: %d", 546 printk(KERN_ERR "%s unknown codec type: %d",
592 __func__, pd->model); 547 __func__, pd->model);
593 return -EINVAL; 548 kfree(uda134x);
549 return -EINVAL;
594 } 550 }
595 551
596 if (ret < 0) { 552 if (ret < 0) {
597 printk(KERN_ERR "UDA134X: failed to register controls\n"); 553 printk(KERN_ERR "UDA134X: failed to register controls\n");
598 goto pcm_err; 554 kfree(uda134x);
555 return ret;
599 } 556 }
600 557
601 return 0; 558 return 0;
602
603pcm_err:
604 kfree(codec->reg_cache);
605reg_err:
606 kfree(snd_soc_codec_get_drvdata(codec));
607priv_err:
608 kfree(codec);
609 return ret;
610} 559}
611 560
612/* power down chip */ 561/* power down chip */
613static int uda134x_soc_remove(struct platform_device *pdev) 562static int uda134x_soc_remove(struct snd_soc_codec *codec)
614{ 563{
615 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 564 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
616 struct snd_soc_codec *codec = socdev->card->codec;
617 565
618 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 566 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
619 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); 567 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
620 568
621 snd_soc_free_pcms(socdev); 569 kfree(uda134x);
622 snd_soc_dapm_free(socdev);
623
624 kfree(snd_soc_codec_get_drvdata(codec));
625 kfree(codec->reg_cache);
626 kfree(codec);
627
628 return 0; 570 return 0;
629} 571}
630 572
631#if defined(CONFIG_PM) 573#if defined(CONFIG_PM)
632static int uda134x_soc_suspend(struct platform_device *pdev, 574static int uda134x_soc_suspend(struct snd_soc_codec *codec,
633 pm_message_t state) 575 pm_message_t state)
634{ 576{
635 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
636 struct snd_soc_codec *codec = socdev->card->codec;
637
638 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 577 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
639 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); 578 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
640 return 0; 579 return 0;
641} 580}
642 581
643static int uda134x_soc_resume(struct platform_device *pdev) 582static int uda134x_soc_resume(struct snd_soc_codec *codec)
644{ 583{
645 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
646 struct snd_soc_codec *codec = socdev->card->codec;
647
648 uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 584 uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
649 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); 585 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
650 return 0; 586 return 0;
@@ -654,25 +590,53 @@ static int uda134x_soc_resume(struct platform_device *pdev)
654#define uda134x_soc_resume NULL 590#define uda134x_soc_resume NULL
655#endif /* CONFIG_PM */ 591#endif /* CONFIG_PM */
656 592
657struct snd_soc_codec_device soc_codec_dev_uda134x = { 593static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
658 .probe = uda134x_soc_probe, 594 .probe = uda134x_soc_probe,
659 .remove = uda134x_soc_remove, 595 .remove = uda134x_soc_remove,
660 .suspend = uda134x_soc_suspend, 596 .suspend = uda134x_soc_suspend,
661 .resume = uda134x_soc_resume, 597 .resume = uda134x_soc_resume,
598 .reg_cache_size = sizeof(uda134x_reg),
599 .reg_word_size = sizeof(u8),
600 .reg_cache_step = 1,
601 .read = uda134x_read_reg_cache,
602 .write = uda134x_write,
603#ifdef POWER_OFF_ON_STANDBY
604 .set_bias_level = uda134x_set_bias_level,
605#endif
606};
607
608static int __devinit uda134x_codec_probe(struct platform_device *pdev)
609{
610 return snd_soc_register_codec(&pdev->dev,
611 &soc_codec_dev_uda134x, &uda134x_dai, 1);
612}
613
614static int __devexit uda134x_codec_remove(struct platform_device *pdev)
615{
616 snd_soc_unregister_codec(&pdev->dev);
617 return 0;
618}
619
620static struct platform_driver uda134x_codec_driver = {
621 .driver = {
622 .name = "uda134x-codec",
623 .owner = THIS_MODULE,
624 },
625 .probe = uda134x_codec_probe,
626 .remove = __devexit_p(uda134x_codec_remove),
662}; 627};
663EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x);
664 628
665static int __init uda134x_init(void) 629static int __init uda134x_codec_init(void)
666{ 630{
667 return snd_soc_register_dai(&uda134x_dai); 631 return platform_driver_register(&uda134x_codec_driver);
668} 632}
669module_init(uda134x_init); 633module_init(uda134x_codec_init);
670 634
671static void __exit uda134x_exit(void) 635static void __exit uda134x_codec_exit(void)
672{ 636{
673 snd_soc_unregister_dai(&uda134x_dai); 637 platform_driver_unregister(&uda134x_codec_driver);
674} 638}
675module_exit(uda134x_exit); 639module_exit(uda134x_codec_exit);
676 640
677MODULE_DESCRIPTION("UDA134X ALSA soc codec driver"); 641MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
678MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); 642MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h
index 205f03b3eaf..9faae06972b 100644
--- a/sound/soc/codecs/uda134x.h
+++ b/sound/soc/codecs/uda134x.h
@@ -31,7 +31,4 @@
31#define STATUS0_DAIFMT_MASK (~(7<<1)) 31#define STATUS0_DAIFMT_MASK (~(7<<1))
32#define STATUS0_SYSCLK_MASK (~(3<<4)) 32#define STATUS0_SYSCLK_MASK (~(3<<4))
33 33
34extern struct snd_soc_dai uda134x_dai;
35extern struct snd_soc_codec_device soc_codec_dev_uda134x;
36
37#endif 34#endif
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 2f925a27dcd..1a51c816e54 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -33,11 +33,9 @@
33 33
34#include "uda1380.h" 34#include "uda1380.h"
35 35
36static struct snd_soc_codec *uda1380_codec;
37
38/* codec private data */ 36/* codec private data */
39struct uda1380_priv { 37struct uda1380_priv {
40 struct snd_soc_codec codec; 38 struct snd_soc_codec *codec;
41 u16 reg_cache[UDA1380_CACHEREGNUM]; 39 u16 reg_cache[UDA1380_CACHEREGNUM];
42 unsigned int dac_clk; 40 unsigned int dac_clk;
43 struct work_struct work; 41 struct work_struct work;
@@ -135,6 +133,8 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
135 133
136static void uda1380_flush_work(struct work_struct *work) 134static void uda1380_flush_work(struct work_struct *work)
137{ 135{
136 struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
137 struct snd_soc_codec *uda1380_codec = uda1380->codec;
138 int bit, reg; 138 int bit, reg;
139 139
140 for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) { 140 for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
@@ -145,6 +145,7 @@ static void uda1380_flush_work(struct work_struct *work)
145 uda1380_read_reg_cache(uda1380_codec, reg)); 145 uda1380_read_reg_cache(uda1380_codec, reg));
146 clear_bit(bit, &uda1380_cache_dirty); 146 clear_bit(bit, &uda1380_cache_dirty);
147 } 147 }
148
148} 149}
149 150
150/* declarations of ALSA reg_elem_REAL controls */ 151/* declarations of ALSA reg_elem_REAL controls */
@@ -474,8 +475,7 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
474 struct snd_soc_dai *dai) 475 struct snd_soc_dai *dai)
475{ 476{
476 struct snd_soc_pcm_runtime *rtd = substream->private_data; 477 struct snd_soc_pcm_runtime *rtd = substream->private_data;
477 struct snd_soc_device *socdev = rtd->socdev; 478 struct snd_soc_codec *codec = rtd->codec;
478 struct snd_soc_codec *codec = socdev->card->codec;
479 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); 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
@@ -501,8 +501,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
501 struct snd_soc_dai *dai) 501 struct snd_soc_dai *dai)
502{ 502{
503 struct snd_soc_pcm_runtime *rtd = substream->private_data; 503 struct snd_soc_pcm_runtime *rtd = substream->private_data;
504 struct snd_soc_device *socdev = rtd->socdev; 504 struct snd_soc_codec *codec = rtd->codec;
505 struct snd_soc_codec *codec = socdev->card->codec;
506 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 505 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
507 506
508 /* set WSPLL power and divider if running from this clock */ 507 /* set WSPLL power and divider if running from this clock */
@@ -540,8 +539,7 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
540 struct snd_soc_dai *dai) 539 struct snd_soc_dai *dai)
541{ 540{
542 struct snd_soc_pcm_runtime *rtd = substream->private_data; 541 struct snd_soc_pcm_runtime *rtd = substream->private_data;
543 struct snd_soc_device *socdev = rtd->socdev; 542 struct snd_soc_codec *codec = rtd->codec;
544 struct snd_soc_codec *codec = socdev->card->codec;
545 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 543 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
546 544
547 /* shut down WSPLL power if running from this clock */ 545 /* shut down WSPLL power if running from this clock */
@@ -604,9 +602,9 @@ static struct snd_soc_dai_ops uda1380_dai_ops_capture = {
604 .set_fmt = uda1380_set_dai_fmt_capture, 602 .set_fmt = uda1380_set_dai_fmt_capture,
605}; 603};
606 604
607struct snd_soc_dai uda1380_dai[] = { 605static struct snd_soc_dai_driver uda1380_dai[] = {
608{ 606{
609 .name = "UDA1380", 607 .name = "uda1380-hifi",
610 .playback = { 608 .playback = {
611 .stream_name = "Playback", 609 .stream_name = "Playback",
612 .channels_min = 1, 610 .channels_min = 1,
@@ -622,7 +620,7 @@ struct snd_soc_dai uda1380_dai[] = {
622 .ops = &uda1380_dai_ops, 620 .ops = &uda1380_dai_ops,
623}, 621},
624{ /* playback only - dual interface */ 622{ /* playback only - dual interface */
625 .name = "UDA1380", 623 .name = "uda1380-hifi-playback",
626 .playback = { 624 .playback = {
627 .stream_name = "Playback", 625 .stream_name = "Playback",
628 .channels_min = 1, 626 .channels_min = 1,
@@ -633,7 +631,7 @@ struct snd_soc_dai uda1380_dai[] = {
633 .ops = &uda1380_dai_ops_playback, 631 .ops = &uda1380_dai_ops_playback,
634}, 632},
635{ /* capture only - dual interface*/ 633{ /* capture only - dual interface*/
636 .name = "UDA1380", 634 .name = "uda1380-hifi-capture",
637 .capture = { 635 .capture = {
638 .stream_name = "Capture", 636 .stream_name = "Capture",
639 .channels_min = 1, 637 .channels_min = 1,
@@ -644,21 +642,15 @@ struct snd_soc_dai uda1380_dai[] = {
644 .ops = &uda1380_dai_ops_capture, 642 .ops = &uda1380_dai_ops_capture,
645}, 643},
646}; 644};
647EXPORT_SYMBOL_GPL(uda1380_dai);
648 645
649static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) 646static int uda1380_suspend(struct snd_soc_codec *codec, pm_message_t state)
650{ 647{
651 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
652 struct snd_soc_codec *codec = socdev->card->codec;
653
654 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); 648 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
655 return 0; 649 return 0;
656} 650}
657 651
658static int uda1380_resume(struct platform_device *pdev) 652static int uda1380_resume(struct snd_soc_codec *codec)
659{ 653{
660 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
661 struct snd_soc_codec *codec = socdev->card->codec;
662 int i; 654 int i;
663 u8 data[2]; 655 u8 data[2];
664 u16 *cache = codec->reg_cache; 656 u16 *cache = codec->reg_cache;
@@ -673,91 +665,20 @@ static int uda1380_resume(struct platform_device *pdev)
673 return 0; 665 return 0;
674} 666}
675 667
676static int uda1380_probe(struct platform_device *pdev) 668static int uda1380_probe(struct snd_soc_codec *codec)
677{
678 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
679 struct snd_soc_codec *codec;
680 struct uda1380_platform_data *pdata;
681 int ret = 0;
682
683 if (uda1380_codec == NULL) {
684 dev_err(&pdev->dev, "Codec device not registered\n");
685 return -ENODEV;
686 }
687
688 socdev->card->codec = uda1380_codec;
689 codec = uda1380_codec;
690 pdata = codec->dev->platform_data;
691
692 /* register pcms */
693 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
694 if (ret < 0) {
695 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
696 goto pcm_err;
697 }
698
699 /* power on device */
700 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
701 /* set clock input */
702 switch (pdata->dac_clk) {
703 case UDA1380_DAC_CLK_SYSCLK:
704 uda1380_write(codec, UDA1380_CLK, 0);
705 break;
706 case UDA1380_DAC_CLK_WSPLL:
707 uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK);
708 break;
709 }
710
711 snd_soc_add_controls(codec, uda1380_snd_controls,
712 ARRAY_SIZE(uda1380_snd_controls));
713 uda1380_add_widgets(codec);
714
715 return ret;
716
717pcm_err:
718 return ret;
719}
720
721/* power down chip */
722static int uda1380_remove(struct platform_device *pdev)
723{
724 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
725 struct snd_soc_codec *codec = socdev->card->codec;
726
727 if (codec->control_data)
728 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
729
730 snd_soc_free_pcms(socdev);
731 snd_soc_dapm_free(socdev);
732
733 return 0;
734}
735
736struct snd_soc_codec_device soc_codec_dev_uda1380 = {
737 .probe = uda1380_probe,
738 .remove = uda1380_remove,
739 .suspend = uda1380_suspend,
740 .resume = uda1380_resume,
741};
742EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
743
744static int uda1380_register(struct uda1380_priv *uda1380)
745{ 669{
746 int ret, i; 670 struct uda1380_platform_data *pdata =codec->dev->platform_data;
747 struct snd_soc_codec *codec = &uda1380->codec; 671 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
748 struct uda1380_platform_data *pdata = codec->dev->platform_data; 672 int ret;
749 673
750 if (uda1380_codec) { 674 codec->hw_write = (hw_write_t)i2c_master_send;
751 dev_err(codec->dev, "Another UDA1380 is registered\n");
752 return -EINVAL;
753 }
754 675
755 if (!pdata || !pdata->gpio_power || !pdata->gpio_reset) 676 if (!pdata || !pdata->gpio_power || !pdata->gpio_reset)
756 return -EINVAL; 677 return -EINVAL;
757 678
758 ret = gpio_request(pdata->gpio_power, "uda1380 power"); 679 ret = gpio_request(pdata->gpio_power, "uda1380 power");
759 if (ret) 680 if (ret)
760 goto err_out; 681 return ret;
761 ret = gpio_request(pdata->gpio_reset, "uda1380 reset"); 682 ret = gpio_request(pdata->gpio_reset, "uda1380 reset");
762 if (ret) 683 if (ret)
763 goto err_gpio; 684 goto err_gpio;
@@ -769,25 +690,6 @@ static int uda1380_register(struct uda1380_priv *uda1380)
769 udelay(5); 690 udelay(5);
770 gpio_set_value(pdata->gpio_reset, 0); 691 gpio_set_value(pdata->gpio_reset, 0);
771 692
772 mutex_init(&codec->mutex);
773 INIT_LIST_HEAD(&codec->dapm_widgets);
774 INIT_LIST_HEAD(&codec->dapm_paths);
775
776 snd_soc_codec_set_drvdata(codec, uda1380);
777 codec->name = "UDA1380";
778 codec->owner = THIS_MODULE;
779 codec->read = uda1380_read_reg_cache;
780 codec->write = uda1380_write;
781 codec->bias_level = SND_SOC_BIAS_OFF;
782 codec->set_bias_level = uda1380_set_bias_level;
783 codec->dai = uda1380_dai;
784 codec->num_dai = ARRAY_SIZE(uda1380_dai);
785 codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
786 codec->reg_cache = &uda1380->reg_cache;
787 codec->reg_cache_step = 1;
788
789 memcpy(codec->reg_cache, uda1380_reg, sizeof(uda1380_reg));
790
791 ret = uda1380_reset(codec); 693 ret = uda1380_reset(codec);
792 if (ret < 0) { 694 if (ret < 0) {
793 dev_err(codec->dev, "Failed to issue reset\n"); 695 dev_err(codec->dev, "Failed to issue reset\n");
@@ -796,83 +698,84 @@ static int uda1380_register(struct uda1380_priv *uda1380)
796 698
797 INIT_WORK(&uda1380->work, uda1380_flush_work); 699 INIT_WORK(&uda1380->work, uda1380_flush_work);
798 700
799 for (i = 0; i < ARRAY_SIZE(uda1380_dai); i++) 701 /* power on device */
800 uda1380_dai[i].dev = codec->dev; 702 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
801 703 /* set clock input */
802 uda1380_codec = codec; 704 switch (pdata->dac_clk) {
803 705 case UDA1380_DAC_CLK_SYSCLK:
804 ret = snd_soc_register_codec(codec); 706 uda1380_write(codec, UDA1380_CLK, 0);
805 if (ret != 0) { 707 break;
806 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 708 case UDA1380_DAC_CLK_WSPLL:
807 goto err_reset; 709 uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK);
710 break;
808 } 711 }
809 712
810 ret = snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); 713 snd_soc_add_controls(codec, uda1380_snd_controls,
811 if (ret != 0) { 714 ARRAY_SIZE(uda1380_snd_controls));
812 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret); 715 uda1380_add_widgets(codec);
813 goto err_dai;
814 }
815 716
816 return 0; 717 return 0;
817 718
818err_dai:
819 snd_soc_unregister_codec(codec);
820err_reset: 719err_reset:
821 gpio_set_value(pdata->gpio_power, 0); 720 gpio_set_value(pdata->gpio_power, 0);
822 gpio_free(pdata->gpio_reset); 721 gpio_free(pdata->gpio_reset);
823err_gpio: 722err_gpio:
824 gpio_free(pdata->gpio_power); 723 gpio_free(pdata->gpio_power);
825err_out:
826 return ret; 724 return ret;
827} 725}
828 726
829static void uda1380_unregister(struct uda1380_priv *uda1380) 727/* power down chip */
728static int uda1380_remove(struct snd_soc_codec *codec)
830{ 729{
831 struct snd_soc_codec *codec = &uda1380->codec; 730 struct uda1380_platform_data *pdata =codec->dev->platform_data;
832 struct uda1380_platform_data *pdata = codec->dev->platform_data;
833 731
834 snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); 732 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
835 snd_soc_unregister_codec(&uda1380->codec);
836 733
837 gpio_set_value(pdata->gpio_power, 0); 734 gpio_set_value(pdata->gpio_power, 0);
838 gpio_free(pdata->gpio_reset); 735 gpio_free(pdata->gpio_reset);
839 gpio_free(pdata->gpio_power); 736 gpio_free(pdata->gpio_power);
840 737
841 kfree(uda1380); 738 return 0;
842 uda1380_codec = NULL;
843} 739}
844 740
741static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
742 .probe = uda1380_probe,
743 .remove = uda1380_remove,
744 .suspend = uda1380_suspend,
745 .resume = uda1380_resume,
746 .read = uda1380_read_reg_cache,
747 .write = uda1380_write,
748 .set_bias_level = uda1380_set_bias_level,
749 .reg_cache_size = ARRAY_SIZE(uda1380_reg),
750 .reg_word_size = sizeof(u16),
751 .reg_cache_default = uda1380_reg,
752 .reg_cache_step = 1,
753};
754
845#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 755#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
846static __devinit int uda1380_i2c_probe(struct i2c_client *i2c, 756static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
847 const struct i2c_device_id *id) 757 const struct i2c_device_id *id)
848{ 758{
849 struct uda1380_priv *uda1380; 759 struct uda1380_priv *uda1380;
850 struct snd_soc_codec *codec;
851 int ret; 760 int ret;
852 761
853 uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL); 762 uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL);
854 if (uda1380 == NULL) 763 if (uda1380 == NULL)
855 return -ENOMEM; 764 return -ENOMEM;
856 765
857 codec = &uda1380->codec;
858 codec->hw_write = (hw_write_t)i2c_master_send;
859
860 i2c_set_clientdata(i2c, uda1380); 766 i2c_set_clientdata(i2c, uda1380);
861 codec->control_data = i2c;
862
863 codec->dev = &i2c->dev;
864 767
865 ret = uda1380_register(uda1380); 768 ret = snd_soc_register_codec(&i2c->dev,
866 if (ret != 0) 769 &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
770 if (ret < 0)
867 kfree(uda1380); 771 kfree(uda1380);
868
869 return ret; 772 return ret;
870} 773}
871 774
872static int __devexit uda1380_i2c_remove(struct i2c_client *i2c) 775static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
873{ 776{
874 struct uda1380_priv *uda1380 = i2c_get_clientdata(i2c); 777 snd_soc_unregister_codec(&i2c->dev);
875 uda1380_unregister(uda1380); 778 kfree(i2c_get_clientdata(i2c));
876 return 0; 779 return 0;
877} 780}
878 781
@@ -884,7 +787,7 @@ MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
884 787
885static struct i2c_driver uda1380_i2c_driver = { 788static struct i2c_driver uda1380_i2c_driver = {
886 .driver = { 789 .driver = {
887 .name = "UDA1380 I2C Codec", 790 .name = "uda1380-codec",
888 .owner = THIS_MODULE, 791 .owner = THIS_MODULE,
889 }, 792 },
890 .probe = uda1380_i2c_probe, 793 .probe = uda1380_i2c_probe,
diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h
index 9cefa8a5477..942e3927c72 100644
--- a/sound/soc/codecs/uda1380.h
+++ b/sound/soc/codecs/uda1380.h
@@ -76,7 +76,4 @@
76#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */ 76#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */
77#define UDA1380_DAI_CAPTURE 2 /* capture DAI */ 77#define UDA1380_DAI_CAPTURE 2 /* capture DAI */
78 78
79extern struct snd_soc_dai uda1380_dai[3];
80extern struct snd_soc_codec_device soc_codec_dev_uda1380;
81
82#endif /* _UDA1380_H */ 79#endif /* _UDA1380_H */
diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h
index c18e261c3c7..0b6f056f73c 100644
--- a/sound/soc/codecs/wm2000.h
+++ b/sound/soc/codecs/wm2000.h
@@ -16,9 +16,6 @@ struct wm2000_setup_data {
16 16
17extern int wm2000_add_controls(struct snd_soc_codec *codec); 17extern int wm2000_add_controls(struct snd_soc_codec *codec);
18 18
19extern struct snd_soc_dai wm2000_dai;
20extern struct snd_soc_codec_device soc_codec_dev_wm2000;
21
22#define WM2000_REG_SYS_START 0x8000 19#define WM2000_REG_SYS_START 0x8000
23#define WM2000_REG_SPEECH_CLARITY 0x8fef 20#define WM2000_REG_SPEECH_CLARITY 0x8fef
24#define WM2000_REG_SYS_WATCHDOG 0x8ff6 21#define WM2000_REG_SYS_WATCHDOG 0x8ff6
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 0221ca79b3a..f4f1fba38eb 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1321,20 +1321,14 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1321 return 0; 1321 return 0;
1322} 1322}
1323 1323
1324static int wm8350_suspend(struct platform_device *pdev, pm_message_t state) 1324static int wm8350_suspend(struct snd_soc_codec *codec, pm_message_t state)
1325{ 1325{
1326 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1327 struct snd_soc_codec *codec = socdev->card->codec;
1328
1329 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); 1326 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1330 return 0; 1327 return 0;
1331} 1328}
1332 1329
1333static int wm8350_resume(struct platform_device *pdev) 1330static int wm8350_resume(struct snd_soc_codec *codec)
1334{ 1331{
1335 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1336 struct snd_soc_codec *codec = socdev->card->codec;
1337
1338 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1332 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1339 1333
1340 return 0; 1334 return 0;
@@ -1489,24 +1483,74 @@ int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
1489} 1483}
1490EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect); 1484EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect);
1491 1485
1492static struct snd_soc_codec *wm8350_codec; 1486#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
1487
1488#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1489 SNDRV_PCM_FMTBIT_S20_3LE |\
1490 SNDRV_PCM_FMTBIT_S24_LE)
1491
1492static struct snd_soc_dai_ops wm8350_dai_ops = {
1493 .hw_params = wm8350_pcm_hw_params,
1494 .digital_mute = wm8350_mute,
1495 .trigger = wm8350_pcm_trigger,
1496 .set_fmt = wm8350_set_dai_fmt,
1497 .set_sysclk = wm8350_set_dai_sysclk,
1498 .set_pll = wm8350_set_fll,
1499 .set_clkdiv = wm8350_set_clkdiv,
1500};
1501
1502static struct snd_soc_dai_driver wm8350_dai = {
1503 .name = "wm8350-hifi",
1504 .playback = {
1505 .stream_name = "Playback",
1506 .channels_min = 1,
1507 .channels_max = 2,
1508 .rates = WM8350_RATES,
1509 .formats = WM8350_FORMATS,
1510 },
1511 .capture = {
1512 .stream_name = "Capture",
1513 .channels_min = 1,
1514 .channels_max = 2,
1515 .rates = WM8350_RATES,
1516 .formats = WM8350_FORMATS,
1517 },
1518 .ops = &wm8350_dai_ops,
1519};
1493 1520
1494static int wm8350_probe(struct platform_device *pdev) 1521static int wm8350_codec_probe(struct snd_soc_codec *codec)
1495{ 1522{
1496 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1523 struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
1497 struct snd_soc_codec *codec;
1498 struct wm8350 *wm8350;
1499 struct wm8350_data *priv; 1524 struct wm8350_data *priv;
1500 int ret;
1501 struct wm8350_output *out1; 1525 struct wm8350_output *out1;
1502 struct wm8350_output *out2; 1526 struct wm8350_output *out2;
1527 int ret, i;
1503 1528
1504 BUG_ON(!wm8350_codec); 1529 if (wm8350->codec.platform_data == NULL) {
1530 dev_err(codec->dev, "No audio platform data supplied\n");
1531 return -EINVAL;
1532 }
1533
1534 priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
1535 if (priv == NULL)
1536 return -ENOMEM;
1537 snd_soc_codec_set_drvdata(codec, priv);
1538
1539 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
1540 priv->supplies[i].supply = supply_names[i];
1541
1542 ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
1543 priv->supplies);
1544 if (ret != 0)
1545 goto err_priv;
1546
1547 wm8350->codec.codec = codec;
1548 codec->control_data = wm8350;
1505 1549
1506 socdev->card->codec = wm8350_codec; 1550 /* Put the codec into reset if it wasn't already */
1507 codec = socdev->card->codec; 1551 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1508 wm8350 = codec->control_data; 1552
1509 priv = snd_soc_codec_get_drvdata(codec); 1553 INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
1510 1554
1511 /* Enable the codec */ 1555 /* Enable the codec */
1512 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1556 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1557,11 +1601,6 @@ static int wm8350_probe(struct platform_device *pdev)
1557 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD, 1601 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD,
1558 wm8350_mic_handler, 0, "Microphone detect", priv); 1602 wm8350_mic_handler, 0, "Microphone detect", priv);
1559 1603
1560 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1561 if (ret < 0) {
1562 dev_err(&pdev->dev, "failed to create pcms\n");
1563 return ret;
1564 }
1565 1604
1566 snd_soc_add_controls(codec, wm8350_snd_controls, 1605 snd_soc_add_controls(codec, wm8350_snd_controls,
1567 ARRAY_SIZE(wm8350_snd_controls)); 1606 ARRAY_SIZE(wm8350_snd_controls));
@@ -1570,14 +1609,16 @@ static int wm8350_probe(struct platform_device *pdev)
1570 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1609 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1571 1610
1572 return 0; 1611 return 0;
1612
1613err_priv:
1614 kfree(priv);
1615 return ret;
1573} 1616}
1574 1617
1575static int wm8350_remove(struct platform_device *pdev) 1618static int wm8350_codec_remove(struct snd_soc_codec *codec)
1576{ 1619{
1577 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1578 struct snd_soc_codec *codec = socdev->card->codec;
1579 struct wm8350 *wm8350 = codec->control_data;
1580 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); 1620 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1621 struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
1581 int ret; 1622 int ret;
1582 1623
1583 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, 1624 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
@@ -1607,134 +1648,30 @@ static int wm8350_remove(struct platform_device *pdev)
1607 1648
1608 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1649 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1609 1650
1651 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1652 kfree(priv);
1610 return 0; 1653 return 0;
1611} 1654}
1612 1655
1613#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000) 1656static struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
1614 1657 .probe = wm8350_codec_probe,
1615#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 1658 .remove = wm8350_codec_remove,
1616 SNDRV_PCM_FMTBIT_S20_3LE |\
1617 SNDRV_PCM_FMTBIT_S24_LE)
1618
1619static struct snd_soc_dai_ops wm8350_dai_ops = {
1620 .hw_params = wm8350_pcm_hw_params,
1621 .digital_mute = wm8350_mute,
1622 .trigger = wm8350_pcm_trigger,
1623 .set_fmt = wm8350_set_dai_fmt,
1624 .set_sysclk = wm8350_set_dai_sysclk,
1625 .set_pll = wm8350_set_fll,
1626 .set_clkdiv = wm8350_set_clkdiv,
1627};
1628
1629struct snd_soc_dai wm8350_dai = {
1630 .name = "WM8350",
1631 .playback = {
1632 .stream_name = "Playback",
1633 .channels_min = 1,
1634 .channels_max = 2,
1635 .rates = WM8350_RATES,
1636 .formats = WM8350_FORMATS,
1637 },
1638 .capture = {
1639 .stream_name = "Capture",
1640 .channels_min = 1,
1641 .channels_max = 2,
1642 .rates = WM8350_RATES,
1643 .formats = WM8350_FORMATS,
1644 },
1645 .ops = &wm8350_dai_ops,
1646};
1647EXPORT_SYMBOL_GPL(wm8350_dai);
1648
1649struct snd_soc_codec_device soc_codec_dev_wm8350 = {
1650 .probe = wm8350_probe,
1651 .remove = wm8350_remove,
1652 .suspend = wm8350_suspend, 1659 .suspend = wm8350_suspend,
1653 .resume = wm8350_resume, 1660 .resume = wm8350_resume,
1661 .read = wm8350_codec_read,
1662 .write = wm8350_codec_write,
1663 .set_bias_level = wm8350_set_bias_level,
1654}; 1664};
1655EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350);
1656 1665
1657static __devinit int wm8350_codec_probe(struct platform_device *pdev) 1666static int __devinit wm8350_probe(struct platform_device *pdev)
1658{ 1667{
1659 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 1668 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8350,
1660 struct wm8350_data *priv; 1669 &wm8350_dai, 1);
1661 struct snd_soc_codec *codec;
1662 int ret, i;
1663
1664 if (wm8350->codec.platform_data == NULL) {
1665 dev_err(&pdev->dev, "No audio platform data supplied\n");
1666 return -EINVAL;
1667 }
1668
1669 priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
1670 if (priv == NULL)
1671 return -ENOMEM;
1672
1673 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
1674 priv->supplies[i].supply = supply_names[i];
1675
1676 ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
1677 priv->supplies);
1678 if (ret != 0)
1679 goto err_priv;
1680
1681 codec = &priv->codec;
1682 wm8350->codec.codec = codec;
1683
1684 wm8350_dai.dev = &pdev->dev;
1685
1686 mutex_init(&codec->mutex);
1687 INIT_LIST_HEAD(&codec->dapm_widgets);
1688 INIT_LIST_HEAD(&codec->dapm_paths);
1689 codec->dev = &pdev->dev;
1690 codec->name = "WM8350";
1691 codec->owner = THIS_MODULE;
1692 codec->read = wm8350_codec_read;
1693 codec->write = wm8350_codec_write;
1694 codec->bias_level = SND_SOC_BIAS_OFF;
1695 codec->set_bias_level = wm8350_set_bias_level;
1696 codec->dai = &wm8350_dai;
1697 codec->num_dai = 1;
1698 codec->reg_cache_size = WM8350_MAX_REGISTER;
1699 snd_soc_codec_set_drvdata(codec, priv);
1700 codec->control_data = wm8350;
1701
1702 /* Put the codec into reset if it wasn't already */
1703 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1704
1705 INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
1706 ret = snd_soc_register_codec(codec);
1707 if (ret != 0)
1708 goto err_supply;
1709
1710 wm8350_codec = codec;
1711
1712 ret = snd_soc_register_dai(&wm8350_dai);
1713 if (ret != 0)
1714 goto err_codec;
1715 return 0;
1716
1717err_codec:
1718 snd_soc_unregister_codec(codec);
1719err_supply:
1720 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1721err_priv:
1722 kfree(priv);
1723 wm8350_codec = NULL;
1724 return ret;
1725} 1670}
1726 1671
1727static int __devexit wm8350_codec_remove(struct platform_device *pdev) 1672static int __devexit wm8350_remove(struct platform_device *pdev)
1728{ 1673{
1729 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 1674 snd_soc_unregister_codec(&pdev->dev);
1730 struct snd_soc_codec *codec = wm8350->codec.codec;
1731 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1732
1733 snd_soc_unregister_dai(&wm8350_dai);
1734 snd_soc_unregister_codec(codec);
1735 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1736 kfree(priv);
1737 wm8350_codec = NULL;
1738 return 0; 1675 return 0;
1739} 1676}
1740 1677
@@ -1743,8 +1680,8 @@ static struct platform_driver wm8350_codec_driver = {
1743 .name = "wm8350-codec", 1680 .name = "wm8350-codec",
1744 .owner = THIS_MODULE, 1681 .owner = THIS_MODULE,
1745 }, 1682 },
1746 .probe = wm8350_codec_probe, 1683 .probe = wm8350_probe,
1747 .remove = __devexit_p(wm8350_codec_remove), 1684 .remove = __devexit_p(wm8350_remove),
1748}; 1685};
1749 1686
1750static __init int wm8350_init(void) 1687static __init int wm8350_init(void)
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
index 9ed0467c71d..74108eb8293 100644
--- a/sound/soc/codecs/wm8350.h
+++ b/sound/soc/codecs/wm8350.h
@@ -15,9 +15,6 @@
15#include <sound/soc.h> 15#include <sound/soc.h>
16#include <linux/mfd/wm8350/audio.h> 16#include <linux/mfd/wm8350/audio.h>
17 17
18extern struct snd_soc_dai wm8350_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8350;
20
21enum wm8350_jack { 18enum wm8350_jack {
22 WM8350_JDL = 1, 19 WM8350_JDL = 1,
23 WM8350_JDR = 2, 20 WM8350_JDR = 2,
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 8f294066b0e..850299786e0 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -65,7 +65,7 @@ static struct regulator_bulk_data power[] = {
65 65
66/* codec private data */ 66/* codec private data */
67struct wm8400_priv { 67struct wm8400_priv {
68 struct snd_soc_codec codec; 68 struct snd_soc_codec *codec;
69 struct wm8400 *wm8400; 69 struct wm8400 *wm8400;
70 u16 fake_register; 70 u16 fake_register;
71 unsigned int sysclk; 71 unsigned int sysclk;
@@ -1163,8 +1163,7 @@ static int wm8400_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_pcm_runtime *rtd = substream->private_data; 1165 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1166 struct snd_soc_device *socdev = rtd->socdev; 1166 struct snd_soc_codec *codec = rtd->codec;
1167 struct snd_soc_codec *codec = socdev->card->codec;
1168 u16 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1); 1167 u16 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1);
1169 1168
1170 audio1 &= ~WM8400_AIF_WL_MASK; 1169 audio1 &= ~WM8400_AIF_WL_MASK;
@@ -1332,10 +1331,9 @@ static struct snd_soc_dai_ops wm8400_dai_ops = {
1332 * 1. ADC/DAC on Primary Interface 1331 * 1. ADC/DAC on Primary Interface
1333 * 2. ADC on Primary Interface/DAC on secondary 1332 * 2. ADC on Primary Interface/DAC on secondary
1334 */ 1333 */
1335struct snd_soc_dai wm8400_dai = { 1334static struct snd_soc_dai_driver wm8400_dai = {
1336/* ADC/DAC on primary */ 1335/* ADC/DAC on primary */
1337 .name = "WM8400 ADC/DAC Primary", 1336 .name = "wm8400-hifi",
1338 .id = 1,
1339 .playback = { 1337 .playback = {
1340 .stream_name = "Playback", 1338 .stream_name = "Playback",
1341 .channels_min = 1, 1339 .channels_min = 1,
@@ -1352,147 +1350,53 @@ struct snd_soc_dai wm8400_dai = {
1352 }, 1350 },
1353 .ops = &wm8400_dai_ops, 1351 .ops = &wm8400_dai_ops,
1354}; 1352};
1355EXPORT_SYMBOL_GPL(wm8400_dai);
1356 1353
1357static int wm8400_suspend(struct platform_device *pdev, pm_message_t state) 1354static int wm8400_suspend(struct snd_soc_codec *codec, pm_message_t state)
1358{ 1355{
1359 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1360 struct snd_soc_codec *codec = socdev->card->codec;
1361
1362 wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF); 1356 wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF);
1363 1357
1364 return 0; 1358 return 0;
1365} 1359}
1366 1360
1367static int wm8400_resume(struct platform_device *pdev) 1361static int wm8400_resume(struct snd_soc_codec *codec)
1368{ 1362{
1369 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1370 struct snd_soc_codec *codec = socdev->card->codec;
1371
1372 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1363 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1373 1364
1374 return 0; 1365 return 0;
1375} 1366}
1376 1367
1377static struct snd_soc_codec *wm8400_codec;
1378
1379static int wm8400_probe(struct platform_device *pdev)
1380{
1381 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1382 struct snd_soc_codec *codec;
1383 int ret;
1384
1385 if (!wm8400_codec) {
1386 dev_err(&pdev->dev, "wm8400 not yet discovered\n");
1387 return -ENODEV;
1388 }
1389 codec = wm8400_codec;
1390
1391 socdev->card->codec = codec;
1392
1393 /* register pcms */
1394 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1395 if (ret < 0) {
1396 dev_err(&pdev->dev, "failed to create pcms\n");
1397 goto pcm_err;
1398 }
1399
1400 wm8400_add_controls(codec);
1401 wm8400_add_widgets(codec);
1402
1403pcm_err:
1404 return ret;
1405}
1406
1407/* power down chip */
1408static int wm8400_remove(struct platform_device *pdev)
1409{
1410 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1411
1412 snd_soc_free_pcms(socdev);
1413 snd_soc_dapm_free(socdev);
1414
1415 return 0;
1416}
1417
1418struct snd_soc_codec_device soc_codec_dev_wm8400 = {
1419 .probe = wm8400_probe,
1420 .remove = wm8400_remove,
1421 .suspend = wm8400_suspend,
1422 .resume = wm8400_resume,
1423};
1424
1425static void wm8400_probe_deferred(struct work_struct *work) 1368static void wm8400_probe_deferred(struct work_struct *work)
1426{ 1369{
1427 struct wm8400_priv *priv = container_of(work, struct wm8400_priv, 1370 struct wm8400_priv *priv = container_of(work, struct wm8400_priv,
1428 work); 1371 work);
1429 struct snd_soc_codec *codec = &priv->codec; 1372 struct snd_soc_codec *codec = priv->codec;
1430 int ret;
1431 1373
1432 /* charge output caps */ 1374 /* charge output caps */
1433 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1375 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1434
1435 /* We're done, tell the subsystem. */
1436 ret = snd_soc_register_codec(codec);
1437 if (ret != 0) {
1438 dev_err(priv->wm8400->dev,
1439 "Failed to register codec: %d\n", ret);
1440 goto err;
1441 }
1442
1443 ret = snd_soc_register_dai(&wm8400_dai);
1444 if (ret != 0) {
1445 dev_err(priv->wm8400->dev,
1446 "Failed to register DAI: %d\n", ret);
1447 goto err_codec;
1448 }
1449
1450 return;
1451
1452err_codec:
1453 snd_soc_unregister_codec(codec);
1454err:
1455 wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF);
1456} 1376}
1457 1377
1458static int wm8400_codec_probe(struct platform_device *dev) 1378static int wm8400_codec_probe(struct snd_soc_codec *codec)
1459{ 1379{
1380 struct wm8400 *wm8400 = dev_get_platdata(codec->dev);
1460 struct wm8400_priv *priv; 1381 struct wm8400_priv *priv;
1461 int ret; 1382 int ret;
1462 u16 reg; 1383 u16 reg;
1463 struct snd_soc_codec *codec;
1464 1384
1465 priv = kzalloc(sizeof(struct wm8400_priv), GFP_KERNEL); 1385 priv = kzalloc(sizeof(struct wm8400_priv), GFP_KERNEL);
1466 if (priv == NULL) 1386 if (priv == NULL)
1467 return -ENOMEM; 1387 return -ENOMEM;
1468 1388
1469 codec = &priv->codec;
1470 snd_soc_codec_set_drvdata(codec, priv); 1389 snd_soc_codec_set_drvdata(codec, priv);
1471 codec->control_data = dev_get_drvdata(&dev->dev); 1390 codec->control_data = priv->wm8400 = wm8400;
1472 priv->wm8400 = dev_get_drvdata(&dev->dev); 1391 priv->codec = codec;
1473 1392
1474 ret = regulator_bulk_get(priv->wm8400->dev, 1393 ret = regulator_bulk_get(wm8400->dev,
1475 ARRAY_SIZE(power), &power[0]); 1394 ARRAY_SIZE(power), &power[0]);
1476 if (ret != 0) { 1395 if (ret != 0) {
1477 dev_err(&dev->dev, "Failed to get regulators: %d\n", ret); 1396 dev_err(codec->dev, "Failed to get regulators: %d\n", ret);
1478 goto err; 1397 goto err;
1479 } 1398 }
1480 1399
1481 codec->dev = &dev->dev;
1482 wm8400_dai.dev = &dev->dev;
1483
1484 codec->name = "WM8400";
1485 codec->owner = THIS_MODULE;
1486 codec->read = wm8400_read;
1487 codec->write = wm8400_write;
1488 codec->bias_level = SND_SOC_BIAS_OFF;
1489 codec->set_bias_level = wm8400_set_bias_level;
1490 codec->dai = &wm8400_dai;
1491 codec->num_dai = 1;
1492 codec->reg_cache_size = WM8400_REGISTER_COUNT;
1493 mutex_init(&codec->mutex);
1494 INIT_LIST_HEAD(&codec->dapm_widgets);
1495 INIT_LIST_HEAD(&codec->dapm_paths);
1496 INIT_WORK(&priv->work, wm8400_probe_deferred); 1400 INIT_WORK(&priv->work, wm8400_probe_deferred);
1497 1401
1498 wm8400_codec_reset(codec); 1402 wm8400_codec_reset(codec);
@@ -1511,65 +1415,78 @@ static int wm8400_codec_probe(struct platform_device *dev)
1511 wm8400_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1415 wm8400_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1512 wm8400_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1416 wm8400_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1513 1417
1514 wm8400_codec = codec;
1515
1516 if (!schedule_work(&priv->work)) { 1418 if (!schedule_work(&priv->work)) {
1517 ret = -EINVAL; 1419 ret = -EINVAL;
1518 goto err_regulator; 1420 goto err_regulator;
1519 } 1421 }
1520 1422 wm8400_add_controls(codec);
1423 wm8400_add_widgets(codec);
1521 return 0; 1424 return 0;
1522 1425
1523err_regulator: 1426err_regulator:
1524 wm8400_codec = NULL;
1525 regulator_bulk_free(ARRAY_SIZE(power), power); 1427 regulator_bulk_free(ARRAY_SIZE(power), power);
1526err: 1428err:
1527 kfree(priv); 1429 kfree(priv);
1528 return ret; 1430 return ret;
1529} 1431}
1530 1432
1531static int __exit wm8400_codec_remove(struct platform_device *dev) 1433static int wm8400_codec_remove(struct snd_soc_codec *codec)
1532{ 1434{
1533 struct wm8400_priv *priv = snd_soc_codec_get_drvdata(wm8400_codec); 1435 struct wm8400_priv *priv = snd_soc_codec_get_drvdata(codec);
1534 u16 reg; 1436 u16 reg;
1535 1437
1536 snd_soc_unregister_dai(&wm8400_dai); 1438 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1);
1537 snd_soc_unregister_codec(wm8400_codec); 1439 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1,
1538
1539 reg = wm8400_read(wm8400_codec, WM8400_POWER_MANAGEMENT_1);
1540 wm8400_write(wm8400_codec, WM8400_POWER_MANAGEMENT_1,
1541 reg & (~WM8400_CODEC_ENA)); 1440 reg & (~WM8400_CODEC_ENA));
1542 1441
1543 regulator_bulk_free(ARRAY_SIZE(power), power); 1442 regulator_bulk_free(ARRAY_SIZE(power), power);
1544 kfree(priv); 1443 kfree(priv);
1545 1444
1546 wm8400_codec = NULL; 1445 return 0;
1446}
1447
1448static struct snd_soc_codec_driver soc_codec_dev_wm8400 = {
1449 .probe = wm8400_codec_probe,
1450 .remove = wm8400_codec_remove,
1451 .suspend = wm8400_suspend,
1452 .resume = wm8400_resume,
1453 .read = wm8400_read,
1454 .write = wm8400_write,
1455 .set_bias_level = wm8400_set_bias_level,
1456};
1457
1458static int __devinit wm8400_probe(struct platform_device *pdev)
1459{
1460 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8400,
1461 &wm8400_dai, 1);
1462}
1547 1463
1464static int __devexit wm8400_remove(struct platform_device *pdev)
1465{
1466 snd_soc_unregister_codec(&pdev->dev);
1548 return 0; 1467 return 0;
1549} 1468}
1550 1469
1551static struct platform_driver wm8400_codec_driver = { 1470static struct platform_driver wm8400_codec_driver = {
1552 .driver = { 1471 .driver = {
1553 .name = "wm8400-codec", 1472 .name = "wm8400-codec",
1554 .owner = THIS_MODULE, 1473 .owner = THIS_MODULE,
1555 }, 1474 },
1556 .probe = wm8400_codec_probe, 1475 .probe = wm8400_probe,
1557 .remove = __exit_p(wm8400_codec_remove), 1476 .remove = __devexit_p(wm8400_remove),
1558}; 1477};
1559 1478
1560static int __init wm8400_codec_init(void) 1479static __init int wm8400_init(void)
1561{ 1480{
1562 return platform_driver_register(&wm8400_codec_driver); 1481 return platform_driver_register(&wm8400_codec_driver);
1563} 1482}
1564module_init(wm8400_codec_init); 1483module_init(wm8400_init);
1565 1484
1566static void __exit wm8400_codec_exit(void) 1485static __exit void wm8400_exit(void)
1567{ 1486{
1568 platform_driver_unregister(&wm8400_codec_driver); 1487 platform_driver_unregister(&wm8400_codec_driver);
1569} 1488}
1570module_exit(wm8400_codec_exit); 1489module_exit(wm8400_exit);
1571
1572EXPORT_SYMBOL_GPL(soc_codec_dev_wm8400);
1573 1490
1574MODULE_DESCRIPTION("ASoC WM8400 driver"); 1491MODULE_DESCRIPTION("ASoC WM8400 driver");
1575MODULE_AUTHOR("Mark Brown"); 1492MODULE_AUTHOR("Mark Brown");
diff --git a/sound/soc/codecs/wm8400.h b/sound/soc/codecs/wm8400.h
index 79c5934d477..521adb19387 100644
--- a/sound/soc/codecs/wm8400.h
+++ b/sound/soc/codecs/wm8400.h
@@ -56,7 +56,4 @@
56#define WM8400_BCLK_DIV_44 (0xE << 1) 56#define WM8400_BCLK_DIV_44 (0xE << 1)
57#define WM8400_BCLK_DIV_48 (0xF << 1) 57#define WM8400_BCLK_DIV_48 (0xF << 1)
58 58
59extern struct snd_soc_dai wm8400_dai;
60extern struct snd_soc_codec_device soc_codec_dev_wm8400;
61
62#endif 59#endif
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 0f7bcb61071..dbfa05d2cb9 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -31,8 +31,6 @@
31 31
32#define WM8510_VERSION "0.6" 32#define WM8510_VERSION "0.6"
33 33
34struct snd_soc_codec_device soc_codec_dev_wm8510;
35
36/* 34/*
37 * wm8510 register cache 35 * wm8510 register cache
38 * We can't read the WM8510 register space when we are 36 * We can't read the WM8510 register space when we are
@@ -61,6 +59,12 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
61 59
62#define wm8510_reset(c) snd_soc_write(c, WM8510_RESET, 0) 60#define wm8510_reset(c) snd_soc_write(c, WM8510_RESET, 0)
63 61
62/* codec private data */
63struct wm8510_priv {
64 enum snd_soc_control_type control_type;
65 void *control_data;
66};
67
64static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" }; 68static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" };
65static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" }; 69static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
66static const char *wm8510_alc[] = { "ALC", "Limiter" }; 70static const char *wm8510_alc[] = { "ALC", "Limiter" };
@@ -403,8 +407,7 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
403 struct snd_soc_dai *dai) 407 struct snd_soc_dai *dai)
404{ 408{
405 struct snd_soc_pcm_runtime *rtd = substream->private_data; 409 struct snd_soc_pcm_runtime *rtd = substream->private_data;
406 struct snd_soc_device *socdev = rtd->socdev; 410 struct snd_soc_codec *codec = rtd->codec;
407 struct snd_soc_codec *codec = socdev->card->codec;
408 u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f; 411 u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f;
409 u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1; 412 u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1;
410 413
@@ -514,8 +517,8 @@ static struct snd_soc_dai_ops wm8510_dai_ops = {
514 .set_pll = wm8510_set_dai_pll, 517 .set_pll = wm8510_set_dai_pll,
515}; 518};
516 519
517struct snd_soc_dai wm8510_dai = { 520static struct snd_soc_dai_driver wm8510_dai = {
518 .name = "WM8510 HiFi", 521 .name = "wm8510-hifi",
519 .playback = { 522 .playback = {
520 .stream_name = "Playback", 523 .stream_name = "Playback",
521 .channels_min = 2, 524 .channels_min = 2,
@@ -531,21 +534,15 @@ struct snd_soc_dai wm8510_dai = {
531 .ops = &wm8510_dai_ops, 534 .ops = &wm8510_dai_ops,
532 .symmetric_rates = 1, 535 .symmetric_rates = 1,
533}; 536};
534EXPORT_SYMBOL_GPL(wm8510_dai);
535 537
536static int wm8510_suspend(struct platform_device *pdev, pm_message_t state) 538static int wm8510_suspend(struct snd_soc_codec *codec, pm_message_t state)
537{ 539{
538 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
539 struct snd_soc_codec *codec = socdev->card->codec;
540
541 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); 540 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
542 return 0; 541 return 0;
543} 542}
544 543
545static int wm8510_resume(struct platform_device *pdev) 544static int wm8510_resume(struct snd_soc_codec *codec)
546{ 545{
547 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
548 struct snd_soc_codec *codec = socdev->card->codec;
549 int i; 546 int i;
550 u8 data[2]; 547 u8 data[2];
551 u16 *cache = codec->reg_cache; 548 u16 *cache = codec->reg_cache;
@@ -561,43 +558,22 @@ static int wm8510_resume(struct platform_device *pdev)
561 return 0; 558 return 0;
562} 559}
563 560
564/* 561static int wm8510_probe(struct snd_soc_codec *codec)
565 * initialise the WM8510 driver
566 * register the mixer and dsp interfaces with the kernel
567 */
568static int wm8510_init(struct snd_soc_device *socdev,
569 enum snd_soc_control_type control)
570{ 562{
571 struct snd_soc_codec *codec = socdev->card->codec; 563 struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
572 int ret = 0; 564 int ret;
573
574 codec->name = "WM8510";
575 codec->owner = THIS_MODULE;
576 codec->set_bias_level = wm8510_set_bias_level;
577 codec->dai = &wm8510_dai;
578 codec->num_dai = 1;
579 codec->reg_cache_size = ARRAY_SIZE(wm8510_reg);
580 codec->reg_cache = kmemdup(wm8510_reg, sizeof(wm8510_reg), GFP_KERNEL);
581 565
582 if (codec->reg_cache == NULL) 566 pr_info("WM8510 Audio Codec %s", WM8510_VERSION);
583 return -ENOMEM;
584 567
585 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 568 codec->control_data = wm8510->control_data;
569 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8510->control_type);
586 if (ret < 0) { 570 if (ret < 0) {
587 printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", 571 printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret);
588 ret); 572 return ret;
589 goto err;
590 } 573 }
591 574
592 wm8510_reset(codec); 575 wm8510_reset(codec);
593 576
594 /* register pcms */
595 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
596 if (ret < 0) {
597 printk(KERN_ERR "wm8510: failed to create pcms\n");
598 goto err;
599 }
600
601 /* power on device */ 577 /* power on device */
602 codec->bias_level = SND_SOC_BIAS_OFF; 578 codec->bias_level = SND_SOC_BIAS_OFF;
603 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 579 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -606,119 +582,53 @@ static int wm8510_init(struct snd_soc_device *socdev,
606 wm8510_add_widgets(codec); 582 wm8510_add_widgets(codec);
607 583
608 return ret; 584 return ret;
609
610err:
611 kfree(codec->reg_cache);
612 return ret;
613} 585}
614 586
615static struct snd_soc_device *wm8510_socdev; 587/* power down chip */
616 588static int wm8510_remove(struct snd_soc_codec *codec)
617#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
618
619/*
620 * WM8510 2 wire address is 0x1a
621 */
622
623static int wm8510_i2c_probe(struct i2c_client *i2c,
624 const struct i2c_device_id *id)
625{ 589{
626 struct snd_soc_device *socdev = wm8510_socdev; 590 struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
627 struct snd_soc_codec *codec = socdev->card->codec;
628 int ret;
629
630 i2c_set_clientdata(i2c, codec);
631 codec->control_data = i2c;
632
633 ret = wm8510_init(socdev, SND_SOC_I2C);
634 if (ret < 0)
635 pr_err("failed to initialise WM8510\n");
636
637 return ret;
638}
639 591
640static int wm8510_i2c_remove(struct i2c_client *client) 592 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
641{ 593 kfree(wm8510);
642 struct snd_soc_codec *codec = i2c_get_clientdata(client);
643 kfree(codec->reg_cache);
644 return 0; 594 return 0;
645} 595}
646 596
647static const struct i2c_device_id wm8510_i2c_id[] = { 597static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
648 { "wm8510", 0 }, 598 .probe = wm8510_probe,
649 { } 599 .remove = wm8510_remove,
650}; 600 .suspend = wm8510_suspend,
651MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id); 601 .resume = wm8510_resume,
652 602 .set_bias_level = wm8510_set_bias_level,
653static struct i2c_driver wm8510_i2c_driver = { 603 .reg_cache_size = ARRAY_SIZE(wm8510_reg),
654 .driver = { 604 .reg_word_size = sizeof(u16),
655 .name = "WM8510 I2C Codec", 605 .reg_cache_default =wm8510_reg,
656 .owner = THIS_MODULE,
657 },
658 .probe = wm8510_i2c_probe,
659 .remove = wm8510_i2c_remove,
660 .id_table = wm8510_i2c_id,
661}; 606};
662 607
663static int wm8510_add_i2c_device(struct platform_device *pdev,
664 const struct wm8510_setup_data *setup)
665{
666 struct i2c_board_info info;
667 struct i2c_adapter *adapter;
668 struct i2c_client *client;
669 int ret;
670
671 ret = i2c_add_driver(&wm8510_i2c_driver);
672 if (ret != 0) {
673 dev_err(&pdev->dev, "can't add i2c driver\n");
674 return ret;
675 }
676
677 memset(&info, 0, sizeof(struct i2c_board_info));
678 info.addr = setup->i2c_address;
679 strlcpy(info.type, "wm8510", I2C_NAME_SIZE);
680
681 adapter = i2c_get_adapter(setup->i2c_bus);
682 if (!adapter) {
683 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
684 setup->i2c_bus);
685 goto err_driver;
686 }
687
688 client = i2c_new_device(adapter, &info);
689 i2c_put_adapter(adapter);
690 if (!client) {
691 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
692 (unsigned int)info.addr);
693 goto err_driver;
694 }
695
696 return 0;
697
698err_driver:
699 i2c_del_driver(&wm8510_i2c_driver);
700 return -ENODEV;
701}
702#endif
703
704#if defined(CONFIG_SPI_MASTER) 608#if defined(CONFIG_SPI_MASTER)
705static int __devinit wm8510_spi_probe(struct spi_device *spi) 609static int __devinit wm8510_spi_probe(struct spi_device *spi)
706{ 610{
707 struct snd_soc_device *socdev = wm8510_socdev; 611 struct wm8510_priv *wm8510;
708 struct snd_soc_codec *codec = socdev->card->codec;
709 int ret; 612 int ret;
710 613
711 codec->control_data = spi; 614 wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
615 if (wm8510 == NULL)
616 return -ENOMEM;
617
618 wm8510->control_data = spi;
619 wm8510->control_type = SND_SOC_SPI;
620 spi_set_drvdata(spi, wm8510);
712 621
713 ret = wm8510_init(socdev, SND_SOC_SPI); 622 ret = snd_soc_register_codec(&spi->dev,
623 &soc_codec_dev_wm8510, &wm8510_dai, 1);
714 if (ret < 0) 624 if (ret < 0)
715 dev_err(&spi->dev, "failed to initialise WM8510\n"); 625 kfree(wm8510);
716
717 return ret; 626 return ret;
718} 627}
719 628
720static int __devexit wm8510_spi_remove(struct spi_device *spi) 629static int __devexit wm8510_spi_remove(struct spi_device *spi)
721{ 630{
631 snd_soc_unregister_codec(&spi->dev);
722 return 0; 632 return 0;
723} 633}
724 634
@@ -733,84 +643,80 @@ static struct spi_driver wm8510_spi_driver = {
733}; 643};
734#endif /* CONFIG_SPI_MASTER */ 644#endif /* CONFIG_SPI_MASTER */
735 645
736static int wm8510_probe(struct platform_device *pdev) 646#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
647static __devinit int wm8510_i2c_probe(struct i2c_client *i2c,
648 const struct i2c_device_id *id)
737{ 649{
738 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 650 struct wm8510_priv *wm8510;
739 struct wm8510_setup_data *setup; 651 int ret;
740 struct snd_soc_codec *codec;
741 int ret = 0;
742
743 pr_info("WM8510 Audio Codec %s", WM8510_VERSION);
744 652
745 setup = socdev->codec_data; 653 wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
746 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 654 if (wm8510 == NULL)
747 if (codec == NULL)
748 return -ENOMEM; 655 return -ENOMEM;
749 656
750 socdev->card->codec = codec; 657 i2c_set_clientdata(i2c, wm8510);
751 mutex_init(&codec->mutex); 658 wm8510->control_data = i2c;
752 INIT_LIST_HEAD(&codec->dapm_widgets); 659 wm8510->control_type = SND_SOC_I2C;
753 INIT_LIST_HEAD(&codec->dapm_paths);
754 660
755 wm8510_socdev = socdev; 661 ret = snd_soc_register_codec(&i2c->dev,
756#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 662 &soc_codec_dev_wm8510, &wm8510_dai, 1);
757 if (setup->i2c_address) { 663 if (ret < 0)
758 ret = wm8510_add_i2c_device(pdev, setup); 664 kfree(wm8510);
759 }
760#endif
761#if defined(CONFIG_SPI_MASTER)
762 if (setup->spi) {
763 ret = spi_register_driver(&wm8510_spi_driver);
764 if (ret != 0)
765 printk(KERN_ERR "can't add spi driver");
766 }
767#endif
768
769 if (ret != 0)
770 kfree(codec);
771 return ret; 665 return ret;
772} 666}
773 667
774/* power down chip */ 668static __devexit int wm8510_i2c_remove(struct i2c_client *client)
775static int wm8510_remove(struct platform_device *pdev)
776{ 669{
777 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 670 snd_soc_unregister_codec(&client->dev);
778 struct snd_soc_codec *codec = socdev->card->codec;
779
780 if (codec->control_data)
781 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
782
783 snd_soc_free_pcms(socdev);
784 snd_soc_dapm_free(socdev);
785#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
786 i2c_unregister_device(codec->control_data);
787 i2c_del_driver(&wm8510_i2c_driver);
788#endif
789#if defined(CONFIG_SPI_MASTER)
790 spi_unregister_driver(&wm8510_spi_driver);
791#endif
792 kfree(codec);
793
794 return 0; 671 return 0;
795} 672}
796 673
797struct snd_soc_codec_device soc_codec_dev_wm8510 = { 674static const struct i2c_device_id wm8510_i2c_id[] = {
798 .probe = wm8510_probe, 675 { "wm8510", 0 },
799 .remove = wm8510_remove, 676 { }
800 .suspend = wm8510_suspend, 677};
801 .resume = wm8510_resume, 678MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id);
679
680static struct i2c_driver wm8510_i2c_driver = {
681 .driver = {
682 .name = "wm8510-codec",
683 .owner = THIS_MODULE,
684 },
685 .probe = wm8510_i2c_probe,
686 .remove = __devexit_p(wm8510_i2c_remove),
687 .id_table = wm8510_i2c_id,
802}; 688};
803EXPORT_SYMBOL_GPL(soc_codec_dev_wm8510); 689#endif
804 690
805static int __init wm8510_modinit(void) 691static int __init wm8510_modinit(void)
806{ 692{
807 return snd_soc_register_dai(&wm8510_dai); 693 int ret = 0;
694#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
695 ret = i2c_add_driver(&wm8510_i2c_driver);
696 if (ret != 0) {
697 printk(KERN_ERR "Failed to register WM8510 I2C driver: %d\n",
698 ret);
699 }
700#endif
701#if defined(CONFIG_SPI_MASTER)
702 ret = spi_register_driver(&wm8510_spi_driver);
703 if (ret != 0) {
704 printk(KERN_ERR "Failed to register WM8510 SPI driver: %d\n",
705 ret);
706 }
707#endif
708 return ret;
808} 709}
809module_init(wm8510_modinit); 710module_init(wm8510_modinit);
810 711
811static void __exit wm8510_exit(void) 712static void __exit wm8510_exit(void)
812{ 713{
813 snd_soc_unregister_dai(&wm8510_dai); 714#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
715 i2c_del_driver(&wm8510_i2c_driver);
716#endif
717#if defined(CONFIG_SPI_MASTER)
718 spi_unregister_driver(&wm8510_spi_driver);
719#endif
814} 720}
815module_exit(wm8510_exit); 721module_exit(wm8510_exit);
816 722
diff --git a/sound/soc/codecs/wm8510.h b/sound/soc/codecs/wm8510.h
index bdefcf5c69f..b3e26ed9f2d 100644
--- a/sound/soc/codecs/wm8510.h
+++ b/sound/soc/codecs/wm8510.h
@@ -99,7 +99,4 @@ struct wm8510_setup_data {
99 unsigned short i2c_address; 99 unsigned short i2c_address;
100}; 100};
101 101
102extern struct snd_soc_dai wm8510_dai;
103extern struct snd_soc_codec_device soc_codec_dev_wm8510;
104
105#endif 102#endif
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 0ad039b4adf..58d411b6faa 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -30,9 +30,6 @@
30 30
31#include "wm8523.h" 31#include "wm8523.h"
32 32
33static struct snd_soc_codec *wm8523_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8523;
35
36#define WM8523_NUM_SUPPLIES 2 33#define WM8523_NUM_SUPPLIES 2
37static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = { 34static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
38 "AVDD", 35 "AVDD",
@@ -43,7 +40,8 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
43 40
44/* codec private data */ 41/* codec private data */
45struct wm8523_priv { 42struct wm8523_priv {
46 struct snd_soc_codec codec; 43 enum snd_soc_control_type control_type;
44 void *control_data;
47 u16 reg_cache[WM8523_REGISTER_COUNT]; 45 u16 reg_cache[WM8523_REGISTER_COUNT];
48 struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES]; 46 struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
49 unsigned int sysclk; 47 unsigned int sysclk;
@@ -162,8 +160,7 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
162 struct snd_soc_dai *dai) 160 struct snd_soc_dai *dai)
163{ 161{
164 struct snd_soc_pcm_runtime *rtd = substream->private_data; 162 struct snd_soc_pcm_runtime *rtd = substream->private_data;
165 struct snd_soc_device *socdev = rtd->socdev; 163 struct snd_soc_codec *codec = rtd->codec;
166 struct snd_soc_codec *codec = socdev->card->codec;
167 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); 164 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
168 int i; 165 int i;
169 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1); 166 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
@@ -387,8 +384,8 @@ static struct snd_soc_dai_ops wm8523_dai_ops = {
387 .set_fmt = wm8523_set_dai_fmt, 384 .set_fmt = wm8523_set_dai_fmt,
388}; 385};
389 386
390struct snd_soc_dai wm8523_dai = { 387static struct snd_soc_dai_driver wm8523_dai = {
391 .name = "WM8523", 388 .name = "wm8523-hifi",
392 .playback = { 389 .playback = {
393 .stream_name = "Playback", 390 .stream_name = "Playback",
394 .channels_min = 2, /* Mono modes not yet supported */ 391 .channels_min = 2, /* Mono modes not yet supported */
@@ -398,25 +395,17 @@ struct snd_soc_dai wm8523_dai = {
398 }, 395 },
399 .ops = &wm8523_dai_ops, 396 .ops = &wm8523_dai_ops,
400}; 397};
401EXPORT_SYMBOL_GPL(wm8523_dai);
402 398
403#ifdef CONFIG_PM 399#ifdef CONFIG_PM
404static int wm8523_suspend(struct platform_device *pdev, pm_message_t state) 400static int wm8523_suspend(struct snd_soc_codec *codec, pm_message_t state)
405{ 401{
406 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
407 struct snd_soc_codec *codec = socdev->card->codec;
408
409 wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF); 402 wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
410 return 0; 403 return 0;
411} 404}
412 405
413static int wm8523_resume(struct platform_device *pdev) 406static int wm8523_resume(struct snd_soc_codec *codec)
414{ 407{
415 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
416 struct snd_soc_codec *codec = socdev->card->codec;
417
418 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 408 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
419
420 return 0; 409 return 0;
421} 410}
422#else 411#else
@@ -424,93 +413,21 @@ static int wm8523_resume(struct platform_device *pdev)
424#define wm8523_resume NULL 413#define wm8523_resume NULL
425#endif 414#endif
426 415
427static int wm8523_probe(struct platform_device *pdev) 416static int wm8523_probe(struct snd_soc_codec *codec)
428{
429 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
430 struct snd_soc_codec *codec;
431 int ret = 0;
432
433 if (wm8523_codec == NULL) {
434 dev_err(&pdev->dev, "Codec device not registered\n");
435 return -ENODEV;
436 }
437
438 socdev->card->codec = wm8523_codec;
439 codec = wm8523_codec;
440
441 /* register pcms */
442 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
443 if (ret < 0) {
444 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
445 goto pcm_err;
446 }
447
448 snd_soc_add_controls(codec, wm8523_snd_controls,
449 ARRAY_SIZE(wm8523_snd_controls));
450 wm8523_add_widgets(codec);
451
452 return ret;
453
454pcm_err:
455 return ret;
456}
457
458static int wm8523_remove(struct platform_device *pdev)
459{
460 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
461
462 snd_soc_free_pcms(socdev);
463 snd_soc_dapm_free(socdev);
464
465 return 0;
466}
467
468struct snd_soc_codec_device soc_codec_dev_wm8523 = {
469 .probe = wm8523_probe,
470 .remove = wm8523_remove,
471 .suspend = wm8523_suspend,
472 .resume = wm8523_resume,
473};
474EXPORT_SYMBOL_GPL(soc_codec_dev_wm8523);
475
476static int wm8523_register(struct wm8523_priv *wm8523,
477 enum snd_soc_control_type control)
478{ 417{
479 int ret; 418 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
480 struct snd_soc_codec *codec = &wm8523->codec; 419 int ret, i;
481 int i;
482
483 if (wm8523_codec) {
484 dev_err(codec->dev, "Another WM8523 is registered\n");
485 ret = -EINVAL;
486 goto err;
487 }
488
489 mutex_init(&codec->mutex);
490 INIT_LIST_HEAD(&codec->dapm_widgets);
491 INIT_LIST_HEAD(&codec->dapm_paths);
492
493 snd_soc_codec_set_drvdata(codec, wm8523);
494 codec->name = "WM8523";
495 codec->owner = THIS_MODULE;
496 codec->bias_level = SND_SOC_BIAS_OFF;
497 codec->set_bias_level = wm8523_set_bias_level;
498 codec->dai = &wm8523_dai;
499 codec->num_dai = 1;
500 codec->reg_cache_size = WM8523_REGISTER_COUNT;
501 codec->reg_cache = &wm8523->reg_cache;
502 codec->volatile_register = wm8523_volatile_register;
503 420
421 codec->hw_write = (hw_write_t)i2c_master_send;
422 codec->control_data = wm8523->control_data;
504 wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; 423 wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
505 wm8523->rate_constraint.count = 424 wm8523->rate_constraint.count =
506 ARRAY_SIZE(wm8523->rate_constraint_list); 425 ARRAY_SIZE(wm8523->rate_constraint_list);
507 426
508 memcpy(codec->reg_cache, wm8523_reg, sizeof(wm8523_reg)); 427 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8523->control_type);
509
510 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
511 if (ret != 0) { 428 if (ret != 0) {
512 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 429 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
513 goto err; 430 return ret;
514 } 431 }
515 432
516 for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++) 433 for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
@@ -520,7 +437,7 @@ static int wm8523_register(struct wm8523_priv *wm8523,
520 wm8523->supplies); 437 wm8523->supplies);
521 if (ret != 0) { 438 if (ret != 0) {
522 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 439 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
523 goto err; 440 return ret;
524 } 441 }
525 442
526 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), 443 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
@@ -555,8 +472,6 @@ static int wm8523_register(struct wm8523_priv *wm8523,
555 goto err_enable; 472 goto err_enable;
556 } 473 }
557 474
558 wm8523_dai.dev = codec->dev;
559
560 /* Change some default settings - latch VU and enable ZC */ 475 /* Change some default settings - latch VU and enable ZC */
561 wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU; 476 wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
562 wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC; 477 wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
@@ -566,69 +481,68 @@ static int wm8523_register(struct wm8523_priv *wm8523,
566 /* Bias level configuration will have done an extra enable */ 481 /* Bias level configuration will have done an extra enable */
567 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 482 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
568 483
569 wm8523_codec = codec; 484 snd_soc_add_controls(codec, wm8523_snd_controls,
570 485 ARRAY_SIZE(wm8523_snd_controls));
571 ret = snd_soc_register_codec(codec); 486 wm8523_add_widgets(codec);
572 if (ret != 0) {
573 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
574 goto err_enable;
575 }
576
577 ret = snd_soc_register_dai(&wm8523_dai);
578 if (ret != 0) {
579 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
580 goto err_codec;
581 }
582 487
583 return 0; 488 return 0;
584 489
585err_codec:
586 snd_soc_unregister_codec(codec);
587err_enable: 490err_enable:
588 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 491 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
589err_get: 492err_get:
590 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 493 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
591err: 494
592 kfree(wm8523);
593 return ret; 495 return ret;
594} 496}
595 497
596static void wm8523_unregister(struct wm8523_priv *wm8523) 498static int wm8523_remove(struct snd_soc_codec *codec)
597{ 499{
598 wm8523_set_bias_level(&wm8523->codec, SND_SOC_BIAS_OFF); 500 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
501
502 wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
599 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 503 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
600 snd_soc_unregister_dai(&wm8523_dai); 504 return 0;
601 snd_soc_unregister_codec(&wm8523->codec);
602 kfree(wm8523);
603 wm8523_codec = NULL;
604} 505}
605 506
507static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
508 .probe = wm8523_probe,
509 .remove = wm8523_remove,
510 .suspend = wm8523_suspend,
511 .resume = wm8523_resume,
512 .set_bias_level = wm8523_set_bias_level,
513 .reg_cache_size = WM8523_REGISTER_COUNT,
514 .reg_word_size = sizeof(u16),
515 .reg_cache_default = wm8523_reg,
516 .volatile_register = wm8523_volatile_register,
517};
518
606#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 519#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
607static __devinit int wm8523_i2c_probe(struct i2c_client *i2c, 520static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
608 const struct i2c_device_id *id) 521 const struct i2c_device_id *id)
609{ 522{
610 struct wm8523_priv *wm8523; 523 struct wm8523_priv *wm8523;
611 struct snd_soc_codec *codec; 524 int ret;
612 525
613 wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL); 526 wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL);
614 if (wm8523 == NULL) 527 if (wm8523 == NULL)
615 return -ENOMEM; 528 return -ENOMEM;
616 529
617 codec = &wm8523->codec;
618 codec->hw_write = (hw_write_t)i2c_master_send;
619
620 i2c_set_clientdata(i2c, wm8523); 530 i2c_set_clientdata(i2c, wm8523);
621 codec->control_data = i2c; 531 wm8523->control_data = i2c;
532 wm8523->control_type = SND_SOC_I2C;
622 533
623 codec->dev = &i2c->dev; 534 ret = snd_soc_register_codec(&i2c->dev,
535 &soc_codec_dev_wm8523, &wm8523_dai, 1);
536 if (ret < 0)
537 kfree(wm8523);
538 return ret;
624 539
625 return wm8523_register(wm8523, SND_SOC_I2C);
626} 540}
627 541
628static __devexit int wm8523_i2c_remove(struct i2c_client *client) 542static __devexit int wm8523_i2c_remove(struct i2c_client *client)
629{ 543{
630 struct wm8523_priv *wm8523 = i2c_get_clientdata(client); 544 snd_soc_unregister_codec(&client->dev);
631 wm8523_unregister(wm8523); 545 kfree(i2c_get_clientdata(client));
632 return 0; 546 return 0;
633} 547}
634 548
@@ -640,7 +554,7 @@ MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
640 554
641static struct i2c_driver wm8523_i2c_driver = { 555static struct i2c_driver wm8523_i2c_driver = {
642 .driver = { 556 .driver = {
643 .name = "WM8523", 557 .name = "wm8523-codec",
644 .owner = THIS_MODULE, 558 .owner = THIS_MODULE,
645 }, 559 },
646 .probe = wm8523_i2c_probe, 560 .probe = wm8523_i2c_probe,
diff --git a/sound/soc/codecs/wm8523.h b/sound/soc/codecs/wm8523.h
index 1aa9ce3e135..4d5b1eb8f2f 100644
--- a/sound/soc/codecs/wm8523.h
+++ b/sound/soc/codecs/wm8523.h
@@ -154,7 +154,4 @@
154#define WM8523_ZD_COUNT_SHIFT 0 /* ZD_COUNT - [1:0] */ 154#define WM8523_ZD_COUNT_SHIFT 0 /* ZD_COUNT - [1:0] */
155#define WM8523_ZD_COUNT_WIDTH 2 /* ZD_COUNT - [1:0] */ 155#define WM8523_ZD_COUNT_WIDTH 2 /* ZD_COUNT - [1:0] */
156 156
157extern struct snd_soc_dai wm8523_dai;
158extern struct snd_soc_codec_device soc_codec_dev_wm8523;
159
160#endif 157#endif
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index c3571ee5c11..cae58941a32 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -199,7 +199,8 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
199 199
200/* codec private data */ 200/* codec private data */
201struct wm8580_priv { 201struct wm8580_priv {
202 struct snd_soc_codec codec; 202 enum snd_soc_control_type control_type;
203 void *control_data;
203 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES]; 204 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
204 u16 reg_cache[WM8580_MAX_REGISTER + 1]; 205 u16 reg_cache[WM8580_MAX_REGISTER + 1];
205 struct pll_state a; 206 struct pll_state a;
@@ -484,9 +485,8 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
484 struct snd_soc_dai *dai) 485 struct snd_soc_dai *dai)
485{ 486{
486 struct snd_soc_pcm_runtime *rtd = substream->private_data; 487 struct snd_soc_pcm_runtime *rtd = substream->private_data;
487 struct snd_soc_device *socdev = rtd->socdev; 488 struct snd_soc_codec *codec = rtd->codec;
488 struct snd_soc_codec *codec = socdev->card->codec; 489 u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->driver->id);
489 u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->id);
490 490
491 paifb &= ~WM8580_AIF_LENGTH_MASK; 491 paifb &= ~WM8580_AIF_LENGTH_MASK;
492 /* bit size */ 492 /* bit size */
@@ -506,7 +506,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
506 return -EINVAL; 506 return -EINVAL;
507 } 507 }
508 508
509 snd_soc_write(codec, WM8580_PAIF3 + dai->id, paifb); 509 snd_soc_write(codec, WM8580_PAIF3 + dai->driver->id, paifb);
510 return 0; 510 return 0;
511} 511}
512 512
@@ -518,8 +518,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
518 unsigned int aifb; 518 unsigned int aifb;
519 int can_invert_lrclk; 519 int can_invert_lrclk;
520 520
521 aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->id); 521 aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->driver->id);
522 aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->id); 522 aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->driver->id);
523 523
524 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP); 524 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
525 525
@@ -585,8 +585,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
585 return -EINVAL; 585 return -EINVAL;
586 } 586 }
587 587
588 snd_soc_write(codec, WM8580_PAIF1 + codec_dai->id, aifa); 588 snd_soc_write(codec, WM8580_PAIF1 + codec_dai->driver->id, aifa);
589 snd_soc_write(codec, WM8580_PAIF3 + codec_dai->id, aifb); 589 snd_soc_write(codec, WM8580_PAIF3 + codec_dai->driver->id, aifb);
590 590
591 return 0; 591 return 0;
592} 592}
@@ -746,10 +746,10 @@ static struct snd_soc_dai_ops wm8580_dai_ops_capture = {
746 .set_pll = wm8580_set_dai_pll, 746 .set_pll = wm8580_set_dai_pll,
747}; 747};
748 748
749struct snd_soc_dai wm8580_dai[] = { 749static struct snd_soc_dai_driver wm8580_dai[] = {
750 { 750 {
751 .name = "WM8580 PAIFRX", 751 .name = "wm8580-hifi-playback",
752 .id = 0, 752 .id = WM8580_DAI_PAIFRX,
753 .playback = { 753 .playback = {
754 .stream_name = "Playback", 754 .stream_name = "Playback",
755 .channels_min = 1, 755 .channels_min = 1,
@@ -760,8 +760,8 @@ struct snd_soc_dai wm8580_dai[] = {
760 .ops = &wm8580_dai_ops_playback, 760 .ops = &wm8580_dai_ops_playback,
761 }, 761 },
762 { 762 {
763 .name = "WM8580 PAIFTX", 763 .name = "wm8580-hifi-capture",
764 .id = 1, 764 .id = WM8580_DAI_PAIFTX,
765 .capture = { 765 .capture = {
766 .stream_name = "Capture", 766 .stream_name = "Capture",
767 .channels_min = 2, 767 .channels_min = 2,
@@ -772,90 +772,17 @@ struct snd_soc_dai wm8580_dai[] = {
772 .ops = &wm8580_dai_ops_capture, 772 .ops = &wm8580_dai_ops_capture,
773 }, 773 },
774}; 774};
775EXPORT_SYMBOL_GPL(wm8580_dai);
776 775
777static struct snd_soc_codec *wm8580_codec; 776static int wm8580_probe(struct snd_soc_codec *codec)
778
779static int wm8580_probe(struct platform_device *pdev)
780{ 777{
781 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 778 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
782 struct snd_soc_codec *codec; 779 int ret = 0,i;
783 int ret = 0;
784
785 if (wm8580_codec == NULL) {
786 dev_err(&pdev->dev, "Codec device not registered\n");
787 return -ENODEV;
788 }
789
790 socdev->card->codec = wm8580_codec;
791 codec = wm8580_codec;
792
793 /* register pcms */
794 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
795 if (ret < 0) {
796 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
797 goto pcm_err;
798 }
799
800 snd_soc_add_controls(codec, wm8580_snd_controls,
801 ARRAY_SIZE(wm8580_snd_controls));
802 wm8580_add_widgets(codec);
803
804 return ret;
805
806pcm_err:
807 return ret;
808}
809
810/* power down chip */
811static int wm8580_remove(struct platform_device *pdev)
812{
813 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
814
815 snd_soc_free_pcms(socdev);
816 snd_soc_dapm_free(socdev);
817
818 return 0;
819}
820
821struct snd_soc_codec_device soc_codec_dev_wm8580 = {
822 .probe = wm8580_probe,
823 .remove = wm8580_remove,
824};
825EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
826
827static int wm8580_register(struct wm8580_priv *wm8580,
828 enum snd_soc_control_type control)
829{
830 int ret, i;
831 struct snd_soc_codec *codec = &wm8580->codec;
832
833 if (wm8580_codec) {
834 dev_err(codec->dev, "Another WM8580 is registered\n");
835 ret = -EINVAL;
836 goto err;
837 }
838
839 mutex_init(&codec->mutex);
840 INIT_LIST_HEAD(&codec->dapm_widgets);
841 INIT_LIST_HEAD(&codec->dapm_paths);
842
843 snd_soc_codec_set_drvdata(codec, wm8580);
844 codec->name = "WM8580";
845 codec->owner = THIS_MODULE;
846 codec->bias_level = SND_SOC_BIAS_OFF;
847 codec->set_bias_level = wm8580_set_bias_level;
848 codec->dai = wm8580_dai;
849 codec->num_dai = ARRAY_SIZE(wm8580_dai);
850 codec->reg_cache_size = ARRAY_SIZE(wm8580->reg_cache);
851 codec->reg_cache = &wm8580->reg_cache;
852
853 memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg));
854 780
855 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 781 codec->control_data = wm8580->control_data;
782 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8580->control_type);
856 if (ret < 0) { 783 if (ret < 0) {
857 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 784 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
858 goto err; 785 return ret;
859 } 786 }
860 787
861 for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++) 788 for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
@@ -865,7 +792,7 @@ static int wm8580_register(struct wm8580_priv *wm8580,
865 wm8580->supplies); 792 wm8580->supplies);
866 if (ret != 0) { 793 if (ret != 0) {
867 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 794 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
868 goto err; 795 return ret;
869 } 796 }
870 797
871 ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies), 798 ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
@@ -882,74 +809,69 @@ static int wm8580_register(struct wm8580_priv *wm8580,
882 goto err_regulator_enable; 809 goto err_regulator_enable;
883 } 810 }
884 811
885 for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++)
886 wm8580_dai[i].dev = codec->dev;
887
888 wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 812 wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
889 813
890 wm8580_codec = codec; 814 snd_soc_add_controls(codec, wm8580_snd_controls,
891 815 ARRAY_SIZE(wm8580_snd_controls));
892 ret = snd_soc_register_codec(codec); 816 wm8580_add_widgets(codec);
893 if (ret != 0) {
894 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
895 goto err_regulator_enable;
896 }
897
898 ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
899 if (ret != 0) {
900 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
901 goto err_codec;
902 }
903 817
904 return 0; 818 return 0;
905 819
906err_codec:
907 snd_soc_unregister_codec(codec);
908err_regulator_enable: 820err_regulator_enable:
909 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 821 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
910err_regulator_get: 822err_regulator_get:
911 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 823 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
912err:
913 kfree(wm8580);
914 return ret; 824 return ret;
915} 825}
916 826
917static void wm8580_unregister(struct wm8580_priv *wm8580) 827/* power down chip */
828static int wm8580_remove(struct snd_soc_codec *codec)
918{ 829{
919 wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF); 830 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
920 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); 831
921 snd_soc_unregister_codec(&wm8580->codec); 832 wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
833
922 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 834 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
923 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 835 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
924 kfree(wm8580); 836
925 wm8580_codec = NULL; 837 return 0;
926} 838}
927 839
840static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
841 .probe = wm8580_probe,
842 .remove = wm8580_remove,
843 .set_bias_level = wm8580_set_bias_level,
844 .reg_cache_size = sizeof(wm8580_reg),
845 .reg_word_size = sizeof(u16),
846 .reg_cache_default = &wm8580_reg,
847};
848
928#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 849#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
929static int wm8580_i2c_probe(struct i2c_client *i2c, 850static int wm8580_i2c_probe(struct i2c_client *i2c,
930 const struct i2c_device_id *id) 851 const struct i2c_device_id *id)
931{ 852{
932 struct wm8580_priv *wm8580; 853 struct wm8580_priv *wm8580;
933 struct snd_soc_codec *codec; 854 int ret;
934 855
935 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL); 856 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
936 if (wm8580 == NULL) 857 if (wm8580 == NULL)
937 return -ENOMEM; 858 return -ENOMEM;
938 859
939 codec = &wm8580->codec;
940
941 i2c_set_clientdata(i2c, wm8580); 860 i2c_set_clientdata(i2c, wm8580);
942 codec->control_data = i2c; 861 wm8580->control_data = i2c;
943 862 wm8580->control_type = SND_SOC_I2C;
944 codec->dev = &i2c->dev;
945 863
946 return wm8580_register(wm8580, SND_SOC_I2C); 864 ret = snd_soc_register_codec(&i2c->dev,
865 &soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
866 if (ret < 0)
867 kfree(wm8580);
868 return ret;
947} 869}
948 870
949static int wm8580_i2c_remove(struct i2c_client *client) 871static int wm8580_i2c_remove(struct i2c_client *client)
950{ 872{
951 struct wm8580_priv *wm8580 = i2c_get_clientdata(client); 873 snd_soc_unregister_codec(&client->dev);
952 wm8580_unregister(wm8580); 874 kfree(i2c_get_clientdata(client));
953 return 0; 875 return 0;
954} 876}
955 877
@@ -961,7 +883,7 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
961 883
962static struct i2c_driver wm8580_i2c_driver = { 884static struct i2c_driver wm8580_i2c_driver = {
963 .driver = { 885 .driver = {
964 .name = "wm8580", 886 .name = "wm8580-codec",
965 .owner = THIS_MODULE, 887 .owner = THIS_MODULE,
966 }, 888 },
967 .probe = wm8580_i2c_probe, 889 .probe = wm8580_i2c_probe,
@@ -972,7 +894,7 @@ static struct i2c_driver wm8580_i2c_driver = {
972 894
973static int __init wm8580_modinit(void) 895static int __init wm8580_modinit(void)
974{ 896{
975 int ret; 897 int ret = 0;
976 898
977#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 899#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
978 ret = i2c_add_driver(&wm8580_i2c_driver); 900 ret = i2c_add_driver(&wm8580_i2c_driver);
@@ -981,7 +903,7 @@ static int __init wm8580_modinit(void)
981 } 903 }
982#endif 904#endif
983 905
984 return 0; 906 return ret;
985} 907}
986module_init(wm8580_modinit); 908module_init(wm8580_modinit);
987 909
diff --git a/sound/soc/codecs/wm8580.h b/sound/soc/codecs/wm8580.h
index 0dfb5ddde6a..8328ef66759 100644
--- a/sound/soc/codecs/wm8580.h
+++ b/sound/soc/codecs/wm8580.h
@@ -31,8 +31,5 @@
31#define WM8580_DAI_PAIFRX 0 31#define WM8580_DAI_PAIFRX 0
32#define WM8580_DAI_PAIFTX 1 32#define WM8580_DAI_PAIFTX 1
33 33
34extern struct snd_soc_dai wm8580_dai[];
35extern struct snd_soc_codec_device soc_codec_dev_wm8580;
36
37#endif 34#endif
38 35
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index e2dba07f026..8d942b3b111 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -31,11 +31,10 @@
31 31
32#include "wm8711.h" 32#include "wm8711.h"
33 33
34static struct snd_soc_codec *wm8711_codec;
35
36/* codec private data */ 34/* codec private data */
37struct wm8711_priv { 35struct wm8711_priv {
38 struct snd_soc_codec codec; 36 enum snd_soc_control_type bus_type;
37 void *control_data;
39 u16 reg_cache[WM8711_CACHEREGNUM]; 38 u16 reg_cache[WM8711_CACHEREGNUM];
40 unsigned int sysclk; 39 unsigned int sysclk;
41}; 40};
@@ -163,7 +162,7 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
163 struct snd_soc_dai *dai) 162 struct snd_soc_dai *dai)
164{ 163{
165 struct snd_soc_codec *codec = dai->codec; 164 struct snd_soc_codec *codec = dai->codec;
166 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); 165 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
167 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc; 166 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
168 int i = get_coeff(wm8711->sysclk, params_rate(params)); 167 int i = get_coeff(wm8711->sysclk, params_rate(params));
169 u16 srate = (coeff_div[i].sr << 2) | 168 u16 srate = (coeff_div[i].sr << 2) |
@@ -227,7 +226,7 @@ static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
227 int clk_id, unsigned int freq, int dir) 226 int clk_id, unsigned int freq, int dir)
228{ 227{
229 struct snd_soc_codec *codec = codec_dai->codec; 228 struct snd_soc_codec *codec = codec_dai->codec;
230 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); 229 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
231 230
232 switch (freq) { 231 switch (freq) {
233 case 11289600: 232 case 11289600:
@@ -338,8 +337,8 @@ static struct snd_soc_dai_ops wm8711_ops = {
338 .set_fmt = wm8711_set_dai_fmt, 337 .set_fmt = wm8711_set_dai_fmt,
339}; 338};
340 339
341struct snd_soc_dai wm8711_dai = { 340static struct snd_soc_dai_driver wm8711_dai = {
342 .name = "WM8711", 341 .name = "wm8711-hifi",
343 .playback = { 342 .playback = {
344 .stream_name = "Playback", 343 .stream_name = "Playback",
345 .channels_min = 1, 344 .channels_min = 1,
@@ -349,22 +348,16 @@ struct snd_soc_dai wm8711_dai = {
349 }, 348 },
350 .ops = &wm8711_ops, 349 .ops = &wm8711_ops,
351}; 350};
352EXPORT_SYMBOL_GPL(wm8711_dai);
353 351
354static int wm8711_suspend(struct platform_device *pdev, pm_message_t state) 352static int wm8711_suspend(struct snd_soc_codec *codec, pm_message_t state)
355{ 353{
356 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
357 struct snd_soc_codec *codec = socdev->card->codec;
358
359 snd_soc_write(codec, WM8711_ACTIVE, 0x0); 354 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
360 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF); 355 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
361 return 0; 356 return 0;
362} 357}
363 358
364static int wm8711_resume(struct platform_device *pdev) 359static int wm8711_resume(struct snd_soc_codec *codec)
365{ 360{
366 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
367 struct snd_soc_codec *codec = socdev->card->codec;
368 int i; 361 int i;
369 u8 data[2]; 362 u8 data[2];
370 u16 *cache = codec->reg_cache; 363 u16 *cache = codec->reg_cache;
@@ -380,99 +373,24 @@ static int wm8711_resume(struct platform_device *pdev)
380 return 0; 373 return 0;
381} 374}
382 375
383static int wm8711_probe(struct platform_device *pdev) 376static int wm8711_probe(struct snd_soc_codec *codec)
384{ 377{
385 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 378 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
386 struct snd_soc_codec *codec; 379 int ret, reg;
387 int ret = 0;
388
389 if (wm8711_codec == NULL) {
390 dev_err(&pdev->dev, "Codec device not registered\n");
391 return -ENODEV;
392 }
393
394 socdev->card->codec = wm8711_codec;
395 codec = wm8711_codec;
396
397 /* register pcms */
398 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
399 if (ret < 0) {
400 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
401 goto pcm_err;
402 }
403
404 snd_soc_add_controls(codec, wm8711_snd_controls,
405 ARRAY_SIZE(wm8711_snd_controls));
406 wm8711_add_widgets(codec);
407
408 return ret;
409
410pcm_err:
411 return ret;
412}
413
414/* power down chip */
415static int wm8711_remove(struct platform_device *pdev)
416{
417 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
418
419 snd_soc_free_pcms(socdev);
420 snd_soc_dapm_free(socdev);
421
422 return 0;
423}
424
425struct snd_soc_codec_device soc_codec_dev_wm8711 = {
426 .probe = wm8711_probe,
427 .remove = wm8711_remove,
428 .suspend = wm8711_suspend,
429 .resume = wm8711_resume,
430};
431EXPORT_SYMBOL_GPL(soc_codec_dev_wm8711);
432
433static int wm8711_register(struct wm8711_priv *wm8711,
434 enum snd_soc_control_type control)
435{
436 int ret;
437 struct snd_soc_codec *codec = &wm8711->codec;
438 u16 reg;
439
440 if (wm8711_codec) {
441 dev_err(codec->dev, "Another WM8711 is registered\n");
442 ret = -EINVAL;
443 goto err;
444 }
445
446 mutex_init(&codec->mutex);
447 INIT_LIST_HEAD(&codec->dapm_widgets);
448 INIT_LIST_HEAD(&codec->dapm_paths);
449
450 snd_soc_codec_set_drvdata(codec, wm8711);
451 codec->name = "WM8711";
452 codec->owner = THIS_MODULE;
453 codec->bias_level = SND_SOC_BIAS_OFF;
454 codec->set_bias_level = wm8711_set_bias_level;
455 codec->dai = &wm8711_dai;
456 codec->num_dai = 1;
457 codec->reg_cache_size = WM8711_CACHEREGNUM;
458 codec->reg_cache = &wm8711->reg_cache;
459
460 memcpy(codec->reg_cache, wm8711_reg, sizeof(wm8711_reg));
461 380
462 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 381 codec->control_data = wm8711->control_data;
382 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type);
463 if (ret < 0) { 383 if (ret < 0) {
464 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 384 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
465 goto err; 385 return ret;
466 } 386 }
467 387
468 ret = wm8711_reset(codec); 388 ret = wm8711_reset(codec);
469 if (ret < 0) { 389 if (ret < 0) {
470 dev_err(codec->dev, "Failed to issue reset\n"); 390 dev_err(codec->dev, "Failed to issue reset\n");
471 goto err; 391 return ret;
472 } 392 }
473 393
474 wm8711_dai.dev = codec->dev;
475
476 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 394 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
477 395
478 /* Latch the update bits */ 396 /* Latch the update bits */
@@ -481,69 +399,63 @@ static int wm8711_register(struct wm8711_priv *wm8711,
481 reg = snd_soc_read(codec, WM8711_ROUT1V); 399 reg = snd_soc_read(codec, WM8711_ROUT1V);
482 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100); 400 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100);
483 401
484 wm8711_codec = codec; 402 snd_soc_add_controls(codec, wm8711_snd_controls,
485 403 ARRAY_SIZE(wm8711_snd_controls));
486 ret = snd_soc_register_codec(codec); 404 wm8711_add_widgets(codec);
487 if (ret != 0) {
488 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
489 goto err;
490 }
491
492 ret = snd_soc_register_dai(&wm8711_dai);
493 if (ret != 0) {
494 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
495 goto err_codec;
496 }
497
498 return 0;
499 405
500err_codec:
501 snd_soc_unregister_codec(codec);
502err:
503 kfree(wm8711);
504 return ret; 406 return ret;
407
505} 408}
506 409
507static void wm8711_unregister(struct wm8711_priv *wm8711) 410/* power down chip */
411static int wm8711_remove(struct snd_soc_codec *codec)
508{ 412{
509 wm8711_set_bias_level(&wm8711->codec, SND_SOC_BIAS_OFF); 413 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
510 snd_soc_unregister_dai(&wm8711_dai); 414 return 0;
511 snd_soc_unregister_codec(&wm8711->codec);
512 kfree(wm8711);
513 wm8711_codec = NULL;
514} 415}
515 416
417static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
418 .probe = wm8711_probe,
419 .remove = wm8711_remove,
420 .suspend = wm8711_suspend,
421 .resume = wm8711_resume,
422 .set_bias_level = wm8711_set_bias_level,
423 .reg_cache_size = sizeof(wm8711_reg),
424 .reg_word_size = sizeof(u16),
425 .reg_cache_default = wm8711_reg,
426};
427
516#if defined(CONFIG_SPI_MASTER) 428#if defined(CONFIG_SPI_MASTER)
517static int __devinit wm8711_spi_probe(struct spi_device *spi) 429static int __devinit wm8711_spi_probe(struct spi_device *spi)
518{ 430{
519 struct snd_soc_codec *codec;
520 struct wm8711_priv *wm8711; 431 struct wm8711_priv *wm8711;
432 int ret;
521 433
522 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL); 434 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
523 if (wm8711 == NULL) 435 if (wm8711 == NULL)
524 return -ENOMEM; 436 return -ENOMEM;
525 437
526 codec = &wm8711->codec; 438 spi_set_drvdata(spi, wm8711);
527 codec->control_data = spi; 439 wm8711->control_data = spi;
528 codec->dev = &spi->dev; 440 wm8711->bus_type = SND_SOC_SPI;
529 441
530 dev_set_drvdata(&spi->dev, wm8711); 442 ret = snd_soc_register_codec(&spi->dev,
531 443 &soc_codec_dev_wm8711, &wm8711_dai, 1);
532 return wm8711_register(wm8711, SND_SOC_SPI); 444 if (ret < 0)
445 kfree(wm8711);
446 return ret;
533} 447}
534 448
535static int __devexit wm8711_spi_remove(struct spi_device *spi) 449static int __devexit wm8711_spi_remove(struct spi_device *spi)
536{ 450{
537 struct wm8711_priv *wm8711 = dev_get_drvdata(&spi->dev); 451 snd_soc_unregister_codec(&spi->dev);
538 452 kfree(spi_get_drvdata(spi));
539 wm8711_unregister(wm8711);
540
541 return 0; 453 return 0;
542} 454}
543 455
544static struct spi_driver wm8711_spi_driver = { 456static struct spi_driver wm8711_spi_driver = {
545 .driver = { 457 .driver = {
546 .name = "wm8711", 458 .name = "wm8711-codec",
547 .bus = &spi_bus_type, 459 .bus = &spi_bus_type,
548 .owner = THIS_MODULE, 460 .owner = THIS_MODULE,
549 }, 461 },
@@ -553,31 +465,31 @@ static struct spi_driver wm8711_spi_driver = {
553#endif /* CONFIG_SPI_MASTER */ 465#endif /* CONFIG_SPI_MASTER */
554 466
555#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 467#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
556static __devinit int wm8711_i2c_probe(struct i2c_client *i2c, 468static __devinit int wm8711_i2c_probe(struct i2c_client *client,
557 const struct i2c_device_id *id) 469 const struct i2c_device_id *id)
558{ 470{
559 struct wm8711_priv *wm8711; 471 struct wm8711_priv *wm8711;
560 struct snd_soc_codec *codec; 472 int ret;
561 473
562 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL); 474 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
563 if (wm8711 == NULL) 475 if (wm8711 == NULL)
564 return -ENOMEM; 476 return -ENOMEM;
565 477
566 codec = &wm8711->codec; 478 i2c_set_clientdata(client, wm8711);
567 codec->hw_write = (hw_write_t)i2c_master_send; 479 wm8711->control_data = client;
568 480 wm8711->bus_type = SND_SOC_I2C;
569 i2c_set_clientdata(i2c, wm8711);
570 codec->control_data = i2c;
571 481
572 codec->dev = &i2c->dev; 482 ret = snd_soc_register_codec(&client->dev,
573 483 &soc_codec_dev_wm8711, &wm8711_dai, 1);
574 return wm8711_register(wm8711, SND_SOC_I2C); 484 if (ret < 0)
485 kfree(wm8711);
486 return ret;
575} 487}
576 488
577static __devexit int wm8711_i2c_remove(struct i2c_client *client) 489static __devexit int wm8711_i2c_remove(struct i2c_client *client)
578{ 490{
579 struct wm8711_priv *wm8711 = i2c_get_clientdata(client); 491 snd_soc_unregister_codec(&client->dev);
580 wm8711_unregister(wm8711); 492 kfree(i2c_get_clientdata(client));
581 return 0; 493 return 0;
582} 494}
583 495
@@ -589,7 +501,7 @@ MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
589 501
590static struct i2c_driver wm8711_i2c_driver = { 502static struct i2c_driver wm8711_i2c_driver = {
591 .driver = { 503 .driver = {
592 .name = "WM8711 I2C Codec", 504 .name = "wm8711-codec",
593 .owner = THIS_MODULE, 505 .owner = THIS_MODULE,
594 }, 506 },
595 .probe = wm8711_i2c_probe, 507 .probe = wm8711_i2c_probe,
diff --git a/sound/soc/codecs/wm8711.h b/sound/soc/codecs/wm8711.h
index 381e84a4381..a61db985499 100644
--- a/sound/soc/codecs/wm8711.h
+++ b/sound/soc/codecs/wm8711.h
@@ -36,7 +36,4 @@ struct wm8711_setup_data {
36 unsigned short i2c_address; 36 unsigned short i2c_address;
37}; 37};
38 38
39extern struct snd_soc_dai wm8711_dai;
40extern struct snd_soc_codec_device soc_codec_dev_wm8711;
41
42#endif 39#endif
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index 9d1df262813..6a40080ba70 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -23,7 +23,6 @@
23#include <sound/initval.h> 23#include <sound/initval.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25 25
26#include "wm8727.h"
27/* 26/*
28 * Note this is a simple chip with no configuration interface, sample rate is 27 * Note this is a simple chip with no configuration interface, sample rate is
29 * determined automatically by examining the Master clock and Bit clock ratios 28 * determined automatically by examining the Master clock and Bit clock ratios
@@ -33,8 +32,8 @@
33 SNDRV_PCM_RATE_192000) 32 SNDRV_PCM_RATE_192000)
34 33
35 34
36struct snd_soc_dai wm8727_dai = { 35static struct snd_soc_dai_driver wm8727_dai = {
37 .name = "WM8727", 36 .name = "wm8727-hifi",
38 .playback = { 37 .playback = {
39 .stream_name = "Playback", 38 .stream_name = "Playback",
40 .channels_min = 2, 39 .channels_min = 2,
@@ -43,103 +42,18 @@ struct snd_soc_dai wm8727_dai = {
43 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 42 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
44 }, 43 },
45}; 44};
46EXPORT_SYMBOL_GPL(wm8727_dai);
47 45
48static struct snd_soc_codec *wm8727_codec; 46struct snd_soc_codec_driver soc_codec_dev_wm8727;
49 47
50static int wm8727_soc_probe(struct platform_device *pdev) 48static __devinit int wm8727_probe(struct platform_device *pdev)
51{ 49{
52 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 50 return snd_soc_register_codec(&pdev->dev,
53 int ret = 0; 51 &soc_codec_dev_wm8727, &wm8727_dai, 1);
54
55 BUG_ON(!wm8727_codec);
56
57 socdev->card->codec = wm8727_codec;
58
59 /* register pcms */
60 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
61 if (ret < 0) {
62 printk(KERN_ERR "wm8727: failed to create pcms\n");
63 goto pcm_err;
64 }
65
66 return ret;
67
68pcm_err:
69 kfree(socdev->card->codec);
70 socdev->card->codec = NULL;
71 return ret;
72}
73
74static int wm8727_soc_remove(struct platform_device *pdev)
75{
76 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
77
78 snd_soc_free_pcms(socdev);
79
80 return 0;
81}
82
83struct snd_soc_codec_device soc_codec_dev_wm8727 = {
84 .probe = wm8727_soc_probe,
85 .remove = wm8727_soc_remove,
86};
87EXPORT_SYMBOL_GPL(soc_codec_dev_wm8727);
88
89
90static __devinit int wm8727_platform_probe(struct platform_device *pdev)
91{
92 struct snd_soc_codec *codec;
93 int ret;
94
95 if (wm8727_codec) {
96 dev_err(&pdev->dev, "Another WM8727 is registered\n");
97 return -EBUSY;
98 }
99
100 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
101 if (codec == NULL)
102 return -ENOMEM;
103 wm8727_codec = codec;
104
105 platform_set_drvdata(pdev, codec);
106
107 mutex_init(&codec->mutex);
108 codec->dev = &pdev->dev;
109 codec->name = "WM8727";
110 codec->owner = THIS_MODULE;
111 codec->dai = &wm8727_dai;
112 codec->num_dai = 1;
113 INIT_LIST_HEAD(&codec->dapm_widgets);
114 INIT_LIST_HEAD(&codec->dapm_paths);
115
116 wm8727_dai.dev = &pdev->dev;
117
118 ret = snd_soc_register_codec(codec);
119 if (ret != 0) {
120 dev_err(&pdev->dev, "Failed to register CODEC: %d\n", ret);
121 goto err;
122 }
123
124 ret = snd_soc_register_dai(&wm8727_dai);
125 if (ret != 0) {
126 dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
127 goto err_codec;
128 }
129
130 return 0;
131
132err_codec:
133 snd_soc_unregister_codec(codec);
134err:
135 kfree(codec);
136 return ret;
137} 52}
138 53
139static int __devexit wm8727_platform_remove(struct platform_device *pdev) 54static int __devexit wm8727_remove(struct platform_device *pdev)
140{ 55{
141 snd_soc_unregister_dai(&wm8727_dai); 56 snd_soc_unregister_codec(&pdev->dev);
142 snd_soc_unregister_codec(platform_get_drvdata(pdev));
143 return 0; 57 return 0;
144} 58}
145 59
@@ -149,8 +63,8 @@ static struct platform_driver wm8727_codec_driver = {
149 .owner = THIS_MODULE, 63 .owner = THIS_MODULE,
150 }, 64 },
151 65
152 .probe = wm8727_platform_probe, 66 .probe = wm8727_probe,
153 .remove = __devexit_p(wm8727_platform_remove), 67 .remove = __devexit_p(wm8727_remove),
154}; 68};
155 69
156static int __init wm8727_init(void) 70static int __init wm8727_init(void)
diff --git a/sound/soc/codecs/wm8727.h b/sound/soc/codecs/wm8727.h
deleted file mode 100644
index ee19aa71bcd..00000000000
--- a/sound/soc/codecs/wm8727.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/*
2 * wm8727.h
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
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#ifndef WM8727_H_
16#define WM8727_H_
17
18extern struct snd_soc_dai wm8727_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8727;
20
21#endif /* WM8727_H_ */
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 34be2d2b69e..ae229244478 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -29,8 +29,6 @@
29 29
30#include "wm8728.h" 30#include "wm8728.h"
31 31
32struct snd_soc_codec_device soc_codec_dev_wm8728;
33
34/* 32/*
35 * We can't read the WM8728 register space so we cache them instead. 33 * We can't read the WM8728 register space so we cache them instead.
36 * Note that the defaults here aren't the physical defaults, we latch 34 * Note that the defaults here aren't the physical defaults, we latch
@@ -44,6 +42,12 @@ static const u16 wm8728_reg_defaults[] = {
44 0x100, 42 0x100,
45}; 43};
46 44
45/* codec private data */
46struct wm8728_priv {
47 enum snd_soc_control_type control_type;
48 void *control_data;
49};
50
47static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1); 51static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
48 52
49static const struct snd_kcontrol_new wm8728_snd_controls[] = { 53static const struct snd_kcontrol_new wm8728_snd_controls[] = {
@@ -96,8 +100,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
96 struct snd_soc_dai *dai) 100 struct snd_soc_dai *dai)
97{ 101{
98 struct snd_soc_pcm_runtime *rtd = substream->private_data; 102 struct snd_soc_pcm_runtime *rtd = substream->private_data;
99 struct snd_soc_device *socdev = rtd->socdev; 103 struct snd_soc_codec *codec = rtd->codec;
100 struct snd_soc_codec *codec = socdev->card->codec;
101 u16 dac = snd_soc_read(codec, WM8728_DACCTL); 104 u16 dac = snd_soc_read(codec, WM8728_DACCTL);
102 105
103 dac &= ~0x18; 106 dac &= ~0x18;
@@ -210,8 +213,8 @@ static struct snd_soc_dai_ops wm8728_dai_ops = {
210 .set_fmt = wm8728_set_dai_fmt, 213 .set_fmt = wm8728_set_dai_fmt,
211}; 214};
212 215
213struct snd_soc_dai wm8728_dai = { 216static struct snd_soc_dai_driver wm8728_dai = {
214 .name = "WM8728", 217 .name = "wm8728-hifi",
215 .playback = { 218 .playback = {
216 .stream_name = "Playback", 219 .stream_name = "Playback",
217 .channels_min = 2, 220 .channels_min = 2,
@@ -221,63 +224,32 @@ struct snd_soc_dai wm8728_dai = {
221 }, 224 },
222 .ops = &wm8728_dai_ops, 225 .ops = &wm8728_dai_ops,
223}; 226};
224EXPORT_SYMBOL_GPL(wm8728_dai);
225 227
226static int wm8728_suspend(struct platform_device *pdev, pm_message_t state) 228static int wm8728_suspend(struct snd_soc_codec *codec, pm_message_t state)
227{ 229{
228 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
229 struct snd_soc_codec *codec = socdev->card->codec;
230
231 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); 230 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
232 231
233 return 0; 232 return 0;
234} 233}
235 234
236static int wm8728_resume(struct platform_device *pdev) 235static int wm8728_resume(struct snd_soc_codec *codec)
237{ 236{
238 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
239 struct snd_soc_codec *codec = socdev->card->codec;
240
241 wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 237 wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
242 238
243 return 0; 239 return 0;
244} 240}
245 241
246/* 242static int wm8728_probe(struct snd_soc_codec *codec)
247 * initialise the WM8728 driver
248 * register the mixer and dsp interfaces with the kernel
249 */
250static int wm8728_init(struct snd_soc_device *socdev,
251 enum snd_soc_control_type control)
252{ 243{
253 struct snd_soc_codec *codec = socdev->card->codec; 244 struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec);
254 int ret = 0; 245 int ret;
255
256 codec->name = "WM8728";
257 codec->owner = THIS_MODULE;
258 codec->set_bias_level = wm8728_set_bias_level;
259 codec->dai = &wm8728_dai;
260 codec->num_dai = 1;
261 codec->bias_level = SND_SOC_BIAS_OFF;
262 codec->reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults);
263 codec->reg_cache = kmemdup(wm8728_reg_defaults,
264 sizeof(wm8728_reg_defaults),
265 GFP_KERNEL);
266 if (codec->reg_cache == NULL)
267 return -ENOMEM;
268 246
269 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 247 codec->control_data = wm8728->control_data;
248 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8728->control_type);
270 if (ret < 0) { 249 if (ret < 0) {
271 printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n", 250 printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n",
272 ret); 251 ret);
273 goto err; 252 return ret;
274 }
275
276 /* register pcms */
277 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
278 if (ret < 0) {
279 printk(KERN_ERR "wm8728: failed to create pcms\n");
280 goto err;
281 } 253 }
282 254
283 /* power on device */ 255 /* power on device */
@@ -288,128 +260,56 @@ static int wm8728_init(struct snd_soc_device *socdev,
288 wm8728_add_widgets(codec); 260 wm8728_add_widgets(codec);
289 261
290 return ret; 262 return ret;
291
292err:
293 kfree(codec->reg_cache);
294 return ret;
295} 263}
296 264
297static struct snd_soc_device *wm8728_socdev; 265static int wm8728_remove(struct snd_soc_codec *codec)
298
299#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
300
301/*
302 * WM8728 2 wire address is determined by GPIO5
303 * state during powerup.
304 * low = 0x1a
305 * high = 0x1b
306 */
307
308static int wm8728_i2c_probe(struct i2c_client *i2c,
309 const struct i2c_device_id *id)
310{ 266{
311 struct snd_soc_device *socdev = wm8728_socdev; 267 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
312 struct snd_soc_codec *codec = socdev->card->codec;
313 int ret;
314
315 i2c_set_clientdata(i2c, codec);
316 codec->control_data = i2c;
317
318 ret = wm8728_init(socdev, SND_SOC_I2C);
319 if (ret < 0)
320 pr_err("failed to initialise WM8728\n");
321
322 return ret;
323}
324
325static int wm8728_i2c_remove(struct i2c_client *client)
326{
327 struct snd_soc_codec *codec = i2c_get_clientdata(client);
328 kfree(codec->reg_cache);
329 return 0; 268 return 0;
330} 269}
331 270
332static const struct i2c_device_id wm8728_i2c_id[] = { 271static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
333 { "wm8728", 0 }, 272 .probe = wm8728_probe,
334 { } 273 .remove = wm8728_remove,
335}; 274 .suspend = wm8728_suspend,
336MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id); 275 .resume = wm8728_resume,
337 276 .set_bias_level = wm8728_set_bias_level,
338static struct i2c_driver wm8728_i2c_driver = { 277 .reg_cache_size = sizeof(wm8728_reg_defaults),
339 .driver = { 278 .reg_word_size = sizeof(u16),
340 .name = "WM8728 I2C Codec", 279 .reg_cache_default = wm8728_reg_defaults,
341 .owner = THIS_MODULE,
342 },
343 .probe = wm8728_i2c_probe,
344 .remove = wm8728_i2c_remove,
345 .id_table = wm8728_i2c_id,
346}; 280};
347 281
348static int wm8728_add_i2c_device(struct platform_device *pdev,
349 const struct wm8728_setup_data *setup)
350{
351 struct i2c_board_info info;
352 struct i2c_adapter *adapter;
353 struct i2c_client *client;
354 int ret;
355
356 ret = i2c_add_driver(&wm8728_i2c_driver);
357 if (ret != 0) {
358 dev_err(&pdev->dev, "can't add i2c driver\n");
359 return ret;
360 }
361
362 memset(&info, 0, sizeof(struct i2c_board_info));
363 info.addr = setup->i2c_address;
364 strlcpy(info.type, "wm8728", I2C_NAME_SIZE);
365
366 adapter = i2c_get_adapter(setup->i2c_bus);
367 if (!adapter) {
368 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
369 setup->i2c_bus);
370 goto err_driver;
371 }
372
373 client = i2c_new_device(adapter, &info);
374 i2c_put_adapter(adapter);
375 if (!client) {
376 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
377 (unsigned int)info.addr);
378 goto err_driver;
379 }
380
381 return 0;
382
383err_driver:
384 i2c_del_driver(&wm8728_i2c_driver);
385 return -ENODEV;
386}
387#endif
388
389#if defined(CONFIG_SPI_MASTER) 282#if defined(CONFIG_SPI_MASTER)
390static int __devinit wm8728_spi_probe(struct spi_device *spi) 283static int __devinit wm8728_spi_probe(struct spi_device *spi)
391{ 284{
392 struct snd_soc_device *socdev = wm8728_socdev; 285 struct wm8728_priv *wm8728;
393 struct snd_soc_codec *codec = socdev->card->codec;
394 int ret; 286 int ret;
395 287
396 codec->control_data = spi; 288 wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
289 if (wm8728 == NULL)
290 return -ENOMEM;
397 291
398 ret = wm8728_init(socdev, SND_SOC_SPI); 292 wm8728->control_data = spi;
399 if (ret < 0) 293 wm8728->control_type = SND_SOC_SPI;
400 dev_err(&spi->dev, "failed to initialise WM8728\n"); 294 spi_set_drvdata(spi, wm8728);
401 295
296 ret = snd_soc_register_codec(&spi->dev,
297 &soc_codec_dev_wm8728, &wm8728_dai, 1);
298 if (ret < 0)
299 kfree(wm8728);
402 return ret; 300 return ret;
403} 301}
404 302
405static int __devexit wm8728_spi_remove(struct spi_device *spi) 303static int __devexit wm8728_spi_remove(struct spi_device *spi)
406{ 304{
305 snd_soc_unregister_codec(&spi->dev);
306 kfree(spi_get_drvdata(spi));
407 return 0; 307 return 0;
408} 308}
409 309
410static struct spi_driver wm8728_spi_driver = { 310static struct spi_driver wm8728_spi_driver = {
411 .driver = { 311 .driver = {
412 .name = "wm8728", 312 .name = "wm8728-codec",
413 .bus = &spi_bus_type, 313 .bus = &spi_bus_type,
414 .owner = THIS_MODULE, 314 .owner = THIS_MODULE,
415 }, 315 },
@@ -418,85 +318,81 @@ static struct spi_driver wm8728_spi_driver = {
418}; 318};
419#endif /* CONFIG_SPI_MASTER */ 319#endif /* CONFIG_SPI_MASTER */
420 320
421static int wm8728_probe(struct platform_device *pdev) 321#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
322static __devinit int wm8728_i2c_probe(struct i2c_client *i2c,
323 const struct i2c_device_id *id)
422{ 324{
423 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 325 struct wm8728_priv *wm8728;
424 struct wm8728_setup_data *setup; 326 int ret;
425 struct snd_soc_codec *codec;
426 int ret = 0;
427 327
428 setup = socdev->codec_data; 328 wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
429 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 329 if (wm8728 == NULL)
430 if (codec == NULL)
431 return -ENOMEM; 330 return -ENOMEM;
432 331
433 socdev->card->codec = codec; 332 i2c_set_clientdata(i2c, wm8728);
434 mutex_init(&codec->mutex); 333 wm8728->control_data = i2c;
435 INIT_LIST_HEAD(&codec->dapm_widgets); 334 wm8728->control_type = SND_SOC_I2C;
436 INIT_LIST_HEAD(&codec->dapm_paths); 335
336 ret = snd_soc_register_codec(&i2c->dev,
337 &soc_codec_dev_wm8728, &wm8728_dai, 1);
338 if (ret < 0)
339 kfree(wm8728);
340 return ret;
341}
342
343static __devexit int wm8728_i2c_remove(struct i2c_client *client)
344{
345 snd_soc_unregister_codec(&client->dev);
346 kfree(i2c_get_clientdata(client));
347 return 0;
348}
437 349
438 wm8728_socdev = socdev; 350static const struct i2c_device_id wm8728_i2c_id[] = {
439 ret = -ENODEV; 351 { "wm8728", 0 },
352 { }
353};
354MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
355
356static struct i2c_driver wm8728_i2c_driver = {
357 .driver = {
358 .name = "wm8728-codec",
359 .owner = THIS_MODULE,
360 },
361 .probe = wm8728_i2c_probe,
362 .remove = __devexit_p(wm8728_i2c_remove),
363 .id_table = wm8728_i2c_id,
364};
365#endif
440 366
367static int __init wm8728_modinit(void)
368{
369 int ret = 0;
441#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 370#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
442 if (setup->i2c_address) { 371 ret = i2c_add_driver(&wm8728_i2c_driver);
443 ret = wm8728_add_i2c_device(pdev, setup); 372 if (ret != 0) {
373 printk(KERN_ERR "Failed to register wm8728 I2C driver: %d\n",
374 ret);
444 } 375 }
445#endif 376#endif
446#if defined(CONFIG_SPI_MASTER) 377#if defined(CONFIG_SPI_MASTER)
447 if (setup->spi) { 378 ret = spi_register_driver(&wm8728_spi_driver);
448 ret = spi_register_driver(&wm8728_spi_driver); 379 if (ret != 0) {
449 if (ret != 0) 380 printk(KERN_ERR "Failed to register wm8728 SPI driver: %d\n",
450 printk(KERN_ERR "can't add spi driver"); 381 ret);
451 } 382 }
452#endif 383#endif
453
454 if (ret != 0)
455 kfree(codec);
456
457 return ret; 384 return ret;
458} 385}
386module_init(wm8728_modinit);
459 387
460/* power down chip */ 388static void __exit wm8728_exit(void)
461static int wm8728_remove(struct platform_device *pdev)
462{ 389{
463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
464 struct snd_soc_codec *codec = socdev->card->codec;
465
466 if (codec->control_data)
467 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
468
469 snd_soc_free_pcms(socdev);
470 snd_soc_dapm_free(socdev);
471#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 390#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
472 i2c_unregister_device(codec->control_data);
473 i2c_del_driver(&wm8728_i2c_driver); 391 i2c_del_driver(&wm8728_i2c_driver);
474#endif 392#endif
475#if defined(CONFIG_SPI_MASTER) 393#if defined(CONFIG_SPI_MASTER)
476 spi_unregister_driver(&wm8728_spi_driver); 394 spi_unregister_driver(&wm8728_spi_driver);
477#endif 395#endif
478 kfree(codec);
479
480 return 0;
481}
482
483struct snd_soc_codec_device soc_codec_dev_wm8728 = {
484 .probe = wm8728_probe,
485 .remove = wm8728_remove,
486 .suspend = wm8728_suspend,
487 .resume = wm8728_resume,
488};
489EXPORT_SYMBOL_GPL(soc_codec_dev_wm8728);
490
491static int __init wm8728_modinit(void)
492{
493 return snd_soc_register_dai(&wm8728_dai);
494}
495module_init(wm8728_modinit);
496
497static void __exit wm8728_exit(void)
498{
499 snd_soc_unregister_dai(&wm8728_dai);
500} 396}
501module_exit(wm8728_exit); 397module_exit(wm8728_exit);
502 398
diff --git a/sound/soc/codecs/wm8728.h b/sound/soc/codecs/wm8728.h
index d269c132474..8aea362ffd4 100644
--- a/sound/soc/codecs/wm8728.h
+++ b/sound/soc/codecs/wm8728.h
@@ -18,13 +18,4 @@
18#define WM8728_DACCTL 0x02 18#define WM8728_DACCTL 0x02
19#define WM8728_IFCTL 0x03 19#define WM8728_IFCTL 0x03
20 20
21struct wm8728_setup_data {
22 int spi;
23 int i2c_bus;
24 unsigned short i2c_address;
25};
26
27extern struct snd_soc_dai wm8728_dai;
28extern struct snd_soc_codec_device soc_codec_dev_wm8728;
29
30#endif 21#endif
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 0ab9b635529..7da360ee1fe 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -32,9 +32,6 @@
32 32
33#include "wm8731.h" 33#include "wm8731.h"
34 34
35static struct snd_soc_codec *wm8731_codec;
36struct snd_soc_codec_device soc_codec_dev_wm8731;
37
38#define WM8731_NUM_SUPPLIES 4 35#define WM8731_NUM_SUPPLIES 4
39static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { 36static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
40 "AVDD", 37 "AVDD",
@@ -45,7 +42,8 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
45 42
46/* codec private data */ 43/* codec private data */
47struct wm8731_priv { 44struct wm8731_priv {
48 struct snd_soc_codec codec; 45 enum snd_soc_control_type control_type;
46 void *control_data;
49 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 47 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
50 u16 reg_cache[WM8731_CACHEREGNUM]; 48 u16 reg_cache[WM8731_CACHEREGNUM];
51 unsigned int sysclk; 49 unsigned int sysclk;
@@ -222,9 +220,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
222 struct snd_pcm_hw_params *params, 220 struct snd_pcm_hw_params *params,
223 struct snd_soc_dai *dai) 221 struct snd_soc_dai *dai)
224{ 222{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data; 223 struct snd_soc_codec *codec = dai->codec;
226 struct snd_soc_device *socdev = rtd->socdev;
227 struct snd_soc_codec *codec = socdev->card->codec;
228 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 224 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
229 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; 225 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
230 int i = get_coeff(wm8731->sysclk, params_rate(params)); 226 int i = get_coeff(wm8731->sysclk, params_rate(params));
@@ -252,9 +248,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
252static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, 248static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
253 struct snd_soc_dai *dai) 249 struct snd_soc_dai *dai)
254{ 250{
255 struct snd_soc_pcm_runtime *rtd = substream->private_data; 251 struct snd_soc_codec *codec = dai->codec;
256 struct snd_soc_device *socdev = rtd->socdev;
257 struct snd_soc_codec *codec = socdev->card->codec;
258 252
259 /* set active */ 253 /* set active */
260 snd_soc_write(codec, WM8731_ACTIVE, 0x0001); 254 snd_soc_write(codec, WM8731_ACTIVE, 0x0001);
@@ -265,9 +259,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
265static void wm8731_shutdown(struct snd_pcm_substream *substream, 259static void wm8731_shutdown(struct snd_pcm_substream *substream,
266 struct snd_soc_dai *dai) 260 struct snd_soc_dai *dai)
267{ 261{
268 struct snd_soc_pcm_runtime *rtd = substream->private_data; 262 struct snd_soc_codec *codec = dai->codec;
269 struct snd_soc_device *socdev = rtd->socdev;
270 struct snd_soc_codec *codec = socdev->card->codec;
271 263
272 /* deactivate */ 264 /* deactivate */
273 if (!codec->active) { 265 if (!codec->active) {
@@ -428,8 +420,8 @@ static struct snd_soc_dai_ops wm8731_dai_ops = {
428 .set_fmt = wm8731_set_dai_fmt, 420 .set_fmt = wm8731_set_dai_fmt,
429}; 421};
430 422
431struct snd_soc_dai wm8731_dai = { 423static struct snd_soc_dai_driver wm8731_dai = {
432 .name = "WM8731", 424 .name = "wm8731-hifi",
433 .playback = { 425 .playback = {
434 .stream_name = "Playback", 426 .stream_name = "Playback",
435 .channels_min = 1, 427 .channels_min = 1,
@@ -445,24 +437,17 @@ struct snd_soc_dai wm8731_dai = {
445 .ops = &wm8731_dai_ops, 437 .ops = &wm8731_dai_ops,
446 .symmetric_rates = 1, 438 .symmetric_rates = 1,
447}; 439};
448EXPORT_SYMBOL_GPL(wm8731_dai);
449 440
450#ifdef CONFIG_PM 441#ifdef CONFIG_PM
451static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) 442static int wm8731_suspend(struct snd_soc_codec *codec, pm_message_t state)
452{ 443{
453 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
454 struct snd_soc_codec *codec = socdev->card->codec;
455
456 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 444 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
457 445
458 return 0; 446 return 0;
459} 447}
460 448
461static int wm8731_resume(struct platform_device *pdev) 449static int wm8731_resume(struct snd_soc_codec *codec)
462{ 450{
463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
464 struct snd_soc_codec *codec = socdev->card->codec;
465
466 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 451 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
467 452
468 return 0; 453 return 0;
@@ -472,88 +457,18 @@ static int wm8731_resume(struct platform_device *pdev)
472#define wm8731_resume NULL 457#define wm8731_resume NULL
473#endif 458#endif
474 459
475static int wm8731_probe(struct platform_device *pdev) 460static int wm8731_probe(struct snd_soc_codec *codec)
476{
477 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
478 struct snd_soc_codec *codec;
479 int ret = 0;
480
481 if (wm8731_codec == NULL) {
482 dev_err(&pdev->dev, "Codec device not registered\n");
483 return -ENODEV;
484 }
485
486 socdev->card->codec = wm8731_codec;
487 codec = wm8731_codec;
488
489 /* register pcms */
490 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
491 if (ret < 0) {
492 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
493 goto pcm_err;
494 }
495
496 snd_soc_add_controls(codec, wm8731_snd_controls,
497 ARRAY_SIZE(wm8731_snd_controls));
498 wm8731_add_widgets(codec);
499
500 return ret;
501
502pcm_err:
503 return ret;
504}
505
506/* power down chip */
507static int wm8731_remove(struct platform_device *pdev)
508{ 461{
509 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 462 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
510 463 int ret = 0, i;
511 snd_soc_free_pcms(socdev);
512 snd_soc_dapm_free(socdev);
513
514 return 0;
515}
516
517struct snd_soc_codec_device soc_codec_dev_wm8731 = {
518 .probe = wm8731_probe,
519 .remove = wm8731_remove,
520 .suspend = wm8731_suspend,
521 .resume = wm8731_resume,
522};
523EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
524
525static int wm8731_register(struct wm8731_priv *wm8731,
526 enum snd_soc_control_type control)
527{
528 int ret, i;
529 struct snd_soc_codec *codec = &wm8731->codec;
530
531 if (wm8731_codec) {
532 dev_err(codec->dev, "Another WM8731 is registered\n");
533 ret = -EINVAL;
534 goto err;
535 }
536
537 mutex_init(&codec->mutex);
538 INIT_LIST_HEAD(&codec->dapm_widgets);
539 INIT_LIST_HEAD(&codec->dapm_paths);
540
541 snd_soc_codec_set_drvdata(codec, wm8731);
542 codec->name = "WM8731";
543 codec->owner = THIS_MODULE;
544 codec->bias_level = SND_SOC_BIAS_OFF;
545 codec->set_bias_level = wm8731_set_bias_level;
546 codec->dai = &wm8731_dai;
547 codec->num_dai = 1;
548 codec->reg_cache_size = WM8731_CACHEREGNUM;
549 codec->reg_cache = &wm8731->reg_cache;
550 464
551 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg)); 465 codec->bias_level = SND_SOC_BIAS_OFF,
466 codec->control_data = wm8731->control_data;
552 467
553 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 468 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8731->control_type);
554 if (ret < 0) { 469 if (ret < 0) {
555 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 470 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
556 goto err; 471 return ret;
557 } 472 }
558 473
559 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) 474 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
@@ -563,7 +478,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
563 wm8731->supplies); 478 wm8731->supplies);
564 if (ret != 0) { 479 if (ret != 0) {
565 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 480 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
566 goto err; 481 return ret;
567 } 482 }
568 483
569 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), 484 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
@@ -579,8 +494,6 @@ static int wm8731_register(struct wm8731_priv *wm8731,
579 goto err_regulator_enable; 494 goto err_regulator_enable;
580 } 495 }
581 496
582 wm8731_dai.dev = codec->dev;
583
584 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 497 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
585 498
586 /* Latch the update bits */ 499 /* Latch the update bits */
@@ -592,78 +505,79 @@ static int wm8731_register(struct wm8731_priv *wm8731,
592 /* Disable bypass path by default */ 505 /* Disable bypass path by default */
593 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0); 506 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
594 507
595 wm8731_codec = codec; 508 snd_soc_add_controls(codec, wm8731_snd_controls,
596 509 ARRAY_SIZE(wm8731_snd_controls));
597 ret = snd_soc_register_codec(codec); 510 wm8731_add_widgets(codec);
598 if (ret != 0) {
599 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
600 goto err_regulator_enable;
601 }
602
603 ret = snd_soc_register_dai(&wm8731_dai);
604 if (ret != 0) {
605 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
606 snd_soc_unregister_codec(codec);
607 goto err_codec;
608 }
609 511
610 /* Regulators will have been enabled by bias management */ 512 /* Regulators will have been enabled by bias management */
611 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 513 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
612 514
613 return 0; 515 return 0;
614 516
615err_codec:
616 snd_soc_unregister_codec(codec);
617err_regulator_enable: 517err_regulator_enable:
618 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 518 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
619err_regulator_get: 519err_regulator_get:
620 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 520 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
621err: 521
622 kfree(wm8731); 522 kfree(wm8731);
623 return ret; 523 return ret;
624} 524}
625 525
626static void wm8731_unregister(struct wm8731_priv *wm8731) 526/* power down chip */
527static int wm8731_remove(struct snd_soc_codec *codec)
627{ 528{
628 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 529 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
629 snd_soc_unregister_dai(&wm8731_dai); 530
630 snd_soc_unregister_codec(&wm8731->codec); 531 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
532
533 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 534 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
632 kfree(wm8731); 535
633 wm8731_codec = NULL; 536 return 0;
634} 537}
635 538
539static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
540 .probe = wm8731_probe,
541 .remove = wm8731_remove,
542 .suspend = wm8731_suspend,
543 .resume = wm8731_resume,
544 .set_bias_level = wm8731_set_bias_level,
545 .reg_cache_size = sizeof(wm8731_reg),
546 .reg_word_size = sizeof(u16),
547 .reg_cache_default = wm8731_reg,
548};
549
636#if defined(CONFIG_SPI_MASTER) 550#if defined(CONFIG_SPI_MASTER)
637static int __devinit wm8731_spi_probe(struct spi_device *spi) 551static int __devinit wm8731_spi_probe(struct spi_device *spi)
638{ 552{
639 struct snd_soc_codec *codec;
640 struct wm8731_priv *wm8731; 553 struct wm8731_priv *wm8731;
554 int ret;
641 555
642 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 556 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
643 if (wm8731 == NULL) 557 if (wm8731 == NULL)
644 return -ENOMEM; 558 return -ENOMEM;
645 559
646 codec = &wm8731->codec; 560 wm8731->control_data = spi;
647 codec->control_data = spi; 561 wm8731->control_type = SND_SOC_SPI;
648 codec->dev = &spi->dev; 562 spi_set_drvdata(spi, wm8731);
649
650 dev_set_drvdata(&spi->dev, wm8731);
651 563
652 return wm8731_register(wm8731, SND_SOC_SPI); 564 ret = snd_soc_register_codec(&spi->dev,
565 &soc_codec_dev_wm8731, &wm8731_dai, 1);
566 if (ret < 0)
567 kfree(wm8731);
568 return ret;
653} 569}
654 570
655static int __devexit wm8731_spi_remove(struct spi_device *spi) 571static int __devexit wm8731_spi_remove(struct spi_device *spi)
656{ 572{
657 struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev); 573 snd_soc_unregister_codec(&spi->dev);
658 574 kfree(spi_get_drvdata(spi));
659 wm8731_unregister(wm8731);
660
661 return 0; 575 return 0;
662} 576}
663 577
664static struct spi_driver wm8731_spi_driver = { 578static struct spi_driver wm8731_spi_driver = {
665 .driver = { 579 .driver = {
666 .name = "wm8731", 580 .name = "wm8731-codec",
667 .bus = &spi_bus_type, 581 .bus = &spi_bus_type,
668 .owner = THIS_MODULE, 582 .owner = THIS_MODULE,
669 }, 583 },
@@ -677,26 +591,27 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
677 const struct i2c_device_id *id) 591 const struct i2c_device_id *id)
678{ 592{
679 struct wm8731_priv *wm8731; 593 struct wm8731_priv *wm8731;
680 struct snd_soc_codec *codec; 594 int ret;
681 595
682 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 596 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
683 if (wm8731 == NULL) 597 if (wm8731 == NULL)
684 return -ENOMEM; 598 return -ENOMEM;
685 599
686 codec = &wm8731->codec;
687
688 i2c_set_clientdata(i2c, wm8731); 600 i2c_set_clientdata(i2c, wm8731);
689 codec->control_data = i2c; 601 wm8731->control_data = i2c;
602 wm8731->control_type = SND_SOC_I2C;
690 603
691 codec->dev = &i2c->dev; 604 ret = snd_soc_register_codec(&i2c->dev,
692 605 &soc_codec_dev_wm8731, &wm8731_dai, 1);
693 return wm8731_register(wm8731, SND_SOC_I2C); 606 if (ret < 0)
607 kfree(wm8731);
608 return ret;
694} 609}
695 610
696static __devexit int wm8731_i2c_remove(struct i2c_client *client) 611static __devexit int wm8731_i2c_remove(struct i2c_client *client)
697{ 612{
698 struct wm8731_priv *wm8731 = i2c_get_clientdata(client); 613 snd_soc_unregister_codec(&client->dev);
699 wm8731_unregister(wm8731); 614 kfree(i2c_get_clientdata(client));
700 return 0; 615 return 0;
701} 616}
702 617
@@ -708,7 +623,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
708 623
709static struct i2c_driver wm8731_i2c_driver = { 624static struct i2c_driver wm8731_i2c_driver = {
710 .driver = { 625 .driver = {
711 .name = "wm8731", 626 .name = "wm8731-codec",
712 .owner = THIS_MODULE, 627 .owner = THIS_MODULE,
713 }, 628 },
714 .probe = wm8731_i2c_probe, 629 .probe = wm8731_i2c_probe,
@@ -719,7 +634,7 @@ static struct i2c_driver wm8731_i2c_driver = {
719 634
720static int __init wm8731_modinit(void) 635static int __init wm8731_modinit(void)
721{ 636{
722 int ret; 637 int ret = 0;
723#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 638#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
724 ret = i2c_add_driver(&wm8731_i2c_driver); 639 ret = i2c_add_driver(&wm8731_i2c_driver);
725 if (ret != 0) { 640 if (ret != 0) {
@@ -734,7 +649,7 @@ static int __init wm8731_modinit(void)
734 ret); 649 ret);
735 } 650 }
736#endif 651#endif
737 return 0; 652 return ret;
738} 653}
739module_init(wm8731_modinit); 654module_init(wm8731_modinit);
740 655
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h
index cd7b806e8ad..73a70e206ba 100644
--- a/sound/soc/codecs/wm8731.h
+++ b/sound/soc/codecs/wm8731.h
@@ -34,7 +34,4 @@
34#define WM8731_SYSCLK 0 34#define WM8731_SYSCLK 0
35#define WM8731_DAI 0 35#define WM8731_DAI 0
36 36
37extern struct snd_soc_dai wm8731_dai;
38extern struct snd_soc_codec_device soc_codec_dev_wm8731;
39
40#endif 37#endif
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index b9ea8904ad4..0c6d59e4d22 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -30,9 +30,6 @@
30 30
31#include "wm8741.h" 31#include "wm8741.h"
32 32
33static struct snd_soc_codec *wm8741_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8741;
35
36#define WM8741_NUM_SUPPLIES 2 33#define WM8741_NUM_SUPPLIES 2
37static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = { 34static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
38 "AVDD", 35 "AVDD",
@@ -43,7 +40,8 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
43 40
44/* codec private data */ 41/* codec private data */
45struct wm8741_priv { 42struct wm8741_priv {
46 struct snd_soc_codec codec; 43 enum snd_soc_control_type control_type;
44 void *control_data;
47 u16 reg_cache[WM8741_REGISTER_COUNT]; 45 u16 reg_cache[WM8741_REGISTER_COUNT];
48 struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; 46 struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
49 unsigned int sysclk; 47 unsigned int sysclk;
@@ -145,8 +143,7 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
145 struct snd_soc_dai *dai) 143 struct snd_soc_dai *dai)
146{ 144{
147 struct snd_soc_pcm_runtime *rtd = substream->private_data; 145 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct snd_soc_device *socdev = rtd->socdev; 146 struct snd_soc_codec *codec = rtd->codec;
149 struct snd_soc_codec *codec = socdev->card->codec;
150 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 147 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
151 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC; 148 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
152 int i; 149 int i;
@@ -314,7 +311,7 @@ static struct snd_soc_dai_ops wm8741_dai_ops = {
314 .set_fmt = wm8741_set_dai_fmt, 311 .set_fmt = wm8741_set_dai_fmt,
315}; 312};
316 313
317struct snd_soc_dai wm8741_dai = { 314static struct snd_soc_dai_driver wm8741_dai = {
318 .name = "WM8741", 315 .name = "WM8741",
319 .playback = { 316 .playback = {
320 .stream_name = "Playback", 317 .stream_name = "Playback",
@@ -325,13 +322,10 @@ struct snd_soc_dai wm8741_dai = {
325 }, 322 },
326 .ops = &wm8741_dai_ops, 323 .ops = &wm8741_dai_ops,
327}; 324};
328EXPORT_SYMBOL_GPL(wm8741_dai);
329 325
330#ifdef CONFIG_PM 326#ifdef CONFIG_PM
331static int wm8741_resume(struct platform_device *pdev) 327static int wm8741_resume(struct snd_soc_codec *codec)
332{ 328{
333 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
334 struct snd_soc_codec *codec = socdev->card->codec;
335 u16 *cache = codec->reg_cache; 329 u16 *cache = codec->reg_cache;
336 int i; 330 int i;
337 331
@@ -348,189 +342,105 @@ static int wm8741_resume(struct platform_device *pdev)
348#define wm8741_resume NULL 342#define wm8741_resume NULL
349#endif 343#endif
350 344
351static int wm8741_probe(struct platform_device *pdev) 345static int wm8741_probe(struct snd_soc_codec *codec)
352{ 346{
353 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 347 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
354 struct snd_soc_codec *codec;
355 int ret = 0; 348 int ret = 0;
356 349
357 if (wm8741_codec == NULL) { 350 codec->control_data = wm8741->control_data;
358 dev_err(&pdev->dev, "Codec device not registered\n"); 351 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
359 return -ENODEV; 352 if (ret != 0) {
353 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
354 return ret;
360 } 355 }
361 356
362 socdev->card->codec = wm8741_codec; 357 ret = wm8741_reset(codec);
363 codec = wm8741_codec;
364
365 /* register pcms */
366 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
367 if (ret < 0) { 358 if (ret < 0) {
368 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 359 dev_err(codec->dev, "Failed to issue reset\n");
369 goto pcm_err; 360 return ret;
370 } 361 }
371 362
363 /* Change some default settings - latch VU */
364 wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
365 wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
366 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
367 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
368
372 snd_soc_add_controls(codec, wm8741_snd_controls, 369 snd_soc_add_controls(codec, wm8741_snd_controls,
373 ARRAY_SIZE(wm8741_snd_controls)); 370 ARRAY_SIZE(wm8741_snd_controls));
374 wm8741_add_widgets(codec); 371 wm8741_add_widgets(codec);
375 372
373 dev_dbg(codec->dev, "Successful registration\n");
376 return ret; 374 return ret;
377
378pcm_err:
379 return ret;
380}
381
382static int wm8741_remove(struct platform_device *pdev)
383{
384 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
385
386 snd_soc_free_pcms(socdev);
387 snd_soc_dapm_free(socdev);
388
389 return 0;
390} 375}
391 376
392struct snd_soc_codec_device soc_codec_dev_wm8741 = { 377static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
393 .probe = wm8741_probe, 378 .probe = wm8741_probe,
394 .remove = wm8741_remove,
395 .resume = wm8741_resume, 379 .resume = wm8741_resume,
380 .reg_cache_size = sizeof(wm8741_reg_defaults),
381 .reg_word_size = sizeof(u16),
382 .reg_cache_default = &wm8741_reg_defaults,
396}; 383};
397EXPORT_SYMBOL_GPL(soc_codec_dev_wm8741);
398 384
399static int wm8741_register(struct wm8741_priv *wm8741, 385#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
400 enum snd_soc_control_type control) 386static int wm8741_i2c_probe(struct i2c_client *i2c,
387 const struct i2c_device_id *id)
401{ 388{
402 int ret; 389 struct wm8741_priv *wm8741;
403 struct snd_soc_codec *codec = &wm8741->codec; 390 int ret, i;
404 int i;
405
406 if (wm8741_codec) {
407 dev_err(codec->dev, "Another WM8741 is registered\n");
408 return -EINVAL;
409 }
410
411 mutex_init(&codec->mutex);
412 INIT_LIST_HEAD(&codec->dapm_widgets);
413 INIT_LIST_HEAD(&codec->dapm_paths);
414 391
415 snd_soc_codec_set_drvdata(codec, wm8741); 392 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
416 codec->name = "WM8741"; 393 if (wm8741 == NULL)
417 codec->owner = THIS_MODULE; 394 return -ENOMEM;
418 codec->bias_level = SND_SOC_BIAS_OFF;
419 codec->set_bias_level = NULL;
420 codec->dai = &wm8741_dai;
421 codec->num_dai = 1;
422 codec->reg_cache_size = WM8741_REGISTER_COUNT;
423 codec->reg_cache = &wm8741->reg_cache;
424 395
425 wm8741->rate_constraint.list = &wm8741->rate_constraint_list[0]; 396 wm8741->rate_constraint.list = &wm8741->rate_constraint_list[0];
426 wm8741->rate_constraint.count = 397 wm8741->rate_constraint.count =
427 ARRAY_SIZE(wm8741->rate_constraint_list); 398 ARRAY_SIZE(wm8741->rate_constraint_list);
428 399
429 memcpy(codec->reg_cache, wm8741_reg_defaults,
430 sizeof(wm8741->reg_cache));
431
432 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
433 if (ret != 0) {
434 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
435 goto err;
436 }
437
438 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++) 400 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
439 wm8741->supplies[i].supply = wm8741_supply_names[i]; 401 wm8741->supplies[i].supply = wm8741_supply_names[i];
440 402
441 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies), 403 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),
442 wm8741->supplies); 404 wm8741->supplies);
443 if (ret != 0) { 405 if (ret != 0) {
444 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 406 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
445 goto err; 407 goto err;
446 } 408 }
447 409
448 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies), 410 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
449 wm8741->supplies); 411 wm8741->supplies);
450 if (ret != 0) { 412 if (ret != 0) {
451 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 413 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
452 goto err_get; 414 goto err_get;
453 } 415 }
454 416
455 ret = wm8741_reset(codec); 417 i2c_set_clientdata(i2c, wm8741);
456 if (ret < 0) { 418 wm8741->control_data = i2c;
457 dev_err(codec->dev, "Failed to issue reset\n"); 419 wm8741->control_type = SND_SOC_I2C;
458 goto err_enable;
459 }
460
461 wm8741_dai.dev = codec->dev;
462
463 /* Change some default settings - latch VU */
464 wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
465 wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
466 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
467 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
468
469 wm8741_codec = codec;
470
471 ret = snd_soc_register_codec(codec);
472 if (ret != 0) {
473 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
474 return ret;
475 }
476
477 ret = snd_soc_register_dai(&wm8741_dai);
478 if (ret != 0) {
479 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
480 snd_soc_unregister_codec(codec);
481 return ret;
482 }
483 420
484 dev_dbg(codec->dev, "Successful registration\n"); 421 ret = snd_soc_register_codec(&i2c->dev,
485 return 0; 422 &soc_codec_dev_wm8741, &wm8741_dai, 1);
423 if (ret < 0)
424 goto err_enable;
425 return ret;
486 426
487err_enable: 427err_enable:
488 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); 428 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
489 429
490err_get: 430err_get:
491 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); 431 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
492
493err: 432err:
494 kfree(wm8741); 433 kfree(wm8741);
495 return ret; 434 return ret;
496} 435}
497 436
498static void wm8741_unregister(struct wm8741_priv *wm8741) 437static int wm8741_i2c_remove(struct i2c_client *client)
499{
500 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
501
502 snd_soc_unregister_dai(&wm8741_dai);
503 snd_soc_unregister_codec(&wm8741->codec);
504 kfree(wm8741);
505 wm8741_codec = NULL;
506}
507
508#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
509static __devinit int wm8741_i2c_probe(struct i2c_client *i2c,
510 const struct i2c_device_id *id)
511{
512 struct wm8741_priv *wm8741;
513 struct snd_soc_codec *codec;
514
515 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
516 if (wm8741 == NULL)
517 return -ENOMEM;
518
519 codec = &wm8741->codec;
520 codec->hw_write = (hw_write_t)i2c_master_send;
521
522 i2c_set_clientdata(i2c, wm8741);
523 codec->control_data = i2c;
524
525 codec->dev = &i2c->dev;
526
527 return wm8741_register(wm8741, SND_SOC_I2C);
528}
529
530static __devexit int wm8741_i2c_remove(struct i2c_client *client)
531{ 438{
532 struct wm8741_priv *wm8741 = i2c_get_clientdata(client); 439 struct wm8741_priv *wm8741 = i2c_get_clientdata(client);
533 wm8741_unregister(wm8741); 440
441 snd_soc_unregister_codec(&client->dev);
442 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
443 kfree(i2c_get_clientdata(client));
534 return 0; 444 return 0;
535} 445}
536 446
@@ -540,29 +450,29 @@ static const struct i2c_device_id wm8741_i2c_id[] = {
540}; 450};
541MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id); 451MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
542 452
543
544static struct i2c_driver wm8741_i2c_driver = { 453static struct i2c_driver wm8741_i2c_driver = {
545 .driver = { 454 .driver = {
546 .name = "WM8741", 455 .name = "wm8741-codec",
547 .owner = THIS_MODULE, 456 .owner = THIS_MODULE,
548 }, 457 },
549 .probe = wm8741_i2c_probe, 458 .probe = wm8741_i2c_probe,
550 .remove = __devexit_p(wm8741_i2c_remove), 459 .remove = wm8741_i2c_remove,
551 .id_table = wm8741_i2c_id, 460 .id_table = wm8741_i2c_id,
552}; 461};
553#endif 462#endif
554 463
555static int __init wm8741_modinit(void) 464static int __init wm8741_modinit(void)
556{ 465{
557 int ret; 466 int ret = 0;
467
558#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 468#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
559 ret = i2c_add_driver(&wm8741_i2c_driver); 469 ret = i2c_add_driver(&wm8741_i2c_driver);
560 if (ret != 0) { 470 if (ret != 0) {
561 printk(KERN_ERR "Failed to register WM8741 I2C driver: %d\n", 471 pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
562 ret);
563 } 472 }
564#endif 473#endif
565 return 0; 474
475 return ret;
566} 476}
567module_init(wm8741_modinit); 477module_init(wm8741_modinit);
568 478
diff --git a/sound/soc/codecs/wm8741.h b/sound/soc/codecs/wm8741.h
index fdef6ecd1f6..56c1b1d4a68 100644
--- a/sound/soc/codecs/wm8741.h
+++ b/sound/soc/codecs/wm8741.h
@@ -208,7 +208,4 @@
208 208
209#define WM8741_SYSCLK 0 209#define WM8741_SYSCLK 0
210 210
211extern struct snd_soc_dai wm8741_dai;
212extern struct snd_soc_codec_device soc_codec_dev_wm8741;
213
214#endif 211#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index e2c05e3e323..89863a5bc83 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -52,7 +52,8 @@ static const u16 wm8750_reg[] = {
52/* codec private data */ 52/* codec private data */
53struct wm8750_priv { 53struct wm8750_priv {
54 unsigned int sysclk; 54 unsigned int sysclk;
55 struct snd_soc_codec codec; 55 enum snd_soc_control_type control_type;
56 void *control_data;
56 u16 reg_cache[ARRAY_SIZE(wm8750_reg)]; 57 u16 reg_cache[ARRAY_SIZE(wm8750_reg)];
57}; 58};
58 59
@@ -560,8 +561,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
560 struct snd_soc_dai *dai) 561 struct snd_soc_dai *dai)
561{ 562{
562 struct snd_soc_pcm_runtime *rtd = substream->private_data; 563 struct snd_soc_pcm_runtime *rtd = substream->private_data;
563 struct snd_soc_device *socdev = rtd->socdev; 564 struct snd_soc_codec *codec = rtd->codec;
564 struct snd_soc_codec *codec = socdev->card->codec;
565 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); 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;
@@ -649,8 +649,8 @@ static struct snd_soc_dai_ops wm8750_dai_ops = {
649 .set_sysclk = wm8750_set_dai_sysclk, 649 .set_sysclk = wm8750_set_dai_sysclk,
650}; 650};
651 651
652struct snd_soc_dai wm8750_dai = { 652static struct snd_soc_dai_driver wm8750_dai = {
653 .name = "WM8750", 653 .name = "wm8750-hifi",
654 .playback = { 654 .playback = {
655 .stream_name = "Playback", 655 .stream_name = "Playback",
656 .channels_min = 1, 656 .channels_min = 1,
@@ -665,21 +665,15 @@ struct snd_soc_dai wm8750_dai = {
665 .formats = WM8750_FORMATS,}, 665 .formats = WM8750_FORMATS,},
666 .ops = &wm8750_dai_ops, 666 .ops = &wm8750_dai_ops,
667}; 667};
668EXPORT_SYMBOL_GPL(wm8750_dai);
669 668
670static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 669static int wm8750_suspend(struct snd_soc_codec *codec, pm_message_t state)
671{ 670{
672 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
673 struct snd_soc_codec *codec = socdev->card->codec;
674
675 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); 671 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
676 return 0; 672 return 0;
677} 673}
678 674
679static int wm8750_resume(struct platform_device *pdev) 675static int wm8750_resume(struct snd_soc_codec *codec)
680{ 676{
681 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
682 struct snd_soc_codec *codec = socdev->card->codec;
683 int i; 677 int i;
684 u8 data[2]; 678 u8 data[2];
685 u16 *cache = codec->reg_cache; 679 u16 *cache = codec->reg_cache;
@@ -698,100 +692,22 @@ static int wm8750_resume(struct platform_device *pdev)
698 return 0; 692 return 0;
699} 693}
700 694
701static struct snd_soc_codec *wm8750_codec; 695static int wm8750_probe(struct snd_soc_codec *codec)
702
703static int wm8750_probe(struct platform_device *pdev)
704{ 696{
705 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 697 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
706 struct snd_soc_codec *codec; 698 int reg, ret;
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;
722 }
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
742 return 0;
743}
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
753/*
754 * initialise the WM8750 driver
755 * register the mixer and dsp interfaces with the kernel
756 */
757static int wm8750_register(struct wm8750_priv *wm8750,
758 enum snd_soc_control_type control)
759{
760 struct snd_soc_codec *codec = &wm8750->codec;
761 int reg, ret = 0;
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
773 codec->name = "WM8750";
774 codec->owner = THIS_MODULE;
775 codec->bias_level = SND_SOC_BIAS_STANDBY;
776 codec->set_bias_level = wm8750_set_bias_level;
777 codec->dai = &wm8750_dai;
778 codec->num_dai = 1;
779 codec->reg_cache_size = ARRAY_SIZE(wm8750->reg_cache) + 1;
780 codec->reg_cache = &wm8750->reg_cache;
781 snd_soc_codec_set_drvdata(codec, wm8750);
782
783 memcpy(codec->reg_cache, wm8750_reg, sizeof(wm8750->reg_cache));
784 699
785 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 700 codec->control_data = wm8750->control_data;
701 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type);
786 if (ret < 0) { 702 if (ret < 0) {
787 printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret); 703 printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
788 goto err; 704 return ret;
789 } 705 }
790 706
791 ret = wm8750_reset(codec); 707 ret = wm8750_reset(codec);
792 if (ret < 0) { 708 if (ret < 0) {
793 printk(KERN_ERR "wm8750: failed to reset: %d\n", ret); 709 printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
794 goto err; 710 return ret;
795 } 711 }
796 712
797 /* charge output caps */ 713 /* charge output caps */
@@ -815,150 +731,133 @@ static int wm8750_register(struct wm8750_priv *wm8750,
815 reg = snd_soc_read(codec, WM8750_RINVOL); 731 reg = snd_soc_read(codec, WM8750_RINVOL);
816 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100); 732 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
817 733
818 wm8750_codec = codec; 734 snd_soc_add_controls(codec, wm8750_snd_controls,
819 735 ARRAY_SIZE(wm8750_snd_controls));
820 ret = snd_soc_register_codec(codec); 736 wm8750_add_widgets(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);
836err:
837 kfree(wm8750);
838 return ret; 737 return ret;
839} 738}
840 739
841static void wm8750_unregister(struct wm8750_priv *wm8750) 740static int wm8750_remove(struct snd_soc_codec *codec)
842{ 741{
843 wm8750_set_bias_level(&wm8750->codec, SND_SOC_BIAS_OFF); 742 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
844 snd_soc_unregister_dais(&wm8750_dai, 1); 743 return 0;
845 snd_soc_unregister_codec(&wm8750->codec);
846 kfree(wm8750);
847 wm8750_codec = NULL;
848} 744}
849 745
850#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 746static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
851 747 .probe = wm8750_probe,
852/* 748 .remove = wm8750_remove,
853 * WM8750 2 wire address is determined by GPIO5 749 .suspend = wm8750_suspend,
854 * state during powerup. 750 .resume = wm8750_resume,
855 * low = 0x1a 751 .set_bias_level = wm8750_set_bias_level,
856 * high = 0x1b 752 .reg_cache_size = sizeof(wm8750_reg),
857 */ 753 .reg_word_size = sizeof(u16),
754 .reg_cache_default = wm8750_reg,
755};
858 756
859static int wm8750_i2c_probe(struct i2c_client *i2c, 757#if defined(CONFIG_SPI_MASTER)
860 const struct i2c_device_id *id) 758static int __devinit wm8750_spi_probe(struct spi_device *spi)
861{ 759{
862 struct snd_soc_codec *codec;
863 struct wm8750_priv *wm8750; 760 struct wm8750_priv *wm8750;
761 int ret;
864 762
865 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL); 763 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
866 if (wm8750 == NULL) 764 if (wm8750 == NULL)
867 return -ENOMEM; 765 return -ENOMEM;
868 766
869 codec = &wm8750->codec; 767 wm8750->control_data = spi;
870 codec->control_data = i2c; 768 wm8750->control_type = SND_SOC_SPI;
871 i2c_set_clientdata(i2c, wm8750); 769 spi_set_drvdata(spi, wm8750);
872
873 codec->dev = &i2c->dev;
874 770
875 return wm8750_register(wm8750, SND_SOC_I2C); 771 ret = snd_soc_register_codec(&spi->dev,
772 &soc_codec_dev_wm8750, &wm8750_dai, 1);
773 if (ret < 0)
774 kfree(wm8750);
775 return ret;
876} 776}
877 777
878static int wm8750_i2c_remove(struct i2c_client *client) 778static int __devexit wm8750_spi_remove(struct spi_device *spi)
879{ 779{
880 struct wm8750_priv *wm8750 = i2c_get_clientdata(client); 780 snd_soc_unregister_codec(&spi->dev);
881 wm8750_unregister(wm8750); 781 kfree(spi_get_drvdata(spi));
882 return 0; 782 return 0;
883} 783}
884 784
885static const struct i2c_device_id wm8750_i2c_id[] = { 785static struct spi_driver wm8750_spi_driver = {
886 { "wm8750", 0 },
887 { "wm8987", 0 }, /* WM8987 is register compatible with WM8750 */
888 { }
889};
890MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
891
892static struct i2c_driver wm8750_i2c_driver = {
893 .driver = { 786 .driver = {
894 .name = "WM8750 I2C Codec", 787 .name = "wm8750-codec",
895 .owner = THIS_MODULE, 788 .bus = &spi_bus_type,
789 .owner = THIS_MODULE,
896 }, 790 },
897 .probe = wm8750_i2c_probe, 791 .probe = wm8750_spi_probe,
898 .remove = wm8750_i2c_remove, 792 .remove = __devexit_p(wm8750_spi_remove),
899 .id_table = wm8750_i2c_id,
900}; 793};
901#endif 794#endif /* CONFIG_SPI_MASTER */
902 795
903#if defined(CONFIG_SPI_MASTER) 796#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
904static int __devinit wm8750_spi_probe(struct spi_device *spi) 797static __devinit int wm8750_i2c_probe(struct i2c_client *i2c,
798 const struct i2c_device_id *id)
905{ 799{
906 struct snd_soc_codec *codec;
907 struct wm8750_priv *wm8750; 800 struct wm8750_priv *wm8750;
801 int ret;
908 802
909 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL); 803 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
910 if (wm8750 == NULL) 804 if (wm8750 == NULL)
911 return -ENOMEM; 805 return -ENOMEM;
912 806
913 codec = &wm8750->codec; 807 i2c_set_clientdata(i2c, wm8750);
914 codec->control_data = spi; 808 wm8750->control_data = i2c;
915 codec->dev = &spi->dev; 809 wm8750->control_type = SND_SOC_I2C;
916
917 dev_set_drvdata(&spi->dev, wm8750);
918 810
919 return wm8750_register(wm8750, SND_SOC_SPI); 811 ret = snd_soc_register_codec(&i2c->dev,
812 &soc_codec_dev_wm8750, &wm8750_dai, 1);
813 if (ret < 0)
814 kfree(wm8750);
815 return ret;
920} 816}
921 817
922static int __devexit wm8750_spi_remove(struct spi_device *spi) 818static __devexit int wm8750_i2c_remove(struct i2c_client *client)
923{ 819{
924 struct wm8750_priv *wm8750 = dev_get_drvdata(&spi->dev); 820 snd_soc_unregister_codec(&client->dev);
925 wm8750_unregister(wm8750); 821 kfree(i2c_get_clientdata(client));
926 return 0; 822 return 0;
927} 823}
928 824
929static const struct spi_device_id wm8750_spi_id[] = { 825static const struct i2c_device_id wm8750_i2c_id[] = {
930 { "wm8750", 0 }, 826 { "wm8750", 0 },
931 { "wm8987", 0 }, 827 { "wm8987", 0 },
932 { } 828 { }
933}; 829};
934MODULE_DEVICE_TABLE(spi, wm8750_spi_id); 830MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
935 831
936static struct spi_driver wm8750_spi_driver = { 832static struct i2c_driver wm8750_i2c_driver = {
937 .driver = { 833 .driver = {
938 .name = "WM8750 SPI Codec", 834 .name = "wm8750-codec",
939 .bus = &spi_bus_type, 835 .owner = THIS_MODULE,
940 .owner = THIS_MODULE,
941 }, 836 },
942 .probe = wm8750_spi_probe, 837 .probe = wm8750_i2c_probe,
943 .remove = __devexit_p(wm8750_spi_remove), 838 .remove = __devexit_p(wm8750_i2c_remove),
944 .id_table = wm8750_spi_id, 839 .id_table = wm8750_i2c_id,
945}; 840};
946#endif 841#endif
947 842
948static int __init wm8750_modinit(void) 843static int __init wm8750_modinit(void)
949{ 844{
950 int ret; 845 int ret = 0;
951#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 846#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
952 ret = i2c_add_driver(&wm8750_i2c_driver); 847 ret = i2c_add_driver(&wm8750_i2c_driver);
953 if (ret != 0) 848 if (ret != 0) {
954 pr_err("Failed to register WM8750 I2C driver: %d\n", ret); 849 printk(KERN_ERR "Failed to register wm8750 I2C driver: %d\n",
850 ret);
851 }
955#endif 852#endif
956#if defined(CONFIG_SPI_MASTER) 853#if defined(CONFIG_SPI_MASTER)
957 ret = spi_register_driver(&wm8750_spi_driver); 854 ret = spi_register_driver(&wm8750_spi_driver);
958 if (ret != 0) 855 if (ret != 0) {
959 pr_err("Failed to register WM8750 SPI driver: %d\n", ret); 856 printk(KERN_ERR "Failed to register wm8750 SPI driver: %d\n",
857 ret);
858 }
960#endif 859#endif
961 return 0; 860 return ret;
962} 861}
963module_init(wm8750_modinit); 862module_init(wm8750_modinit);
964 863
diff --git a/sound/soc/codecs/wm8750.h b/sound/soc/codecs/wm8750.h
index 1dc100e19cf..121427c047f 100644
--- a/sound/soc/codecs/wm8750.h
+++ b/sound/soc/codecs/wm8750.h
@@ -57,13 +57,4 @@
57 57
58#define WM8750_SYSCLK 0 58#define WM8750_SYSCLK 0
59 59
60struct wm8750_setup_data {
61 int spi;
62 int i2c_bus;
63 unsigned short i2c_address;
64};
65
66extern struct snd_soc_dai wm8750_dai;
67extern struct snd_soc_codec_device soc_codec_dev_wm8750;
68
69#endif 60#endif
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index b59f349c521..976e408b361 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -57,7 +57,7 @@ module_param(caps_charge, int, 0);
57MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); 57MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
58 58
59static void wm8753_set_dai_mode(struct snd_soc_codec *codec, 59static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
60 unsigned int mode); 60 struct snd_soc_dai *dai, unsigned int hifi);
61 61
62/* 62/*
63 * wm8753 register cache 63 * wm8753 register cache
@@ -85,10 +85,12 @@ static const u16 wm8753_reg[] = {
85 85
86/* codec private data */ 86/* codec private data */
87struct wm8753_priv { 87struct wm8753_priv {
88 enum snd_soc_control_type control_type;
89 void *control_data;
88 unsigned int sysclk; 90 unsigned int sysclk;
89 unsigned int pcmclk; 91 unsigned int pcmclk;
90 struct snd_soc_codec codec;
91 u16 reg_cache[ARRAY_SIZE(wm8753_reg)]; 92 u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
93 int dai_func;
92}; 94};
93 95
94/* 96/*
@@ -228,6 +230,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
228{ 230{
229 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 231 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
230 int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); 232 int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
233 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
231 234
232 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0]) 235 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
233 return 0; 236 return 0;
@@ -235,8 +238,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
235 mode &= 0xfff3; 238 mode &= 0xfff3;
236 mode |= (ucontrol->value.integer.value[0] << 2); 239 mode |= (ucontrol->value.integer.value[0] << 2);
237 240
238 wm8753_write(codec, WM8753_IOCTL, mode); 241 wm8753->dai_func = ucontrol->value.integer.value[0];
239 wm8753_set_dai_mode(codec, ucontrol->value.integer.value[0]);
240 return 1; 242 return 1;
241} 243}
242 244
@@ -904,6 +906,13 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
904 return 0; 906 return 0;
905} 907}
906 908
909static int wm8753_pcm_startup(struct snd_pcm_substream *substream,
910 struct snd_soc_dai *dai)
911{
912 wm8753_set_dai_mode(dai->codec, dai, 0);
913 return 0;
914}
915
907/* 916/*
908 * Set PCM DAI bit size and sample rate. 917 * Set PCM DAI bit size and sample rate.
909 */ 918 */
@@ -912,8 +921,7 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
912 struct snd_soc_dai *dai) 921 struct snd_soc_dai *dai)
913{ 922{
914 struct snd_soc_pcm_runtime *rtd = substream->private_data; 923 struct snd_soc_pcm_runtime *rtd = substream->private_data;
915 struct snd_soc_device *socdev = rtd->socdev; 924 struct snd_soc_codec *codec = rtd->codec;
916 struct snd_soc_codec *codec = socdev->card->codec;
917 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 925 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
918 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; 926 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
919 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; 927 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
@@ -1138,6 +1146,13 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1138 return 0; 1146 return 0;
1139} 1147}
1140 1148
1149static int wm8753_i2s_startup(struct snd_pcm_substream *substream,
1150 struct snd_soc_dai *dai)
1151{
1152 wm8753_set_dai_mode(dai->codec, dai, 1);
1153 return 0;
1154}
1155
1141/* 1156/*
1142 * Set PCM DAI bit size and sample rate. 1157 * Set PCM DAI bit size and sample rate.
1143 */ 1158 */
@@ -1146,8 +1161,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1146 struct snd_soc_dai *dai) 1161 struct snd_soc_dai *dai)
1147{ 1162{
1148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1163 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1149 struct snd_soc_device *socdev = rtd->socdev; 1164 struct snd_soc_codec *codec = rtd->codec;
1150 struct snd_soc_codec *codec = socdev->card->codec;
1151 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1165 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1152 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; 1166 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
1153 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; 1167 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
@@ -1240,12 +1254,12 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1240{ 1254{
1241 struct snd_soc_codec *codec = dai->codec; 1255 struct snd_soc_codec *codec = dai->codec;
1242 u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7; 1256 u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
1257 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1243 1258
1244 /* the digital mute covers the HiFi and Voice DAC's on the WM8753. 1259 /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
1245 * make sure we check if they are not both active when we mute */ 1260 * make sure we check if they are not both active when we mute */
1246 if (mute && dai->id == 1) { 1261 if (mute && wm8753->dai_func == 1) {
1247 if (!wm8753_dai[WM8753_DAI_VOICE].playback.active || 1262 if (!codec->active)
1248 !wm8753_dai[WM8753_DAI_HIFI].playback.active)
1249 wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); 1263 wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
1250 } else { 1264 } else {
1251 if (mute) 1265 if (mute)
@@ -1303,6 +1317,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1303 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture 1317 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
1304 */ 1318 */
1305static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = { 1319static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = {
1320 .startup = wm8753_i2s_startup,
1306 .hw_params = wm8753_i2s_hw_params, 1321 .hw_params = wm8753_i2s_hw_params,
1307 .digital_mute = wm8753_mute, 1322 .digital_mute = wm8753_mute,
1308 .set_fmt = wm8753_mode1h_set_dai_fmt, 1323 .set_fmt = wm8753_mode1h_set_dai_fmt,
@@ -1312,6 +1327,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = {
1312}; 1327};
1313 1328
1314static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = { 1329static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
1330 .startup = wm8753_pcm_startup,
1315 .hw_params = wm8753_pcm_hw_params, 1331 .hw_params = wm8753_pcm_hw_params,
1316 .digital_mute = wm8753_mute, 1332 .digital_mute = wm8753_mute,
1317 .set_fmt = wm8753_mode1v_set_dai_fmt, 1333 .set_fmt = wm8753_mode1v_set_dai_fmt,
@@ -1321,6 +1337,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
1321}; 1337};
1322 1338
1323static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = { 1339static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = {
1340 .startup = wm8753_pcm_startup,
1324 .hw_params = wm8753_pcm_hw_params, 1341 .hw_params = wm8753_pcm_hw_params,
1325 .digital_mute = wm8753_mute, 1342 .digital_mute = wm8753_mute,
1326 .set_fmt = wm8753_mode2_set_dai_fmt, 1343 .set_fmt = wm8753_mode2_set_dai_fmt,
@@ -1330,6 +1347,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = {
1330}; 1347};
1331 1348
1332static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = { 1349static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = {
1350 .startup = wm8753_i2s_startup,
1333 .hw_params = wm8753_i2s_hw_params, 1351 .hw_params = wm8753_i2s_hw_params,
1334 .digital_mute = wm8753_mute, 1352 .digital_mute = wm8753_mute,
1335 .set_fmt = wm8753_mode3_4_set_dai_fmt, 1353 .set_fmt = wm8753_mode3_4_set_dai_fmt,
@@ -1339,6 +1357,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = {
1339}; 1357};
1340 1358
1341static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = { 1359static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
1360 .startup = wm8753_i2s_startup,
1342 .hw_params = wm8753_i2s_hw_params, 1361 .hw_params = wm8753_i2s_hw_params,
1343 .digital_mute = wm8753_mute, 1362 .digital_mute = wm8753_mute,
1344 .set_fmt = wm8753_mode3_4_set_dai_fmt, 1363 .set_fmt = wm8753_mode3_4_set_dai_fmt,
@@ -1347,10 +1366,9 @@ static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
1347 .set_sysclk = wm8753_set_dai_sysclk, 1366 .set_sysclk = wm8753_set_dai_sysclk,
1348}; 1367};
1349 1368
1350static const struct snd_soc_dai wm8753_all_dai[] = { 1369static struct snd_soc_dai_driver wm8753_all_dai[] = {
1351/* DAI HiFi mode 1 */ 1370/* DAI HiFi mode 1 */
1352{ .name = "WM8753 HiFi", 1371{ .name = "wm8753-hifi",
1353 .id = 1,
1354 .playback = { 1372 .playback = {
1355 .stream_name = "HiFi Playback", 1373 .stream_name = "HiFi Playback",
1356 .channels_min = 1, 1374 .channels_min = 1,
@@ -1366,8 +1384,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1366 .ops = &wm8753_dai_ops_hifi_mode1, 1384 .ops = &wm8753_dai_ops_hifi_mode1,
1367}, 1385},
1368/* DAI Voice mode 1 */ 1386/* DAI Voice mode 1 */
1369{ .name = "WM8753 Voice", 1387{ .name = "wm8753-voice",
1370 .id = 1,
1371 .playback = { 1388 .playback = {
1372 .stream_name = "Voice Playback", 1389 .stream_name = "Voice Playback",
1373 .channels_min = 1, 1390 .channels_min = 1,
@@ -1383,12 +1400,10 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1383 .ops = &wm8753_dai_ops_voice_mode1, 1400 .ops = &wm8753_dai_ops_voice_mode1,
1384}, 1401},
1385/* DAI HiFi mode 2 - dummy */ 1402/* DAI HiFi mode 2 - dummy */
1386{ .name = "WM8753 HiFi", 1403{ .name = "wm8753-hifi",
1387 .id = 2,
1388}, 1404},
1389/* DAI Voice mode 2 */ 1405/* DAI Voice mode 2 */
1390{ .name = "WM8753 Voice", 1406{ .name = "wm8753-voice",
1391 .id = 2,
1392 .playback = { 1407 .playback = {
1393 .stream_name = "Voice Playback", 1408 .stream_name = "Voice Playback",
1394 .channels_min = 1, 1409 .channels_min = 1,
@@ -1404,8 +1419,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1404 .ops = &wm8753_dai_ops_voice_mode2, 1419 .ops = &wm8753_dai_ops_voice_mode2,
1405}, 1420},
1406/* DAI HiFi mode 3 */ 1421/* DAI HiFi mode 3 */
1407{ .name = "WM8753 HiFi", 1422{ .name = "wm8753-hifi",
1408 .id = 3,
1409 .playback = { 1423 .playback = {
1410 .stream_name = "HiFi Playback", 1424 .stream_name = "HiFi Playback",
1411 .channels_min = 1, 1425 .channels_min = 1,
@@ -1421,12 +1435,10 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1421 .ops = &wm8753_dai_ops_hifi_mode3, 1435 .ops = &wm8753_dai_ops_hifi_mode3,
1422}, 1436},
1423/* DAI Voice mode 3 - dummy */ 1437/* DAI Voice mode 3 - dummy */
1424{ .name = "WM8753 Voice", 1438{ .name = "wm8753-voice",
1425 .id = 3,
1426}, 1439},
1427/* DAI HiFi mode 4 */ 1440/* DAI HiFi mode 4 */
1428{ .name = "WM8753 HiFi", 1441{ .name = "wm8753-hifi",
1429 .id = 4,
1430 .playback = { 1442 .playback = {
1431 .stream_name = "HiFi Playback", 1443 .stream_name = "HiFi Playback",
1432 .channels_min = 1, 1444 .channels_min = 1,
@@ -1442,58 +1454,31 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1442 .ops = &wm8753_dai_ops_hifi_mode4, 1454 .ops = &wm8753_dai_ops_hifi_mode4,
1443}, 1455},
1444/* DAI Voice mode 4 - dummy */ 1456/* DAI Voice mode 4 - dummy */
1445{ .name = "WM8753 Voice", 1457{ .name = "wm8753-voice",
1446 .id = 4,
1447}, 1458},
1448}; 1459};
1449 1460
1450struct snd_soc_dai wm8753_dai[] = { 1461static struct snd_soc_dai_driver wm8753_dai[] = {
1451 { 1462 {
1452 .name = "WM8753 DAI 0", 1463 .name = "wm8753-aif0",
1453 }, 1464 },
1454 { 1465 {
1455 .name = "WM8753 DAI 1", 1466 .name = "wm8753-aif1",
1456 }, 1467 },
1457}; 1468};
1458EXPORT_SYMBOL_GPL(wm8753_dai);
1459 1469
1460static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode) 1470static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
1471 struct snd_soc_dai *dai, unsigned int hifi)
1461{ 1472{
1462 if (mode < 4) { 1473 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1463 int playback_active, capture_active, codec_active, pop_wait; 1474
1464 void *private_data; 1475 if (wm8753->dai_func < 4) {
1465 struct list_head list; 1476 if (hifi)
1466 1477 dai->driver = &wm8753_all_dai[wm8753->dai_func << 1];
1467 playback_active = wm8753_dai[0].playback.active; 1478 else
1468 capture_active = wm8753_dai[0].capture.active; 1479 dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
1469 codec_active = wm8753_dai[0].active;
1470 private_data = wm8753_dai[0].private_data;
1471 pop_wait = wm8753_dai[0].pop_wait;
1472 list = wm8753_dai[0].list;
1473 wm8753_dai[0] = wm8753_all_dai[mode << 1];
1474 wm8753_dai[0].playback.active = playback_active;
1475 wm8753_dai[0].capture.active = capture_active;
1476 wm8753_dai[0].active = codec_active;
1477 wm8753_dai[0].private_data = private_data;
1478 wm8753_dai[0].pop_wait = pop_wait;
1479 wm8753_dai[0].list = list;
1480
1481 playback_active = wm8753_dai[1].playback.active;
1482 capture_active = wm8753_dai[1].capture.active;
1483 codec_active = wm8753_dai[1].active;
1484 private_data = wm8753_dai[1].private_data;
1485 pop_wait = wm8753_dai[1].pop_wait;
1486 list = wm8753_dai[1].list;
1487 wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1];
1488 wm8753_dai[1].playback.active = playback_active;
1489 wm8753_dai[1].capture.active = capture_active;
1490 wm8753_dai[1].active = codec_active;
1491 wm8753_dai[1].private_data = private_data;
1492 wm8753_dai[1].pop_wait = pop_wait;
1493 wm8753_dai[1].list = list;
1494 } 1480 }
1495 wm8753_dai[0].codec = codec; 1481 wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func);
1496 wm8753_dai[1].codec = codec;
1497} 1482}
1498 1483
1499static void wm8753_work(struct work_struct *work) 1484static void wm8753_work(struct work_struct *work)
@@ -1503,19 +1488,14 @@ static void wm8753_work(struct work_struct *work)
1503 wm8753_set_bias_level(codec, codec->bias_level); 1488 wm8753_set_bias_level(codec, codec->bias_level);
1504} 1489}
1505 1490
1506static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) 1491static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
1507{ 1492{
1508 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1509 struct snd_soc_codec *codec = socdev->card->codec;
1510
1511 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1493 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1512 return 0; 1494 return 0;
1513} 1495}
1514 1496
1515static int wm8753_resume(struct platform_device *pdev) 1497static int wm8753_resume(struct snd_soc_codec *codec)
1516{ 1498{
1517 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1518 struct snd_soc_codec *codec = socdev->card->codec;
1519 int i; 1499 int i;
1520 u8 data[2]; 1500 u8 data[2];
1521 u16 *cache = codec->reg_cache; 1501 u16 *cache = codec->reg_cache;
@@ -1547,41 +1527,6 @@ static int wm8753_resume(struct platform_device *pdev)
1547 return 0; 1527 return 0;
1548} 1528}
1549 1529
1550static struct snd_soc_codec *wm8753_codec;
1551
1552static int wm8753_probe(struct platform_device *pdev)
1553{
1554 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1555 struct snd_soc_codec *codec;
1556 int ret = 0;
1557
1558 if (!wm8753_codec) {
1559 dev_err(&pdev->dev, "WM8753 codec not yet registered\n");
1560 return -EINVAL;
1561 }
1562
1563 socdev->card->codec = wm8753_codec;
1564 codec = wm8753_codec;
1565
1566 wm8753_set_dai_mode(codec, 0);
1567
1568 /* register pcms */
1569 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1570 if (ret < 0) {
1571 printk(KERN_ERR "wm8753: failed to create pcms\n");
1572 goto pcm_err;
1573 }
1574
1575 snd_soc_add_controls(codec, wm8753_snd_controls,
1576 ARRAY_SIZE(wm8753_snd_controls));
1577 wm8753_add_widgets(codec);
1578
1579 return 0;
1580
1581pcm_err:
1582 return ret;
1583}
1584
1585/* 1530/*
1586 * This function forces any delayed work to be queued and run. 1531 * This function forces any delayed work to be queued and run.
1587 */ 1532 */
@@ -1601,62 +1546,30 @@ static int run_delayed_work(struct delayed_work *dwork)
1601 return ret; 1546 return ret;
1602} 1547}
1603 1548
1604/* power down chip */ 1549static int wm8753_probe(struct snd_soc_codec *codec)
1605static int wm8753_remove(struct platform_device *pdev)
1606{ 1550{
1607 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1551 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1608 1552 int ret = 0, reg;
1609 snd_soc_free_pcms(socdev);
1610 snd_soc_dapm_free(socdev);
1611
1612 return 0;
1613}
1614
1615struct snd_soc_codec_device soc_codec_dev_wm8753 = {
1616 .probe = wm8753_probe,
1617 .remove = wm8753_remove,
1618 .suspend = wm8753_suspend,
1619 .resume = wm8753_resume,
1620};
1621EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
1622 1553
1623static int wm8753_register(struct wm8753_priv *wm8753) 1554 codec->bias_level = SND_SOC_BIAS_OFF,
1624{ 1555 codec->control_data = wm8753->control_data;
1625 int ret, i; 1556 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
1626 struct snd_soc_codec *codec = &wm8753->codec;
1627 u16 reg;
1628 1557
1629 if (wm8753_codec) { 1558 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type);
1630 dev_err(codec->dev, "Multiple WM8753 devices not supported\n"); 1559 if (ret < 0) {
1631 ret = -EINVAL; 1560 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1632 goto err; 1561 return ret;
1633 } 1562 }
1634 1563
1635 mutex_init(&codec->mutex);
1636 INIT_LIST_HEAD(&codec->dapm_widgets);
1637 INIT_LIST_HEAD(&codec->dapm_paths);
1638
1639 codec->name = "WM8753";
1640 codec->owner = THIS_MODULE;
1641 codec->read = wm8753_read_reg_cache;
1642 codec->write = wm8753_write;
1643 codec->bias_level = SND_SOC_BIAS_STANDBY;
1644 codec->set_bias_level = wm8753_set_bias_level;
1645 codec->dai = wm8753_dai;
1646 codec->num_dai = 2;
1647 codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache) + 1;
1648 codec->reg_cache = &wm8753->reg_cache;
1649 snd_soc_codec_set_drvdata(codec, wm8753);
1650
1651 memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache));
1652 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
1653
1654 ret = wm8753_reset(codec); 1564 ret = wm8753_reset(codec);
1655 if (ret < 0) { 1565 if (ret < 0) {
1656 dev_err(codec->dev, "Failed to issue reset\n"); 1566 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1657 goto err; 1567 return ret;
1658 } 1568 }
1659 1569
1570 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1571 wm8753->dai_func = 0;
1572
1660 /* charge output caps */ 1573 /* charge output caps */
1661 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 1574 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1662 schedule_delayed_work(&codec->delayed_work, 1575 schedule_delayed_work(&codec->delayed_work,
@@ -1684,165 +1597,139 @@ static int wm8753_register(struct wm8753_priv *wm8753)
1684 reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); 1597 reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
1685 wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); 1598 wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
1686 1599
1687 wm8753_codec = codec; 1600 snd_soc_add_controls(codec, wm8753_snd_controls,
1688 1601 ARRAY_SIZE(wm8753_snd_controls));
1689 for (i = 0; i < ARRAY_SIZE(wm8753_dai); i++) 1602 wm8753_add_widgets(codec);
1690 wm8753_dai[i].dev = codec->dev;
1691
1692 ret = snd_soc_register_codec(codec);
1693 if (ret != 0) {
1694 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1695 goto err;
1696 }
1697
1698 ret = snd_soc_register_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai));
1699 if (ret != 0) {
1700 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
1701 goto err_codec;
1702 }
1703 1603
1704 return 0; 1604 return 0;
1705 1605
1706err_codec:
1707 run_delayed_work(&codec->delayed_work); 1606 run_delayed_work(&codec->delayed_work);
1708 snd_soc_unregister_codec(codec);
1709err:
1710 kfree(wm8753);
1711 return ret; 1607 return ret;
1712} 1608}
1713 1609
1714static void wm8753_unregister(struct wm8753_priv *wm8753) 1610/* power down chip */
1611static int wm8753_remove(struct snd_soc_codec *codec)
1715{ 1612{
1716 wm8753_set_bias_level(&wm8753->codec, SND_SOC_BIAS_OFF); 1613 run_delayed_work(&codec->delayed_work);
1717 run_delayed_work(&wm8753->codec.delayed_work); 1614 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1718 snd_soc_unregister_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai)); 1615
1719 snd_soc_unregister_codec(&wm8753->codec); 1616 return 0;
1720 kfree(wm8753);
1721 wm8753_codec = NULL;
1722} 1617}
1723 1618
1724#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1619static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1620 .probe = wm8753_probe,
1621 .remove = wm8753_remove,
1622 .suspend = wm8753_suspend,
1623 .resume = wm8753_resume,
1624 .set_bias_level = wm8753_set_bias_level,
1625 .reg_cache_size = sizeof(wm8753_reg),
1626 .reg_word_size = sizeof(u16),
1627 .reg_cache_default = wm8753_reg,
1628};
1725 1629
1726static int wm8753_i2c_probe(struct i2c_client *i2c, 1630#if defined(CONFIG_SPI_MASTER)
1727 const struct i2c_device_id *id) 1631static int __devinit wm8753_spi_probe(struct spi_device *spi)
1728{ 1632{
1729 struct snd_soc_codec *codec;
1730 struct wm8753_priv *wm8753; 1633 struct wm8753_priv *wm8753;
1634 int ret;
1731 1635
1732 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1636 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1733 if (wm8753 == NULL) 1637 if (wm8753 == NULL)
1734 return -ENOMEM; 1638 return -ENOMEM;
1735 1639
1736 codec = &wm8753->codec; 1640 wm8753->control_data = spi;
1737 codec->hw_write = (hw_write_t)i2c_master_send; 1641 wm8753->control_type = SND_SOC_SPI;
1738 codec->control_data = i2c; 1642 spi_set_drvdata(spi, wm8753);
1739 i2c_set_clientdata(i2c, wm8753);
1740
1741 codec->dev = &i2c->dev;
1742 1643
1743 return wm8753_register(wm8753); 1644 ret = snd_soc_register_codec(&spi->dev,
1645 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
1646 if (ret < 0)
1647 kfree(wm8753);
1648 return ret;
1744} 1649}
1745 1650
1746static int wm8753_i2c_remove(struct i2c_client *client) 1651static int __devexit wm8753_spi_remove(struct spi_device *spi)
1747{ 1652{
1748 struct wm8753_priv *wm8753 = i2c_get_clientdata(client); 1653 snd_soc_unregister_codec(&spi->dev);
1749 wm8753_unregister(wm8753); 1654 kfree(spi_get_drvdata(spi));
1750 return 0; 1655 return 0;
1751} 1656}
1752 1657
1753static const struct i2c_device_id wm8753_i2c_id[] = { 1658static struct spi_driver wm8753_spi_driver = {
1754 { "wm8753", 0 },
1755 { }
1756};
1757MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1758
1759static struct i2c_driver wm8753_i2c_driver = {
1760 .driver = { 1659 .driver = {
1761 .name = "wm8753", 1660 .name = "wm8753-codec",
1762 .owner = THIS_MODULE, 1661 .bus = &spi_bus_type,
1662 .owner = THIS_MODULE,
1763 }, 1663 },
1764 .probe = wm8753_i2c_probe, 1664 .probe = wm8753_spi_probe,
1765 .remove = wm8753_i2c_remove, 1665 .remove = __devexit_p(wm8753_spi_remove),
1766 .id_table = wm8753_i2c_id,
1767}; 1666};
1768#endif 1667#endif /* CONFIG_SPI_MASTER */
1769
1770#if defined(CONFIG_SPI_MASTER)
1771static int wm8753_spi_write(struct spi_device *spi, const char *data, int len)
1772{
1773 struct spi_transfer t;
1774 struct spi_message m;
1775 u8 msg[2];
1776
1777 if (len <= 0)
1778 return 0;
1779
1780 msg[0] = data[0];
1781 msg[1] = data[1];
1782 1668
1783 spi_message_init(&m); 1669#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1784 memset(&t, 0, (sizeof t)); 1670static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
1785 1671 const struct i2c_device_id *id)
1786 t.tx_buf = &msg[0];
1787 t.len = len;
1788
1789 spi_message_add_tail(&t, &m);
1790 spi_sync(spi, &m);
1791
1792 return len;
1793}
1794
1795static int __devinit wm8753_spi_probe(struct spi_device *spi)
1796{ 1672{
1797 struct snd_soc_codec *codec;
1798 struct wm8753_priv *wm8753; 1673 struct wm8753_priv *wm8753;
1674 int ret;
1799 1675
1800 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1676 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1801 if (wm8753 == NULL) 1677 if (wm8753 == NULL)
1802 return -ENOMEM; 1678 return -ENOMEM;
1803 1679
1804 codec = &wm8753->codec; 1680 i2c_set_clientdata(i2c, wm8753);
1805 codec->control_data = spi; 1681 wm8753->control_data = i2c;
1806 codec->hw_write = (hw_write_t)wm8753_spi_write; 1682 wm8753->control_type = SND_SOC_I2C;
1807 codec->dev = &spi->dev;
1808
1809 dev_set_drvdata(&spi->dev, wm8753);
1810 1683
1811 return wm8753_register(wm8753); 1684 ret = snd_soc_register_codec(&i2c->dev,
1685 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
1686 if (ret < 0)
1687 kfree(wm8753);
1688 return ret;
1812} 1689}
1813 1690
1814static int __devexit wm8753_spi_remove(struct spi_device *spi) 1691static __devexit int wm8753_i2c_remove(struct i2c_client *client)
1815{ 1692{
1816 struct wm8753_priv *wm8753 = dev_get_drvdata(&spi->dev); 1693 snd_soc_unregister_codec(&client->dev);
1817 wm8753_unregister(wm8753); 1694 kfree(i2c_get_clientdata(client));
1818 return 0; 1695 return 0;
1819} 1696}
1820 1697
1821static struct spi_driver wm8753_spi_driver = { 1698static const struct i2c_device_id wm8753_i2c_id[] = {
1699 { "wm8753", 0 },
1700 { }
1701};
1702MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1703
1704static struct i2c_driver wm8753_i2c_driver = {
1822 .driver = { 1705 .driver = {
1823 .name = "wm8753", 1706 .name = "wm8753-codec",
1824 .bus = &spi_bus_type, 1707 .owner = THIS_MODULE,
1825 .owner = THIS_MODULE,
1826 }, 1708 },
1827 .probe = wm8753_spi_probe, 1709 .probe = wm8753_i2c_probe,
1828 .remove = __devexit_p(wm8753_spi_remove), 1710 .remove = __devexit_p(wm8753_i2c_remove),
1711 .id_table = wm8753_i2c_id,
1829}; 1712};
1830#endif 1713#endif
1831 1714
1832static int __init wm8753_modinit(void) 1715static int __init wm8753_modinit(void)
1833{ 1716{
1834 int ret; 1717 int ret = 0;
1835#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1718#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1836 ret = i2c_add_driver(&wm8753_i2c_driver); 1719 ret = i2c_add_driver(&wm8753_i2c_driver);
1837 if (ret != 0) 1720 if (ret != 0) {
1838 pr_err("Failed to register WM8753 I2C driver: %d\n", ret); 1721 printk(KERN_ERR "Failed to register wm8753 I2C driver: %d\n",
1722 ret);
1723 }
1839#endif 1724#endif
1840#if defined(CONFIG_SPI_MASTER) 1725#if defined(CONFIG_SPI_MASTER)
1841 ret = spi_register_driver(&wm8753_spi_driver); 1726 ret = spi_register_driver(&wm8753_spi_driver);
1842 if (ret != 0) 1727 if (ret != 0) {
1843 pr_err("Failed to register WM8753 SPI driver: %d\n", ret); 1728 printk(KERN_ERR "Failed to register wm8753 SPI driver: %d\n",
1729 ret);
1730 }
1844#endif 1731#endif
1845 return 0; 1732 return ret;
1846} 1733}
1847module_init(wm8753_modinit); 1734module_init(wm8753_modinit);
1848 1735
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
index 57b2ba24404..94edac144bc 100644
--- a/sound/soc/codecs/wm8753.h
+++ b/sound/soc/codecs/wm8753.h
@@ -115,7 +115,4 @@
115#define WM8753_DAI_HIFI 0 115#define WM8753_DAI_HIFI 0
116#define WM8753_DAI_VOICE 1 116#define WM8753_DAI_VOICE 1
117 117
118extern struct snd_soc_dai wm8753_dai[2];
119extern struct snd_soc_codec_device soc_codec_dev_wm8753;
120
121#endif 118#endif
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 4e212ed62ea..51a2d265d40 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -31,20 +31,14 @@
31 31
32#include "wm8776.h" 32#include "wm8776.h"
33 33
34static struct snd_soc_codec *wm8776_codec;
35struct snd_soc_codec_device soc_codec_dev_wm8776;
36
37/* codec private data */ 34/* codec private data */
38struct wm8776_priv { 35struct wm8776_priv {
39 struct snd_soc_codec codec; 36 enum snd_soc_control_type control_type;
37 void *control_data;
40 u16 reg_cache[WM8776_CACHEREGNUM]; 38 u16 reg_cache[WM8776_CACHEREGNUM];
41 int sysclk[2]; 39 int sysclk[2];
42}; 40};
43 41
44#ifdef CONFIG_SPI_MASTER
45static int wm8776_spi_write(struct spi_device *spi, const char *data, int len);
46#endif
47
48static const u16 wm8776_reg[WM8776_CACHEREGNUM] = { 42static const u16 wm8776_reg[WM8776_CACHEREGNUM] = {
49 0x79, 0x79, 0x79, 0xff, 0xff, /* 4 */ 43 0x79, 0x79, 0x79, 0xff, 0xff, /* 4 */
50 0xff, 0x00, 0x90, 0x00, 0x00, /* 9 */ 44 0xff, 0x00, 0x90, 0x00, 0x00, /* 9 */
@@ -144,7 +138,7 @@ static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
144 struct snd_soc_codec *codec = dai->codec; 138 struct snd_soc_codec *codec = dai->codec;
145 int reg, iface, master; 139 int reg, iface, master;
146 140
147 switch (dai->id) { 141 switch (dai->driver->id) {
148 case WM8776_DAI_DAC: 142 case WM8776_DAI_DAC:
149 reg = WM8776_DACIFCTRL; 143 reg = WM8776_DACIFCTRL;
150 master = 0x80; 144 master = 0x80;
@@ -233,7 +227,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
233 227
234 iface = 0; 228 iface = 0;
235 229
236 switch (dai->id) { 230 switch (dai->driver->id) {
237 case WM8776_DAI_DAC: 231 case WM8776_DAI_DAC:
238 iface_reg = WM8776_DACIFCTRL; 232 iface_reg = WM8776_DACIFCTRL;
239 master = 0x80; 233 master = 0x80;
@@ -267,7 +261,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
267 /* Only need to set MCLK/LRCLK ratio if we're master */ 261 /* Only need to set MCLK/LRCLK ratio if we're master */
268 if (snd_soc_read(codec, WM8776_MSTRCTRL) & master) { 262 if (snd_soc_read(codec, WM8776_MSTRCTRL) & master) {
269 for (i = 0; i < ARRAY_SIZE(mclk_ratios); i++) { 263 for (i = 0; i < ARRAY_SIZE(mclk_ratios); i++) {
270 if (wm8776->sysclk[dai->id] / params_rate(params) 264 if (wm8776->sysclk[dai->driver->id] / params_rate(params)
271 == mclk_ratios[i]) 265 == mclk_ratios[i])
272 break; 266 break;
273 } 267 }
@@ -275,7 +269,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
275 if (i == ARRAY_SIZE(mclk_ratios)) { 269 if (i == ARRAY_SIZE(mclk_ratios)) {
276 dev_err(codec->dev, 270 dev_err(codec->dev,
277 "Unable to configure MCLK ratio %d/%d\n", 271 "Unable to configure MCLK ratio %d/%d\n",
278 wm8776->sysclk[dai->id], params_rate(params)); 272 wm8776->sysclk[dai->driver->id], params_rate(params));
279 return -EINVAL; 273 return -EINVAL;
280 } 274 }
281 275
@@ -305,9 +299,9 @@ static int wm8776_set_sysclk(struct snd_soc_dai *dai,
305 struct snd_soc_codec *codec = dai->codec; 299 struct snd_soc_codec *codec = dai->codec;
306 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec); 300 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
307 301
308 BUG_ON(dai->id >= ARRAY_SIZE(wm8776->sysclk)); 302 BUG_ON(dai->driver->id >= ARRAY_SIZE(wm8776->sysclk));
309 303
310 wm8776->sysclk[dai->id] = freq; 304 wm8776->sysclk[dai->driver->id] = freq;
311 305
312 return 0; 306 return 0;
313} 307}
@@ -357,10 +351,10 @@ static struct snd_soc_dai_ops wm8776_adc_ops = {
357 .set_sysclk = wm8776_set_sysclk, 351 .set_sysclk = wm8776_set_sysclk,
358}; 352};
359 353
360struct snd_soc_dai wm8776_dai[] = { 354static struct snd_soc_dai_driver wm8776_dai[] = {
361 { 355 {
362 .name = "WM8776 Playback", 356 .name = "wm8776-hifi-playback",
363 .id = WM8776_DAI_DAC, 357 .id = WM8776_DAI_DAC,
364 .playback = { 358 .playback = {
365 .stream_name = "Playback", 359 .stream_name = "Playback",
366 .channels_min = 2, 360 .channels_min = 2,
@@ -371,8 +365,8 @@ struct snd_soc_dai wm8776_dai[] = {
371 .ops = &wm8776_dac_ops, 365 .ops = &wm8776_dac_ops,
372 }, 366 },
373 { 367 {
374 .name = "WM8776 Capture", 368 .name = "wm8776-hifi-capture",
375 .id = WM8776_DAI_ADC, 369 .id = WM8776_DAI_ADC,
376 .capture = { 370 .capture = {
377 .stream_name = "Capture", 371 .stream_name = "Capture",
378 .channels_min = 2, 372 .channels_min = 2,
@@ -383,23 +377,17 @@ struct snd_soc_dai wm8776_dai[] = {
383 .ops = &wm8776_adc_ops, 377 .ops = &wm8776_adc_ops,
384 }, 378 },
385}; 379};
386EXPORT_SYMBOL_GPL(wm8776_dai);
387 380
388#ifdef CONFIG_PM 381#ifdef CONFIG_PM
389static int wm8776_suspend(struct platform_device *pdev, pm_message_t state) 382static int wm8776_suspend(struct snd_soc_codec *codec, pm_message_t state)
390{ 383{
391 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
392 struct snd_soc_codec *codec = socdev->card->codec;
393
394 wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF); 384 wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF);
395 385
396 return 0; 386 return 0;
397} 387}
398 388
399static int wm8776_resume(struct platform_device *pdev) 389static int wm8776_resume(struct snd_soc_codec *codec)
400{ 390{
401 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
402 struct snd_soc_codec *codec = socdev->card->codec;
403 int i; 391 int i;
404 u8 data[2]; 392 u8 data[2];
405 u16 *cache = codec->reg_cache; 393 u16 *cache = codec->reg_cache;
@@ -422,27 +410,31 @@ static int wm8776_resume(struct platform_device *pdev)
422#define wm8776_resume NULL 410#define wm8776_resume NULL
423#endif 411#endif
424 412
425static int wm8776_probe(struct platform_device *pdev) 413static int wm8776_probe(struct snd_soc_codec *codec)
426{ 414{
427 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 415 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
428 struct snd_soc_codec *codec;
429 int ret = 0; 416 int ret = 0;
430 417
431 if (wm8776_codec == NULL) { 418 codec->control_data = wm8776->control_data;
432 dev_err(&pdev->dev, "Codec device not registered\n"); 419 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type);
433 return -ENODEV; 420 if (ret < 0) {
421 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
422 return ret;
434 } 423 }
435 424
436 socdev->card->codec = wm8776_codec; 425 ret = wm8776_reset(codec);
437 codec = wm8776_codec;
438
439 /* register pcms */
440 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
441 if (ret < 0) { 426 if (ret < 0) {
442 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 427 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
443 goto pcm_err; 428 return ret;
444 } 429 }
445 430
431 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
432
433 /* Latch the update bits; right channel only since we always
434 * update both. */
435 snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100);
436 snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100);
437
446 snd_soc_add_controls(codec, wm8776_snd_controls, 438 snd_soc_add_controls(codec, wm8776_snd_controls,
447 ARRAY_SIZE(wm8776_snd_controls)); 439 ARRAY_SIZE(wm8776_snd_controls));
448 snd_soc_dapm_new_controls(codec, wm8776_dapm_widgets, 440 snd_soc_dapm_new_controls(codec, wm8776_dapm_widgets,
@@ -450,168 +442,57 @@ static int wm8776_probe(struct platform_device *pdev)
450 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); 442 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
451 443
452 return ret; 444 return ret;
453
454pcm_err:
455 return ret;
456} 445}
457 446
458/* power down chip */ 447/* power down chip */
459static int wm8776_remove(struct platform_device *pdev) 448static int wm8776_remove(struct snd_soc_codec *codec)
460{ 449{
461 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 450 wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF);
462
463 snd_soc_free_pcms(socdev);
464 snd_soc_dapm_free(socdev);
465
466 return 0; 451 return 0;
467} 452}
468 453
469struct snd_soc_codec_device soc_codec_dev_wm8776 = { 454static struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
470 .probe = wm8776_probe, 455 .probe = wm8776_probe,
471 .remove = wm8776_remove, 456 .remove = wm8776_remove,
472 .suspend = wm8776_suspend, 457 .suspend = wm8776_suspend,
473 .resume = wm8776_resume, 458 .resume = wm8776_resume,
459 .set_bias_level = wm8776_set_bias_level,
460 .reg_cache_size = sizeof(wm8776_reg),
461 .reg_word_size = sizeof(u16),
462 .reg_cache_default = wm8776_reg,
474}; 463};
475EXPORT_SYMBOL_GPL(soc_codec_dev_wm8776);
476
477static int wm8776_register(struct wm8776_priv *wm8776,
478 enum snd_soc_control_type control)
479{
480 int ret, i;
481 struct snd_soc_codec *codec = &wm8776->codec;
482
483 if (wm8776_codec) {
484 dev_err(codec->dev, "Another WM8776 is registered\n");
485 ret = -EINVAL;
486 goto err;
487 }
488
489 mutex_init(&codec->mutex);
490 INIT_LIST_HEAD(&codec->dapm_widgets);
491 INIT_LIST_HEAD(&codec->dapm_paths);
492
493 snd_soc_codec_set_drvdata(codec, wm8776);
494 codec->name = "WM8776";
495 codec->owner = THIS_MODULE;
496 codec->bias_level = SND_SOC_BIAS_OFF;
497 codec->set_bias_level = wm8776_set_bias_level;
498 codec->dai = wm8776_dai;
499 codec->num_dai = ARRAY_SIZE(wm8776_dai);
500 codec->reg_cache_size = WM8776_CACHEREGNUM;
501 codec->reg_cache = &wm8776->reg_cache;
502
503 memcpy(codec->reg_cache, wm8776_reg, sizeof(wm8776_reg));
504
505 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
506 if (ret < 0) {
507 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
508 goto err;
509 }
510
511 for (i = 0; i < ARRAY_SIZE(wm8776_dai); i++)
512 wm8776_dai[i].dev = codec->dev;
513
514 ret = wm8776_reset(codec);
515 if (ret < 0) {
516 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
517 goto err;
518 }
519
520 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
521
522 /* Latch the update bits; right channel only since we always
523 * update both. */
524 snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100);
525 snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100);
526
527 wm8776_codec = codec;
528
529 ret = snd_soc_register_codec(codec);
530 if (ret != 0) {
531 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
532 goto err;
533 }
534
535 ret = snd_soc_register_dais(wm8776_dai, ARRAY_SIZE(wm8776_dai));
536 if (ret != 0) {
537 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
538 goto err_codec;
539 }
540
541 return 0;
542
543err_codec:
544 snd_soc_unregister_codec(codec);
545err:
546 kfree(wm8776);
547 return ret;
548}
549
550static void wm8776_unregister(struct wm8776_priv *wm8776)
551{
552 wm8776_set_bias_level(&wm8776->codec, SND_SOC_BIAS_OFF);
553 snd_soc_unregister_dais(wm8776_dai, ARRAY_SIZE(wm8776_dai));
554 snd_soc_unregister_codec(&wm8776->codec);
555 kfree(wm8776);
556 wm8776_codec = NULL;
557}
558 464
559#if defined(CONFIG_SPI_MASTER) 465#if defined(CONFIG_SPI_MASTER)
560static int wm8776_spi_write(struct spi_device *spi, const char *data, int len)
561{
562 struct spi_transfer t;
563 struct spi_message m;
564 u8 msg[2];
565
566 if (len <= 0)
567 return 0;
568
569 msg[0] = data[0];
570 msg[1] = data[1];
571
572 spi_message_init(&m);
573 memset(&t, 0, (sizeof t));
574
575 t.tx_buf = &msg[0];
576 t.len = len;
577
578 spi_message_add_tail(&t, &m);
579 spi_sync(spi, &m);
580
581 return len;
582}
583
584static int __devinit wm8776_spi_probe(struct spi_device *spi) 466static int __devinit wm8776_spi_probe(struct spi_device *spi)
585{ 467{
586 struct snd_soc_codec *codec;
587 struct wm8776_priv *wm8776; 468 struct wm8776_priv *wm8776;
469 int ret;
588 470
589 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL); 471 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
590 if (wm8776 == NULL) 472 if (wm8776 == NULL)
591 return -ENOMEM; 473 return -ENOMEM;
592 474
593 codec = &wm8776->codec; 475 wm8776->control_data = spi;
594 codec->control_data = spi; 476 wm8776->control_type = SND_SOC_SPI;
595 codec->hw_write = (hw_write_t)wm8776_spi_write; 477 spi_set_drvdata(spi, wm8776);
596 codec->dev = &spi->dev;
597 478
598 dev_set_drvdata(&spi->dev, wm8776); 479 ret = snd_soc_register_codec(&spi->dev,
599 480 &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
600 return wm8776_register(wm8776, SND_SOC_SPI); 481 if (ret < 0)
482 kfree(wm8776);
483 return ret;
601} 484}
602 485
603static int __devexit wm8776_spi_remove(struct spi_device *spi) 486static int __devexit wm8776_spi_remove(struct spi_device *spi)
604{ 487{
605 struct wm8776_priv *wm8776 = dev_get_drvdata(&spi->dev); 488 snd_soc_unregister_codec(&spi->dev);
606 489 kfree(spi_get_drvdata(spi));
607 wm8776_unregister(wm8776);
608
609 return 0; 490 return 0;
610} 491}
611 492
612static struct spi_driver wm8776_spi_driver = { 493static struct spi_driver wm8776_spi_driver = {
613 .driver = { 494 .driver = {
614 .name = "wm8776", 495 .name = "wm8776-codec",
615 .bus = &spi_bus_type, 496 .bus = &spi_bus_type,
616 .owner = THIS_MODULE, 497 .owner = THIS_MODULE,
617 }, 498 },
@@ -625,27 +506,27 @@ static __devinit int wm8776_i2c_probe(struct i2c_client *i2c,
625 const struct i2c_device_id *id) 506 const struct i2c_device_id *id)
626{ 507{
627 struct wm8776_priv *wm8776; 508 struct wm8776_priv *wm8776;
628 struct snd_soc_codec *codec; 509 int ret;
629 510
630 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL); 511 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
631 if (wm8776 == NULL) 512 if (wm8776 == NULL)
632 return -ENOMEM; 513 return -ENOMEM;
633 514
634 codec = &wm8776->codec;
635 codec->hw_write = (hw_write_t)i2c_master_send;
636
637 i2c_set_clientdata(i2c, wm8776); 515 i2c_set_clientdata(i2c, wm8776);
638 codec->control_data = i2c; 516 wm8776->control_data = i2c;
639 517 wm8776->control_type = SND_SOC_I2C;
640 codec->dev = &i2c->dev;
641 518
642 return wm8776_register(wm8776, SND_SOC_I2C); 519 ret = snd_soc_register_codec(&i2c->dev,
520 &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
521 if (ret < 0)
522 kfree(wm8776);
523 return ret;
643} 524}
644 525
645static __devexit int wm8776_i2c_remove(struct i2c_client *client) 526static __devexit int wm8776_i2c_remove(struct i2c_client *client)
646{ 527{
647 struct wm8776_priv *wm8776 = i2c_get_clientdata(client); 528 snd_soc_unregister_codec(&client->dev);
648 wm8776_unregister(wm8776); 529 kfree(i2c_get_clientdata(client));
649 return 0; 530 return 0;
650} 531}
651 532
@@ -657,7 +538,7 @@ MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
657 538
658static struct i2c_driver wm8776_i2c_driver = { 539static struct i2c_driver wm8776_i2c_driver = {
659 .driver = { 540 .driver = {
660 .name = "wm8776", 541 .name = "wm8776-codec",
661 .owner = THIS_MODULE, 542 .owner = THIS_MODULE,
662 }, 543 },
663 .probe = wm8776_i2c_probe, 544 .probe = wm8776_i2c_probe,
@@ -668,22 +549,22 @@ static struct i2c_driver wm8776_i2c_driver = {
668 549
669static int __init wm8776_modinit(void) 550static int __init wm8776_modinit(void)
670{ 551{
671 int ret; 552 int ret = 0;
672#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 553#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
673 ret = i2c_add_driver(&wm8776_i2c_driver); 554 ret = i2c_add_driver(&wm8776_i2c_driver);
674 if (ret != 0) { 555 if (ret != 0) {
675 printk(KERN_ERR "Failed to register WM8776 I2C driver: %d\n", 556 printk(KERN_ERR "Failed to register wm8776 I2C driver: %d\n",
676 ret); 557 ret);
677 } 558 }
678#endif 559#endif
679#if defined(CONFIG_SPI_MASTER) 560#if defined(CONFIG_SPI_MASTER)
680 ret = spi_register_driver(&wm8776_spi_driver); 561 ret = spi_register_driver(&wm8776_spi_driver);
681 if (ret != 0) { 562 if (ret != 0) {
682 printk(KERN_ERR "Failed to register WM8776 SPI driver: %d\n", 563 printk(KERN_ERR "Failed to register wm8776 SPI driver: %d\n",
683 ret); 564 ret);
684 } 565 }
685#endif 566#endif
686 return 0; 567 return ret;
687} 568}
688module_init(wm8776_modinit); 569module_init(wm8776_modinit);
689 570
diff --git a/sound/soc/codecs/wm8776.h b/sound/soc/codecs/wm8776.h
index 6606d25d2d8..4cf1c8e0bfc 100644
--- a/sound/soc/codecs/wm8776.h
+++ b/sound/soc/codecs/wm8776.h
@@ -45,7 +45,4 @@
45#define WM8776_DAI_DAC 0 45#define WM8776_DAI_DAC 0
46#define WM8776_DAI_ADC 1 46#define WM8776_DAI_ADC 1
47 47
48extern struct snd_soc_dai wm8776_dai[];
49extern struct snd_soc_codec_device soc_codec_dev_wm8776;
50
51#endif 48#endif
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 5da17a704e5..33c3b57f3f6 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -23,6 +23,7 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/spi/spi.h>
26#include <linux/platform_device.h> 27#include <linux/platform_device.h>
27#include <linux/slab.h> 28#include <linux/slab.h>
28#include <sound/core.h> 29#include <sound/core.h>
@@ -137,11 +138,9 @@
137 138
138#define WM8900_LRC_MASK 0xfc00 139#define WM8900_LRC_MASK 0xfc00
139 140
140struct snd_soc_codec_device soc_codec_dev_wm8900;
141
142struct wm8900_priv { 141struct wm8900_priv {
143 struct snd_soc_codec codec; 142 enum snd_soc_control_type control_type;
144 143 void *control_data;
145 u16 reg_cache[WM8900_MAXREG]; 144 u16 reg_cache[WM8900_MAXREG];
146 145
147 u32 fll_in; /* FLL input frequency */ 146 u32 fll_in; /* FLL input frequency */
@@ -627,8 +626,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
627 struct snd_soc_dai *dai) 626 struct snd_soc_dai *dai)
628{ 627{
629 struct snd_soc_pcm_runtime *rtd = substream->private_data; 628 struct snd_soc_pcm_runtime *rtd = substream->private_data;
630 struct snd_soc_device *socdev = rtd->socdev; 629 struct snd_soc_codec *codec = rtd->codec;
631 struct snd_soc_codec *codec = socdev->card->codec;
632 u16 reg; 630 u16 reg;
633 631
634 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60; 632 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60;
@@ -1015,8 +1013,8 @@ static struct snd_soc_dai_ops wm8900_dai_ops = {
1015 .digital_mute = wm8900_digital_mute, 1013 .digital_mute = wm8900_digital_mute,
1016}; 1014};
1017 1015
1018struct snd_soc_dai wm8900_dai = { 1016static struct snd_soc_dai_driver wm8900_dai = {
1019 .name = "WM8900 HiFi", 1017 .name = "wm8900-hifi",
1020 .playback = { 1018 .playback = {
1021 .stream_name = "HiFi Playback", 1019 .stream_name = "HiFi Playback",
1022 .channels_min = 1, 1020 .channels_min = 1,
@@ -1033,7 +1031,6 @@ struct snd_soc_dai wm8900_dai = {
1033 }, 1031 },
1034 .ops = &wm8900_dai_ops, 1032 .ops = &wm8900_dai_ops,
1035}; 1033};
1036EXPORT_SYMBOL_GPL(wm8900_dai);
1037 1034
1038static int wm8900_set_bias_level(struct snd_soc_codec *codec, 1035static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1039 enum snd_soc_bias_level level) 1036 enum snd_soc_bias_level level)
@@ -1128,10 +1125,8 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1128 return 0; 1125 return 0;
1129} 1126}
1130 1127
1131static int wm8900_suspend(struct platform_device *pdev, pm_message_t state) 1128static int wm8900_suspend(struct snd_soc_codec *codec, pm_message_t state)
1132{ 1129{
1133 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1134 struct snd_soc_codec *codec = socdev->card->codec;
1135 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); 1130 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1136 int fll_out = wm8900->fll_out; 1131 int fll_out = wm8900->fll_out;
1137 int fll_in = wm8900->fll_in; 1132 int fll_in = wm8900->fll_in;
@@ -1140,7 +1135,7 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1140 /* Stop the FLL in an orderly fashion */ 1135 /* Stop the FLL in an orderly fashion */
1141 ret = wm8900_set_fll(codec, 0, 0, 0); 1136 ret = wm8900_set_fll(codec, 0, 0, 0);
1142 if (ret != 0) { 1137 if (ret != 0) {
1143 dev_err(&pdev->dev, "Failed to stop FLL\n"); 1138 dev_err(codec->dev, "Failed to stop FLL\n");
1144 return ret; 1139 return ret;
1145 } 1140 }
1146 1141
@@ -1152,10 +1147,8 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1152 return 0; 1147 return 0;
1153} 1148}
1154 1149
1155static int wm8900_resume(struct platform_device *pdev) 1150static int wm8900_resume(struct snd_soc_codec *codec)
1156{ 1151{
1157 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1158 struct snd_soc_codec *codec = socdev->card->codec;
1159 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); 1152 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1160 u16 *cache; 1153 u16 *cache;
1161 int i, ret; 1154 int i, ret;
@@ -1176,7 +1169,7 @@ static int wm8900_resume(struct platform_device *pdev)
1176 1169
1177 ret = wm8900_set_fll(codec, 0, fll_in, fll_out); 1170 ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
1178 if (ret != 0) { 1171 if (ret != 0) {
1179 dev_err(&pdev->dev, "Failed to restart FLL\n"); 1172 dev_err(codec->dev, "Failed to restart FLL\n");
1180 return ret; 1173 return ret;
1181 } 1174 }
1182 } 1175 }
@@ -1186,60 +1179,33 @@ static int wm8900_resume(struct platform_device *pdev)
1186 snd_soc_write(codec, i, cache[i]); 1179 snd_soc_write(codec, i, cache[i]);
1187 kfree(cache); 1180 kfree(cache);
1188 } else 1181 } else
1189 dev_err(&pdev->dev, "Unable to allocate register cache\n"); 1182 dev_err(codec->dev, "Unable to allocate register cache\n");
1190 1183
1191 return 0; 1184 return 0;
1192} 1185}
1193 1186
1194static struct snd_soc_codec *wm8900_codec; 1187static int wm8900_probe(struct snd_soc_codec *codec)
1195
1196static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1197 const struct i2c_device_id *id)
1198{ 1188{
1199 struct wm8900_priv *wm8900; 1189 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1200 struct snd_soc_codec *codec; 1190 int ret = 0, reg;
1201 unsigned int reg;
1202 int ret;
1203
1204 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1205 if (wm8900 == NULL)
1206 return -ENOMEM;
1207 1191
1208 codec = &wm8900->codec; 1192 codec->control_data = wm8900->control_data;
1209 snd_soc_codec_set_drvdata(codec, wm8900); 1193 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8900->control_type);
1210 codec->reg_cache = &wm8900->reg_cache[0];
1211 codec->reg_cache_size = WM8900_MAXREG;
1212
1213 mutex_init(&codec->mutex);
1214 INIT_LIST_HEAD(&codec->dapm_widgets);
1215 INIT_LIST_HEAD(&codec->dapm_paths);
1216
1217 codec->name = "WM8900";
1218 codec->owner = THIS_MODULE;
1219 codec->dai = &wm8900_dai;
1220 codec->num_dai = 1;
1221 codec->control_data = i2c;
1222 codec->set_bias_level = wm8900_set_bias_level;
1223 codec->volatile_register = wm8900_volatile_register;
1224 codec->dev = &i2c->dev;
1225
1226 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1227 if (ret != 0) { 1194 if (ret != 0) {
1228 dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret); 1195 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1229 goto err; 1196 return ret;
1230 } 1197 }
1231 1198
1232 reg = snd_soc_read(codec, WM8900_REG_ID); 1199 reg = snd_soc_read(codec, WM8900_REG_ID);
1233 if (reg != 0x8900) { 1200 if (reg != 0x8900) {
1234 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg); 1201 dev_err(codec->dev, "Device is not a WM8900 - ID %x\n", reg);
1235 ret = -ENODEV; 1202 return -ENODEV;
1236 goto err;
1237 } 1203 }
1238 1204
1239 /* Read back from the chip */ 1205 /* Read back from the chip */
1240 reg = snd_soc_read(codec, WM8900_REG_POWER1); 1206 reg = snd_soc_read(codec, WM8900_REG_POWER1);
1241 reg = (reg >> 12) & 0xf; 1207 reg = (reg >> 12) & 0xf;
1242 dev_info(&i2c->dev, "WM8900 revision %d\n", reg); 1208 dev_info(codec->dev, "WM8900 revision %d\n", reg);
1243 1209
1244 wm8900_reset(codec); 1210 wm8900_reset(codec);
1245 1211
@@ -1271,43 +1237,97 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1271 /* Set the DAC and mixer output bias */ 1237 /* Set the DAC and mixer output bias */
1272 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1238 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1273 1239
1274 wm8900_dai.dev = &i2c->dev; 1240 snd_soc_add_controls(codec, wm8900_snd_controls,
1241 ARRAY_SIZE(wm8900_snd_controls));
1242 wm8900_add_widgets(codec);
1275 1243
1276 wm8900_codec = codec; 1244 return 0;
1245}
1277 1246
1278 ret = snd_soc_register_codec(codec); 1247/* power down chip */
1279 if (ret != 0) { 1248static int wm8900_remove(struct snd_soc_codec *codec)
1280 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); 1249{
1281 goto err; 1250 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1282 } 1251 return 0;
1252}
1283 1253
1284 ret = snd_soc_register_dai(&wm8900_dai); 1254static struct snd_soc_codec_driver soc_codec_dev_wm8900 = {
1285 if (ret != 0) { 1255 .probe = wm8900_probe,
1286 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret); 1256 .remove = wm8900_remove,
1287 goto err_codec; 1257 .suspend = wm8900_suspend,
1288 } 1258 .resume = wm8900_resume,
1259 .set_bias_level = wm8900_set_bias_level,
1260 .volatile_register = wm8900_volatile_register,
1261 .reg_cache_size = sizeof(wm8900_reg_defaults),
1262 .reg_word_size = sizeof(u16),
1263 .reg_cache_default = wm8900_reg_defaults,
1264};
1289 1265
1290 return ret; 1266#if defined(CONFIG_SPI_MASTER)
1267static int __devinit wm8900_spi_probe(struct spi_device *spi)
1268{
1269 struct wm8900_priv *wm8900;
1270 int ret;
1271
1272 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1273 if (wm8900 == NULL)
1274 return -ENOMEM;
1291 1275
1292err_codec: 1276 wm8900->control_data = spi;
1293 snd_soc_unregister_codec(codec); 1277 wm8900->control_type = SND_SOC_SPI;
1294err: 1278 spi_set_drvdata(spi, wm8900);
1295 kfree(wm8900); 1279
1296 wm8900_codec = NULL; 1280 ret = snd_soc_register_codec(&spi->dev,
1281 &soc_codec_dev_wm8900, &wm8900_dai, 1);
1282 if (ret < 0)
1283 kfree(wm8900);
1297 return ret; 1284 return ret;
1298} 1285}
1299 1286
1300static __devexit int wm8900_i2c_remove(struct i2c_client *client) 1287static int __devexit wm8900_spi_remove(struct spi_device *spi)
1301{ 1288{
1302 snd_soc_unregister_dai(&wm8900_dai); 1289 snd_soc_unregister_codec(&spi->dev);
1303 snd_soc_unregister_codec(wm8900_codec); 1290 kfree(spi_get_drvdata(spi));
1291 return 0;
1292}
1304 1293
1305 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF); 1294static struct spi_driver wm8900_spi_driver = {
1295 .driver = {
1296 .name = "wm8900-codec",
1297 .bus = &spi_bus_type,
1298 .owner = THIS_MODULE,
1299 },
1300 .probe = wm8900_spi_probe,
1301 .remove = __devexit_p(wm8900_spi_remove),
1302};
1303#endif /* CONFIG_SPI_MASTER */
1304
1305#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1306static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1307 const struct i2c_device_id *id)
1308{
1309 struct wm8900_priv *wm8900;
1310 int ret;
1311
1312 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1313 if (wm8900 == NULL)
1314 return -ENOMEM;
1315
1316 i2c_set_clientdata(i2c, wm8900);
1317 wm8900->control_data = i2c;
1318 wm8900->control_type = SND_SOC_I2C;
1306 1319
1307 wm8900_dai.dev = NULL; 1320 ret = snd_soc_register_codec(&i2c->dev,
1308 kfree(snd_soc_codec_get_drvdata(wm8900_codec)); 1321 &soc_codec_dev_wm8900, &wm8900_dai, 1);
1309 wm8900_codec = NULL; 1322 if (ret < 0)
1323 kfree(wm8900);
1324 return ret;
1325}
1310 1326
1327static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1328{
1329 snd_soc_unregister_codec(&client->dev);
1330 kfree(i2c_get_clientdata(client));
1311 return 0; 1331 return 0;
1312} 1332}
1313 1333
@@ -1319,71 +1339,44 @@ MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
1319 1339
1320static struct i2c_driver wm8900_i2c_driver = { 1340static struct i2c_driver wm8900_i2c_driver = {
1321 .driver = { 1341 .driver = {
1322 .name = "WM8900", 1342 .name = "wm8900-codec",
1323 .owner = THIS_MODULE, 1343 .owner = THIS_MODULE,
1324 }, 1344 },
1325 .probe = wm8900_i2c_probe, 1345 .probe = wm8900_i2c_probe,
1326 .remove = __devexit_p(wm8900_i2c_remove), 1346 .remove = __devexit_p(wm8900_i2c_remove),
1327 .id_table = wm8900_i2c_id, 1347 .id_table = wm8900_i2c_id,
1328}; 1348};
1349#endif
1329 1350
1330static int wm8900_probe(struct platform_device *pdev) 1351static int __init wm8900_modinit(void)
1331{ 1352{
1332 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1333 struct snd_soc_codec *codec;
1334 int ret = 0; 1353 int ret = 0;
1335 1354#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1336 if (!wm8900_codec) { 1355 ret = i2c_add_driver(&wm8900_i2c_driver);
1337 dev_err(&pdev->dev, "I2C client not yet instantiated\n"); 1356 if (ret != 0) {
1338 return -ENODEV; 1357 printk(KERN_ERR "Failed to register wm8900 I2C driver: %d\n",
1358 ret);
1339 } 1359 }
1340 1360#endif
1341 codec = wm8900_codec; 1361#if defined(CONFIG_SPI_MASTER)
1342 socdev->card->codec = codec; 1362 ret = spi_register_driver(&wm8900_spi_driver);
1343 1363 if (ret != 0) {
1344 /* Register pcms */ 1364 printk(KERN_ERR "Failed to register wm8900 SPI driver: %d\n",
1345 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1365 ret);
1346 if (ret < 0) {
1347 dev_err(&pdev->dev, "Failed to register new PCMs\n");
1348 goto pcm_err;
1349 } 1366 }
1350 1367#endif
1351 snd_soc_add_controls(codec, wm8900_snd_controls,
1352 ARRAY_SIZE(wm8900_snd_controls));
1353 wm8900_add_widgets(codec);
1354
1355pcm_err:
1356 return ret; 1368 return ret;
1357} 1369}
1358
1359/* power down chip */
1360static int wm8900_remove(struct platform_device *pdev)
1361{
1362 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1363
1364 snd_soc_free_pcms(socdev);
1365 snd_soc_dapm_free(socdev);
1366
1367 return 0;
1368}
1369
1370struct snd_soc_codec_device soc_codec_dev_wm8900 = {
1371 .probe = wm8900_probe,
1372 .remove = wm8900_remove,
1373 .suspend = wm8900_suspend,
1374 .resume = wm8900_resume,
1375};
1376EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
1377
1378static int __init wm8900_modinit(void)
1379{
1380 return i2c_add_driver(&wm8900_i2c_driver);
1381}
1382module_init(wm8900_modinit); 1370module_init(wm8900_modinit);
1383 1371
1384static void __exit wm8900_exit(void) 1372static void __exit wm8900_exit(void)
1385{ 1373{
1374#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1386 i2c_del_driver(&wm8900_i2c_driver); 1375 i2c_del_driver(&wm8900_i2c_driver);
1376#endif
1377#if defined(CONFIG_SPI_MASTER)
1378 spi_unregister_driver(&wm8900_spi_driver);
1379#endif
1387} 1380}
1388module_exit(wm8900_exit); 1381module_exit(wm8900_exit);
1389 1382
diff --git a/sound/soc/codecs/wm8900.h b/sound/soc/codecs/wm8900.h
index fd15007d10c..583f257e799 100644
--- a/sound/soc/codecs/wm8900.h
+++ b/sound/soc/codecs/wm8900.h
@@ -52,7 +52,4 @@
52#define WM8900_DAC_CLKDIV_5_5 0x14 52#define WM8900_DAC_CLKDIV_5_5 0x14
53#define WM8900_DAC_CLKDIV_6 0x18 53#define WM8900_DAC_CLKDIV_6 0x18
54 54
55extern struct snd_soc_dai wm8900_dai;
56extern struct snd_soc_codec_device soc_codec_dev_wm8900;
57
58#endif 55#endif
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index bf08282d5ee..f5d73ed72cb 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -213,10 +213,12 @@ static u16 wm8903_reg_defaults[] = {
213}; 213};
214 214
215struct wm8903_priv { 215struct wm8903_priv {
216 struct snd_soc_codec codec; 216
217 u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)]; 217 u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
218 218
219 int sysclk; 219 int sysclk;
220 struct i2c_client *control_data;
221 int irq;
220 222
221 /* Reference counts */ 223 /* Reference counts */
222 int class_w_users; 224 int class_w_users;
@@ -252,7 +254,6 @@ static int wm8903_volatile_register(unsigned int reg)
252static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start) 254static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
253{ 255{
254 u16 reg[5]; 256 u16 reg[5];
255 struct i2c_client *i2c = codec->control_data;
256 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 257 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
257 258
258 BUG_ON(start > 48); 259 BUG_ON(start > 48);
@@ -262,7 +263,7 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
262 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 263 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
263 reg[0] | WM8903_WSEQ_ENA); 264 reg[0] | WM8903_WSEQ_ENA);
264 265
265 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start); 266 dev_dbg(codec->dev, "Starting sequence at %d\n", start);
266 267
267 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3, 268 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3,
268 start | WM8903_WSEQ_START); 269 start | WM8903_WSEQ_START);
@@ -277,7 +278,7 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
277 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4); 278 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
278 } while (reg[4] & WM8903_WSEQ_BUSY); 279 } while (reg[4] & WM8903_WSEQ_BUSY);
279 280
280 dev_dbg(&i2c->dev, "Sequence complete\n"); 281 dev_dbg(codec->dev, "Sequence complete\n");
281 282
282 /* Disable the sequencer again if we enabled it */ 283 /* Disable the sequencer again if we enabled it */
283 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]); 284 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
@@ -422,7 +423,6 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
422 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 423 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
423 struct snd_soc_codec *codec = widget->codec; 424 struct snd_soc_codec *codec = widget->codec;
424 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 425 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
425 struct i2c_client *i2c = codec->control_data;
426 u16 reg; 426 u16 reg;
427 int ret; 427 int ret;
428 428
@@ -431,7 +431,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
431 /* Turn it off if we're about to enable bypass */ 431 /* Turn it off if we're about to enable bypass */
432 if (ucontrol->value.integer.value[0]) { 432 if (ucontrol->value.integer.value[0]) {
433 if (wm8903->class_w_users == 0) { 433 if (wm8903->class_w_users == 0) {
434 dev_dbg(&i2c->dev, "Disabling Class W\n"); 434 dev_dbg(codec->dev, "Disabling Class W\n");
435 snd_soc_write(codec, WM8903_CLASS_W_0, reg & 435 snd_soc_write(codec, WM8903_CLASS_W_0, reg &
436 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V)); 436 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
437 } 437 }
@@ -444,14 +444,14 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
444 /* If we've just disabled the last bypass path turn Class W on */ 444 /* If we've just disabled the last bypass path turn Class W on */
445 if (!ucontrol->value.integer.value[0]) { 445 if (!ucontrol->value.integer.value[0]) {
446 if (wm8903->class_w_users == 1) { 446 if (wm8903->class_w_users == 1) {
447 dev_dbg(&i2c->dev, "Enabling Class W\n"); 447 dev_dbg(codec->dev, "Enabling Class W\n");
448 snd_soc_write(codec, WM8903_CLASS_W_0, reg | 448 snd_soc_write(codec, WM8903_CLASS_W_0, reg |
449 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 449 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
450 } 450 }
451 wm8903->class_w_users--; 451 wm8903->class_w_users--;
452 } 452 }
453 453
454 dev_dbg(&i2c->dev, "Bypass use count now %d\n", 454 dev_dbg(codec->dev, "Bypass use count now %d\n",
455 wm8903->class_w_users); 455 wm8903->class_w_users);
456 456
457 return ret; 457 return ret;
@@ -935,7 +935,6 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
935static int wm8903_set_bias_level(struct snd_soc_codec *codec, 935static int wm8903_set_bias_level(struct snd_soc_codec *codec,
936 enum snd_soc_bias_level level) 936 enum snd_soc_bias_level level)
937{ 937{
938 struct i2c_client *i2c = codec->control_data;
939 u16 reg, reg2; 938 u16 reg, reg2;
940 939
941 switch (level) { 940 switch (level) {
@@ -974,7 +973,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
974 /* By default no bypass paths are enabled so 973 /* By default no bypass paths are enabled so
975 * enable Class W support. 974 * enable Class W support.
976 */ 975 */
977 dev_dbg(&i2c->dev, "Enabling Class W\n"); 976 dev_dbg(codec->dev, "Enabling Class W\n");
978 snd_soc_write(codec, WM8903_CLASS_W_0, reg | 977 snd_soc_write(codec, WM8903_CLASS_W_0, reg |
979 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 978 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
980 } 979 }
@@ -1228,10 +1227,8 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
1228 struct snd_soc_dai *dai) 1227 struct snd_soc_dai *dai)
1229{ 1228{
1230 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1229 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1231 struct snd_soc_device *socdev = rtd->socdev; 1230 struct snd_soc_codec *codec = rtd->codec;
1232 struct snd_soc_codec *codec = socdev->card->codec;
1233 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1231 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1234 struct i2c_client *i2c = codec->control_data;
1235 struct snd_pcm_runtime *master_runtime; 1232 struct snd_pcm_runtime *master_runtime;
1236 1233
1237 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1234 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -1245,7 +1242,7 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
1245 if (wm8903->master_substream) { 1242 if (wm8903->master_substream) {
1246 master_runtime = wm8903->master_substream->runtime; 1243 master_runtime = wm8903->master_substream->runtime;
1247 1244
1248 dev_dbg(&i2c->dev, "Constraining to %d bits\n", 1245 dev_dbg(codec->dev, "Constraining to %d bits\n",
1249 master_runtime->sample_bits); 1246 master_runtime->sample_bits);
1250 1247
1251 snd_pcm_hw_constraint_minmax(substream->runtime, 1248 snd_pcm_hw_constraint_minmax(substream->runtime,
@@ -1264,8 +1261,7 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream,
1264 struct snd_soc_dai *dai) 1261 struct snd_soc_dai *dai)
1265{ 1262{
1266 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1263 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1267 struct snd_soc_device *socdev = rtd->socdev; 1264 struct snd_soc_codec *codec = rtd->codec;
1268 struct snd_soc_codec *codec = socdev->card->codec;
1269 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1265 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1270 1266
1271 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1267 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -1284,10 +1280,8 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1284 struct snd_soc_dai *dai) 1280 struct snd_soc_dai *dai)
1285{ 1281{
1286 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1282 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1287 struct snd_soc_device *socdev = rtd->socdev; 1283 struct snd_soc_codec *codec =rtd->codec;
1288 struct snd_soc_codec *codec = socdev->card->codec;
1289 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1284 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1290 struct i2c_client *i2c = codec->control_data;
1291 int fs = params_rate(params); 1285 int fs = params_rate(params);
1292 int bclk; 1286 int bclk;
1293 int bclk_div; 1287 int bclk_div;
@@ -1306,7 +1300,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1306 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); 1300 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
1307 1301
1308 if (substream == wm8903->slave_substream) { 1302 if (substream == wm8903->slave_substream) {
1309 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n"); 1303 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
1310 return 0; 1304 return 0;
1311 } 1305 }
1312 1306
@@ -1332,7 +1326,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1332 switch (sample_rates[dsp_config].rate) { 1326 switch (sample_rates[dsp_config].rate) {
1333 case 88200: 1327 case 88200:
1334 case 96000: 1328 case 96000:
1335 dev_err(&i2c->dev, "%dHz unsupported by ADC\n", 1329 dev_err(codec->dev, "%dHz unsupported by ADC\n",
1336 fs); 1330 fs);
1337 return -EINVAL; 1331 return -EINVAL;
1338 1332
@@ -1340,7 +1334,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1340 break; 1334 break;
1341 } 1335 }
1342 1336
1343 dev_dbg(&i2c->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate); 1337 dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
1344 clock1 &= ~WM8903_SAMPLE_RATE_MASK; 1338 clock1 &= ~WM8903_SAMPLE_RATE_MASK;
1345 clock1 |= sample_rates[dsp_config].value; 1339 clock1 |= sample_rates[dsp_config].value;
1346 1340
@@ -1366,7 +1360,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1366 return -EINVAL; 1360 return -EINVAL;
1367 } 1361 }
1368 1362
1369 dev_dbg(&i2c->dev, "MCLK = %dHz, target sample rate = %dHz\n", 1363 dev_dbg(codec->dev, "MCLK = %dHz, target sample rate = %dHz\n",
1370 wm8903->sysclk, fs); 1364 wm8903->sysclk, fs);
1371 1365
1372 /* We may not have an MCLK which allows us to generate exactly 1366 /* We may not have an MCLK which allows us to generate exactly
@@ -1401,12 +1395,12 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1401 clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT; 1395 clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT;
1402 clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT; 1396 clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT;
1403 1397
1404 dev_dbg(&i2c->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n", 1398 dev_dbg(codec->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n",
1405 clk_sys_ratios[clk_config].rate, 1399 clk_sys_ratios[clk_config].rate,
1406 clk_sys_ratios[clk_config].mode, 1400 clk_sys_ratios[clk_config].mode,
1407 clk_sys_ratios[clk_config].div); 1401 clk_sys_ratios[clk_config].div);
1408 1402
1409 dev_dbg(&i2c->dev, "Actual CLK_SYS = %dHz\n", clk_sys); 1403 dev_dbg(codec->dev, "Actual CLK_SYS = %dHz\n", clk_sys);
1410 1404
1411 /* We may not get quite the right frequency if using 1405 /* We may not get quite the right frequency if using
1412 * approximate clocks so look for the closest match that is 1406 * approximate clocks so look for the closest match that is
@@ -1428,7 +1422,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1428 aif2 &= ~WM8903_BCLK_DIV_MASK; 1422 aif2 &= ~WM8903_BCLK_DIV_MASK;
1429 aif3 &= ~WM8903_LRCLK_RATE_MASK; 1423 aif3 &= ~WM8903_LRCLK_RATE_MASK;
1430 1424
1431 dev_dbg(&i2c->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n", 1425 dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
1432 bclk_divs[bclk_div].ratio / 10, bclk, 1426 bclk_divs[bclk_div].ratio / 10, bclk,
1433 (clk_sys * 10) / bclk_divs[bclk_div].ratio); 1427 (clk_sys * 10) / bclk_divs[bclk_div].ratio);
1434 1428
@@ -1504,8 +1498,8 @@ EXPORT_SYMBOL_GPL(wm8903_mic_detect);
1504 1498
1505static irqreturn_t wm8903_irq(int irq, void *data) 1499static irqreturn_t wm8903_irq(int irq, void *data)
1506{ 1500{
1507 struct wm8903_priv *wm8903 = data; 1501 struct snd_soc_codec *codec = data;
1508 struct snd_soc_codec *codec = &wm8903->codec; 1502 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1509 int mic_report; 1503 int mic_report;
1510 int int_pol; 1504 int int_pol;
1511 int int_val = 0; 1505 int int_val = 0;
@@ -1586,8 +1580,8 @@ static struct snd_soc_dai_ops wm8903_dai_ops = {
1586 .set_sysclk = wm8903_set_dai_sysclk, 1580 .set_sysclk = wm8903_set_dai_sysclk,
1587}; 1581};
1588 1582
1589struct snd_soc_dai wm8903_dai = { 1583static struct snd_soc_dai_driver wm8903_dai = {
1590 .name = "WM8903", 1584 .name = "wm8903-hifi",
1591 .playback = { 1585 .playback = {
1592 .stream_name = "Playback", 1586 .stream_name = "Playback",
1593 .channels_min = 2, 1587 .channels_min = 2,
@@ -1605,23 +1599,16 @@ struct snd_soc_dai wm8903_dai = {
1605 .ops = &wm8903_dai_ops, 1599 .ops = &wm8903_dai_ops,
1606 .symmetric_rates = 1, 1600 .symmetric_rates = 1,
1607}; 1601};
1608EXPORT_SYMBOL_GPL(wm8903_dai);
1609 1602
1610static int wm8903_suspend(struct platform_device *pdev, pm_message_t state) 1603static int wm8903_suspend(struct snd_soc_codec *codec, pm_message_t state)
1611{ 1604{
1612 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1613 struct snd_soc_codec *codec = socdev->card->codec;
1614
1615 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1605 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1616 1606
1617 return 0; 1607 return 0;
1618} 1608}
1619 1609
1620static int wm8903_resume(struct platform_device *pdev) 1610static int wm8903_resume(struct snd_soc_codec *codec)
1621{ 1611{
1622 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1623 struct snd_soc_codec *codec = socdev->card->codec;
1624 struct i2c_client *i2c = codec->control_data;
1625 int i; 1612 int i;
1626 u16 *reg_cache = codec->reg_cache; 1613 u16 *reg_cache = codec->reg_cache;
1627 u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults), 1614 u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults),
@@ -1637,65 +1624,38 @@ static int wm8903_resume(struct platform_device *pdev)
1637 snd_soc_write(codec, i, tmp_cache[i]); 1624 snd_soc_write(codec, i, tmp_cache[i]);
1638 kfree(tmp_cache); 1625 kfree(tmp_cache);
1639 } else { 1626 } else {
1640 dev_err(&i2c->dev, "Failed to allocate temporary cache\n"); 1627 dev_err(codec->dev, "Failed to allocate temporary cache\n");
1641 } 1628 }
1642 1629
1643 return 0; 1630 return 0;
1644} 1631}
1645 1632
1646static struct snd_soc_codec *wm8903_codec; 1633static int wm8903_probe(struct snd_soc_codec *codec)
1647
1648static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1649 const struct i2c_device_id *id)
1650{ 1634{
1651 struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); 1635 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
1652 struct wm8903_priv *wm8903; 1636 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1653 struct snd_soc_codec *codec;
1654 int ret, i; 1637 int ret, i;
1655 int trigger, irq_pol; 1638 int trigger, irq_pol;
1656 u16 val; 1639 u16 val;
1657 1640
1658 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
1659 if (wm8903 == NULL)
1660 return -ENOMEM;
1661
1662 codec = &wm8903->codec;
1663
1664 mutex_init(&codec->mutex);
1665 INIT_LIST_HEAD(&codec->dapm_widgets);
1666 INIT_LIST_HEAD(&codec->dapm_paths);
1667
1668 codec->dev = &i2c->dev;
1669 codec->name = "WM8903";
1670 codec->owner = THIS_MODULE;
1671 codec->bias_level = SND_SOC_BIAS_OFF;
1672 codec->set_bias_level = wm8903_set_bias_level;
1673 codec->dai = &wm8903_dai;
1674 codec->num_dai = 1;
1675 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
1676 codec->reg_cache = &wm8903->reg_cache[0];
1677 snd_soc_codec_set_drvdata(codec, wm8903);
1678 codec->volatile_register = wm8903_volatile_register;
1679 init_completion(&wm8903->wseq); 1641 init_completion(&wm8903->wseq);
1680 1642 codec->control_data = wm8903->control_data;
1681 i2c_set_clientdata(i2c, codec);
1682 codec->control_data = i2c;
1683 1643
1684 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1644 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1685 if (ret != 0) { 1645 if (ret != 0) {
1686 dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret); 1646 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1687 goto err; 1647 return ret;
1688 } 1648 }
1689 1649
1690 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID); 1650 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID);
1691 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { 1651 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
1692 dev_err(&i2c->dev, 1652 dev_err(codec->dev,
1693 "Device with ID register %x is not a WM8903\n", val); 1653 "Device with ID register %x is not a WM8903\n", val);
1694 return -ENODEV; 1654 return -ENODEV;
1695 } 1655 }
1696 1656
1697 val = snd_soc_read(codec, WM8903_REVISION_NUMBER); 1657 val = snd_soc_read(codec, WM8903_REVISION_NUMBER);
1698 dev_info(&i2c->dev, "WM8903 revision %d\n", 1658 dev_info(codec->dev, "WM8903 revision %d\n",
1699 val & WM8903_CHIP_REV_MASK); 1659 val & WM8903_CHIP_REV_MASK);
1700 1660
1701 wm8903_reset(codec); 1661 wm8903_reset(codec);
@@ -1721,7 +1681,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1721 wm8903->mic_delay = pdata->micdet_delay; 1681 wm8903->mic_delay = pdata->micdet_delay;
1722 } 1682 }
1723 1683
1724 if (i2c->irq) { 1684 if (wm8903->irq) {
1725 if (pdata && pdata->irq_active_low) { 1685 if (pdata && pdata->irq_active_low) {
1726 trigger = IRQF_TRIGGER_LOW; 1686 trigger = IRQF_TRIGGER_LOW;
1727 irq_pol = WM8903_IRQ_POL; 1687 irq_pol = WM8903_IRQ_POL;
@@ -1733,13 +1693,13 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1733 snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL, 1693 snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL,
1734 WM8903_IRQ_POL, irq_pol); 1694 WM8903_IRQ_POL, irq_pol);
1735 1695
1736 ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq, 1696 ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq,
1737 trigger | IRQF_ONESHOT, 1697 trigger | IRQF_ONESHOT,
1738 "wm8903", wm8903); 1698 "wm8903", codec);
1739 if (ret != 0) { 1699 if (ret != 0) {
1740 dev_err(&i2c->dev, "Failed to request IRQ: %d\n", 1700 dev_err(codec->dev, "Failed to request IRQ: %d\n",
1741 ret); 1701 ret);
1742 goto err; 1702 return ret;
1743 } 1703 }
1744 1704
1745 /* Enable write sequencer interrupts */ 1705 /* Enable write sequencer interrupts */
@@ -1781,133 +1741,97 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1781 val |= WM8903_DAC_MUTEMODE; 1741 val |= WM8903_DAC_MUTEMODE;
1782 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val); 1742 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val);
1783 1743
1784 wm8903_dai.dev = &i2c->dev; 1744 snd_soc_add_controls(codec, wm8903_snd_controls,
1785 wm8903_codec = codec; 1745 ARRAY_SIZE(wm8903_snd_controls));
1786 1746 wm8903_add_widgets(codec);
1787 ret = snd_soc_register_codec(codec);
1788 if (ret != 0) {
1789 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1790 goto err_irq;
1791 }
1792
1793 ret = snd_soc_register_dai(&wm8903_dai);
1794 if (ret != 0) {
1795 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
1796 goto err_codec;
1797 }
1798
1799 return ret;
1800 1747
1801err_codec:
1802 snd_soc_unregister_codec(codec);
1803err_irq:
1804 if (i2c->irq)
1805 free_irq(i2c->irq, wm8903);
1806err:
1807 wm8903_codec = NULL;
1808 kfree(wm8903);
1809 return ret; 1748 return ret;
1810} 1749}
1811 1750
1812static __devexit int wm8903_i2c_remove(struct i2c_client *client) 1751/* power down chip */
1752static int wm8903_remove(struct snd_soc_codec *codec)
1813{ 1753{
1814 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1754 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1815 struct wm8903_priv *priv = snd_soc_codec_get_drvdata(codec); 1755 return 0;
1756}
1816 1757
1817 snd_soc_unregister_dai(&wm8903_dai); 1758static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
1818 snd_soc_unregister_codec(codec); 1759 .probe = wm8903_probe,
1760 .remove = wm8903_remove,
1761 .suspend = wm8903_suspend,
1762 .resume = wm8903_resume,
1763 .set_bias_level = wm8903_set_bias_level,
1764 .reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults),
1765 .reg_word_size = sizeof(u16),
1766 .reg_cache_default = wm8903_reg_defaults,
1767 .volatile_register = wm8903_volatile_register,
1768};
1819 1769
1820 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1770#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1771static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1772 const struct i2c_device_id *id)
1773{
1774 struct wm8903_priv *wm8903;
1775 int ret;
1821 1776
1822 if (client->irq) 1777 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
1823 free_irq(client->irq, priv); 1778 if (wm8903 == NULL)
1779 return -ENOMEM;
1824 1780
1825 kfree(priv); 1781 i2c_set_clientdata(i2c, wm8903);
1782 wm8903->control_data = i2c;
1783 wm8903->irq = i2c->irq;
1826 1784
1827 wm8903_codec = NULL; 1785 ret = snd_soc_register_codec(&i2c->dev,
1828 wm8903_dai.dev = NULL; 1786 &soc_codec_dev_wm8903, &wm8903_dai, 1);
1787 if (ret < 0)
1788 kfree(wm8903);
1789 return ret;
1790}
1829 1791
1792static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1793{
1794 snd_soc_unregister_codec(&client->dev);
1795 kfree(i2c_get_clientdata(client));
1830 return 0; 1796 return 0;
1831} 1797}
1832 1798
1833/* i2c codec control layer */
1834static const struct i2c_device_id wm8903_i2c_id[] = { 1799static const struct i2c_device_id wm8903_i2c_id[] = {
1835 { "wm8903", 0 }, 1800 { "wm8903", 0 },
1836 { } 1801 { }
1837}; 1802};
1838MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id); 1803MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id);
1839 1804
1840static struct i2c_driver wm8903_i2c_driver = { 1805static struct i2c_driver wm8903_i2c_driver = {
1841 .driver = { 1806 .driver = {
1842 .name = "WM8903", 1807 .name = "wm8903-codec",
1843 .owner = THIS_MODULE, 1808 .owner = THIS_MODULE,
1844 }, 1809 },
1845 .probe = wm8903_i2c_probe, 1810 .probe = wm8903_i2c_probe,
1846 .remove = __devexit_p(wm8903_i2c_remove), 1811 .remove = __devexit_p(wm8903_i2c_remove),
1847 .id_table = wm8903_i2c_id, 1812 .id_table = wm8903_i2c_id,
1848}; 1813};
1814#endif
1849 1815
1850static int wm8903_probe(struct platform_device *pdev) 1816static int __init wm8903_modinit(void)
1851{ 1817{
1852 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1853 int ret = 0; 1818 int ret = 0;
1854 1819#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1855 if (!wm8903_codec) { 1820 ret = i2c_add_driver(&wm8903_i2c_driver);
1856 dev_err(&pdev->dev, "I2C device not yet probed\n"); 1821 if (ret != 0) {
1857 goto err; 1822 printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n",
1858 } 1823 ret);
1859
1860 socdev->card->codec = wm8903_codec;
1861
1862 /* register pcms */
1863 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1864 if (ret < 0) {
1865 dev_err(&pdev->dev, "failed to create pcms\n");
1866 goto err;
1867 } 1824 }
1868 1825#endif
1869 snd_soc_add_controls(socdev->card->codec, wm8903_snd_controls,
1870 ARRAY_SIZE(wm8903_snd_controls));
1871 wm8903_add_widgets(socdev->card->codec);
1872
1873 return ret; 1826 return ret;
1874
1875err:
1876 return ret;
1877}
1878
1879/* power down chip */
1880static int wm8903_remove(struct platform_device *pdev)
1881{
1882 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1883 struct snd_soc_codec *codec = socdev->card->codec;
1884
1885 if (codec->control_data)
1886 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1887
1888 snd_soc_free_pcms(socdev);
1889 snd_soc_dapm_free(socdev);
1890
1891 return 0;
1892}
1893
1894struct snd_soc_codec_device soc_codec_dev_wm8903 = {
1895 .probe = wm8903_probe,
1896 .remove = wm8903_remove,
1897 .suspend = wm8903_suspend,
1898 .resume = wm8903_resume,
1899};
1900EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
1901
1902static int __init wm8903_modinit(void)
1903{
1904 return i2c_add_driver(&wm8903_i2c_driver);
1905} 1827}
1906module_init(wm8903_modinit); 1828module_init(wm8903_modinit);
1907 1829
1908static void __exit wm8903_exit(void) 1830static void __exit wm8903_exit(void)
1909{ 1831{
1832#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1910 i2c_del_driver(&wm8903_i2c_driver); 1833 i2c_del_driver(&wm8903_i2c_driver);
1834#endif
1911} 1835}
1912module_exit(wm8903_exit); 1836module_exit(wm8903_exit);
1913 1837
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index ce384a2ad82..996435e681e 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -15,9 +15,6 @@
15 15
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17 17
18extern struct snd_soc_dai wm8903_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8903;
20
21extern int wm8903_mic_detect(struct snd_soc_codec *codec, 18extern int wm8903_mic_detect(struct snd_soc_codec *codec,
22 struct snd_soc_jack *jack, 19 struct snd_soc_jack *jack,
23 int det, int shrt); 20 int det, int shrt);
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index f7dcabf6283..33be84e506e 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -31,9 +31,6 @@
31 31
32#include "wm8904.h" 32#include "wm8904.h"
33 33
34static struct snd_soc_codec *wm8904_codec;
35struct snd_soc_codec_device soc_codec_dev_wm8904;
36
37enum wm8904_type { 34enum wm8904_type {
38 WM8904, 35 WM8904,
39 WM8912, 36 WM8912,
@@ -52,10 +49,11 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
52 49
53/* codec private data */ 50/* codec private data */
54struct wm8904_priv { 51struct wm8904_priv {
55 struct snd_soc_codec codec; 52
56 u16 reg_cache[WM8904_MAX_REGISTER + 1]; 53 u16 reg_cache[WM8904_MAX_REGISTER + 1];
57 54
58 enum wm8904_type devtype; 55 enum wm8904_type devtype;
56 void *control_data;
59 57
60 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES]; 58 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
61 59
@@ -689,7 +687,7 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
689 struct snd_ctl_elem_value *ucontrol) 687 struct snd_ctl_elem_value *ucontrol)
690{ 688{
691 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 689 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
692 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 690 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
693 struct wm8904_pdata *pdata = wm8904->pdata; 691 struct wm8904_pdata *pdata = wm8904->pdata;
694 int value = ucontrol->value.integer.value[0]; 692 int value = ucontrol->value.integer.value[0];
695 693
@@ -760,7 +758,7 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
760 struct snd_ctl_elem_value *ucontrol) 758 struct snd_ctl_elem_value *ucontrol)
761{ 759{
762 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 760 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
763 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 761 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
764 struct wm8904_pdata *pdata = wm8904->pdata; 762 struct wm8904_pdata *pdata = wm8904->pdata;
765 int value = ucontrol->value.integer.value[0]; 763 int value = ucontrol->value.integer.value[0];
766 764
@@ -2218,8 +2216,8 @@ static struct snd_soc_dai_ops wm8904_dai_ops = {
2218 .digital_mute = wm8904_digital_mute, 2216 .digital_mute = wm8904_digital_mute,
2219}; 2217};
2220 2218
2221struct snd_soc_dai wm8904_dai = { 2219static struct snd_soc_dai_driver wm8904_dai = {
2222 .name = "WM8904", 2220 .name = "wm8904-hifi",
2223 .playback = { 2221 .playback = {
2224 .stream_name = "Playback", 2222 .stream_name = "Playback",
2225 .channels_min = 2, 2223 .channels_min = 2,
@@ -2237,24 +2235,17 @@ struct snd_soc_dai wm8904_dai = {
2237 .ops = &wm8904_dai_ops, 2235 .ops = &wm8904_dai_ops,
2238 .symmetric_rates = 1, 2236 .symmetric_rates = 1,
2239}; 2237};
2240EXPORT_SYMBOL_GPL(wm8904_dai);
2241 2238
2242#ifdef CONFIG_PM 2239#ifdef CONFIG_PM
2243static int wm8904_suspend(struct platform_device *pdev, pm_message_t state) 2240static int wm8904_suspend(struct snd_soc_codec *codec, pm_message_t state)
2244{ 2241{
2245 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2246 struct snd_soc_codec *codec = socdev->card->codec;
2247
2248 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF); 2242 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2249 2243
2250 return 0; 2244 return 0;
2251} 2245}
2252 2246
2253static int wm8904_resume(struct platform_device *pdev) 2247static int wm8904_resume(struct snd_soc_codec *codec)
2254{ 2248{
2255 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2256 struct snd_soc_codec *codec = socdev->card->codec;
2257
2258 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2249 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2259 2250
2260 return 0; 2251 return 0;
@@ -2264,9 +2255,9 @@ static int wm8904_resume(struct platform_device *pdev)
2264#define wm8904_resume NULL 2255#define wm8904_resume NULL
2265#endif 2256#endif
2266 2257
2267static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904) 2258static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
2268{ 2259{
2269 struct snd_soc_codec *codec = &wm8904->codec; 2260 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2270 struct wm8904_pdata *pdata = wm8904->pdata; 2261 struct wm8904_pdata *pdata = wm8904->pdata;
2271 struct snd_kcontrol_new control = 2262 struct snd_kcontrol_new control =
2272 SOC_ENUM_EXT("EQ Mode", 2263 SOC_ENUM_EXT("EQ Mode",
@@ -2315,20 +2306,20 @@ static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904)
2315 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; 2306 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2316 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; 2307 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2317 2308
2318 ret = snd_soc_add_controls(&wm8904->codec, &control, 1); 2309 ret = snd_soc_add_controls(codec, &control, 1);
2319 if (ret != 0) 2310 if (ret != 0)
2320 dev_err(wm8904->codec.dev, 2311 dev_err(codec->dev,
2321 "Failed to add ReTune Mobile control: %d\n", ret); 2312 "Failed to add ReTune Mobile control: %d\n", ret);
2322} 2313}
2323 2314
2324static void wm8904_handle_pdata(struct wm8904_priv *wm8904) 2315static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2325{ 2316{
2326 struct snd_soc_codec *codec = &wm8904->codec; 2317 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2327 struct wm8904_pdata *pdata = wm8904->pdata; 2318 struct wm8904_pdata *pdata = wm8904->pdata;
2328 int ret, i; 2319 int ret, i;
2329 2320
2330 if (!pdata) { 2321 if (!pdata) {
2331 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls, 2322 snd_soc_add_controls(codec, wm8904_eq_controls,
2332 ARRAY_SIZE(wm8904_eq_controls)); 2323 ARRAY_SIZE(wm8904_eq_controls));
2333 return; 2324 return;
2334 } 2325 }
@@ -2344,7 +2335,7 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2344 wm8904->drc_texts = kmalloc(sizeof(char *) 2335 wm8904->drc_texts = kmalloc(sizeof(char *)
2345 * pdata->num_drc_cfgs, GFP_KERNEL); 2336 * pdata->num_drc_cfgs, GFP_KERNEL);
2346 if (!wm8904->drc_texts) { 2337 if (!wm8904->drc_texts) {
2347 dev_err(wm8904->codec.dev, 2338 dev_err(codec->dev,
2348 "Failed to allocate %d DRC config texts\n", 2339 "Failed to allocate %d DRC config texts\n",
2349 pdata->num_drc_cfgs); 2340 pdata->num_drc_cfgs);
2350 return; 2341 return;
@@ -2356,9 +2347,9 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2356 wm8904->drc_enum.max = pdata->num_drc_cfgs; 2347 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2357 wm8904->drc_enum.texts = wm8904->drc_texts; 2348 wm8904->drc_enum.texts = wm8904->drc_texts;
2358 2349
2359 ret = snd_soc_add_controls(&wm8904->codec, &control, 1); 2350 ret = snd_soc_add_controls(codec, &control, 1);
2360 if (ret != 0) 2351 if (ret != 0)
2361 dev_err(wm8904->codec.dev, 2352 dev_err(codec->dev,
2362 "Failed to add DRC mode control: %d\n", ret); 2353 "Failed to add DRC mode control: %d\n", ret);
2363 2354
2364 wm8904_set_drc(codec); 2355 wm8904_set_drc(codec);
@@ -2368,89 +2359,19 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2368 pdata->num_retune_mobile_cfgs); 2359 pdata->num_retune_mobile_cfgs);
2369 2360
2370 if (pdata->num_retune_mobile_cfgs) 2361 if (pdata->num_retune_mobile_cfgs)
2371 wm8904_handle_retune_mobile_pdata(wm8904); 2362 wm8904_handle_retune_mobile_pdata(codec);
2372 else 2363 else
2373 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls, 2364 snd_soc_add_controls(codec, wm8904_eq_controls,
2374 ARRAY_SIZE(wm8904_eq_controls)); 2365 ARRAY_SIZE(wm8904_eq_controls));
2375} 2366}
2376 2367
2377static int wm8904_probe(struct platform_device *pdev)
2378{
2379 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2380 struct snd_soc_codec *codec;
2381 int ret = 0;
2382
2383 if (wm8904_codec == NULL) {
2384 dev_err(&pdev->dev, "Codec device not registered\n");
2385 return -ENODEV;
2386 }
2387 2368
2388 socdev->card->codec = wm8904_codec; 2369static int wm8904_probe(struct snd_soc_codec *codec)
2389 codec = wm8904_codec;
2390
2391 /* register pcms */
2392 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2393 if (ret < 0) {
2394 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
2395 goto pcm_err;
2396 }
2397
2398 wm8904_handle_pdata(snd_soc_codec_get_drvdata(codec));
2399
2400 wm8904_add_widgets(codec);
2401
2402 return ret;
2403
2404pcm_err:
2405 return ret;
2406}
2407
2408static int wm8904_remove(struct platform_device *pdev)
2409{
2410 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2411
2412 snd_soc_free_pcms(socdev);
2413 snd_soc_dapm_free(socdev);
2414
2415 return 0;
2416}
2417
2418struct snd_soc_codec_device soc_codec_dev_wm8904 = {
2419 .probe = wm8904_probe,
2420 .remove = wm8904_remove,
2421 .suspend = wm8904_suspend,
2422 .resume = wm8904_resume,
2423};
2424EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
2425
2426static int wm8904_register(struct wm8904_priv *wm8904,
2427 enum snd_soc_control_type control)
2428{ 2370{
2371 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2429 struct wm8904_pdata *pdata = wm8904->pdata; 2372 struct wm8904_pdata *pdata = wm8904->pdata;
2430 int ret; 2373 int ret, i;
2431 struct snd_soc_codec *codec = &wm8904->codec;
2432 int i;
2433
2434 if (wm8904_codec) {
2435 dev_err(codec->dev, "Another WM8904 is registered\n");
2436 ret = -EINVAL;
2437 goto err;
2438 }
2439 2374
2440 mutex_init(&codec->mutex);
2441 INIT_LIST_HEAD(&codec->dapm_widgets);
2442 INIT_LIST_HEAD(&codec->dapm_paths);
2443
2444 snd_soc_codec_set_drvdata(codec, wm8904);
2445 codec->name = "WM8904";
2446 codec->owner = THIS_MODULE;
2447 codec->bias_level = SND_SOC_BIAS_OFF;
2448 codec->set_bias_level = wm8904_set_bias_level;
2449 codec->dai = &wm8904_dai;
2450 codec->num_dai = 1;
2451 codec->reg_cache_size = WM8904_MAX_REGISTER;
2452 codec->reg_cache = &wm8904->reg_cache;
2453 codec->volatile_register = wm8904_volatile_register;
2454 codec->cache_sync = 1; 2375 codec->cache_sync = 1;
2455 codec->idle_bias_off = 1; 2376 codec->idle_bias_off = 1;
2456 2377
@@ -2463,16 +2384,13 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2463 default: 2384 default:
2464 dev_err(codec->dev, "Unknown device type %d\n", 2385 dev_err(codec->dev, "Unknown device type %d\n",
2465 wm8904->devtype); 2386 wm8904->devtype);
2466 ret = -EINVAL; 2387 return -EINVAL;
2467 goto err;
2468 } 2388 }
2469 2389
2470 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg)); 2390 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
2471
2472 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
2473 if (ret != 0) { 2391 if (ret != 0) {
2474 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 2392 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2475 goto err; 2393 return ret;
2476 } 2394 }
2477 2395
2478 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++) 2396 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
@@ -2482,7 +2400,7 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2482 wm8904->supplies); 2400 wm8904->supplies);
2483 if (ret != 0) { 2401 if (ret != 0) {
2484 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 2402 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2485 goto err; 2403 return ret;
2486 } 2404 }
2487 2405
2488 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), 2406 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
@@ -2517,8 +2435,6 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2517 goto err_enable; 2435 goto err_enable;
2518 } 2436 }
2519 2437
2520 wm8904_dai.dev = codec->dev;
2521
2522 /* Change some default settings - latch VU and enable ZC */ 2438 /* Change some default settings - latch VU and enable ZC */
2523 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; 2439 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
2524 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; 2440 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
@@ -2563,72 +2479,68 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2563 /* Bias level configuration will have done an extra enable */ 2479 /* Bias level configuration will have done an extra enable */
2564 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2480 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2565 2481
2566 wm8904_codec = codec; 2482 wm8904_handle_pdata(codec);
2567 2483
2568 ret = snd_soc_register_codec(codec); 2484 wm8904_add_widgets(codec);
2569 if (ret != 0) {
2570 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2571 goto err_enable;
2572 }
2573
2574 ret = snd_soc_register_dai(&wm8904_dai);
2575 if (ret != 0) {
2576 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
2577 goto err_codec;
2578 }
2579 2485
2580 return 0; 2486 return 0;
2581 2487
2582err_codec:
2583 snd_soc_unregister_codec(codec);
2584err_enable: 2488err_enable:
2585 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2489 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2586err_get: 2490err_get:
2587 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2491 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2588err:
2589 kfree(wm8904);
2590 return ret; 2492 return ret;
2591} 2493}
2592 2494
2593static void wm8904_unregister(struct wm8904_priv *wm8904) 2495static int wm8904_remove(struct snd_soc_codec *codec)
2594{ 2496{
2595 wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF); 2497 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2498
2499 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2596 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2500 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2597 snd_soc_unregister_dai(&wm8904_dai); 2501
2598 snd_soc_unregister_codec(&wm8904->codec); 2502 return 0;
2599 kfree(wm8904);
2600 wm8904_codec = NULL;
2601} 2503}
2602 2504
2505static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
2506 .probe = wm8904_probe,
2507 .remove = wm8904_remove,
2508 .suspend = wm8904_suspend,
2509 .resume = wm8904_resume,
2510 .set_bias_level = wm8904_set_bias_level,
2511 .reg_cache_size = ARRAY_SIZE(wm8904_reg),
2512 .reg_word_size = sizeof(u16),
2513 .reg_cache_default = wm8904_reg,
2514 .volatile_register = wm8904_volatile_register,
2515};
2516
2603#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2517#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2604static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, 2518static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2605 const struct i2c_device_id *id) 2519 const struct i2c_device_id *id)
2606{ 2520{
2607 struct wm8904_priv *wm8904; 2521 struct wm8904_priv *wm8904;
2608 struct snd_soc_codec *codec; 2522 int ret;
2609 2523
2610 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL); 2524 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL);
2611 if (wm8904 == NULL) 2525 if (wm8904 == NULL)
2612 return -ENOMEM; 2526 return -ENOMEM;
2613 2527
2614 codec = &wm8904->codec;
2615 codec->hw_write = (hw_write_t)i2c_master_send;
2616
2617 wm8904->devtype = id->driver_data; 2528 wm8904->devtype = id->driver_data;
2618
2619 i2c_set_clientdata(i2c, wm8904); 2529 i2c_set_clientdata(i2c, wm8904);
2620 codec->control_data = i2c; 2530 wm8904->control_data = i2c;
2621 wm8904->pdata = i2c->dev.platform_data; 2531 wm8904->pdata = i2c->dev.platform_data;
2622 2532
2623 codec->dev = &i2c->dev; 2533 ret = snd_soc_register_codec(&i2c->dev,
2624 2534 &soc_codec_dev_wm8904, &wm8904_dai, 1);
2625 return wm8904_register(wm8904, SND_SOC_I2C); 2535 if (ret < 0)
2536 kfree(wm8904);
2537 return ret;
2626} 2538}
2627 2539
2628static __devexit int wm8904_i2c_remove(struct i2c_client *client) 2540static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2629{ 2541{
2630 struct wm8904_priv *wm8904 = i2c_get_clientdata(client); 2542 snd_soc_unregister_codec(&client->dev);
2631 wm8904_unregister(wm8904); 2543 kfree(i2c_get_clientdata(client));
2632 return 0; 2544 return 0;
2633} 2545}
2634 2546
@@ -2641,7 +2553,7 @@ MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
2641 2553
2642static struct i2c_driver wm8904_i2c_driver = { 2554static struct i2c_driver wm8904_i2c_driver = {
2643 .driver = { 2555 .driver = {
2644 .name = "WM8904", 2556 .name = "wm8904-codec",
2645 .owner = THIS_MODULE, 2557 .owner = THIS_MODULE,
2646 }, 2558 },
2647 .probe = wm8904_i2c_probe, 2559 .probe = wm8904_i2c_probe,
@@ -2652,15 +2564,15 @@ static struct i2c_driver wm8904_i2c_driver = {
2652 2564
2653static int __init wm8904_modinit(void) 2565static int __init wm8904_modinit(void)
2654{ 2566{
2655 int ret; 2567 int ret = 0;
2656#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2568#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2657 ret = i2c_add_driver(&wm8904_i2c_driver); 2569 ret = i2c_add_driver(&wm8904_i2c_driver);
2658 if (ret != 0) { 2570 if (ret != 0) {
2659 printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n", 2571 printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n",
2660 ret); 2572 ret);
2661 } 2573 }
2662#endif 2574#endif
2663 return 0; 2575 return ret;
2664} 2576}
2665module_init(wm8904_modinit); 2577module_init(wm8904_modinit);
2666 2578
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h
index abe5059b300..9e8c84188ba 100644
--- a/sound/soc/codecs/wm8904.h
+++ b/sound/soc/codecs/wm8904.h
@@ -21,9 +21,6 @@
21#define WM8904_FLL_LRCLK 3 21#define WM8904_FLL_LRCLK 3
22#define WM8904_FLL_FREE_RUNNING 4 22#define WM8904_FLL_FREE_RUNNING 4
23 23
24extern struct snd_soc_dai wm8904_dai;
25extern struct snd_soc_codec_device soc_codec_dev_wm8904;
26
27/* 24/*
28 * Register values. 25 * Register values.
29 */ 26 */
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index f0c11138e61..d28bf0dfdb1 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -44,7 +44,8 @@
44struct wm8940_priv { 44struct wm8940_priv {
45 unsigned int sysclk; 45 unsigned int sysclk;
46 u16 reg_cache[WM8940_CACHEREGNUM]; 46 u16 reg_cache[WM8940_CACHEREGNUM];
47 struct snd_soc_codec codec; 47 enum snd_soc_control_type control_type;
48 void *control_data;
48}; 49};
49 50
50static u16 wm8940_reg_defaults[] = { 51static u16 wm8940_reg_defaults[] = {
@@ -365,8 +366,7 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
365 struct snd_soc_dai *dai) 366 struct snd_soc_dai *dai)
366{ 367{
367 struct snd_soc_pcm_runtime *rtd = substream->private_data; 368 struct snd_soc_pcm_runtime *rtd = substream->private_data;
368 struct snd_soc_device *socdev = rtd->socdev; 369 struct snd_soc_codec *codec = rtd->codec;
369 struct snd_soc_codec *codec = socdev->card->codec;
370 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F; 370 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F;
371 u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1; 371 u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1;
372 u16 companding = snd_soc_read(codec, 372 u16 companding = snd_soc_read(codec,
@@ -636,8 +636,8 @@ static struct snd_soc_dai_ops wm8940_dai_ops = {
636 .set_pll = wm8940_set_dai_pll, 636 .set_pll = wm8940_set_dai_pll,
637}; 637};
638 638
639struct snd_soc_dai wm8940_dai = { 639static struct snd_soc_dai_driver wm8940_dai = {
640 .name = "WM8940", 640 .name = "wm8940-hifi",
641 .playback = { 641 .playback = {
642 .stream_name = "Playback", 642 .stream_name = "Playback",
643 .channels_min = 1, 643 .channels_min = 1,
@@ -655,20 +655,14 @@ struct snd_soc_dai wm8940_dai = {
655 .ops = &wm8940_dai_ops, 655 .ops = &wm8940_dai_ops,
656 .symmetric_rates = 1, 656 .symmetric_rates = 1,
657}; 657};
658EXPORT_SYMBOL_GPL(wm8940_dai);
659 658
660static int wm8940_suspend(struct platform_device *pdev, pm_message_t state) 659static int wm8940_suspend(struct snd_soc_codec *codec, pm_message_t state)
661{ 660{
662 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
663 struct snd_soc_codec *codec = socdev->card->codec;
664
665 return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF); 661 return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
666} 662}
667 663
668static int wm8940_resume(struct platform_device *pdev) 664static int wm8940_resume(struct snd_soc_codec *codec)
669{ 665{
670 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
671 struct snd_soc_codec *codec = socdev->card->codec;
672 int i; 666 int i;
673 int ret; 667 int ret;
674 u8 data[3]; 668 u8 data[3];
@@ -697,108 +691,26 @@ error_ret:
697 return ret; 691 return ret;
698} 692}
699 693
700static struct snd_soc_codec *wm8940_codec; 694static int wm8940_probe(struct snd_soc_codec *codec)
701
702static int wm8940_probe(struct platform_device *pdev)
703{
704 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
705 struct snd_soc_codec *codec;
706
707 int ret = 0;
708
709 if (wm8940_codec == NULL) {
710 dev_err(&pdev->dev, "Codec device not registered\n");
711 return -ENODEV;
712 }
713
714 socdev->card->codec = wm8940_codec;
715 codec = wm8940_codec;
716
717 mutex_init(&codec->mutex);
718 /* register pcms */
719 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
720 if (ret < 0) {
721 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
722 goto pcm_err;
723 }
724
725 ret = snd_soc_add_controls(codec, wm8940_snd_controls,
726 ARRAY_SIZE(wm8940_snd_controls));
727 if (ret)
728 goto error_free_pcms;
729 ret = wm8940_add_widgets(codec);
730 if (ret)
731 goto error_free_pcms;
732
733 return ret;
734
735error_free_pcms:
736 snd_soc_free_pcms(socdev);
737 snd_soc_dapm_free(socdev);
738pcm_err:
739 return ret;
740}
741
742static int wm8940_remove(struct platform_device *pdev)
743{
744 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
745
746 snd_soc_free_pcms(socdev);
747 snd_soc_dapm_free(socdev);
748
749 return 0;
750}
751
752struct snd_soc_codec_device soc_codec_dev_wm8940 = {
753 .probe = wm8940_probe,
754 .remove = wm8940_remove,
755 .suspend = wm8940_suspend,
756 .resume = wm8940_resume,
757};
758EXPORT_SYMBOL_GPL(soc_codec_dev_wm8940);
759
760static int wm8940_register(struct wm8940_priv *wm8940,
761 enum snd_soc_control_type control)
762{ 695{
763 struct wm8940_setup_data *pdata = wm8940->codec.dev->platform_data; 696 struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
764 struct snd_soc_codec *codec = &wm8940->codec; 697 struct wm8940_setup_data *pdata = codec->dev->platform_data;
765 int ret; 698 int ret;
766 u16 reg; 699 u16 reg;
767 if (wm8940_codec) {
768 dev_err(codec->dev, "Another WM8940 is registered\n");
769 return -EINVAL;
770 }
771
772 INIT_LIST_HEAD(&codec->dapm_widgets);
773 INIT_LIST_HEAD(&codec->dapm_paths);
774
775 snd_soc_codec_set_drvdata(codec, wm8940);
776 codec->name = "WM8940";
777 codec->owner = THIS_MODULE;
778 codec->bias_level = SND_SOC_BIAS_OFF;
779 codec->set_bias_level = wm8940_set_bias_level;
780 codec->dai = &wm8940_dai;
781 codec->num_dai = 1;
782 codec->reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults);
783 codec->reg_cache = &wm8940->reg_cache;
784 700
785 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control); 701 codec->control_data = wm8940->control_data;
702 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type);
786 if (ret < 0) { 703 if (ret < 0) {
787 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 704 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
788 return ret; 705 return ret;
789 } 706 }
790 707
791 memcpy(codec->reg_cache, wm8940_reg_defaults,
792 sizeof(wm8940_reg_defaults));
793
794 ret = wm8940_reset(codec); 708 ret = wm8940_reset(codec);
795 if (ret < 0) { 709 if (ret < 0) {
796 dev_err(codec->dev, "Failed to issue reset\n"); 710 dev_err(codec->dev, "Failed to issue reset\n");
797 return ret; 711 return ret;
798 } 712 }
799 713
800 wm8940_dai.dev = codec->dev;
801
802 wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 714 wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
803 715
804 ret = snd_soc_write(codec, WM8940_POWER1, 0x180); 716 ret = snd_soc_write(codec, WM8940_POWER1, 0x180);
@@ -814,64 +726,60 @@ static int wm8940_register(struct wm8940_priv *wm8940,
814 return ret; 726 return ret;
815 } 727 }
816 728
817 729 ret = snd_soc_add_controls(codec, wm8940_snd_controls,
818 wm8940_codec = codec; 730 ARRAY_SIZE(wm8940_snd_controls));
819 731 if (ret)
820 ret = snd_soc_register_codec(codec);
821 if (ret) {
822 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
823 return ret; 732 return ret;
824 } 733 ret = wm8940_add_widgets(codec);
825 734 if (ret)
826 ret = snd_soc_register_dai(&wm8940_dai);
827 if (ret) {
828 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
829 snd_soc_unregister_codec(codec);
830 return ret; 735 return ret;
831 }
832 736
833 return 0; 737 return ret;
738;
834} 739}
835 740
836static void wm8940_unregister(struct wm8940_priv *wm8940) 741static int wm8940_remove(struct snd_soc_codec *codec)
837{ 742{
838 wm8940_set_bias_level(&wm8940->codec, SND_SOC_BIAS_OFF); 743 wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
839 snd_soc_unregister_dai(&wm8940_dai); 744 return 0;
840 snd_soc_unregister_codec(&wm8940->codec);
841 kfree(wm8940);
842 wm8940_codec = NULL;
843} 745}
844 746
845static int wm8940_i2c_probe(struct i2c_client *i2c, 747static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
846 const struct i2c_device_id *id) 748 .probe = wm8940_probe,
749 .remove = wm8940_remove,
750 .suspend = wm8940_suspend,
751 .resume = wm8940_resume,
752 .set_bias_level = wm8940_set_bias_level,
753 .reg_cache_size = sizeof(wm8940_reg_defaults),
754 .reg_word_size = sizeof(u16),
755 .reg_cache_default = wm8940_reg_defaults,
756};
757
758#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
759static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
760 const struct i2c_device_id *id)
847{ 761{
848 int ret;
849 struct wm8940_priv *wm8940; 762 struct wm8940_priv *wm8940;
850 struct snd_soc_codec *codec; 763 int ret;
851 764
852 wm8940 = kzalloc(sizeof *wm8940, GFP_KERNEL); 765 wm8940 = kzalloc(sizeof(struct wm8940_priv), GFP_KERNEL);
853 if (wm8940 == NULL) 766 if (wm8940 == NULL)
854 return -ENOMEM; 767 return -ENOMEM;
855 768
856 codec = &wm8940->codec;
857 codec->hw_write = (hw_write_t)i2c_master_send;
858 i2c_set_clientdata(i2c, wm8940); 769 i2c_set_clientdata(i2c, wm8940);
859 codec->control_data = i2c; 770 wm8940->control_data = i2c;
860 codec->dev = &i2c->dev;
861 771
862 ret = wm8940_register(wm8940, SND_SOC_I2C); 772 ret = snd_soc_register_codec(&i2c->dev,
773 &soc_codec_dev_wm8940, &wm8940_dai, 1);
863 if (ret < 0) 774 if (ret < 0)
864 kfree(wm8940); 775 kfree(wm8940);
865
866 return ret; 776 return ret;
867} 777}
868 778
869static int __devexit wm8940_i2c_remove(struct i2c_client *client) 779static __devexit int wm8940_i2c_remove(struct i2c_client *client)
870{ 780{
871 struct wm8940_priv *wm8940 = i2c_get_clientdata(client); 781 snd_soc_unregister_codec(&client->dev);
872 782 kfree(i2c_get_clientdata(client));
873 wm8940_unregister(wm8940);
874
875 return 0; 783 return 0;
876} 784}
877 785
@@ -883,29 +791,34 @@ MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id);
883 791
884static struct i2c_driver wm8940_i2c_driver = { 792static struct i2c_driver wm8940_i2c_driver = {
885 .driver = { 793 .driver = {
886 .name = "WM8940 I2C Codec", 794 .name = "wm8940-codec",
887 .owner = THIS_MODULE, 795 .owner = THIS_MODULE,
888 }, 796 },
889 .probe = wm8940_i2c_probe, 797 .probe = wm8940_i2c_probe,
890 .remove = __devexit_p(wm8940_i2c_remove), 798 .remove = __devexit_p(wm8940_i2c_remove),
891 .id_table = wm8940_i2c_id, 799 .id_table = wm8940_i2c_id,
892}; 800};
801#endif
893 802
894static int __init wm8940_modinit(void) 803static int __init wm8940_modinit(void)
895{ 804{
896 int ret; 805 int ret = 0;
897 806#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
898 ret = i2c_add_driver(&wm8940_i2c_driver); 807 ret = i2c_add_driver(&wm8940_i2c_driver);
899 if (ret) 808 if (ret != 0) {
900 printk(KERN_ERR "Failed to register WM8940 I2C driver: %d\n", 809 printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n",
901 ret); 810 ret);
811 }
812#endif
902 return ret; 813 return ret;
903} 814}
904module_init(wm8940_modinit); 815module_init(wm8940_modinit);
905 816
906static void __exit wm8940_exit(void) 817static void __exit wm8940_exit(void)
907{ 818{
819#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
908 i2c_del_driver(&wm8940_i2c_driver); 820 i2c_del_driver(&wm8940_i2c_driver);
821#endif
909} 822}
910module_exit(wm8940_exit); 823module_exit(wm8940_exit);
911 824
diff --git a/sound/soc/codecs/wm8940.h b/sound/soc/codecs/wm8940.h
index 8410eed3ef8..907fe192e9e 100644
--- a/sound/soc/codecs/wm8940.h
+++ b/sound/soc/codecs/wm8940.h
@@ -15,8 +15,6 @@ struct wm8940_setup_data {
15#define WM8940_VROI_30K 1 15#define WM8940_VROI_30K 1
16 unsigned int vroi:1; 16 unsigned int vroi:1;
17}; 17};
18extern struct snd_soc_dai wm8940_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8940;
20 18
21/* WM8940 register space */ 19/* WM8940 register space */
22#define WM8940_SOFTRESET 0x00 20#define WM8940_SOFTRESET 0x00
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 5f025593d84..a5a9f8ef577 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -30,9 +30,6 @@
30 30
31#include "wm8955.h" 31#include "wm8955.h"
32 32
33static struct snd_soc_codec *wm8955_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8955;
35
36#define WM8955_NUM_SUPPLIES 4 33#define WM8955_NUM_SUPPLIES 4
37static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = { 34static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
38 "DCVDD", 35 "DCVDD",
@@ -43,7 +40,9 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
43 40
44/* codec private data */ 41/* codec private data */
45struct wm8955_priv { 42struct wm8955_priv {
46 struct snd_soc_codec codec; 43 enum snd_soc_control_type control_type;
44 void *control_data;
45
47 u16 reg_cache[WM8955_MAX_REGISTER + 1]; 46 u16 reg_cache[WM8955_MAX_REGISTER + 1];
48 47
49 unsigned int mclk_rate; 48 unsigned int mclk_rate;
@@ -52,8 +51,6 @@ struct wm8955_priv {
52 int fs; 51 int fs;
53 52
54 struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES]; 53 struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES];
55
56 struct wm8955_pdata *pdata;
57}; 54};
58 55
59static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = { 56static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = {
@@ -870,8 +867,8 @@ static struct snd_soc_dai_ops wm8955_dai_ops = {
870 .digital_mute = wm8955_digital_mute, 867 .digital_mute = wm8955_digital_mute,
871}; 868};
872 869
873struct snd_soc_dai wm8955_dai = { 870static struct snd_soc_dai_driver wm8955_dai = {
874 .name = "WM8955", 871 .name = "wm8955-hifi",
875 .playback = { 872 .playback = {
876 .stream_name = "Playback", 873 .stream_name = "Playback",
877 .channels_min = 2, 874 .channels_min = 2,
@@ -881,24 +878,17 @@ struct snd_soc_dai wm8955_dai = {
881 }, 878 },
882 .ops = &wm8955_dai_ops, 879 .ops = &wm8955_dai_ops,
883}; 880};
884EXPORT_SYMBOL_GPL(wm8955_dai);
885 881
886#ifdef CONFIG_PM 882#ifdef CONFIG_PM
887static int wm8955_suspend(struct platform_device *pdev, pm_message_t state) 883static int wm8955_suspend(struct snd_soc_codec *codec, pm_message_t state)
888{ 884{
889 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
890 struct snd_soc_codec *codec = socdev->card->codec;
891
892 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); 885 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
893 886
894 return 0; 887 return 0;
895} 888}
896 889
897static int wm8955_resume(struct platform_device *pdev) 890static int wm8955_resume(struct snd_soc_codec *codec)
898{ 891{
899 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
900 struct snd_soc_codec *codec = socdev->card->codec;
901
902 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 892 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
903 893
904 return 0; 894 return 0;
@@ -908,86 +898,17 @@ static int wm8955_resume(struct platform_device *pdev)
908#define wm8955_resume NULL 898#define wm8955_resume NULL
909#endif 899#endif
910 900
911static int wm8955_probe(struct platform_device *pdev) 901static int wm8955_probe(struct snd_soc_codec *codec)
912{
913 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
914 struct snd_soc_codec *codec;
915 int ret = 0;
916
917 if (wm8955_codec == NULL) {
918 dev_err(&pdev->dev, "Codec device not registered\n");
919 return -ENODEV;
920 }
921
922 socdev->card->codec = wm8955_codec;
923 codec = wm8955_codec;
924
925 /* register pcms */
926 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
927 if (ret < 0) {
928 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
929 goto pcm_err;
930 }
931
932 wm8955_add_widgets(codec);
933
934 return ret;
935
936pcm_err:
937 return ret;
938}
939
940static int wm8955_remove(struct platform_device *pdev)
941{ 902{
942 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 903 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
943 904 struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
944 snd_soc_free_pcms(socdev); 905 int ret, i;
945 snd_soc_dapm_free(socdev);
946
947 return 0;
948}
949
950struct snd_soc_codec_device soc_codec_dev_wm8955 = {
951 .probe = wm8955_probe,
952 .remove = wm8955_remove,
953 .suspend = wm8955_suspend,
954 .resume = wm8955_resume,
955};
956EXPORT_SYMBOL_GPL(soc_codec_dev_wm8955);
957
958static int wm8955_register(struct wm8955_priv *wm8955,
959 enum snd_soc_control_type control)
960{
961 int ret;
962 struct snd_soc_codec *codec = &wm8955->codec;
963 int i;
964
965 if (wm8955_codec) {
966 dev_err(codec->dev, "Another WM8955 is registered\n");
967 ret = -EINVAL;
968 goto err;
969 }
970
971 mutex_init(&codec->mutex);
972 INIT_LIST_HEAD(&codec->dapm_widgets);
973 INIT_LIST_HEAD(&codec->dapm_paths);
974
975 snd_soc_codec_set_drvdata(codec, wm8955);
976 codec->name = "WM8955";
977 codec->owner = THIS_MODULE;
978 codec->bias_level = SND_SOC_BIAS_OFF;
979 codec->set_bias_level = wm8955_set_bias_level;
980 codec->dai = &wm8955_dai;
981 codec->num_dai = 1;
982 codec->reg_cache_size = WM8955_MAX_REGISTER;
983 codec->reg_cache = &wm8955->reg_cache;
984
985 memcpy(codec->reg_cache, wm8955_reg, sizeof(wm8955_reg));
986 906
987 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 907 codec->control_data = wm8955->control_data;
908 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type);
988 if (ret != 0) { 909 if (ret != 0) {
989 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 910 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
990 goto err; 911 return ret;
991 } 912 }
992 913
993 for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++) 914 for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
@@ -997,7 +918,7 @@ static int wm8955_register(struct wm8955_priv *wm8955,
997 wm8955->supplies); 918 wm8955->supplies);
998 if (ret != 0) { 919 if (ret != 0) {
999 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 920 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1000 goto err; 921 return ret;
1001 } 922 }
1002 923
1003 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies), 924 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
@@ -1013,8 +934,6 @@ static int wm8955_register(struct wm8955_priv *wm8955,
1013 goto err_enable; 934 goto err_enable;
1014 } 935 }
1015 936
1016 wm8955_dai.dev = codec->dev;
1017
1018 /* Change some default settings - latch VU and enable ZC */ 937 /* Change some default settings - latch VU and enable ZC */
1019 wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU; 938 wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
1020 wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU; 939 wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
@@ -1028,12 +947,12 @@ static int wm8955_register(struct wm8955_priv *wm8955,
1028 wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB; 947 wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
1029 948
1030 /* Set platform data values */ 949 /* Set platform data values */
1031 if (wm8955->pdata) { 950 if (pdata) {
1032 if (wm8955->pdata->out2_speaker) 951 if (pdata->out2_speaker)
1033 wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2] 952 wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2]
1034 |= WM8955_ROUT2INV; 953 |= WM8955_ROUT2INV;
1035 954
1036 if (wm8955->pdata->monoin_diff) 955 if (pdata->monoin_diff)
1037 wm8955->reg_cache[WM8955_MONO_OUT_MIX_1] 956 wm8955->reg_cache[WM8955_MONO_OUT_MIX_1]
1038 |= WM8955_DMEN; 957 |= WM8955_DMEN;
1039 } 958 }
@@ -1043,70 +962,61 @@ static int wm8955_register(struct wm8955_priv *wm8955,
1043 /* Bias level configuration will have done an extra enable */ 962 /* Bias level configuration will have done an extra enable */
1044 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); 963 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1045 964
1046 wm8955_codec = codec; 965 wm8955_add_widgets(codec);
1047
1048 ret = snd_soc_register_codec(codec);
1049 if (ret != 0) {
1050 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1051 goto err_enable;
1052 }
1053
1054 ret = snd_soc_register_dai(&wm8955_dai);
1055 if (ret != 0) {
1056 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1057 goto err_codec;
1058 }
1059
1060 return 0; 966 return 0;
1061 967
1062err_codec:
1063 snd_soc_unregister_codec(codec);
1064err_enable: 968err_enable:
1065 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); 969 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1066err_get: 970err_get:
1067 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); 971 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1068err:
1069 kfree(wm8955);
1070 return ret; 972 return ret;
1071} 973}
1072 974
1073static void wm8955_unregister(struct wm8955_priv *wm8955) 975static int wm8955_remove(struct snd_soc_codec *codec)
1074{ 976{
1075 wm8955_set_bias_level(&wm8955->codec, SND_SOC_BIAS_OFF); 977 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
978
979 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
1076 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); 980 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1077 snd_soc_unregister_dai(&wm8955_dai); 981 return 0;
1078 snd_soc_unregister_codec(&wm8955->codec);
1079 kfree(wm8955);
1080 wm8955_codec = NULL;
1081} 982}
1082 983
984static struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
985 .probe = wm8955_probe,
986 .remove = wm8955_remove,
987 .suspend = wm8955_suspend,
988 .resume = wm8955_resume,
989 .set_bias_level = wm8955_set_bias_level,
990 .reg_cache_size = ARRAY_SIZE(wm8955_reg),
991 .reg_word_size = sizeof(u16),
992 .reg_cache_default = wm8955_reg,
993};
994
1083#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 995#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1084static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, 996static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
1085 const struct i2c_device_id *id) 997 const struct i2c_device_id *id)
1086{ 998{
1087 struct wm8955_priv *wm8955; 999 struct wm8955_priv *wm8955;
1088 struct snd_soc_codec *codec; 1000 int ret;
1089 1001
1090 wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL); 1002 wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL);
1091 if (wm8955 == NULL) 1003 if (wm8955 == NULL)
1092 return -ENOMEM; 1004 return -ENOMEM;
1093 1005
1094 codec = &wm8955->codec;
1095 codec->hw_write = (hw_write_t)i2c_master_send;
1096
1097 i2c_set_clientdata(i2c, wm8955); 1006 i2c_set_clientdata(i2c, wm8955);
1098 codec->control_data = i2c; 1007 wm8955->control_data = i2c;
1099 wm8955->pdata = i2c->dev.platform_data;
1100
1101 codec->dev = &i2c->dev;
1102 1008
1103 return wm8955_register(wm8955, SND_SOC_I2C); 1009 ret = snd_soc_register_codec(&i2c->dev,
1010 &soc_codec_dev_wm8955, &wm8955_dai, 1);
1011 if (ret < 0)
1012 kfree(wm8955);
1013 return ret;
1104} 1014}
1105 1015
1106static __devexit int wm8955_i2c_remove(struct i2c_client *client) 1016static __devexit int wm8955_i2c_remove(struct i2c_client *client)
1107{ 1017{
1108 struct wm8955_priv *wm8955 = i2c_get_clientdata(client); 1018 snd_soc_unregister_codec(&client->dev);
1109 wm8955_unregister(wm8955); 1019 kfree(i2c_get_clientdata(client));
1110 return 0; 1020 return 0;
1111} 1021}
1112 1022
@@ -1118,7 +1028,7 @@ MODULE_DEVICE_TABLE(i2c, wm8955_i2c_id);
1118 1028
1119static struct i2c_driver wm8955_i2c_driver = { 1029static struct i2c_driver wm8955_i2c_driver = {
1120 .driver = { 1030 .driver = {
1121 .name = "wm8955", 1031 .name = "wm8955-codec",
1122 .owner = THIS_MODULE, 1032 .owner = THIS_MODULE,
1123 }, 1033 },
1124 .probe = wm8955_i2c_probe, 1034 .probe = wm8955_i2c_probe,
@@ -1129,7 +1039,7 @@ static struct i2c_driver wm8955_i2c_driver = {
1129 1039
1130static int __init wm8955_modinit(void) 1040static int __init wm8955_modinit(void)
1131{ 1041{
1132 int ret; 1042 int ret = 0;
1133#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1043#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1134 ret = i2c_add_driver(&wm8955_i2c_driver); 1044 ret = i2c_add_driver(&wm8955_i2c_driver);
1135 if (ret != 0) { 1045 if (ret != 0) {
@@ -1137,7 +1047,7 @@ static int __init wm8955_modinit(void)
1137 ret); 1047 ret);
1138 } 1048 }
1139#endif 1049#endif
1140 return 0; 1050 return ret;
1141} 1051}
1142module_init(wm8955_modinit); 1052module_init(wm8955_modinit);
1143 1053
diff --git a/sound/soc/codecs/wm8955.h b/sound/soc/codecs/wm8955.h
index ae349c8531f..d13fd5c5fa6 100644
--- a/sound/soc/codecs/wm8955.h
+++ b/sound/soc/codecs/wm8955.h
@@ -15,9 +15,6 @@
15 15
16#define WM8955_CLK_MCLK 1 16#define WM8955_CLK_MCLK 1
17 17
18extern struct snd_soc_dai wm8955_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8955;
20
21/* 18/*
22 * Register values. 19 * Register values.
23 */ 20 */
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 3c6ee61f6c9..8d5efb333c3 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -29,8 +29,6 @@
29 29
30#define AUDIO_NAME "wm8960" 30#define AUDIO_NAME "wm8960"
31 31
32struct snd_soc_codec_device soc_codec_dev_wm8960;
33
34/* R25 - Power 1 */ 32/* R25 - Power 1 */
35#define WM8960_VMID_MASK 0x180 33#define WM8960_VMID_MASK 0x180
36#define WM8960_VREF 0x40 34#define WM8960_VREF 0x40
@@ -75,7 +73,10 @@ static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
75 73
76struct wm8960_priv { 74struct wm8960_priv {
77 u16 reg_cache[WM8960_CACHEREGNUM]; 75 u16 reg_cache[WM8960_CACHEREGNUM];
78 struct snd_soc_codec codec; 76 enum snd_soc_control_type control_type;
77 void *control_data;
78 int (*set_bias_level)(struct snd_soc_codec *,
79 enum snd_soc_bias_level level);
79 struct snd_soc_dapm_widget *lout1; 80 struct snd_soc_dapm_widget *lout1;
80 struct snd_soc_dapm_widget *rout1; 81 struct snd_soc_dapm_widget *rout1;
81 struct snd_soc_dapm_widget *out3; 82 struct snd_soc_dapm_widget *out3;
@@ -507,8 +508,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
507 struct snd_soc_dai *dai) 508 struct snd_soc_dai *dai)
508{ 509{
509 struct snd_soc_pcm_runtime *rtd = substream->private_data; 510 struct snd_soc_pcm_runtime *rtd = substream->private_data;
510 struct snd_soc_device *socdev = rtd->socdev; 511 struct snd_soc_codec *codec = rtd->codec;
511 struct snd_soc_codec *codec = socdev->card->codec;
512 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 512 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
513 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3; 513 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
514 int i; 514 int i;
@@ -849,6 +849,14 @@ static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
849 return 0; 849 return 0;
850} 850}
851 851
852static int wm8960_set_bias_level(struct snd_soc_codec *codec,
853 enum snd_soc_bias_level level)
854{
855 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
856
857 return wm8960->set_bias_level(codec, level);
858}
859
852#define WM8960_RATES SNDRV_PCM_RATE_8000_48000 860#define WM8960_RATES SNDRV_PCM_RATE_8000_48000
853 861
854#define WM8960_FORMATS \ 862#define WM8960_FORMATS \
@@ -863,8 +871,8 @@ static struct snd_soc_dai_ops wm8960_dai_ops = {
863 .set_pll = wm8960_set_dai_pll, 871 .set_pll = wm8960_set_dai_pll,
864}; 872};
865 873
866struct snd_soc_dai wm8960_dai = { 874static struct snd_soc_dai_driver wm8960_dai = {
867 .name = "WM8960", 875 .name = "wm8960-hifi",
868 .playback = { 876 .playback = {
869 .stream_name = "Playback", 877 .stream_name = "Playback",
870 .channels_min = 1, 878 .channels_min = 1,
@@ -880,21 +888,18 @@ struct snd_soc_dai wm8960_dai = {
880 .ops = &wm8960_dai_ops, 888 .ops = &wm8960_dai_ops,
881 .symmetric_rates = 1, 889 .symmetric_rates = 1,
882}; 890};
883EXPORT_SYMBOL_GPL(wm8960_dai);
884 891
885static int wm8960_suspend(struct platform_device *pdev, pm_message_t state) 892static int wm8960_suspend(struct snd_soc_codec *codec, pm_message_t state)
886{ 893{
887 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 894 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
888 struct snd_soc_codec *codec = socdev->card->codec;
889 895
890 codec->set_bias_level(codec, SND_SOC_BIAS_OFF); 896 wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
891 return 0; 897 return 0;
892} 898}
893 899
894static int wm8960_resume(struct platform_device *pdev) 900static int wm8960_resume(struct snd_soc_codec *codec)
895{ 901{
896 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 902 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
897 struct snd_soc_codec *codec = socdev->card->codec;
898 int i; 903 int i;
899 u8 data[2]; 904 u8 data[2];
900 u16 *cache = codec->reg_cache; 905 u16 *cache = codec->reg_cache;
@@ -906,78 +911,19 @@ static int wm8960_resume(struct platform_device *pdev)
906 codec->hw_write(codec->control_data, data, 2); 911 codec->hw_write(codec->control_data, data, 2);
907 } 912 }
908 913
909 codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY); 914 wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
910
911 return 0; 915 return 0;
912} 916}
913 917
914static struct snd_soc_codec *wm8960_codec; 918static int wm8960_probe(struct snd_soc_codec *codec)
915
916static int wm8960_probe(struct platform_device *pdev)
917{
918 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
919 struct snd_soc_codec *codec;
920 int ret = 0;
921
922 if (wm8960_codec == NULL) {
923 dev_err(&pdev->dev, "Codec device not registered\n");
924 return -ENODEV;
925 }
926
927 socdev->card->codec = wm8960_codec;
928 codec = wm8960_codec;
929
930 /* register pcms */
931 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
932 if (ret < 0) {
933 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
934 goto pcm_err;
935 }
936
937 snd_soc_add_controls(codec, wm8960_snd_controls,
938 ARRAY_SIZE(wm8960_snd_controls));
939 wm8960_add_widgets(codec);
940
941 return ret;
942
943pcm_err:
944 return ret;
945}
946
947/* power down chip */
948static int wm8960_remove(struct platform_device *pdev)
949{
950 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
951
952 snd_soc_free_pcms(socdev);
953 snd_soc_dapm_free(socdev);
954
955 return 0;
956}
957
958struct snd_soc_codec_device soc_codec_dev_wm8960 = {
959 .probe = wm8960_probe,
960 .remove = wm8960_remove,
961 .suspend = wm8960_suspend,
962 .resume = wm8960_resume,
963};
964EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960);
965
966static int wm8960_register(struct wm8960_priv *wm8960,
967 enum snd_soc_control_type control)
968{ 919{
969 struct wm8960_data *pdata = wm8960->codec.dev->platform_data; 920 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
970 struct snd_soc_codec *codec = &wm8960->codec; 921 struct wm8960_data *pdata = dev_get_platdata(codec->dev);
971 int ret; 922 int ret;
972 u16 reg; 923 u16 reg;
973 924
974 if (wm8960_codec) { 925 wm8960->set_bias_level = wm8960_set_bias_level_out3;
975 dev_err(codec->dev, "Another WM8960 is registered\n"); 926 codec->control_data = wm8960->control_data;
976 ret = -EINVAL;
977 goto err;
978 }
979
980 codec->set_bias_level = wm8960_set_bias_level_out3;
981 927
982 if (!pdata) { 928 if (!pdata) {
983 dev_warn(codec->dev, "No platform data supplied\n"); 929 dev_warn(codec->dev, "No platform data supplied\n");
@@ -988,39 +934,22 @@ static int wm8960_register(struct wm8960_priv *wm8960,
988 } 934 }
989 935
990 if (pdata->capless) 936 if (pdata->capless)
991 codec->set_bias_level = wm8960_set_bias_level_capless; 937 wm8960->set_bias_level = wm8960_set_bias_level_capless;
992 } 938 }
993 939
994 mutex_init(&codec->mutex); 940 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8960->control_type);
995 INIT_LIST_HEAD(&codec->dapm_widgets);
996 INIT_LIST_HEAD(&codec->dapm_paths);
997
998 snd_soc_codec_set_drvdata(codec, wm8960);
999 codec->name = "WM8960";
1000 codec->owner = THIS_MODULE;
1001 codec->bias_level = SND_SOC_BIAS_OFF;
1002 codec->dai = &wm8960_dai;
1003 codec->num_dai = 1;
1004 codec->reg_cache_size = WM8960_CACHEREGNUM;
1005 codec->reg_cache = &wm8960->reg_cache;
1006
1007 memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg));
1008
1009 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
1010 if (ret < 0) { 941 if (ret < 0) {
1011 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 942 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1012 goto err; 943 return ret;
1013 } 944 }
1014 945
1015 ret = wm8960_reset(codec); 946 ret = wm8960_reset(codec);
1016 if (ret < 0) { 947 if (ret < 0) {
1017 dev_err(codec->dev, "Failed to issue reset\n"); 948 dev_err(codec->dev, "Failed to issue reset\n");
1018 goto err; 949 return ret;
1019 } 950 }
1020 951
1021 wm8960_dai.dev = codec->dev; 952 wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1022
1023 codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1024 953
1025 /* Latch the update bits */ 954 /* Latch the update bits */
1026 reg = snd_soc_read(codec, WM8960_LINVOL); 955 reg = snd_soc_read(codec, WM8960_LINVOL);
@@ -1044,62 +973,58 @@ static int wm8960_register(struct wm8960_priv *wm8960,
1044 reg = snd_soc_read(codec, WM8960_ROUT2); 973 reg = snd_soc_read(codec, WM8960_ROUT2);
1045 snd_soc_write(codec, WM8960_ROUT2, reg | 0x100); 974 snd_soc_write(codec, WM8960_ROUT2, reg | 0x100);
1046 975
1047 wm8960_codec = codec; 976 snd_soc_add_controls(codec, wm8960_snd_controls,
1048 977 ARRAY_SIZE(wm8960_snd_controls));
1049 ret = snd_soc_register_codec(codec); 978 wm8960_add_widgets(codec);
1050 if (ret != 0) {
1051 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1052 goto err;
1053 }
1054
1055 ret = snd_soc_register_dai(&wm8960_dai);
1056 if (ret != 0) {
1057 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1058 goto err_codec;
1059 }
1060 979
1061 return 0; 980 return 0;
1062
1063err_codec:
1064 snd_soc_unregister_codec(codec);
1065err:
1066 kfree(wm8960);
1067 return ret;
1068} 981}
1069 982
1070static void wm8960_unregister(struct wm8960_priv *wm8960) 983/* power down chip */
984static int wm8960_remove(struct snd_soc_codec *codec)
1071{ 985{
1072 wm8960->codec.set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF); 986 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
1073 snd_soc_unregister_dai(&wm8960_dai); 987
1074 snd_soc_unregister_codec(&wm8960->codec); 988 wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
1075 kfree(wm8960); 989 return 0;
1076 wm8960_codec = NULL;
1077} 990}
1078 991
992static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
993 .probe = wm8960_probe,
994 .remove = wm8960_remove,
995 .suspend = wm8960_suspend,
996 .resume = wm8960_resume,
997 .set_bias_level = wm8960_set_bias_level,
998 .reg_cache_size = ARRAY_SIZE(wm8960_reg),
999 .reg_word_size = sizeof(u16),
1000 .reg_cache_default = wm8960_reg,
1001};
1002
1003#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1079static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, 1004static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
1080 const struct i2c_device_id *id) 1005 const struct i2c_device_id *id)
1081{ 1006{
1082 struct wm8960_priv *wm8960; 1007 struct wm8960_priv *wm8960;
1083 struct snd_soc_codec *codec; 1008 int ret;
1084 1009
1085 wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL); 1010 wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL);
1086 if (wm8960 == NULL) 1011 if (wm8960 == NULL)
1087 return -ENOMEM; 1012 return -ENOMEM;
1088 1013
1089 codec = &wm8960->codec;
1090
1091 i2c_set_clientdata(i2c, wm8960); 1014 i2c_set_clientdata(i2c, wm8960);
1092 codec->control_data = i2c; 1015 wm8960->control_data = i2c;
1093
1094 codec->dev = &i2c->dev;
1095 1016
1096 return wm8960_register(wm8960, SND_SOC_I2C); 1017 ret = snd_soc_register_codec(&i2c->dev,
1018 &soc_codec_dev_wm8960, &wm8960_dai, 1);
1019 if (ret < 0)
1020 kfree(wm8960);
1021 return ret;
1097} 1022}
1098 1023
1099static __devexit int wm8960_i2c_remove(struct i2c_client *client) 1024static __devexit int wm8960_i2c_remove(struct i2c_client *client)
1100{ 1025{
1101 struct wm8960_priv *wm8960 = i2c_get_clientdata(client); 1026 snd_soc_unregister_codec(&client->dev);
1102 wm8960_unregister(wm8960); 1027 kfree(i2c_get_clientdata(client));
1103 return 0; 1028 return 0;
1104} 1029}
1105 1030
@@ -1111,35 +1036,37 @@ MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id);
1111 1036
1112static struct i2c_driver wm8960_i2c_driver = { 1037static struct i2c_driver wm8960_i2c_driver = {
1113 .driver = { 1038 .driver = {
1114 .name = "wm8960", 1039 .name = "wm8960-codec",
1115 .owner = THIS_MODULE, 1040 .owner = THIS_MODULE,
1116 }, 1041 },
1117 .probe = wm8960_i2c_probe, 1042 .probe = wm8960_i2c_probe,
1118 .remove = __devexit_p(wm8960_i2c_remove), 1043 .remove = __devexit_p(wm8960_i2c_remove),
1119 .id_table = wm8960_i2c_id, 1044 .id_table = wm8960_i2c_id,
1120}; 1045};
1046#endif
1121 1047
1122static int __init wm8960_modinit(void) 1048static int __init wm8960_modinit(void)
1123{ 1049{
1124 int ret; 1050 int ret = 0;
1125 1051#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1126 ret = i2c_add_driver(&wm8960_i2c_driver); 1052 ret = i2c_add_driver(&wm8960_i2c_driver);
1127 if (ret != 0) { 1053 if (ret != 0) {
1128 printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n", 1054 printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n",
1129 ret); 1055 ret);
1130 } 1056 }
1131 1057#endif
1132 return ret; 1058 return ret;
1133} 1059}
1134module_init(wm8960_modinit); 1060module_init(wm8960_modinit);
1135 1061
1136static void __exit wm8960_exit(void) 1062static void __exit wm8960_exit(void)
1137{ 1063{
1064#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1138 i2c_del_driver(&wm8960_i2c_driver); 1065 i2c_del_driver(&wm8960_i2c_driver);
1066#endif
1139} 1067}
1140module_exit(wm8960_exit); 1068module_exit(wm8960_exit);
1141 1069
1142
1143MODULE_DESCRIPTION("ASoC WM8960 driver"); 1070MODULE_DESCRIPTION("ASoC WM8960 driver");
1144MODULE_AUTHOR("Liam Girdwood"); 1071MODULE_AUTHOR("Liam Girdwood");
1145MODULE_LICENSE("GPL"); 1072MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8960.h b/sound/soc/codecs/wm8960.h
index a5ef65481b8..2d8163d7004 100644
--- a/sound/soc/codecs/wm8960.h
+++ b/sound/soc/codecs/wm8960.h
@@ -110,7 +110,4 @@
110#define WM8960_OPCLK_DIV_5_5 (4 << 0) 110#define WM8960_OPCLK_DIV_5_5 (4 << 0)
111#define WM8960_OPCLK_DIV_6 (5 << 0) 111#define WM8960_OPCLK_DIV_6 (5 << 0)
112 112
113extern struct snd_soc_dai wm8960_dai;
114extern struct snd_soc_codec_device soc_codec_dev_wm8960;
115
116#endif 113#endif
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 2549d3a297a..5ebe2c04e5c 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -288,7 +288,8 @@ static u16 wm8961_reg_defaults[] = {
288}; 288};
289 289
290struct wm8961_priv { 290struct wm8961_priv {
291 struct snd_soc_codec codec; 291 enum snd_soc_control_type control_type;
292 void *control_data;
292 int sysclk; 293 int sysclk;
293 u16 reg_cache[WM8961_MAX_REGISTER]; 294 u16 reg_cache[WM8961_MAX_REGISTER];
294}; 295};
@@ -940,8 +941,8 @@ static struct snd_soc_dai_ops wm8961_dai_ops = {
940 .set_clkdiv = wm8961_set_clkdiv, 941 .set_clkdiv = wm8961_set_clkdiv,
941}; 942};
942 943
943struct snd_soc_dai wm8961_dai = { 944static struct snd_soc_dai_driver wm8961_dai = {
944 .name = "WM8961", 945 .name = "wm8961-hifi",
945 .playback = { 946 .playback = {
946 .stream_name = "HiFi Playback", 947 .stream_name = "HiFi Playback",
947 .channels_min = 1, 948 .channels_min = 1,
@@ -956,140 +957,24 @@ struct snd_soc_dai wm8961_dai = {
956 .formats = WM8961_FORMATS,}, 957 .formats = WM8961_FORMATS,},
957 .ops = &wm8961_dai_ops, 958 .ops = &wm8961_dai_ops,
958}; 959};
959EXPORT_SYMBOL_GPL(wm8961_dai);
960 960
961 961static int wm8961_probe(struct snd_soc_codec *codec)
962static struct snd_soc_codec *wm8961_codec;
963
964static int wm8961_probe(struct platform_device *pdev)
965{ 962{
966 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 963 struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
967 struct snd_soc_codec *codec;
968 int ret = 0; 964 int ret = 0;
969
970 if (wm8961_codec == NULL) {
971 dev_err(&pdev->dev, "Codec device not registered\n");
972 return -ENODEV;
973 }
974
975 socdev->card->codec = wm8961_codec;
976 codec = wm8961_codec;
977
978 /* register pcms */
979 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
980 if (ret < 0) {
981 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
982 goto pcm_err;
983 }
984
985 snd_soc_add_controls(codec, wm8961_snd_controls,
986 ARRAY_SIZE(wm8961_snd_controls));
987 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
988 ARRAY_SIZE(wm8961_dapm_widgets));
989 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
990
991 return ret;
992
993pcm_err:
994 return ret;
995}
996
997static int wm8961_remove(struct platform_device *pdev)
998{
999 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1000
1001 snd_soc_free_pcms(socdev);
1002 snd_soc_dapm_free(socdev);
1003
1004 return 0;
1005}
1006
1007#ifdef CONFIG_PM
1008static int wm8961_suspend(struct platform_device *pdev, pm_message_t state)
1009{
1010 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1011 struct snd_soc_codec *codec = socdev->card->codec;
1012
1013 wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
1014
1015 return 0;
1016}
1017
1018static int wm8961_resume(struct platform_device *pdev)
1019{
1020 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1021 struct snd_soc_codec *codec = socdev->card->codec;
1022 u16 *reg_cache = codec->reg_cache;
1023 int i;
1024
1025 for (i = 0; i < codec->reg_cache_size; i++) {
1026 if (reg_cache[i] == wm8961_reg_defaults[i])
1027 continue;
1028
1029 if (i == WM8961_SOFTWARE_RESET)
1030 continue;
1031
1032 snd_soc_write(codec, i, reg_cache[i]);
1033 }
1034
1035 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1036
1037 return 0;
1038}
1039#else
1040#define wm8961_suspend NULL
1041#define wm8961_resume NULL
1042#endif
1043
1044struct snd_soc_codec_device soc_codec_dev_wm8961 = {
1045 .probe = wm8961_probe,
1046 .remove = wm8961_remove,
1047 .suspend = wm8961_suspend,
1048 .resume = wm8961_resume,
1049};
1050EXPORT_SYMBOL_GPL(soc_codec_dev_wm8961);
1051
1052static int wm8961_register(struct wm8961_priv *wm8961)
1053{
1054 struct snd_soc_codec *codec = &wm8961->codec;
1055 int ret;
1056 u16 reg; 965 u16 reg;
1057 966
1058 if (wm8961_codec) { 967 codec->control_data = wm8961->control_data;
1059 dev_err(codec->dev, "Another WM8961 is registered\n");
1060 ret = -EINVAL;
1061 goto err;
1062 }
1063
1064 mutex_init(&codec->mutex);
1065 INIT_LIST_HEAD(&codec->dapm_widgets);
1066 INIT_LIST_HEAD(&codec->dapm_paths);
1067
1068 snd_soc_codec_set_drvdata(codec, wm8961);
1069 codec->name = "WM8961";
1070 codec->owner = THIS_MODULE;
1071 codec->dai = &wm8961_dai;
1072 codec->num_dai = 1;
1073 codec->reg_cache_size = ARRAY_SIZE(wm8961->reg_cache);
1074 codec->reg_cache = &wm8961->reg_cache;
1075 codec->bias_level = SND_SOC_BIAS_OFF;
1076 codec->set_bias_level = wm8961_set_bias_level;
1077 codec->volatile_register = wm8961_volatile_register;
1078
1079 memcpy(codec->reg_cache, wm8961_reg_defaults,
1080 sizeof(wm8961_reg_defaults));
1081
1082 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 968 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1083 if (ret != 0) { 969 if (ret != 0) {
1084 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 970 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1085 goto err; 971 return ret;
1086 } 972 }
1087 973
1088 reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET); 974 reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
1089 if (reg != 0x1801) { 975 if (reg != 0x1801) {
1090 dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg); 976 dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
1091 ret = -EINVAL; 977 return -EINVAL;
1092 goto err;
1093 } 978 }
1094 979
1095 /* This isn't volatile - readback doesn't correspond to write */ 980 /* This isn't volatile - readback doesn't correspond to write */
@@ -1102,7 +987,7 @@ static int wm8961_register(struct wm8961_priv *wm8961)
1102 ret = wm8961_reset(codec); 987 ret = wm8961_reset(codec);
1103 if (ret < 0) { 988 if (ret < 0) {
1104 dev_err(codec->dev, "Failed to issue reset\n"); 989 dev_err(codec->dev, "Failed to issue reset\n");
1105 goto err; 990 return ret;
1106 } 991 }
1107 992
1108 /* Enable class W */ 993 /* Enable class W */
@@ -1140,64 +1025,90 @@ static int wm8961_register(struct wm8961_priv *wm8961)
1140 1025
1141 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1026 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1142 1027
1143 wm8961_dai.dev = codec->dev; 1028 snd_soc_add_controls(codec, wm8961_snd_controls,
1029 ARRAY_SIZE(wm8961_snd_controls));
1030 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
1031 ARRAY_SIZE(wm8961_dapm_widgets));
1032 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
1144 1033
1145 wm8961_codec = codec; 1034 return 0;
1035}
1146 1036
1147 ret = snd_soc_register_codec(codec); 1037static int wm8961_remove(struct snd_soc_codec *codec)
1148 if (ret != 0) { 1038{
1149 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 1039 wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
1150 goto err; 1040 return 0;
1151 } 1041}
1152 1042
1153 ret = snd_soc_register_dai(&wm8961_dai); 1043#ifdef CONFIG_PM
1154 if (ret != 0) { 1044static int wm8961_suspend(struct snd_soc_codec *codec, pm_message_t state)
1155 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 1045{
1156 goto err_codec; 1046 wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
1157 }
1158 1047
1159 return 0; 1048 return 0;
1160
1161err_codec:
1162 snd_soc_unregister_codec(codec);
1163err:
1164 kfree(wm8961);
1165 return ret;
1166} 1049}
1167 1050
1168static void wm8961_unregister(struct wm8961_priv *wm8961) 1051static int wm8961_resume(struct snd_soc_codec *codec)
1169{ 1052{
1170 wm8961_set_bias_level(&wm8961->codec, SND_SOC_BIAS_OFF); 1053 u16 *reg_cache = codec->reg_cache;
1171 snd_soc_unregister_dai(&wm8961_dai); 1054 int i;
1172 snd_soc_unregister_codec(&wm8961->codec); 1055
1173 kfree(wm8961); 1056 for (i = 0; i < codec->driver->reg_cache_size; i++) {
1174 wm8961_codec = NULL; 1057 if (reg_cache[i] == wm8961_reg_defaults[i])
1058 continue;
1059
1060 if (i == WM8961_SOFTWARE_RESET)
1061 continue;
1062
1063 snd_soc_write(codec, i, reg_cache[i]);
1064 }
1065
1066 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1067
1068 return 0;
1175} 1069}
1070#else
1071#define wm8961_suspend NULL
1072#define wm8961_resume NULL
1073#endif
1176 1074
1075static struct snd_soc_codec_driver soc_codec_dev_wm8961 = {
1076 .probe = wm8961_probe,
1077 .remove = wm8961_remove,
1078 .suspend = wm8961_suspend,
1079 .resume = wm8961_resume,
1080 .set_bias_level = wm8961_set_bias_level,
1081 .reg_cache_size = sizeof(wm8961_reg_defaults),
1082 .reg_word_size = sizeof(u16),
1083 .reg_cache_default = wm8961_reg_defaults,
1084 .volatile_register = wm8961_volatile_register,
1085};
1086
1087#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1177static __devinit int wm8961_i2c_probe(struct i2c_client *i2c, 1088static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
1178 const struct i2c_device_id *id) 1089 const struct i2c_device_id *id)
1179{ 1090{
1180 struct wm8961_priv *wm8961; 1091 struct wm8961_priv *wm8961;
1181 struct snd_soc_codec *codec; 1092 int ret;
1182 1093
1183 wm8961 = kzalloc(sizeof(struct wm8961_priv), GFP_KERNEL); 1094 wm8961 = kzalloc(sizeof(struct wm8961_priv), GFP_KERNEL);
1184 if (wm8961 == NULL) 1095 if (wm8961 == NULL)
1185 return -ENOMEM; 1096 return -ENOMEM;
1186 1097
1187 codec = &wm8961->codec;
1188
1189 i2c_set_clientdata(i2c, wm8961); 1098 i2c_set_clientdata(i2c, wm8961);
1190 codec->control_data = i2c; 1099 wm8961->control_data = i2c;
1191
1192 codec->dev = &i2c->dev;
1193 1100
1194 return wm8961_register(wm8961); 1101 ret = snd_soc_register_codec(&i2c->dev,
1102 &soc_codec_dev_wm8961, &wm8961_dai, 1);
1103 if (ret < 0)
1104 kfree(wm8961);
1105 return ret;
1195} 1106}
1196 1107
1197static __devexit int wm8961_i2c_remove(struct i2c_client *client) 1108static __devexit int wm8961_i2c_remove(struct i2c_client *client)
1198{ 1109{
1199 struct wm8961_priv *wm8961 = i2c_get_clientdata(client); 1110 snd_soc_unregister_codec(&client->dev);
1200 wm8961_unregister(wm8961); 1111 kfree(i2c_get_clientdata(client));
1201 return 0; 1112 return 0;
1202} 1113}
1203 1114
@@ -1209,35 +1120,37 @@ MODULE_DEVICE_TABLE(i2c, wm8961_i2c_id);
1209 1120
1210static struct i2c_driver wm8961_i2c_driver = { 1121static struct i2c_driver wm8961_i2c_driver = {
1211 .driver = { 1122 .driver = {
1212 .name = "wm8961", 1123 .name = "wm8961-codec",
1213 .owner = THIS_MODULE, 1124 .owner = THIS_MODULE,
1214 }, 1125 },
1215 .probe = wm8961_i2c_probe, 1126 .probe = wm8961_i2c_probe,
1216 .remove = __devexit_p(wm8961_i2c_remove), 1127 .remove = __devexit_p(wm8961_i2c_remove),
1217 .id_table = wm8961_i2c_id, 1128 .id_table = wm8961_i2c_id,
1218}; 1129};
1130#endif
1219 1131
1220static int __init wm8961_modinit(void) 1132static int __init wm8961_modinit(void)
1221{ 1133{
1222 int ret; 1134 int ret = 0;
1223 1135#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1224 ret = i2c_add_driver(&wm8961_i2c_driver); 1136 ret = i2c_add_driver(&wm8961_i2c_driver);
1225 if (ret != 0) { 1137 if (ret != 0) {
1226 printk(KERN_ERR "Failed to register WM8961 I2C driver: %d\n", 1138 printk(KERN_ERR "Failed to register wm8961 I2C driver: %d\n",
1227 ret); 1139 ret);
1228 } 1140 }
1229 1141#endif
1230 return ret; 1142 return ret;
1231} 1143}
1232module_init(wm8961_modinit); 1144module_init(wm8961_modinit);
1233 1145
1234static void __exit wm8961_exit(void) 1146static void __exit wm8961_exit(void)
1235{ 1147{
1148#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1236 i2c_del_driver(&wm8961_i2c_driver); 1149 i2c_del_driver(&wm8961_i2c_driver);
1150#endif
1237} 1151}
1238module_exit(wm8961_exit); 1152module_exit(wm8961_exit);
1239 1153
1240
1241MODULE_DESCRIPTION("ASoC WM8961 driver"); 1154MODULE_DESCRIPTION("ASoC WM8961 driver");
1242MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1155MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1243MODULE_LICENSE("GPL"); 1156MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8961.h b/sound/soc/codecs/wm8961.h
index 5513bfd720d..1d736e5701c 100644
--- a/sound/soc/codecs/wm8961.h
+++ b/sound/soc/codecs/wm8961.h
@@ -11,9 +11,6 @@
11 11
12#include <sound/soc.h> 12#include <sound/soc.h>
13 13
14extern struct snd_soc_codec_device soc_codec_dev_wm8961;
15extern struct snd_soc_dai wm8961_dai;
16
17#define WM8961_BCLK 1 14#define WM8961_BCLK 1
18#define WM8961_LRCLK 2 15#define WM8961_LRCLK 2
19 16
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index a99620f335d..ad2692afbb3 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -38,6 +38,8 @@ static struct workqueue_struct *wm8971_workq = NULL;
38 38
39/* codec private data */ 39/* codec private data */
40struct wm8971_priv { 40struct wm8971_priv {
41 enum snd_soc_control_type control_type;
42 void *control_data;
41 unsigned int sysclk; 43 unsigned int sysclk;
42}; 44};
43 45
@@ -492,8 +494,7 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
492 struct snd_soc_dai *dai) 494 struct snd_soc_dai *dai)
493{ 495{
494 struct snd_soc_pcm_runtime *rtd = substream->private_data; 496 struct snd_soc_pcm_runtime *rtd = substream->private_data;
495 struct snd_soc_device *socdev = rtd->socdev; 497 struct snd_soc_codec *codec = rtd->codec;
496 struct snd_soc_codec *codec = socdev->card->codec;
497 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec); 498 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
498 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3; 499 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
499 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0; 500 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
@@ -573,8 +574,8 @@ static struct snd_soc_dai_ops wm8971_dai_ops = {
573 .set_sysclk = wm8971_set_dai_sysclk, 574 .set_sysclk = wm8971_set_dai_sysclk,
574}; 575};
575 576
576struct snd_soc_dai wm8971_dai = { 577static struct snd_soc_dai_driver wm8971_dai = {
577 .name = "WM8971", 578 .name = "wm8971-hifi",
578 .playback = { 579 .playback = {
579 .stream_name = "Playback", 580 .stream_name = "Playback",
580 .channels_min = 1, 581 .channels_min = 1,
@@ -589,7 +590,6 @@ struct snd_soc_dai wm8971_dai = {
589 .formats = WM8971_FORMATS,}, 590 .formats = WM8971_FORMATS,},
590 .ops = &wm8971_dai_ops, 591 .ops = &wm8971_dai_ops,
591}; 592};
592EXPORT_SYMBOL_GPL(wm8971_dai);
593 593
594static void wm8971_work(struct work_struct *work) 594static void wm8971_work(struct work_struct *work)
595{ 595{
@@ -598,19 +598,14 @@ static void wm8971_work(struct work_struct *work)
598 wm8971_set_bias_level(codec, codec->bias_level); 598 wm8971_set_bias_level(codec, codec->bias_level);
599} 599}
600 600
601static int wm8971_suspend(struct platform_device *pdev, pm_message_t state) 601static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state)
602{ 602{
603 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
604 struct snd_soc_codec *codec = socdev->card->codec;
605
606 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); 603 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
607 return 0; 604 return 0;
608} 605}
609 606
610static int wm8971_resume(struct platform_device *pdev) 607static int wm8971_resume(struct snd_soc_codec *codec)
611{ 608{
612 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
613 struct snd_soc_codec *codec = socdev->card->codec;
614 int i; 609 int i;
615 u8 data[2]; 610 u8 data[2];
616 u16 *cache = codec->reg_cache; 611 u16 *cache = codec->reg_cache;
@@ -639,37 +634,27 @@ static int wm8971_resume(struct platform_device *pdev)
639 return 0; 634 return 0;
640} 635}
641 636
642static int wm8971_init(struct snd_soc_device *socdev, 637static int wm8971_probe(struct snd_soc_codec *codec)
643 enum snd_soc_control_type control)
644{ 638{
645 struct snd_soc_codec *codec = socdev->card->codec; 639 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
646 int reg, ret = 0; 640 int ret = 0;
647 641 u16 reg;
648 codec->name = "WM8971"; 642
649 codec->owner = THIS_MODULE; 643 pr_info("WM8971 Audio Codec %s", WM8971_VERSION);
650 codec->set_bias_level = wm8971_set_bias_level;
651 codec->dai = &wm8971_dai;
652 codec->reg_cache_size = ARRAY_SIZE(wm8971_reg);
653 codec->num_dai = 1;
654 codec->reg_cache = kmemdup(wm8971_reg, sizeof(wm8971_reg), GFP_KERNEL);
655
656 if (codec->reg_cache == NULL)
657 return -ENOMEM;
658 644
659 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 645 codec->control_data = wm8971->control_data;
646 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8971->control_type);
660 if (ret < 0) { 647 if (ret < 0) {
661 printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret); 648 printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret);
662 goto err; 649 return ret;
663 } 650 }
664 651
665 wm8971_reset(codec); 652 INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
653 wm8971_workq = create_workqueue("wm8971");
654 if (wm8971_workq == NULL)
655 return -ENOMEM;
666 656
667 /* register pcms */ 657 wm8971_reset(codec);
668 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
669 if (ret < 0) {
670 printk(KERN_ERR "wm8971: failed to create pcms\n");
671 goto err;
672 }
673 658
674 /* charge output caps - set vmid to 5k for quick power up */ 659 /* charge output caps - set vmid to 5k for quick power up */
675 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; 660 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
@@ -704,40 +689,55 @@ static int wm8971_init(struct snd_soc_device *socdev,
704 wm8971_add_widgets(codec); 689 wm8971_add_widgets(codec);
705 690
706 return ret; 691 return ret;
707
708err:
709 kfree(codec->reg_cache);
710 return ret;
711} 692}
712 693
713/* If the i2c layer weren't so broken, we could pass this kind of data
714 around */
715static struct snd_soc_device *wm8971_socdev;
716 694
717#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) 695/* power down chip */
696static int wm8971_remove(struct snd_soc_codec *codec)
697{
698 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
699
700 if (wm8971_workq)
701 destroy_workqueue(wm8971_workq);
702 return 0;
703}
704
705static struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
706 .probe = wm8971_probe,
707 .remove = wm8971_remove,
708 .suspend = wm8971_suspend,
709 .resume = wm8971_resume,
710 .set_bias_level = wm8971_set_bias_level,
711 .reg_cache_size = ARRAY_SIZE(wm8971_reg),
712 .reg_word_size = sizeof(u16),
713 .reg_cache_default = wm8971_reg,
714};
718 715
719static int wm8971_i2c_probe(struct i2c_client *i2c, 716#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
720 const struct i2c_device_id *id) 717static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
718 const struct i2c_device_id *id)
721{ 719{
722 struct snd_soc_device *socdev = wm8971_socdev; 720 struct wm8971_priv *wm8971;
723 struct snd_soc_codec *codec = socdev->card->codec;
724 int ret; 721 int ret;
725 722
726 i2c_set_clientdata(i2c, codec); 723 wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL);
724 if (wm8971 == NULL)
725 return -ENOMEM;
727 726
728 codec->control_data = i2c; 727 i2c_set_clientdata(i2c, wm8971);
728 wm8971->control_data = i2c;
729 729
730 ret = wm8971_init(socdev, SND_SOC_I2C); 730 ret = snd_soc_register_codec(&i2c->dev,
731 &soc_codec_dev_wm8971, &wm8971_dai, 1);
731 if (ret < 0) 732 if (ret < 0)
732 pr_err("failed to initialise WM8971\n"); 733 kfree(wm8971);
733
734 return ret; 734 return ret;
735} 735}
736 736
737static int wm8971_i2c_remove(struct i2c_client *client) 737static __devexit int wm8971_i2c_remove(struct i2c_client *client)
738{ 738{
739 struct snd_soc_codec *codec = i2c_get_clientdata(client); 739 snd_soc_unregister_codec(&client->dev);
740 kfree(codec->reg_cache); 740 kfree(i2c_get_clientdata(client));
741 return 0; 741 return 0;
742} 742}
743 743
@@ -749,148 +749,34 @@ MODULE_DEVICE_TABLE(i2c, wm8971_i2c_id);
749 749
750static struct i2c_driver wm8971_i2c_driver = { 750static struct i2c_driver wm8971_i2c_driver = {
751 .driver = { 751 .driver = {
752 .name = "WM8971 I2C Codec", 752 .name = "wm8971-codec",
753 .owner = THIS_MODULE, 753 .owner = THIS_MODULE,
754 }, 754 },
755 .probe = wm8971_i2c_probe, 755 .probe = wm8971_i2c_probe,
756 .remove = wm8971_i2c_remove, 756 .remove = __devexit_p(wm8971_i2c_remove),
757 .id_table = wm8971_i2c_id, 757 .id_table = wm8971_i2c_id,
758}; 758};
759
760static int wm8971_add_i2c_device(struct platform_device *pdev,
761 const struct wm8971_setup_data *setup)
762{
763 struct i2c_board_info info;
764 struct i2c_adapter *adapter;
765 struct i2c_client *client;
766 int ret;
767
768 ret = i2c_add_driver(&wm8971_i2c_driver);
769 if (ret != 0) {
770 dev_err(&pdev->dev, "can't add i2c driver\n");
771 return ret;
772 }
773
774 memset(&info, 0, sizeof(struct i2c_board_info));
775 info.addr = setup->i2c_address;
776 strlcpy(info.type, "wm8971", I2C_NAME_SIZE);
777
778 adapter = i2c_get_adapter(setup->i2c_bus);
779 if (!adapter) {
780 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
781 setup->i2c_bus);
782 goto err_driver;
783 }
784
785 client = i2c_new_device(adapter, &info);
786 i2c_put_adapter(adapter);
787 if (!client) {
788 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
789 (unsigned int)info.addr);
790 goto err_driver;
791 }
792
793 return 0;
794
795err_driver:
796 i2c_del_driver(&wm8971_i2c_driver);
797 return -ENODEV;
798}
799
800#endif 759#endif
801 760
802static int wm8971_probe(struct platform_device *pdev) 761static int __init wm8971_modinit(void)
803{ 762{
804 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
805 struct wm8971_setup_data *setup;
806 struct snd_soc_codec *codec;
807 struct wm8971_priv *wm8971;
808 int ret = 0; 763 int ret = 0;
809 764#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
810 pr_info("WM8971 Audio Codec %s", WM8971_VERSION); 765 ret = i2c_add_driver(&wm8971_i2c_driver);
811
812 setup = socdev->codec_data;
813 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
814 if (codec == NULL)
815 return -ENOMEM;
816
817 wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL);
818 if (wm8971 == NULL) {
819 kfree(codec);
820 return -ENOMEM;
821 }
822
823 snd_soc_codec_set_drvdata(codec, wm8971);
824 socdev->card->codec = codec;
825 mutex_init(&codec->mutex);
826 INIT_LIST_HEAD(&codec->dapm_widgets);
827 INIT_LIST_HEAD(&codec->dapm_paths);
828 wm8971_socdev = socdev;
829
830 INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
831 wm8971_workq = create_workqueue("wm8971");
832 if (wm8971_workq == NULL) {
833 kfree(snd_soc_codec_get_drvdata(codec));
834 kfree(codec);
835 return -ENOMEM;
836 }
837
838#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
839 if (setup->i2c_address) {
840 ret = wm8971_add_i2c_device(pdev, setup);
841 }
842#endif
843 /* Add other interfaces here */
844
845 if (ret != 0) { 766 if (ret != 0) {
846 destroy_workqueue(wm8971_workq); 767 printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n",
847 kfree(snd_soc_codec_get_drvdata(codec)); 768 ret);
848 kfree(codec);
849 } 769 }
850
851 return ret;
852}
853
854/* power down chip */
855static int wm8971_remove(struct platform_device *pdev)
856{
857 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
858 struct snd_soc_codec *codec = socdev->card->codec;
859
860 if (codec->control_data)
861 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
862 if (wm8971_workq)
863 destroy_workqueue(wm8971_workq);
864 snd_soc_free_pcms(socdev);
865 snd_soc_dapm_free(socdev);
866#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
867 i2c_unregister_device(codec->control_data);
868 i2c_del_driver(&wm8971_i2c_driver);
869#endif 770#endif
870 kfree(snd_soc_codec_get_drvdata(codec)); 771 return ret;
871 kfree(codec);
872
873 return 0;
874}
875
876struct snd_soc_codec_device soc_codec_dev_wm8971 = {
877 .probe = wm8971_probe,
878 .remove = wm8971_remove,
879 .suspend = wm8971_suspend,
880 .resume = wm8971_resume,
881};
882
883EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971);
884
885static int __init wm8971_modinit(void)
886{
887 return snd_soc_register_dai(&wm8971_dai);
888} 772}
889module_init(wm8971_modinit); 773module_init(wm8971_modinit);
890 774
891static void __exit wm8971_exit(void) 775static void __exit wm8971_exit(void)
892{ 776{
893 snd_soc_unregister_dai(&wm8971_dai); 777#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
778 i2c_del_driver(&wm8971_i2c_driver);
779#endif
894} 780}
895module_exit(wm8971_exit); 781module_exit(wm8971_exit);
896 782
diff --git a/sound/soc/codecs/wm8971.h b/sound/soc/codecs/wm8971.h
index ef4f08f9f34..f31c38fddfc 100644
--- a/sound/soc/codecs/wm8971.h
+++ b/sound/soc/codecs/wm8971.h
@@ -53,12 +53,4 @@
53 53
54#define WM8971_SYSCLK 0 54#define WM8971_SYSCLK 0
55 55
56struct wm8971_setup_data {
57 int i2c_bus;
58 unsigned short i2c_address;
59};
60
61extern struct snd_soc_dai wm8971_dai;
62extern struct snd_soc_codec_device soc_codec_dev_wm8971;
63
64#endif 56#endif
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 1468fe10cbb..52f631c62e2 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -51,12 +51,11 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
51#define WM8974_POWER1_BUFIOEN 0x04 51#define WM8974_POWER1_BUFIOEN 0x04
52 52
53struct wm8974_priv { 53struct wm8974_priv {
54 struct snd_soc_codec codec; 54 enum snd_soc_control_type control_type;
55 void *control_data;
55 u16 reg_cache[WM8974_CACHEREGNUM]; 56 u16 reg_cache[WM8974_CACHEREGNUM];
56}; 57};
57 58
58static struct snd_soc_codec *wm8974_codec;
59
60#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0) 59#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0)
61 60
62static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" }; 61static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
@@ -566,8 +565,8 @@ static struct snd_soc_dai_ops wm8974_ops = {
566 .set_pll = wm8974_set_dai_pll, 565 .set_pll = wm8974_set_dai_pll,
567}; 566};
568 567
569struct snd_soc_dai wm8974_dai = { 568static struct snd_soc_dai_driver wm8974_dai = {
570 .name = "WM8974 HiFi", 569 .name = "wm8974-hifi",
571 .playback = { 570 .playback = {
572 .stream_name = "Playback", 571 .stream_name = "Playback",
573 .channels_min = 1, 572 .channels_min = 1,
@@ -583,21 +582,15 @@ struct snd_soc_dai wm8974_dai = {
583 .ops = &wm8974_ops, 582 .ops = &wm8974_ops,
584 .symmetric_rates = 1, 583 .symmetric_rates = 1,
585}; 584};
586EXPORT_SYMBOL_GPL(wm8974_dai);
587 585
588static int wm8974_suspend(struct platform_device *pdev, pm_message_t state) 586static int wm8974_suspend(struct snd_soc_codec *codec, pm_message_t state)
589{ 587{
590 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
591 struct snd_soc_codec *codec = socdev->card->codec;
592
593 wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF); 588 wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
594 return 0; 589 return 0;
595} 590}
596 591
597static int wm8974_resume(struct platform_device *pdev) 592static int wm8974_resume(struct snd_soc_codec *codec)
598{ 593{
599 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
600 struct snd_soc_codec *codec = socdev->card->codec;
601 int i; 594 int i;
602 u8 data[2]; 595 u8 data[2];
603 u16 *cache = codec->reg_cache; 596 u16 *cache = codec->reg_cache;
@@ -613,156 +606,75 @@ static int wm8974_resume(struct platform_device *pdev)
613 return 0; 606 return 0;
614} 607}
615 608
616static int wm8974_probe(struct platform_device *pdev) 609static int wm8974_probe(struct snd_soc_codec *codec)
617{ 610{
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 611 struct wm8974_priv *wm8974 = snd_soc_codec_get_drvdata(codec);
619 struct snd_soc_codec *codec;
620 int ret = 0; 612 int ret = 0;
621 613
622 if (wm8974_codec == NULL) { 614 codec->control_data = wm8974->control_data;
623 dev_err(&pdev->dev, "Codec device not registered\n"); 615 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
624 return -ENODEV; 616 if (ret < 0) {
617 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
618 return ret;
625 } 619 }
626 620
627 socdev->card->codec = wm8974_codec; 621 ret = wm8974_reset(codec);
628 codec = wm8974_codec;
629
630 /* register pcms */
631 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
632 if (ret < 0) { 622 if (ret < 0) {
633 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 623 dev_err(codec->dev, "Failed to issue reset\n");
634 goto pcm_err; 624 return ret;
635 } 625 }
636 626
627 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
637 snd_soc_add_controls(codec, wm8974_snd_controls, 628 snd_soc_add_controls(codec, wm8974_snd_controls,
638 ARRAY_SIZE(wm8974_snd_controls)); 629 ARRAY_SIZE(wm8974_snd_controls));
639 wm8974_add_widgets(codec); 630 wm8974_add_widgets(codec);
640 631
641 return ret; 632 return ret;
642
643pcm_err:
644 return ret;
645} 633}
646 634
647/* power down chip */ 635/* power down chip */
648static int wm8974_remove(struct platform_device *pdev) 636static int wm8974_remove(struct snd_soc_codec *codec)
649{ 637{
650 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 638 wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
651
652 snd_soc_free_pcms(socdev);
653 snd_soc_dapm_free(socdev);
654
655 return 0; 639 return 0;
656} 640}
657 641
658struct snd_soc_codec_device soc_codec_dev_wm8974 = { 642static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
659 .probe = wm8974_probe, 643 .probe = wm8974_probe,
660 .remove = wm8974_remove, 644 .remove = wm8974_remove,
661 .suspend = wm8974_suspend, 645 .suspend = wm8974_suspend,
662 .resume = wm8974_resume, 646 .resume = wm8974_resume,
647 .set_bias_level = wm8974_set_bias_level,
648 .reg_cache_size = ARRAY_SIZE(wm8974_reg),
649 .reg_word_size = sizeof(u16),
650 .reg_cache_default = wm8974_reg,
663}; 651};
664EXPORT_SYMBOL_GPL(soc_codec_dev_wm8974);
665
666static __devinit int wm8974_register(struct wm8974_priv *wm8974)
667{
668 int ret;
669 struct snd_soc_codec *codec = &wm8974->codec;
670
671 if (wm8974_codec) {
672 dev_err(codec->dev, "Another WM8974 is registered\n");
673 ret = -EINVAL;
674 goto err;
675 }
676
677 mutex_init(&codec->mutex);
678 INIT_LIST_HEAD(&codec->dapm_widgets);
679 INIT_LIST_HEAD(&codec->dapm_paths);
680
681 snd_soc_codec_set_drvdata(codec, wm8974);
682 codec->name = "WM8974";
683 codec->owner = THIS_MODULE;
684 codec->bias_level = SND_SOC_BIAS_OFF;
685 codec->set_bias_level = wm8974_set_bias_level;
686 codec->dai = &wm8974_dai;
687 codec->num_dai = 1;
688 codec->reg_cache_size = WM8974_CACHEREGNUM;
689 codec->reg_cache = &wm8974->reg_cache;
690
691 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
692 if (ret < 0) {
693 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
694 goto err;
695 }
696
697 memcpy(codec->reg_cache, wm8974_reg, sizeof(wm8974_reg));
698
699 ret = wm8974_reset(codec);
700 if (ret < 0) {
701 dev_err(codec->dev, "Failed to issue reset\n");
702 goto err;
703 }
704
705 wm8974_dai.dev = codec->dev;
706
707 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
708
709 wm8974_codec = codec;
710
711 ret = snd_soc_register_codec(codec);
712 if (ret != 0) {
713 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
714 goto err;
715 }
716
717 ret = snd_soc_register_dai(&wm8974_dai);
718 if (ret != 0) {
719 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
720 goto err_codec;
721 }
722
723 return 0;
724
725err_codec:
726 snd_soc_unregister_codec(codec);
727err:
728 kfree(wm8974);
729 return ret;
730}
731
732static __devexit void wm8974_unregister(struct wm8974_priv *wm8974)
733{
734 wm8974_set_bias_level(&wm8974->codec, SND_SOC_BIAS_OFF);
735 snd_soc_unregister_dai(&wm8974_dai);
736 snd_soc_unregister_codec(&wm8974->codec);
737 kfree(wm8974);
738 wm8974_codec = NULL;
739}
740 652
653#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
741static __devinit int wm8974_i2c_probe(struct i2c_client *i2c, 654static __devinit int wm8974_i2c_probe(struct i2c_client *i2c,
742 const struct i2c_device_id *id) 655 const struct i2c_device_id *id)
743{ 656{
744 struct wm8974_priv *wm8974; 657 struct wm8974_priv *wm8974;
745 struct snd_soc_codec *codec; 658 int ret;
746 659
747 wm8974 = kzalloc(sizeof(struct wm8974_priv), GFP_KERNEL); 660 wm8974 = kzalloc(sizeof(struct wm8974_priv), GFP_KERNEL);
748 if (wm8974 == NULL) 661 if (wm8974 == NULL)
749 return -ENOMEM; 662 return -ENOMEM;
750 663
751 codec = &wm8974->codec;
752 codec->hw_write = (hw_write_t)i2c_master_send;
753
754 i2c_set_clientdata(i2c, wm8974); 664 i2c_set_clientdata(i2c, wm8974);
755 codec->control_data = i2c; 665 wm8974->control_data = i2c;
756
757 codec->dev = &i2c->dev;
758 666
759 return wm8974_register(wm8974); 667 ret = snd_soc_register_codec(&i2c->dev,
668 &soc_codec_dev_wm8974, &wm8974_dai, 1);
669 if (ret < 0)
670 kfree(wm8974);
671 return ret;
760} 672}
761 673
762static __devexit int wm8974_i2c_remove(struct i2c_client *client) 674static __devexit int wm8974_i2c_remove(struct i2c_client *client)
763{ 675{
764 struct wm8974_priv *wm8974 = i2c_get_clientdata(client); 676 snd_soc_unregister_codec(&client->dev);
765 wm8974_unregister(wm8974); 677 kfree(i2c_get_clientdata(client));
766 return 0; 678 return 0;
767} 679}
768 680
@@ -774,23 +686,34 @@ MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id);
774 686
775static struct i2c_driver wm8974_i2c_driver = { 687static struct i2c_driver wm8974_i2c_driver = {
776 .driver = { 688 .driver = {
777 .name = "WM8974", 689 .name = "wm8974-codec",
778 .owner = THIS_MODULE, 690 .owner = THIS_MODULE,
779 }, 691 },
780 .probe = wm8974_i2c_probe, 692 .probe = wm8974_i2c_probe,
781 .remove = __devexit_p(wm8974_i2c_remove), 693 .remove = __devexit_p(wm8974_i2c_remove),
782 .id_table = wm8974_i2c_id, 694 .id_table = wm8974_i2c_id,
783}; 695};
696#endif
784 697
785static int __init wm8974_modinit(void) 698static int __init wm8974_modinit(void)
786{ 699{
787 return i2c_add_driver(&wm8974_i2c_driver); 700 int ret = 0;
701#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
702 ret = i2c_add_driver(&wm8974_i2c_driver);
703 if (ret != 0) {
704 printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n",
705 ret);
706 }
707#endif
708 return ret;
788} 709}
789module_init(wm8974_modinit); 710module_init(wm8974_modinit);
790 711
791static void __exit wm8974_exit(void) 712static void __exit wm8974_exit(void)
792{ 713{
714#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
793 i2c_del_driver(&wm8974_i2c_driver); 715 i2c_del_driver(&wm8974_i2c_driver);
716#endif
794} 717}
795module_exit(wm8974_exit); 718module_exit(wm8974_exit);
796 719
diff --git a/sound/soc/codecs/wm8974.h b/sound/soc/codecs/wm8974.h
index 896a7f0f3fc..3c94e7bb55a 100644
--- a/sound/soc/codecs/wm8974.h
+++ b/sound/soc/codecs/wm8974.h
@@ -83,7 +83,4 @@
83#define WM8974_MCLKDIV_8 (6 << 5) 83#define WM8974_MCLKDIV_8 (6 << 5)
84#define WM8974_MCLKDIV_12 (7 << 5) 84#define WM8974_MCLKDIV_12 (7 << 5)
85 85
86extern struct snd_soc_dai wm8974_dai;
87extern struct snd_soc_codec_device soc_codec_dev_wm8974;
88
89#endif 86#endif
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 8a1ad778e7e..676a4306cc8 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -31,8 +31,6 @@
31 31
32#include "wm8978.h" 32#include "wm8978.h"
33 33
34static struct snd_soc_codec *wm8978_codec;
35
36/* wm8978 register cache. Note that register 0 is not included in the cache. */ 34/* wm8978 register cache. Note that register 0 is not included in the cache. */
37static const u16 wm8978_reg[WM8978_CACHEREGNUM] = { 35static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
38 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */ 36 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */
@@ -54,7 +52,8 @@ static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
54 52
55/* codec private data */ 53/* codec private data */
56struct wm8978_priv { 54struct wm8978_priv {
57 struct snd_soc_codec codec; 55 enum snd_soc_control_type control_type;
56 void *control_data;
58 unsigned int f_pllout; 57 unsigned int f_pllout;
59 unsigned int f_mclk; 58 unsigned int f_mclk;
60 unsigned int f_256fs; 59 unsigned int f_256fs;
@@ -374,8 +373,8 @@ struct wm8978_pll_div {
374 373
375#define FIXED_PLL_SIZE (1 << 24) 374#define FIXED_PLL_SIZE (1 << 24)
376 375
377static void pll_factors(struct wm8978_pll_div *pll_div, unsigned int target, 376static void pll_factors(struct snd_soc_codec *codec,
378 unsigned int source) 377 struct wm8978_pll_div *pll_div, unsigned int target, unsigned int source)
379{ 378{
380 u64 k_part; 379 u64 k_part;
381 unsigned int k, n_div, n_mod; 380 unsigned int k, n_div, n_mod;
@@ -390,7 +389,7 @@ static void pll_factors(struct wm8978_pll_div *pll_div, unsigned int target,
390 } 389 }
391 390
392 if (n_div < 6 || n_div > 12) 391 if (n_div < 6 || n_div > 12)
393 dev_warn(wm8978_codec->dev, 392 dev_warn(codec->dev,
394 "WM8978 N value exceeds recommended range! N = %u\n", 393 "WM8978 N value exceeds recommended range! N = %u\n",
395 n_div); 394 n_div);
396 395
@@ -505,7 +504,7 @@ static int wm8978_configure_pll(struct snd_soc_codec *codec)
505 dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__, 504 dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
506 wm8978->f_mclk, wm8978->f_pllout); 505 wm8978->f_mclk, wm8978->f_pllout);
507 506
508 pll_factors(&pll_div, f2, wm8978->f_mclk); 507 pll_factors(codec, &pll_div, f2, wm8978->f_mclk);
509 508
510 dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n", 509 dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
511 __func__, pll_div.n, pll_div.k, pll_div.div2); 510 __func__, pll_div.n, pll_div.k, pll_div.div2);
@@ -690,8 +689,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
690 struct snd_soc_dai *dai) 689 struct snd_soc_dai *dai)
691{ 690{
692 struct snd_soc_pcm_runtime *rtd = substream->private_data; 691 struct snd_soc_pcm_runtime *rtd = substream->private_data;
693 struct snd_soc_device *socdev = rtd->socdev; 692 struct snd_soc_codec *codec = rtd->codec;
694 struct snd_soc_codec *codec = socdev->card->codec;
695 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); 693 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
696 /* Word length mask = 0x60 */ 694 /* Word length mask = 0x60 */
697 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60; 695 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
@@ -875,9 +873,8 @@ static struct snd_soc_dai_ops wm8978_dai_ops = {
875}; 873};
876 874
877/* Also supports 12kHz */ 875/* Also supports 12kHz */
878struct snd_soc_dai wm8978_dai = { 876static struct snd_soc_dai_driver wm8978_dai = {
879 .name = "WM8978 HiFi", 877 .name = "wm8978-hifi",
880 .id = 1,
881 .playback = { 878 .playback = {
882 .stream_name = "Playback", 879 .stream_name = "Playback",
883 .channels_min = 1, 880 .channels_min = 1,
@@ -894,13 +891,9 @@ struct snd_soc_dai wm8978_dai = {
894 }, 891 },
895 .ops = &wm8978_dai_ops, 892 .ops = &wm8978_dai_ops,
896}; 893};
897EXPORT_SYMBOL_GPL(wm8978_dai);
898 894
899static int wm8978_suspend(struct platform_device *pdev, pm_message_t state) 895static int wm8978_suspend(struct snd_soc_codec *codec, pm_message_t state)
900{ 896{
901 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
902 struct snd_soc_codec *codec = socdev->card->codec;
903
904 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF); 897 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
905 /* Also switch PLL off */ 898 /* Also switch PLL off */
906 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0); 899 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
@@ -908,10 +901,8 @@ static int wm8978_suspend(struct platform_device *pdev, pm_message_t state)
908 return 0; 901 return 0;
909} 902}
910 903
911static int wm8978_resume(struct platform_device *pdev) 904static int wm8978_resume(struct snd_soc_codec *codec)
912{ 905{
913 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
914 struct snd_soc_codec *codec = socdev->card->codec;
915 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); 906 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
916 int i; 907 int i;
917 u16 *cache = codec->reg_cache; 908 u16 *cache = codec->reg_cache;
@@ -933,54 +924,6 @@ static int wm8978_resume(struct platform_device *pdev)
933 return 0; 924 return 0;
934} 925}
935 926
936static int wm8978_probe(struct platform_device *pdev)
937{
938 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
939 struct snd_soc_codec *codec;
940 int ret = 0;
941
942 if (wm8978_codec == NULL) {
943 dev_err(&pdev->dev, "Codec device not registered\n");
944 return -ENODEV;
945 }
946
947 socdev->card->codec = wm8978_codec;
948 codec = wm8978_codec;
949
950 /* register pcms */
951 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
952 if (ret < 0) {
953 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
954 goto pcm_err;
955 }
956
957 snd_soc_add_controls(codec, wm8978_snd_controls,
958 ARRAY_SIZE(wm8978_snd_controls));
959 wm8978_add_widgets(codec);
960
961pcm_err:
962 return ret;
963}
964
965/* power down chip */
966static int wm8978_remove(struct platform_device *pdev)
967{
968 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
969
970 snd_soc_free_pcms(socdev);
971 snd_soc_dapm_free(socdev);
972
973 return 0;
974}
975
976struct snd_soc_codec_device soc_codec_dev_wm8978 = {
977 .probe = wm8978_probe,
978 .remove = wm8978_remove,
979 .suspend = wm8978_suspend,
980 .resume = wm8978_resume,
981};
982EXPORT_SYMBOL_GPL(soc_codec_dev_wm8978);
983
984/* 927/*
985 * These registers contain an "update" bit - bit 8. This means, for example, 928 * These registers contain an "update" bit - bit 8. This means, for example,
986 * that one can write new DAC digital volume for both channels, but only when 929 * that one can write new DAC digital volume for both channels, but only when
@@ -1000,44 +943,23 @@ static const int update_reg[] = {
1000 WM8978_ROUT2_SPK_CONTROL, 943 WM8978_ROUT2_SPK_CONTROL,
1001}; 944};
1002 945
1003static __devinit int wm8978_register(struct wm8978_priv *wm8978) 946static int wm8978_probe(struct snd_soc_codec *codec)
1004{ 947{
1005 int ret, i; 948 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
1006 struct snd_soc_codec *codec = &wm8978->codec; 949 int ret = 0, i;
1007
1008 if (wm8978_codec) {
1009 dev_err(codec->dev, "Another WM8978 is registered\n");
1010 return -EINVAL;
1011 }
1012 950
1013 /* 951 /*
1014 * Set default system clock to PLL, it is more precise, this is also the 952 * Set default system clock to PLL, it is more precise, this is also the
1015 * default hardware setting 953 * default hardware setting
1016 */ 954 */
1017 wm8978->sysclk = WM8978_PLL; 955 wm8978->sysclk = WM8978_PLL;
1018 956 codec->control_data = wm8978->control_data;
1019 mutex_init(&codec->mutex);
1020 INIT_LIST_HEAD(&codec->dapm_widgets);
1021 INIT_LIST_HEAD(&codec->dapm_paths);
1022
1023 snd_soc_codec_set_drvdata(codec, wm8978);
1024 codec->name = "WM8978";
1025 codec->owner = THIS_MODULE;
1026 codec->bias_level = SND_SOC_BIAS_OFF;
1027 codec->set_bias_level = wm8978_set_bias_level;
1028 codec->dai = &wm8978_dai;
1029 codec->num_dai = 1;
1030 codec->reg_cache_size = WM8978_CACHEREGNUM;
1031 codec->reg_cache = &wm8978->reg_cache;
1032
1033 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C); 957 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
1034 if (ret < 0) { 958 if (ret < 0) {
1035 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 959 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1036 goto err; 960 return ret;
1037 } 961 }
1038 962
1039 memcpy(codec->reg_cache, wm8978_reg, sizeof(wm8978_reg));
1040
1041 /* 963 /*
1042 * Set the update bit in all registers, that have one. This way all 964 * Set the update bit in all registers, that have one. This way all
1043 * writes to those registers will also cause the update bit to be 965 * writes to those registers will also cause the update bit to be
@@ -1050,74 +972,61 @@ static __devinit int wm8978_register(struct wm8978_priv *wm8978)
1050 ret = snd_soc_write(codec, WM8978_RESET, 0); 972 ret = snd_soc_write(codec, WM8978_RESET, 0);
1051 if (ret < 0) { 973 if (ret < 0) {
1052 dev_err(codec->dev, "Failed to issue reset\n"); 974 dev_err(codec->dev, "Failed to issue reset\n");
1053 goto err; 975 return ret;
1054 } 976 }
1055 977
1056 wm8978_dai.dev = codec->dev;
1057
1058 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 978 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1059 979
1060 wm8978_codec = codec; 980 snd_soc_add_controls(codec, wm8978_snd_controls,
1061 981 ARRAY_SIZE(wm8978_snd_controls));
1062 ret = snd_soc_register_codec(codec); 982 wm8978_add_widgets(codec);
1063 if (ret != 0) {
1064 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1065 goto err;
1066 }
1067
1068 ret = snd_soc_register_dai(&wm8978_dai);
1069 if (ret != 0) {
1070 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1071 goto err_codec;
1072 }
1073 983
1074 return 0; 984 return 0;
1075
1076err_codec:
1077 snd_soc_unregister_codec(codec);
1078err:
1079 return ret;
1080} 985}
1081 986
1082static __devexit void wm8978_unregister(struct wm8978_priv *wm8978) 987/* power down chip */
988static int wm8978_remove(struct snd_soc_codec *codec)
1083{ 989{
1084 wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF); 990 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
1085 snd_soc_unregister_dai(&wm8978_dai); 991 return 0;
1086 snd_soc_unregister_codec(&wm8978->codec);
1087 wm8978_codec = NULL;
1088} 992}
1089 993
994static struct snd_soc_codec_driver soc_codec_dev_wm8978 = {
995 .probe = wm8978_probe,
996 .remove = wm8978_remove,
997 .suspend = wm8978_suspend,
998 .resume = wm8978_resume,
999 .set_bias_level = wm8978_set_bias_level,
1000 .reg_cache_size = ARRAY_SIZE(wm8978_reg),
1001 .reg_word_size = sizeof(u16),
1002 .reg_cache_default = wm8978_reg,
1003};
1004
1005#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1090static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, 1006static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1091 const struct i2c_device_id *id) 1007 const struct i2c_device_id *id)
1092{ 1008{
1093 int ret;
1094 struct wm8978_priv *wm8978; 1009 struct wm8978_priv *wm8978;
1095 struct snd_soc_codec *codec; 1010 int ret;
1096 1011
1097 wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL); 1012 wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL);
1098 if (wm8978 == NULL) 1013 if (wm8978 == NULL)
1099 return -ENOMEM; 1014 return -ENOMEM;
1100 1015
1101 codec = &wm8978->codec;
1102 codec->hw_write = (hw_write_t)i2c_master_send;
1103
1104 i2c_set_clientdata(i2c, wm8978); 1016 i2c_set_clientdata(i2c, wm8978);
1105 codec->control_data = i2c; 1017 wm8978->control_data = i2c;
1106
1107 codec->dev = &i2c->dev;
1108 1018
1109 ret = wm8978_register(wm8978); 1019 ret = snd_soc_register_codec(&i2c->dev,
1020 &soc_codec_dev_wm8978, &wm8978_dai, 1);
1110 if (ret < 0) 1021 if (ret < 0)
1111 kfree(wm8978); 1022 kfree(wm8978);
1112
1113 return ret; 1023 return ret;
1114} 1024}
1115 1025
1116static __devexit int wm8978_i2c_remove(struct i2c_client *client) 1026static __devexit int wm8978_i2c_remove(struct i2c_client *client)
1117{ 1027{
1118 struct wm8978_priv *wm8978 = i2c_get_clientdata(client); 1028 snd_soc_unregister_codec(&client->dev);
1119 wm8978_unregister(wm8978); 1029 kfree(i2c_get_clientdata(client));
1120 kfree(wm8978);
1121 return 0; 1030 return 0;
1122} 1031}
1123 1032
@@ -1129,23 +1038,34 @@ MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id);
1129 1038
1130static struct i2c_driver wm8978_i2c_driver = { 1039static struct i2c_driver wm8978_i2c_driver = {
1131 .driver = { 1040 .driver = {
1132 .name = "WM8978", 1041 .name = "WM8978-codec",
1133 .owner = THIS_MODULE, 1042 .owner = THIS_MODULE,
1134 }, 1043 },
1135 .probe = wm8978_i2c_probe, 1044 .probe = wm8978_i2c_probe,
1136 .remove = __devexit_p(wm8978_i2c_remove), 1045 .remove = __devexit_p(wm8978_i2c_remove),
1137 .id_table = wm8978_i2c_id, 1046 .id_table = wm8978_i2c_id,
1138}; 1047};
1048#endif
1139 1049
1140static int __init wm8978_modinit(void) 1050static int __init wm8978_modinit(void)
1141{ 1051{
1142 return i2c_add_driver(&wm8978_i2c_driver); 1052 int ret = 0;
1053#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1054 ret = i2c_add_driver(&wm8978_i2c_driver);
1055 if (ret != 0) {
1056 printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n",
1057 ret);
1058 }
1059#endif
1060 return ret;
1143} 1061}
1144module_init(wm8978_modinit); 1062module_init(wm8978_modinit);
1145 1063
1146static void __exit wm8978_exit(void) 1064static void __exit wm8978_exit(void)
1147{ 1065{
1066#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1148 i2c_del_driver(&wm8978_i2c_driver); 1067 i2c_del_driver(&wm8978_i2c_driver);
1068#endif
1149} 1069}
1150module_exit(wm8978_exit); 1070module_exit(wm8978_exit);
1151 1071
diff --git a/sound/soc/codecs/wm8978.h b/sound/soc/codecs/wm8978.h
index 56ec8327091..c75525b7f15 100644
--- a/sound/soc/codecs/wm8978.h
+++ b/sound/soc/codecs/wm8978.h
@@ -80,7 +80,4 @@ enum wm8978_sysclk_src {
80 WM8978_MCLK 80 WM8978_MCLK
81}; 81};
82 82
83extern struct snd_soc_dai wm8978_dai;
84extern struct snd_soc_codec_device soc_codec_dev_wm8978;
85
86#endif /* __WM8978_H__ */ 83#endif /* __WM8978_H__ */
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 19ad590ca0b..ecbffcea71d 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -52,7 +52,8 @@ static const u16 wm8988_reg[] = {
52/* codec private data */ 52/* codec private data */
53struct wm8988_priv { 53struct wm8988_priv {
54 unsigned int sysclk; 54 unsigned int sysclk;
55 struct snd_soc_codec codec; 55 enum snd_soc_control_type control_type;
56 void *control_data;
56 struct snd_pcm_hw_constraint_list *sysclk_constraints; 57 struct snd_pcm_hw_constraint_list *sysclk_constraints;
57 u16 reg_cache[WM8988_NUM_REG]; 58 u16 reg_cache[WM8988_NUM_REG];
58}; 59};
@@ -608,8 +609,7 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
608 struct snd_soc_dai *dai) 609 struct snd_soc_dai *dai)
609{ 610{
610 struct snd_soc_pcm_runtime *rtd = substream->private_data; 611 struct snd_soc_pcm_runtime *rtd = substream->private_data;
611 struct snd_soc_device *socdev = rtd->socdev; 612 struct snd_soc_codec *codec = rtd->codec;
612 struct snd_soc_codec *codec = socdev->card->codec;
613 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); 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;
@@ -711,8 +711,8 @@ static struct snd_soc_dai_ops wm8988_ops = {
711 .digital_mute = wm8988_mute, 711 .digital_mute = wm8988_mute,
712}; 712};
713 713
714struct snd_soc_dai wm8988_dai = { 714static struct snd_soc_dai_driver wm8988_dai = {
715 .name = "WM8988", 715 .name = "wm8988-hifi",
716 .playback = { 716 .playback = {
717 .stream_name = "Playback", 717 .stream_name = "Playback",
718 .channels_min = 1, 718 .channels_min = 1,
@@ -730,21 +730,15 @@ struct snd_soc_dai wm8988_dai = {
730 .ops = &wm8988_ops, 730 .ops = &wm8988_ops,
731 .symmetric_rates = 1, 731 .symmetric_rates = 1,
732}; 732};
733EXPORT_SYMBOL_GPL(wm8988_dai);
734 733
735static int wm8988_suspend(struct platform_device *pdev, pm_message_t state) 734static int wm8988_suspend(struct snd_soc_codec *codec, pm_message_t state)
736{ 735{
737 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
738 struct snd_soc_codec *codec = socdev->card->codec;
739
740 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); 736 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
741 return 0; 737 return 0;
742} 738}
743 739
744static int wm8988_resume(struct platform_device *pdev) 740static int wm8988_resume(struct snd_soc_codec *codec)
745{ 741{
746 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
747 struct snd_soc_codec *codec = socdev->card->codec;
748 int i; 742 int i;
749 u8 data[2]; 743 u8 data[2];
750 u16 *cache = codec->reg_cache; 744 u16 *cache = codec->reg_cache;
@@ -763,99 +757,23 @@ static int wm8988_resume(struct platform_device *pdev)
763 return 0; 757 return 0;
764} 758}
765 759
766static struct snd_soc_codec *wm8988_codec; 760static int wm8988_probe(struct snd_soc_codec *codec)
767
768static int wm8988_probe(struct platform_device *pdev)
769{ 761{
770 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 762 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
771 struct snd_soc_codec *codec;
772 int ret = 0; 763 int ret = 0;
773
774 if (wm8988_codec == NULL) {
775 dev_err(&pdev->dev, "Codec device not registered\n");
776 return -ENODEV;
777 }
778
779 socdev->card->codec = wm8988_codec;
780 codec = wm8988_codec;
781
782 /* register pcms */
783 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
784 if (ret < 0) {
785 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
786 goto pcm_err;
787 }
788
789 snd_soc_add_controls(codec, wm8988_snd_controls,
790 ARRAY_SIZE(wm8988_snd_controls));
791 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
792 ARRAY_SIZE(wm8988_dapm_widgets));
793 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
794
795 return ret;
796
797pcm_err:
798 return ret;
799}
800
801static int wm8988_remove(struct platform_device *pdev)
802{
803 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
804
805 snd_soc_free_pcms(socdev);
806 snd_soc_dapm_free(socdev);
807
808 return 0;
809}
810
811struct snd_soc_codec_device soc_codec_dev_wm8988 = {
812 .probe = wm8988_probe,
813 .remove = wm8988_remove,
814 .suspend = wm8988_suspend,
815 .resume = wm8988_resume,
816};
817EXPORT_SYMBOL_GPL(soc_codec_dev_wm8988);
818
819static int wm8988_register(struct wm8988_priv *wm8988,
820 enum snd_soc_control_type control)
821{
822 struct snd_soc_codec *codec = &wm8988->codec;
823 int ret;
824 u16 reg; 764 u16 reg;
825 765
826 if (wm8988_codec) { 766 codec->control_data = wm8988->control_data;
827 dev_err(codec->dev, "Another WM8988 is registered\n"); 767 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type);
828 ret = -EINVAL;
829 goto err;
830 }
831
832 mutex_init(&codec->mutex);
833 INIT_LIST_HEAD(&codec->dapm_widgets);
834 INIT_LIST_HEAD(&codec->dapm_paths);
835
836 snd_soc_codec_set_drvdata(codec, wm8988);
837 codec->name = "WM8988";
838 codec->owner = THIS_MODULE;
839 codec->dai = &wm8988_dai;
840 codec->num_dai = 1;
841 codec->reg_cache_size = ARRAY_SIZE(wm8988->reg_cache);
842 codec->reg_cache = &wm8988->reg_cache;
843 codec->bias_level = SND_SOC_BIAS_OFF;
844 codec->set_bias_level = wm8988_set_bias_level;
845
846 memcpy(codec->reg_cache, wm8988_reg,
847 sizeof(wm8988_reg));
848
849 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
850 if (ret < 0) { 768 if (ret < 0) {
851 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 769 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
852 goto err; 770 return ret;
853 } 771 }
854 772
855 ret = wm8988_reset(codec); 773 ret = wm8988_reset(codec);
856 if (ret < 0) { 774 if (ret < 0) {
857 dev_err(codec->dev, "Failed to issue reset\n"); 775 dev_err(codec->dev, "Failed to issue reset\n");
858 goto err; 776 return ret;
859 } 777 }
860 778
861 /* set the update bits (we always update left then right) */ 779 /* set the update bits (we always update left then right) */
@@ -870,139 +788,135 @@ static int wm8988_register(struct wm8988_priv *wm8988,
870 reg = snd_soc_read(codec, WM8988_RINVOL); 788 reg = snd_soc_read(codec, WM8988_RINVOL);
871 snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100); 789 snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100);
872 790
873 wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY); 791 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
874
875 wm8988_dai.dev = codec->dev;
876
877 wm8988_codec = codec;
878
879 ret = snd_soc_register_codec(codec);
880 if (ret != 0) {
881 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
882 goto err;
883 }
884 792
885 ret = snd_soc_register_dai(&wm8988_dai); 793 snd_soc_add_controls(codec, wm8988_snd_controls,
886 if (ret != 0) { 794 ARRAY_SIZE(wm8988_snd_controls));
887 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 795 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
888 goto err_codec; 796 ARRAY_SIZE(wm8988_dapm_widgets));
889 } 797 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
890 798
891 return 0; 799 return 0;
892
893err_codec:
894 snd_soc_unregister_codec(codec);
895err:
896 kfree(wm8988);
897 return ret;
898} 800}
899 801
900static void wm8988_unregister(struct wm8988_priv *wm8988) 802static int wm8988_remove(struct snd_soc_codec *codec)
901{ 803{
902 wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_OFF); 804 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
903 snd_soc_unregister_dai(&wm8988_dai); 805 return 0;
904 snd_soc_unregister_codec(&wm8988->codec);
905 kfree(wm8988);
906 wm8988_codec = NULL;
907} 806}
908 807
909#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 808static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
910static int wm8988_i2c_probe(struct i2c_client *i2c, 809 .probe = wm8988_probe,
911 const struct i2c_device_id *id) 810 .remove = wm8988_remove,
811 .suspend = wm8988_suspend,
812 .resume = wm8988_resume,
813 .set_bias_level = wm8988_set_bias_level,
814 .reg_cache_size = sizeof(wm8988_reg),
815 .reg_word_size = sizeof(u16),
816 .reg_cache_default = wm8988_reg,
817};
818
819#if defined(CONFIG_SPI_MASTER)
820static int __devinit wm8988_spi_probe(struct spi_device *spi)
912{ 821{
913 struct wm8988_priv *wm8988; 822 struct wm8988_priv *wm8988;
914 struct snd_soc_codec *codec; 823 int ret;
915 824
916 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); 825 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
917 if (wm8988 == NULL) 826 if (wm8988 == NULL)
918 return -ENOMEM; 827 return -ENOMEM;
919 828
920 codec = &wm8988->codec; 829 wm8988->control_data = spi;
921 830 wm8988->control_type = SND_SOC_SPI;
922 i2c_set_clientdata(i2c, wm8988); 831 spi_set_drvdata(spi, wm8988);
923 codec->control_data = i2c;
924
925 codec->dev = &i2c->dev;
926 832
927 return wm8988_register(wm8988, SND_SOC_I2C); 833 ret = snd_soc_register_codec(&spi->dev,
834 &soc_codec_dev_wm8988, &wm8988_dai, 1);
835 if (ret < 0)
836 kfree(wm8988);
837 return ret;
928} 838}
929 839
930static int wm8988_i2c_remove(struct i2c_client *client) 840static int __devexit wm8988_spi_remove(struct spi_device *spi)
931{ 841{
932 struct wm8988_priv *wm8988 = i2c_get_clientdata(client); 842 snd_soc_unregister_codec(&spi->dev);
933 wm8988_unregister(wm8988); 843 kfree(spi_get_drvdata(spi));
934 return 0; 844 return 0;
935} 845}
936 846
937static const struct i2c_device_id wm8988_i2c_id[] = { 847static struct spi_driver wm8988_spi_driver = {
938 { "wm8988", 0 },
939 { }
940};
941MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
942
943static struct i2c_driver wm8988_i2c_driver = {
944 .driver = { 848 .driver = {
945 .name = "WM8988", 849 .name = "wm8988-codec",
946 .owner = THIS_MODULE, 850 .bus = &spi_bus_type,
851 .owner = THIS_MODULE,
947 }, 852 },
948 .probe = wm8988_i2c_probe, 853 .probe = wm8988_spi_probe,
949 .remove = wm8988_i2c_remove, 854 .remove = __devexit_p(wm8988_spi_remove),
950 .id_table = wm8988_i2c_id,
951}; 855};
952#endif 856#endif /* CONFIG_SPI_MASTER */
953 857
954#if defined(CONFIG_SPI_MASTER) 858#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
955static int __devinit wm8988_spi_probe(struct spi_device *spi) 859static __devinit int wm8988_i2c_probe(struct i2c_client *i2c,
860 const struct i2c_device_id *id)
956{ 861{
957 struct wm8988_priv *wm8988; 862 struct wm8988_priv *wm8988;
958 struct snd_soc_codec *codec; 863 int ret;
959 864
960 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); 865 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
961 if (wm8988 == NULL) 866 if (wm8988 == NULL)
962 return -ENOMEM; 867 return -ENOMEM;
963 868
964 codec = &wm8988->codec; 869 i2c_set_clientdata(i2c, wm8988);
965 codec->control_data = spi; 870 wm8988->control_data = i2c;
966 codec->dev = &spi->dev; 871 wm8988->control_type = SND_SOC_I2C;
967
968 dev_set_drvdata(&spi->dev, wm8988);
969 872
970 return wm8988_register(wm8988, SND_SOC_SPI); 873 ret = snd_soc_register_codec(&i2c->dev,
874 &soc_codec_dev_wm8988, &wm8988_dai, 1);
875 if (ret < 0)
876 kfree(wm8988);
877 return ret;
971} 878}
972 879
973static int __devexit wm8988_spi_remove(struct spi_device *spi) 880static __devexit int wm8988_i2c_remove(struct i2c_client *client)
974{ 881{
975 struct wm8988_priv *wm8988 = dev_get_drvdata(&spi->dev); 882 snd_soc_unregister_codec(&client->dev);
976 883 kfree(i2c_get_clientdata(client));
977 wm8988_unregister(wm8988);
978
979 return 0; 884 return 0;
980} 885}
981 886
982static struct spi_driver wm8988_spi_driver = { 887static const struct i2c_device_id wm8988_i2c_id[] = {
888 { "wm8988", 0 },
889 { }
890};
891MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
892
893static struct i2c_driver wm8988_i2c_driver = {
983 .driver = { 894 .driver = {
984 .name = "wm8988", 895 .name = "wm8988-codec",
985 .bus = &spi_bus_type, 896 .owner = THIS_MODULE,
986 .owner = THIS_MODULE,
987 }, 897 },
988 .probe = wm8988_spi_probe, 898 .probe = wm8988_i2c_probe,
989 .remove = __devexit_p(wm8988_spi_remove), 899 .remove = __devexit_p(wm8988_i2c_remove),
900 .id_table = wm8988_i2c_id,
990}; 901};
991#endif 902#endif
992 903
993static int __init wm8988_modinit(void) 904static int __init wm8988_modinit(void)
994{ 905{
995 int ret; 906 int ret = 0;
996
997#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 907#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
998 ret = i2c_add_driver(&wm8988_i2c_driver); 908 ret = i2c_add_driver(&wm8988_i2c_driver);
999 if (ret != 0) 909 if (ret != 0) {
1000 pr_err("WM8988: Unable to register I2C driver: %d\n", ret); 910 printk(KERN_ERR "Failed to register WM8988 I2C driver: %d\n",
911 ret);
912 }
1001#endif 913#endif
1002#if defined(CONFIG_SPI_MASTER) 914#if defined(CONFIG_SPI_MASTER)
1003 ret = spi_register_driver(&wm8988_spi_driver); 915 ret = spi_register_driver(&wm8988_spi_driver);
1004 if (ret != 0) 916 if (ret != 0) {
1005 pr_err("WM8988: Unable to register SPI driver: %d\n", ret); 917 printk(KERN_ERR "Failed to register WM8988 SPI driver: %d\n",
918 ret);
919 }
1006#endif 920#endif
1007 return ret; 921 return ret;
1008} 922}
diff --git a/sound/soc/codecs/wm8988.h b/sound/soc/codecs/wm8988.h
index 4552d37fdd4..5c04024e5f9 100644
--- a/sound/soc/codecs/wm8988.h
+++ b/sound/soc/codecs/wm8988.h
@@ -54,7 +54,4 @@
54 54
55#define WM8988_SYSCLK 0 55#define WM8988_SYSCLK 0
56 56
57extern struct snd_soc_dai wm8988_dai;
58extern struct snd_soc_codec_device soc_codec_dev_wm8988;
59
60#endif 57#endif
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index dd8d909788c..b2524338296 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -32,6 +32,8 @@
32 32
33/* codec private data */ 33/* codec private data */
34struct wm8990_priv { 34struct wm8990_priv {
35 enum snd_soc_control_type control_type;
36 void *control_data;
35 unsigned int sysclk; 37 unsigned int sysclk;
36 unsigned int pcmclk; 38 unsigned int pcmclk;
37}; 39};
@@ -1114,8 +1116,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
1114 struct snd_soc_dai *dai) 1116 struct snd_soc_dai *dai)
1115{ 1117{
1116 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1118 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1117 struct snd_soc_device *socdev = rtd->socdev; 1119 struct snd_soc_codec *codec = rtd->codec;
1118 struct snd_soc_codec *codec = socdev->card->codec;
1119 u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1); 1120 u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
1120 1121
1121 audio1 &= ~WM8990_AIF_WL_MASK; 1122 audio1 &= ~WM8990_AIF_WL_MASK;
@@ -1293,10 +1294,9 @@ static struct snd_soc_dai_ops wm8990_dai_ops = {
1293 .set_sysclk = wm8990_set_dai_sysclk, 1294 .set_sysclk = wm8990_set_dai_sysclk,
1294}; 1295};
1295 1296
1296struct snd_soc_dai wm8990_dai = { 1297static struct snd_soc_dai_driver wm8990_dai = {
1297/* ADC/DAC on primary */ 1298/* ADC/DAC on primary */
1298 .name = "WM8990 ADC/DAC Primary", 1299 .name = "wm8990-hifi",
1299 .id = 1,
1300 .playback = { 1300 .playback = {
1301 .stream_name = "Playback", 1301 .stream_name = "Playback",
1302 .channels_min = 1, 1302 .channels_min = 1,
@@ -1311,21 +1311,15 @@ struct snd_soc_dai wm8990_dai = {
1311 .formats = WM8990_FORMATS,}, 1311 .formats = WM8990_FORMATS,},
1312 .ops = &wm8990_dai_ops, 1312 .ops = &wm8990_dai_ops,
1313}; 1313};
1314EXPORT_SYMBOL_GPL(wm8990_dai);
1315 1314
1316static int wm8990_suspend(struct platform_device *pdev, pm_message_t state) 1315static int wm8990_suspend(struct snd_soc_codec *codec, pm_message_t state)
1317{ 1316{
1318 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1319 struct snd_soc_codec *codec = socdev->card->codec;
1320
1321 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); 1317 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1322 return 0; 1318 return 0;
1323} 1319}
1324 1320
1325static int wm8990_resume(struct platform_device *pdev) 1321static int wm8990_resume(struct snd_soc_codec *codec)
1326{ 1322{
1327 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1328 struct snd_soc_codec *codec = socdev->card->codec;
1329 int i; 1323 int i;
1330 u8 data[2]; 1324 u8 data[2];
1331 u16 *cache = codec->reg_cache; 1325 u16 *cache = codec->reg_cache;
@@ -1347,38 +1341,21 @@ static int wm8990_resume(struct platform_device *pdev)
1347 * initialise the WM8990 driver 1341 * initialise the WM8990 driver
1348 * register the mixer and dsp interfaces with the kernel 1342 * register the mixer and dsp interfaces with the kernel
1349 */ 1343 */
1350static int wm8990_init(struct snd_soc_device *socdev) 1344static int wm8990_probe(struct snd_soc_codec *codec)
1351{ 1345{
1352 struct snd_soc_codec *codec = socdev->card->codec; 1346 struct wm8990_priv *wm8990 = snd_soc_codec_get_drvdata(codec);
1347 int ret;
1353 u16 reg; 1348 u16 reg;
1354 int ret = 0;
1355
1356 codec->name = "WM8990";
1357 codec->owner = THIS_MODULE;
1358 codec->set_bias_level = wm8990_set_bias_level;
1359 codec->dai = &wm8990_dai;
1360 codec->num_dai = 2;
1361 codec->reg_cache_size = ARRAY_SIZE(wm8990_reg);
1362 codec->reg_cache = kmemdup(wm8990_reg, sizeof(wm8990_reg), GFP_KERNEL);
1363
1364 if (codec->reg_cache == NULL)
1365 return -ENOMEM;
1366 1349
1350 codec->control_data = wm8990->control_data;
1367 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1351 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1368 if (ret < 0) { 1352 if (ret < 0) {
1369 printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret); 1353 printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret);
1370 goto pcm_err; 1354 return ret;
1371 } 1355 }
1372 1356
1373 wm8990_reset(codec); 1357 wm8990_reset(codec);
1374 1358
1375 /* register pcms */
1376 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1377 if (ret < 0) {
1378 printk(KERN_ERR "wm8990: failed to create pcms\n");
1379 goto pcm_err;
1380 }
1381
1382 /* charge output caps */ 1359 /* charge output caps */
1383 codec->bias_level = SND_SOC_BIAS_OFF; 1360 codec->bias_level = SND_SOC_BIAS_OFF;
1384 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1361 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1400,47 +1377,52 @@ static int wm8990_init(struct snd_soc_device *socdev)
1400 ARRAY_SIZE(wm8990_snd_controls)); 1377 ARRAY_SIZE(wm8990_snd_controls));
1401 wm8990_add_widgets(codec); 1378 wm8990_add_widgets(codec);
1402 1379
1403 return ret; 1380 return 0;
1381}
1404 1382
1405pcm_err: 1383/* power down chip */
1406 kfree(codec->reg_cache); 1384static int wm8990_remove(struct snd_soc_codec *codec)
1407 return ret; 1385{
1386 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1387 return 0;
1408} 1388}
1409 1389
1410/* If the i2c layer weren't so broken, we could pass this kind of data 1390static struct snd_soc_codec_driver soc_codec_dev_wm8990 = {
1411 around */ 1391 .probe = wm8990_probe,
1412static struct snd_soc_device *wm8990_socdev; 1392 .remove = wm8990_remove,
1393 .suspend = wm8990_suspend,
1394 .resume = wm8990_resume,
1395 .set_bias_level = wm8990_set_bias_level,
1396 .reg_cache_size = ARRAY_SIZE(wm8990_reg),
1397 .reg_word_size = sizeof(u16),
1398 .reg_cache_default = wm8990_reg,
1399};
1413 1400
1414#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1401#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1415 1402static __devinit int wm8990_i2c_probe(struct i2c_client *i2c,
1416/* 1403 const struct i2c_device_id *id)
1417 * WM891 2 wire address is determined by GPIO5
1418 * state during powerup.
1419 * low = 0x34
1420 * high = 0x36
1421 */
1422
1423static int wm8990_i2c_probe(struct i2c_client *i2c,
1424 const struct i2c_device_id *id)
1425{ 1404{
1426 struct snd_soc_device *socdev = wm8990_socdev; 1405 struct wm8990_priv *wm8990;
1427 struct snd_soc_codec *codec = socdev->card->codec;
1428 int ret; 1406 int ret;
1429 1407
1430 i2c_set_clientdata(i2c, codec); 1408 wm8990 = kzalloc(sizeof(struct wm8990_priv), GFP_KERNEL);
1431 codec->control_data = i2c; 1409 if (wm8990 == NULL)
1410 return -ENOMEM;
1432 1411
1433 ret = wm8990_init(socdev); 1412 i2c_set_clientdata(i2c, wm8990);
1434 if (ret < 0) 1413 wm8990->control_data = i2c;
1435 pr_err("failed to initialise WM8990\n");
1436 1414
1415 ret = snd_soc_register_codec(&i2c->dev,
1416 &soc_codec_dev_wm8990, &wm8990_dai, 1);
1417 if (ret < 0)
1418 kfree(wm8990);
1437 return ret; 1419 return ret;
1438} 1420}
1439 1421
1440static int wm8990_i2c_remove(struct i2c_client *client) 1422static __devexit int wm8990_i2c_remove(struct i2c_client *client)
1441{ 1423{
1442 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1424 snd_soc_unregister_codec(&client->dev);
1443 kfree(codec->reg_cache); 1425 kfree(i2c_get_clientdata(client));
1444 return 0; 1426 return 0;
1445} 1427}
1446 1428
@@ -1452,134 +1434,34 @@ MODULE_DEVICE_TABLE(i2c, wm8990_i2c_id);
1452 1434
1453static struct i2c_driver wm8990_i2c_driver = { 1435static struct i2c_driver wm8990_i2c_driver = {
1454 .driver = { 1436 .driver = {
1455 .name = "WM8990 I2C Codec", 1437 .name = "wm8990-codec",
1456 .owner = THIS_MODULE, 1438 .owner = THIS_MODULE,
1457 }, 1439 },
1458 .probe = wm8990_i2c_probe, 1440 .probe = wm8990_i2c_probe,
1459 .remove = wm8990_i2c_remove, 1441 .remove = __devexit_p(wm8990_i2c_remove),
1460 .id_table = wm8990_i2c_id, 1442 .id_table = wm8990_i2c_id,
1461}; 1443};
1462
1463static int wm8990_add_i2c_device(struct platform_device *pdev,
1464 const struct wm8990_setup_data *setup)
1465{
1466 struct i2c_board_info info;
1467 struct i2c_adapter *adapter;
1468 struct i2c_client *client;
1469 int ret;
1470
1471 ret = i2c_add_driver(&wm8990_i2c_driver);
1472 if (ret != 0) {
1473 dev_err(&pdev->dev, "can't add i2c driver\n");
1474 return ret;
1475 }
1476
1477 memset(&info, 0, sizeof(struct i2c_board_info));
1478 info.addr = setup->i2c_address;
1479 strlcpy(info.type, "wm8990", I2C_NAME_SIZE);
1480
1481 adapter = i2c_get_adapter(setup->i2c_bus);
1482 if (!adapter) {
1483 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1484 setup->i2c_bus);
1485 goto err_driver;
1486 }
1487
1488 client = i2c_new_device(adapter, &info);
1489 i2c_put_adapter(adapter);
1490 if (!client) {
1491 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1492 (unsigned int)info.addr);
1493 goto err_driver;
1494 }
1495
1496 return 0;
1497
1498err_driver:
1499 i2c_del_driver(&wm8990_i2c_driver);
1500 return -ENODEV;
1501}
1502#endif 1444#endif
1503 1445
1504static int wm8990_probe(struct platform_device *pdev) 1446static int __init wm8990_modinit(void)
1505{ 1447{
1506 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1448 int ret = 0;
1507 struct wm8990_setup_data *setup;
1508 struct snd_soc_codec *codec;
1509 struct wm8990_priv *wm8990;
1510 int ret;
1511
1512 setup = socdev->codec_data;
1513 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1514 if (codec == NULL)
1515 return -ENOMEM;
1516
1517 wm8990 = kzalloc(sizeof(struct wm8990_priv), GFP_KERNEL);
1518 if (wm8990 == NULL) {
1519 kfree(codec);
1520 return -ENOMEM;
1521 }
1522
1523 snd_soc_codec_set_drvdata(codec, wm8990);
1524 socdev->card->codec = codec;
1525 mutex_init(&codec->mutex);
1526 INIT_LIST_HEAD(&codec->dapm_widgets);
1527 INIT_LIST_HEAD(&codec->dapm_paths);
1528 wm8990_socdev = socdev;
1529
1530 ret = -ENODEV;
1531
1532#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1449#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1533 if (setup->i2c_address) { 1450 ret = i2c_add_driver(&wm8990_i2c_driver);
1534 codec->hw_write = (hw_write_t)i2c_master_send;
1535 ret = wm8990_add_i2c_device(pdev, setup);
1536 }
1537#endif
1538
1539 if (ret != 0) { 1451 if (ret != 0) {
1540 kfree(snd_soc_codec_get_drvdata(codec)); 1452 printk(KERN_ERR "Failed to register wm8990 I2C driver: %d\n",
1541 kfree(codec); 1453 ret);
1542 } 1454 }
1455#endif
1543 return ret; 1456 return ret;
1544} 1457}
1458module_init(wm8990_modinit);
1545 1459
1546/* power down chip */ 1460static void __exit wm8990_exit(void)
1547static int wm8990_remove(struct platform_device *pdev)
1548{ 1461{
1549 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1550 struct snd_soc_codec *codec = socdev->card->codec;
1551
1552 if (codec->control_data)
1553 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1554 snd_soc_free_pcms(socdev);
1555 snd_soc_dapm_free(socdev);
1556#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1462#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1557 i2c_unregister_device(codec->control_data);
1558 i2c_del_driver(&wm8990_i2c_driver); 1463 i2c_del_driver(&wm8990_i2c_driver);
1559#endif 1464#endif
1560 kfree(snd_soc_codec_get_drvdata(codec));
1561 kfree(codec);
1562
1563 return 0;
1564}
1565
1566struct snd_soc_codec_device soc_codec_dev_wm8990 = {
1567 .probe = wm8990_probe,
1568 .remove = wm8990_remove,
1569 .suspend = wm8990_suspend,
1570 .resume = wm8990_resume,
1571};
1572EXPORT_SYMBOL_GPL(soc_codec_dev_wm8990);
1573
1574static int __init wm8990_modinit(void)
1575{
1576 return snd_soc_register_dai(&wm8990_dai);
1577}
1578module_init(wm8990_modinit);
1579
1580static void __exit wm8990_exit(void)
1581{
1582 snd_soc_unregister_dai(&wm8990_dai);
1583} 1465}
1584module_exit(wm8990_exit); 1466module_exit(wm8990_exit);
1585 1467
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h
index 7114ddc88b4..77c98a4bfe9 100644
--- a/sound/soc/codecs/wm8990.h
+++ b/sound/soc/codecs/wm8990.h
@@ -826,18 +826,10 @@
826#define WM8990_INMIXR_PWR_BIT 2 826#define WM8990_INMIXR_PWR_BIT 2
827#define WM8990_AINRMUX_PWR_BIT 3 827#define WM8990_AINRMUX_PWR_BIT 3
828 828
829struct wm8990_setup_data {
830 unsigned i2c_bus;
831 unsigned short i2c_address;
832};
833
834#define WM8990_MCLK_DIV 0 829#define WM8990_MCLK_DIV 0
835#define WM8990_DACCLK_DIV 1 830#define WM8990_DACCLK_DIV 1
836#define WM8990_ADCCLK_DIV 2 831#define WM8990_ADCCLK_DIV 2
837#define WM8990_BCLK_DIV 3 832#define WM8990_BCLK_DIV 3
838 833
839extern struct snd_soc_dai wm8990_dai;
840extern struct snd_soc_codec_device soc_codec_dev_wm8990;
841
842#endif /* __WM8990REGISTERDEFS_H__ */ 834#endif /* __WM8990REGISTERDEFS_H__ */
843/*------------------------------ END OF FILE ---------------------------------*/ 835/*------------------------------ END OF FILE ---------------------------------*/
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index d8d300c6175..1d9e1837a2d 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -229,7 +229,8 @@ struct wm8993_priv {
229 u16 reg_cache[WM8993_REGISTER_COUNT]; 229 u16 reg_cache[WM8993_REGISTER_COUNT];
230 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; 230 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
231 struct wm8993_platform_data pdata; 231 struct wm8993_platform_data pdata;
232 struct snd_soc_codec codec; 232 enum snd_soc_control_type control_type;
233 void *control_data;
233 int master; 234 int master;
234 int sysclk_source; 235 int sysclk_source;
235 int tdm_slots; 236 int tdm_slots;
@@ -367,10 +368,9 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
367 return 0; 368 return 0;
368} 369}
369 370
370static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source, 371static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
371 unsigned int Fref, unsigned int Fout) 372 unsigned int Fref, unsigned int Fout)
372{ 373{
373 struct snd_soc_codec *codec = dai->codec;
374 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 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;
@@ -456,6 +456,12 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
456 return 0; 456 return 0;
457} 457}
458 458
459static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
460 unsigned int Fref, unsigned int Fout)
461{
462 return _wm8993_set_fll(dai->codec, fll_id, source, Fref, Fout);
463}
464
459static int configure_clock(struct snd_soc_codec *codec) 465static int configure_clock(struct snd_soc_codec *codec)
460{ 466{
461 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 467 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
@@ -1394,8 +1400,8 @@ static struct snd_soc_dai_ops wm8993_ops = {
1394 SNDRV_PCM_FMTBIT_S24_LE |\ 1400 SNDRV_PCM_FMTBIT_S24_LE |\
1395 SNDRV_PCM_FMTBIT_S32_LE) 1401 SNDRV_PCM_FMTBIT_S32_LE)
1396 1402
1397struct snd_soc_dai wm8993_dai = { 1403static struct snd_soc_dai_driver wm8993_dai = {
1398 .name = "WM8993", 1404 .name = "wm8993-hifi",
1399 .playback = { 1405 .playback = {
1400 .stream_name = "Playback", 1406 .stream_name = "Playback",
1401 .channels_min = 1, 1407 .channels_min = 1,
@@ -1413,32 +1419,82 @@ struct snd_soc_dai wm8993_dai = {
1413 .ops = &wm8993_ops, 1419 .ops = &wm8993_ops,
1414 .symmetric_rates = 1, 1420 .symmetric_rates = 1,
1415}; 1421};
1416EXPORT_SYMBOL_GPL(wm8993_dai);
1417
1418static struct snd_soc_codec *wm8993_codec;
1419 1422
1420static int wm8993_probe(struct platform_device *pdev) 1423static int wm8993_probe(struct snd_soc_codec *codec)
1421{ 1424{
1422 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1425 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1423 struct snd_soc_codec *codec; 1426 int ret, i, val;
1424 struct wm8993_priv *wm8993; 1427
1425 int ret = 0; 1428 codec->control_data = wm8993->control_data;
1429 wm8993->hubs_data.hp_startup_mode = 1;
1430 wm8993->hubs_data.dcs_codes = -2;
1431
1432 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1433 if (ret != 0) {
1434 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1435 return ret;
1436 }
1437
1438 for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
1439 wm8993->supplies[i].supply = wm8993_supply_names[i];
1426 1440
1427 if (!wm8993_codec) { 1441 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
1428 dev_err(&pdev->dev, "I2C device not yet probed\n"); 1442 wm8993->supplies);
1429 goto err; 1443 if (ret != 0) {
1444 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1445 return ret;
1430 } 1446 }
1431 1447
1432 socdev->card->codec = wm8993_codec; 1448 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
1433 codec = wm8993_codec; 1449 wm8993->supplies);
1434 wm8993 = snd_soc_codec_get_drvdata(codec); 1450 if (ret != 0) {
1451 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1452 goto err_get;
1453 }
1435 1454
1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1455 val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
1437 if (ret < 0) { 1456 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1438 dev_err(codec->dev, "failed to create pcms\n"); 1457 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1439 goto err; 1458 ret = -EINVAL;
1459 goto err_enable;
1440 } 1460 }
1441 1461
1462 ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1463 if (ret != 0)
1464 goto err_enable;
1465
1466 codec->cache_only = 1;
1467
1468 /* By default we're using the output mixers */
1469 wm8993->class_w_users = 2;
1470
1471 /* Latch volume update bits and default ZC on */
1472 snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
1473 WM8993_DAC_VU, WM8993_DAC_VU);
1474 snd_soc_update_bits(codec, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
1475 WM8993_ADC_VU, WM8993_ADC_VU);
1476
1477 /* Manualy manage the HPOUT sequencing for independent stereo
1478 * control. */
1479 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
1480 WM8993_HPOUT1_AUTO_PU, 0);
1481
1482 /* Use automatic clock configuration */
1483 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
1484
1485 wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
1486 wm8993->pdata.lineout2_diff,
1487 wm8993->pdata.lineout1fb,
1488 wm8993->pdata.lineout2fb,
1489 wm8993->pdata.jd_scthr,
1490 wm8993->pdata.jd_thr,
1491 wm8993->pdata.micbias1_lvl,
1492 wm8993->pdata.micbias2_lvl);
1493
1494 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1495 if (ret != 0)
1496 goto err_enable;
1497
1442 snd_soc_add_controls(codec, wm8993_snd_controls, 1498 snd_soc_add_controls(codec, wm8993_snd_controls,
1443 ARRAY_SIZE(wm8993_snd_controls)); 1499 ARRAY_SIZE(wm8993_snd_controls));
1444 if (wm8993->pdata.num_retune_configs != 0) { 1500 if (wm8993->pdata.num_retune_configs != 0) {
@@ -1457,36 +1513,36 @@ static int wm8993_probe(struct platform_device *pdev)
1457 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, 1513 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1458 wm8993->pdata.lineout2_diff); 1514 wm8993->pdata.lineout2_diff);
1459 1515
1460 return ret; 1516 return 0;
1461 1517
1462err: 1518err_enable:
1519 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1520err_get:
1521 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1463 return ret; 1522 return ret;
1464} 1523}
1465 1524
1466static int wm8993_remove(struct platform_device *pdev) 1525static int wm8993_remove(struct snd_soc_codec *codec)
1467{ 1526{
1468 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1527 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1469
1470 snd_soc_free_pcms(socdev);
1471 snd_soc_dapm_free(socdev);
1472 1528
1529 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1530 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1473 return 0; 1531 return 0;
1474} 1532}
1475 1533
1476#ifdef CONFIG_PM 1534#ifdef CONFIG_PM
1477static int wm8993_suspend(struct platform_device *pdev, pm_message_t state) 1535static int wm8993_suspend(struct snd_soc_codec *codec, pm_message_t state)
1478{ 1536{
1479 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1480 struct snd_soc_codec *codec = socdev->card->codec;
1481 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 1537 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1482 int fll_fout = wm8993->fll_fout; 1538 int fll_fout = wm8993->fll_fout;
1483 int fll_fref = wm8993->fll_fref; 1539 int fll_fref = wm8993->fll_fref;
1484 int ret; 1540 int ret;
1485 1541
1486 /* Stop the FLL in an orderly fashion */ 1542 /* Stop the FLL in an orderly fashion */
1487 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0); 1543 ret = _wm8993_set_fll(codec, 0, 0, 0, 0);
1488 if (ret != 0) { 1544 if (ret != 0) {
1489 dev_err(&pdev->dev, "Failed to stop FLL\n"); 1545 dev_err(codec->dev, "Failed to stop FLL\n");
1490 return ret; 1546 return ret;
1491 } 1547 }
1492 1548
@@ -1498,10 +1554,8 @@ static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1498 return 0; 1554 return 0;
1499} 1555}
1500 1556
1501static int wm8993_resume(struct platform_device *pdev) 1557static int wm8993_resume(struct snd_soc_codec *codec)
1502{ 1558{
1503 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1504 struct snd_soc_codec *codec = socdev->card->codec;
1505 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 1559 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1506 int ret; 1560 int ret;
1507 1561
@@ -1515,7 +1569,7 @@ static int wm8993_resume(struct platform_device *pdev)
1515 wm8993->fll_fref = 0; 1569 wm8993->fll_fref = 0;
1516 wm8993->fll_fout = 0; 1570 wm8993->fll_fout = 0;
1517 1571
1518 ret = wm8993_set_fll(codec->dai, 0, wm8993->fll_src, 1572 ret = _wm8993_set_fll(codec, 0, wm8993->fll_src,
1519 fll_fref, fll_fout); 1573 fll_fref, fll_fout);
1520 if (ret != 0) 1574 if (ret != 0)
1521 dev_err(codec->dev, "Failed to restart FLL\n"); 1575 dev_err(codec->dev, "Failed to restart FLL\n");
@@ -1528,162 +1582,43 @@ static int wm8993_resume(struct platform_device *pdev)
1528#define wm8993_resume NULL 1582#define wm8993_resume NULL
1529#endif 1583#endif
1530 1584
1531struct snd_soc_codec_device soc_codec_dev_wm8993 = { 1585static struct snd_soc_codec_driver soc_codec_dev_wm8993 = {
1532 .probe = wm8993_probe, 1586 .probe = wm8993_probe,
1533 .remove = wm8993_remove, 1587 .remove = wm8993_remove,
1534 .suspend = wm8993_suspend, 1588 .suspend = wm8993_suspend,
1535 .resume = wm8993_resume, 1589 .resume = wm8993_resume,
1590 .set_bias_level = wm8993_set_bias_level,
1591 .reg_cache_size = sizeof(wm8993_reg_defaults),
1592 .reg_word_size = sizeof(u16),
1593 .reg_cache_default = wm8993_reg_defaults,
1594 .volatile_register = wm8993_volatile,
1536}; 1595};
1537EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993);
1538 1596
1539static int wm8993_i2c_probe(struct i2c_client *i2c, 1597#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1540 const struct i2c_device_id *id) 1598static __devinit int wm8993_i2c_probe(struct i2c_client *i2c,
1599 const struct i2c_device_id *id)
1541{ 1600{
1542 struct wm8993_priv *wm8993; 1601 struct wm8993_priv *wm8993;
1543 struct snd_soc_codec *codec;
1544 unsigned int val;
1545 int ret; 1602 int ret;
1546 int i;
1547
1548 if (wm8993_codec) {
1549 dev_err(&i2c->dev, "A WM8993 is already registered\n");
1550 return -EINVAL;
1551 }
1552 1603
1553 wm8993 = kzalloc(sizeof(struct wm8993_priv), GFP_KERNEL); 1604 wm8993 = kzalloc(sizeof(struct wm8993_priv), GFP_KERNEL);
1554 if (wm8993 == NULL) 1605 if (wm8993 == NULL)
1555 return -ENOMEM; 1606 return -ENOMEM;
1556 1607
1557 codec = &wm8993->codec;
1558 if (i2c->dev.platform_data)
1559 memcpy(&wm8993->pdata, i2c->dev.platform_data,
1560 sizeof(wm8993->pdata));
1561
1562 mutex_init(&codec->mutex);
1563 INIT_LIST_HEAD(&codec->dapm_widgets);
1564 INIT_LIST_HEAD(&codec->dapm_paths);
1565
1566 codec->name = "WM8993";
1567 codec->volatile_register = wm8993_volatile;
1568 codec->reg_cache = wm8993->reg_cache;
1569 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1570 codec->bias_level = SND_SOC_BIAS_OFF;
1571 codec->set_bias_level = wm8993_set_bias_level;
1572 codec->dai = &wm8993_dai;
1573 codec->num_dai = 1;
1574 snd_soc_codec_set_drvdata(codec, wm8993);
1575
1576 wm8993->hubs_data.hp_startup_mode = 1;
1577 wm8993->hubs_data.dcs_codes = -2;
1578
1579 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1580 sizeof(wm8993->reg_cache));
1581
1582 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1583 if (ret != 0) {
1584 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1585 goto err;
1586 }
1587
1588 i2c_set_clientdata(i2c, wm8993); 1608 i2c_set_clientdata(i2c, wm8993);
1589 codec->control_data = i2c; 1609 wm8993->control_data = i2c;
1590 wm8993_codec = codec;
1591
1592 codec->dev = &i2c->dev;
1593
1594 for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
1595 wm8993->supplies[i].supply = wm8993_supply_names[i];
1596
1597 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
1598 wm8993->supplies);
1599 if (ret != 0) {
1600 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1601 goto err;
1602 }
1603
1604 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
1605 wm8993->supplies);
1606 if (ret != 0) {
1607 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1608 goto err_get;
1609 }
1610
1611 val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
1612 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1613 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1614 ret = -EINVAL;
1615 goto err_enable;
1616 }
1617
1618 ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1619 if (ret != 0)
1620 goto err_enable;
1621
1622 codec->cache_only = 1;
1623
1624 /* By default we're using the output mixers */
1625 wm8993->class_w_users = 2;
1626
1627 /* Latch volume update bits and default ZC on */
1628 snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
1629 WM8993_DAC_VU, WM8993_DAC_VU);
1630 snd_soc_update_bits(codec, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
1631 WM8993_ADC_VU, WM8993_ADC_VU);
1632 1610
1633 /* Manualy manage the HPOUT sequencing for independent stereo 1611 ret = snd_soc_register_codec(&i2c->dev,
1634 * control. */ 1612 &soc_codec_dev_wm8993, &wm8993_dai, 1);
1635 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0, 1613 if (ret < 0)
1636 WM8993_HPOUT1_AUTO_PU, 0); 1614 kfree(wm8993);
1637
1638 /* Use automatic clock configuration */
1639 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
1640
1641 wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
1642 wm8993->pdata.lineout2_diff,
1643 wm8993->pdata.lineout1fb,
1644 wm8993->pdata.lineout2fb,
1645 wm8993->pdata.jd_scthr,
1646 wm8993->pdata.jd_thr,
1647 wm8993->pdata.micbias1_lvl,
1648 wm8993->pdata.micbias2_lvl);
1649
1650 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1651 if (ret != 0)
1652 goto err_enable;
1653
1654 wm8993_dai.dev = codec->dev;
1655
1656 ret = snd_soc_register_dai(&wm8993_dai);
1657 if (ret != 0)
1658 goto err_bias;
1659
1660 ret = snd_soc_register_codec(codec);
1661
1662 return 0;
1663
1664err_bias:
1665 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1666err_enable:
1667 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1668err_get:
1669 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1670err:
1671 wm8993_codec = NULL;
1672 kfree(wm8993);
1673 return ret; 1615 return ret;
1674} 1616}
1675 1617
1676static int wm8993_i2c_remove(struct i2c_client *client) 1618static __devexit int wm8993_i2c_remove(struct i2c_client *client)
1677{ 1619{
1678 struct wm8993_priv *wm8993 = i2c_get_clientdata(client); 1620 snd_soc_unregister_codec(&client->dev);
1679 1621 kfree(i2c_get_clientdata(client));
1680 snd_soc_unregister_codec(&wm8993->codec);
1681 snd_soc_unregister_dai(&wm8993_dai);
1682
1683 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF);
1684 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1685 kfree(wm8993);
1686
1687 return 0; 1622 return 0;
1688} 1623}
1689 1624
@@ -1695,30 +1630,34 @@ MODULE_DEVICE_TABLE(i2c, wm8993_i2c_id);
1695 1630
1696static struct i2c_driver wm8993_i2c_driver = { 1631static struct i2c_driver wm8993_i2c_driver = {
1697 .driver = { 1632 .driver = {
1698 .name = "WM8993", 1633 .name = "wm8993-codec",
1699 .owner = THIS_MODULE, 1634 .owner = THIS_MODULE,
1700 }, 1635 },
1701 .probe = wm8993_i2c_probe, 1636 .probe = wm8993_i2c_probe,
1702 .remove = wm8993_i2c_remove, 1637 .remove = __devexit_p(wm8993_i2c_remove),
1703 .id_table = wm8993_i2c_id, 1638 .id_table = wm8993_i2c_id,
1704}; 1639};
1705 1640#endif
1706 1641
1707static int __init wm8993_modinit(void) 1642static int __init wm8993_modinit(void)
1708{ 1643{
1709 int ret; 1644 int ret = 0;
1710 1645#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1711 ret = i2c_add_driver(&wm8993_i2c_driver); 1646 ret = i2c_add_driver(&wm8993_i2c_driver);
1712 if (ret != 0) 1647 if (ret != 0) {
1713 pr_err("WM8993: Unable to register I2C driver: %d\n", ret); 1648 pr_err("WM8993: Unable to register I2C driver: %d\n",
1714 1649 ret);
1650 }
1651#endif
1715 return ret; 1652 return ret;
1716} 1653}
1717module_init(wm8993_modinit); 1654module_init(wm8993_modinit);
1718 1655
1719static void __exit wm8993_exit(void) 1656static void __exit wm8993_exit(void)
1720{ 1657{
1658#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1721 i2c_del_driver(&wm8993_i2c_driver); 1659 i2c_del_driver(&wm8993_i2c_driver);
1660#endif
1722} 1661}
1723module_exit(wm8993_exit); 1662module_exit(wm8993_exit);
1724 1663
diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h
index 30e71ca88da..2184617b961 100644
--- a/sound/soc/codecs/wm8993.h
+++ b/sound/soc/codecs/wm8993.h
@@ -1,9 +1,6 @@
1#ifndef WM8993_H 1#ifndef WM8993_H
2#define WM8993_H 2#define WM8993_H
3 3
4extern struct snd_soc_dai wm8993_dai;
5extern struct snd_soc_codec_device soc_codec_dev_wm8993;
6
7#define WM8993_SYSCLK_MCLK 1 4#define WM8993_SYSCLK_MCLK 1
8#define WM8993_SYSCLK_FLL 2 5#define WM8993_SYSCLK_FLL 2
9 6
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index a87046a96f2..7823f92413f 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -36,9 +36,6 @@
36#include "wm8994.h" 36#include "wm8994.h"
37#include "wm_hubs.h" 37#include "wm_hubs.h"
38 38
39static struct snd_soc_codec *wm8994_codec;
40struct snd_soc_codec_device soc_codec_dev_wm8994;
41
42struct fll_config { 39struct fll_config {
43 int src; 40 int src;
44 int in; 41 int in;
@@ -71,7 +68,9 @@ struct wm8994_micdet {
71/* codec private data */ 68/* codec private data */
72struct wm8994_priv { 69struct wm8994_priv {
73 struct wm_hubs_data hubs; 70 struct wm_hubs_data hubs;
74 struct snd_soc_codec codec; 71 enum snd_soc_control_type control_type;
72 void *control_data;
73 struct snd_soc_codec *codec;
75 u16 reg_cache[WM8994_REG_CACHE_SIZE + 1]; 74 u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
76 int sysclk[2]; 75 int sysclk[2];
77 int sysclk_rate[2]; 76 int sysclk_rate[2];
@@ -1901,8 +1900,6 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
1901 return snd_soc_put_volsw(kcontrol, ucontrol); 1900 return snd_soc_put_volsw(kcontrol, ucontrol);
1902} 1901}
1903 1902
1904
1905
1906static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) 1903static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
1907{ 1904{
1908 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 1905 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
@@ -1941,7 +1938,7 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
1941 struct snd_ctl_elem_value *ucontrol) 1938 struct snd_ctl_elem_value *ucontrol)
1942{ 1939{
1943 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1940 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1944 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 1941 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1945 struct wm8994_pdata *pdata = wm8994->pdata; 1942 struct wm8994_pdata *pdata = wm8994->pdata;
1946 int drc = wm8994_get_drc(kcontrol->id.name); 1943 int drc = wm8994_get_drc(kcontrol->id.name);
1947 int value = ucontrol->value.integer.value[0]; 1944 int value = ucontrol->value.integer.value[0];
@@ -2044,7 +2041,7 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2044 struct snd_ctl_elem_value *ucontrol) 2041 struct snd_ctl_elem_value *ucontrol)
2045{ 2042{
2046 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2043 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2047 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2044 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2048 struct wm8994_pdata *pdata = wm8994->pdata; 2045 struct wm8994_pdata *pdata = wm8994->pdata;
2049 int block = wm8994_get_retune_mobile_block(kcontrol->id.name); 2046 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2050 int value = ucontrol->value.integer.value[0]; 2047 int value = ucontrol->value.integer.value[0];
@@ -2066,7 +2063,7 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2066 struct snd_ctl_elem_value *ucontrol) 2063 struct snd_ctl_elem_value *ucontrol)
2067{ 2064{
2068 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2065 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2069 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2066 struct wm8994_priv *wm8994 =snd_soc_codec_get_drvdata(codec);
2070 int block = wm8994_get_retune_mobile_block(kcontrol->id.name); 2067 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2071 2068
2072 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block]; 2069 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
@@ -2880,10 +2877,9 @@ static int wm8994_get_fll_config(struct fll_div *fll,
2880 return 0; 2877 return 0;
2881} 2878}
2882 2879
2883static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src, 2880static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2884 unsigned int freq_in, unsigned int freq_out) 2881 unsigned int freq_in, unsigned int freq_out)
2885{ 2882{
2886 struct snd_soc_codec *codec = dai->codec;
2887 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2883 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2888 int reg_offset, ret; 2884 int reg_offset, ret;
2889 struct fll_div fll; 2885 struct fll_div fll;
@@ -2994,8 +2990,15 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2994 return 0; 2990 return 0;
2995} 2991}
2996 2992
2993
2997static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 }; 2994static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
2998 2995
2996static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2997 unsigned int freq_in, unsigned int freq_out)
2998{
2999 return _wm8994_set_fll(dai->codec, id, src, freq_in, freq_out);
3000}
3001
2999static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, 3002static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
3000 int clk_id, unsigned int freq, int dir) 3003 int clk_id, unsigned int freq, int dir)
3001{ 3004{
@@ -3507,10 +3510,9 @@ static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
3507 .set_tristate = wm8994_set_tristate, 3510 .set_tristate = wm8994_set_tristate,
3508}; 3511};
3509 3512
3510struct snd_soc_dai wm8994_dai[] = { 3513static struct snd_soc_dai_driver wm8994_dai[] = {
3511 { 3514 {
3512 .name = "WM8994 AIF1", 3515 .name = "wm8994-aif1",
3513 .id = 1,
3514 .playback = { 3516 .playback = {
3515 .stream_name = "AIF1 Playback", 3517 .stream_name = "AIF1 Playback",
3516 .channels_min = 2, 3518 .channels_min = 2,
@@ -3528,8 +3530,7 @@ struct snd_soc_dai wm8994_dai[] = {
3528 .ops = &wm8994_aif1_dai_ops, 3530 .ops = &wm8994_aif1_dai_ops,
3529 }, 3531 },
3530 { 3532 {
3531 .name = "WM8994 AIF2", 3533 .name = "wm8994-aif2",
3532 .id = 2,
3533 .playback = { 3534 .playback = {
3534 .stream_name = "AIF2 Playback", 3535 .stream_name = "AIF2 Playback",
3535 .channels_min = 2, 3536 .channels_min = 2,
@@ -3547,8 +3548,7 @@ struct snd_soc_dai wm8994_dai[] = {
3547 .ops = &wm8994_aif2_dai_ops, 3548 .ops = &wm8994_aif2_dai_ops,
3548 }, 3549 },
3549 { 3550 {
3550 .name = "WM8994 AIF3", 3551 .name = "wm8994-aif3",
3551 .id = 3,
3552 .playback = { 3552 .playback = {
3553 .stream_name = "AIF3 Playback", 3553 .stream_name = "AIF3 Playback",
3554 .channels_min = 2, 3554 .channels_min = 2,
@@ -3566,20 +3566,17 @@ struct snd_soc_dai wm8994_dai[] = {
3566 .ops = &wm8994_aif3_dai_ops, 3566 .ops = &wm8994_aif3_dai_ops,
3567 } 3567 }
3568}; 3568};
3569EXPORT_SYMBOL_GPL(wm8994_dai);
3570 3569
3571#ifdef CONFIG_PM 3570#ifdef CONFIG_PM
3572static int wm8994_suspend(struct platform_device *pdev, pm_message_t state) 3571static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
3573{ 3572{
3574 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3575 struct snd_soc_codec *codec = socdev->card->codec;
3576 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3573 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3577 int i, ret; 3574 int i, ret;
3578 3575
3579 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 3576 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3580 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], 3577 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
3581 sizeof(struct fll_config)); 3578 sizeof(struct fll_config));
3582 ret = wm8994_set_fll(&codec->dai[0], i + 1, 0, 0, 0); 3579 ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0);
3583 if (ret < 0) 3580 if (ret < 0)
3584 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n", 3581 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
3585 i + 1, ret); 3582 i + 1, ret);
@@ -3590,10 +3587,8 @@ static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
3590 return 0; 3587 return 0;
3591} 3588}
3592 3589
3593static int wm8994_resume(struct platform_device *pdev) 3590static int wm8994_resume(struct snd_soc_codec *codec)
3594{ 3591{
3595 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3596 struct snd_soc_codec *codec = socdev->card->codec;
3597 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3592 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3598 u16 *reg_cache = codec->reg_cache; 3593 u16 *reg_cache = codec->reg_cache;
3599 int i, ret; 3594 int i, ret;
@@ -3622,7 +3617,7 @@ static int wm8994_resume(struct platform_device *pdev)
3622 if (!wm8994->fll_suspend[i].out) 3617 if (!wm8994->fll_suspend[i].out)
3623 continue; 3618 continue;
3624 3619
3625 ret = wm8994_set_fll(&codec->dai[0], i + 1, 3620 ret = _wm8994_set_fll(codec, i + 1,
3626 wm8994->fll_suspend[i].src, 3621 wm8994->fll_suspend[i].src,
3627 wm8994->fll_suspend[i].in, 3622 wm8994->fll_suspend[i].in,
3628 wm8994->fll_suspend[i].out); 3623 wm8994->fll_suspend[i].out);
@@ -3640,7 +3635,7 @@ static int wm8994_resume(struct platform_device *pdev)
3640 3635
3641static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) 3636static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3642{ 3637{
3643 struct snd_soc_codec *codec = &wm8994->codec; 3638 struct snd_soc_codec *codec = wm8994->codec;
3644 struct wm8994_pdata *pdata = wm8994->pdata; 3639 struct wm8994_pdata *pdata = wm8994->pdata;
3645 struct snd_kcontrol_new controls[] = { 3640 struct snd_kcontrol_new controls[] = {
3646 SOC_ENUM_EXT("AIF1.1 EQ Mode", 3641 SOC_ENUM_EXT("AIF1.1 EQ Mode",
@@ -3698,16 +3693,16 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3698 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; 3693 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
3699 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; 3694 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
3700 3695
3701 ret = snd_soc_add_controls(&wm8994->codec, controls, 3696 ret = snd_soc_add_controls(wm8994->codec, controls,
3702 ARRAY_SIZE(controls)); 3697 ARRAY_SIZE(controls));
3703 if (ret != 0) 3698 if (ret != 0)
3704 dev_err(wm8994->codec.dev, 3699 dev_err(wm8994->codec->dev,
3705 "Failed to add ReTune Mobile controls: %d\n", ret); 3700 "Failed to add ReTune Mobile controls: %d\n", ret);
3706} 3701}
3707 3702
3708static void wm8994_handle_pdata(struct wm8994_priv *wm8994) 3703static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3709{ 3704{
3710 struct snd_soc_codec *codec = &wm8994->codec; 3705 struct snd_soc_codec *codec = wm8994->codec;
3711 struct wm8994_pdata *pdata = wm8994->pdata; 3706 struct wm8994_pdata *pdata = wm8994->pdata;
3712 int ret, i; 3707 int ret, i;
3713 3708
@@ -3739,7 +3734,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3739 wm8994->drc_texts = kmalloc(sizeof(char *) 3734 wm8994->drc_texts = kmalloc(sizeof(char *)
3740 * pdata->num_drc_cfgs, GFP_KERNEL); 3735 * pdata->num_drc_cfgs, GFP_KERNEL);
3741 if (!wm8994->drc_texts) { 3736 if (!wm8994->drc_texts) {
3742 dev_err(wm8994->codec.dev, 3737 dev_err(wm8994->codec->dev,
3743 "Failed to allocate %d DRC config texts\n", 3738 "Failed to allocate %d DRC config texts\n",
3744 pdata->num_drc_cfgs); 3739 pdata->num_drc_cfgs);
3745 return; 3740 return;
@@ -3751,10 +3746,10 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3751 wm8994->drc_enum.max = pdata->num_drc_cfgs; 3746 wm8994->drc_enum.max = pdata->num_drc_cfgs;
3752 wm8994->drc_enum.texts = wm8994->drc_texts; 3747 wm8994->drc_enum.texts = wm8994->drc_texts;
3753 3748
3754 ret = snd_soc_add_controls(&wm8994->codec, controls, 3749 ret = snd_soc_add_controls(wm8994->codec, controls,
3755 ARRAY_SIZE(controls)); 3750 ARRAY_SIZE(controls));
3756 if (ret != 0) 3751 if (ret != 0)
3757 dev_err(wm8994->codec.dev, 3752 dev_err(wm8994->codec->dev,
3758 "Failed to add DRC mode controls: %d\n", ret); 3753 "Failed to add DRC mode controls: %d\n", ret);
3759 3754
3760 for (i = 0; i < WM8994_NUM_DRC; i++) 3755 for (i = 0; i < WM8994_NUM_DRC; i++)
@@ -3767,62 +3762,10 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3767 if (pdata->num_retune_mobile_cfgs) 3762 if (pdata->num_retune_mobile_cfgs)
3768 wm8994_handle_retune_mobile_pdata(wm8994); 3763 wm8994_handle_retune_mobile_pdata(wm8994);
3769 else 3764 else
3770 snd_soc_add_controls(&wm8994->codec, wm8994_eq_controls, 3765 snd_soc_add_controls(wm8994->codec, wm8994_eq_controls,
3771 ARRAY_SIZE(wm8994_eq_controls)); 3766 ARRAY_SIZE(wm8994_eq_controls));
3772} 3767}
3773 3768
3774static int wm8994_probe(struct platform_device *pdev)
3775{
3776 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3777 struct snd_soc_codec *codec;
3778 int ret = 0;
3779
3780 if (wm8994_codec == NULL) {
3781 dev_err(&pdev->dev, "Codec device not registered\n");
3782 return -ENODEV;
3783 }
3784
3785 socdev->card->codec = wm8994_codec;
3786 codec = wm8994_codec;
3787
3788 /* register pcms */
3789 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
3790 if (ret < 0) {
3791 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
3792 return ret;
3793 }
3794
3795 wm8994_handle_pdata(snd_soc_codec_get_drvdata(codec));
3796
3797 wm_hubs_add_analogue_controls(codec);
3798 snd_soc_add_controls(codec, wm8994_snd_controls,
3799 ARRAY_SIZE(wm8994_snd_controls));
3800 snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
3801 ARRAY_SIZE(wm8994_dapm_widgets));
3802 wm_hubs_add_analogue_routes(codec, 0, 0);
3803 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
3804
3805 return 0;
3806}
3807
3808static int wm8994_remove(struct platform_device *pdev)
3809{
3810 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3811
3812 snd_soc_free_pcms(socdev);
3813 snd_soc_dapm_free(socdev);
3814
3815 return 0;
3816}
3817
3818struct snd_soc_codec_device soc_codec_dev_wm8994 = {
3819 .probe = wm8994_probe,
3820 .remove = wm8994_remove,
3821 .suspend = wm8994_suspend,
3822 .resume = wm8994_resume,
3823};
3824EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
3825
3826/** 3769/**
3827 * wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ 3770 * wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ
3828 * 3771 *
@@ -3881,7 +3824,7 @@ EXPORT_SYMBOL_GPL(wm8994_mic_detect);
3881static irqreturn_t wm8994_mic_irq(int irq, void *data) 3824static irqreturn_t wm8994_mic_irq(int irq, void *data)
3882{ 3825{
3883 struct wm8994_priv *priv = data; 3826 struct wm8994_priv *priv = data;
3884 struct snd_soc_codec *codec = &priv->codec; 3827 struct snd_soc_codec *codec = priv->codec;
3885 int reg; 3828 int reg;
3886 int report; 3829 int report;
3887 3830
@@ -3913,47 +3856,20 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
3913 return IRQ_HANDLED; 3856 return IRQ_HANDLED;
3914} 3857}
3915 3858
3916static int wm8994_codec_probe(struct platform_device *pdev) 3859static int wm8994_codec_probe(struct snd_soc_codec *codec)
3917{ 3860{
3918 int ret;
3919 struct wm8994_priv *wm8994; 3861 struct wm8994_priv *wm8994;
3920 struct snd_soc_codec *codec; 3862 int ret, i, rev;
3921 int i;
3922 u16 rev;
3923 3863
3924 if (wm8994_codec) { 3864 codec->control_data = dev_get_drvdata(codec->dev->parent);
3925 dev_err(&pdev->dev, "Another WM8994 is registered\n");
3926 return -EINVAL;
3927 }
3928 3865
3929 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); 3866 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
3930 if (!wm8994) { 3867 if (wm8994 == NULL)
3931 dev_err(&pdev->dev, "Failed to allocate private data\n");
3932 return -ENOMEM; 3868 return -ENOMEM;
3933 }
3934
3935 codec = &wm8994->codec;
3936
3937 mutex_init(&codec->mutex);
3938 INIT_LIST_HEAD(&codec->dapm_widgets);
3939 INIT_LIST_HEAD(&codec->dapm_paths);
3940
3941 snd_soc_codec_set_drvdata(codec, wm8994); 3869 snd_soc_codec_set_drvdata(codec, wm8994);
3942 codec->control_data = dev_get_drvdata(pdev->dev.parent); 3870
3943 codec->name = "WM8994"; 3871 wm8994->pdata = dev_get_platdata(codec->dev->parent);
3944 codec->owner = THIS_MODULE; 3872 wm8994->codec = codec;
3945 codec->read = wm8994_read;
3946 codec->write = wm8994_write;
3947 codec->readable_register = wm8994_readable;
3948 codec->bias_level = SND_SOC_BIAS_OFF;
3949 codec->set_bias_level = wm8994_set_bias_level;
3950 codec->dai = &wm8994_dai[0];
3951 codec->num_dai = 3;
3952 codec->reg_cache_size = WM8994_MAX_REGISTER;
3953 codec->reg_cache = &wm8994->reg_cache;
3954 codec->dev = &pdev->dev;
3955
3956 wm8994->pdata = pdev->dev.parent->platform_data;
3957 3873
3958 /* Fill the cache with physical values we inherited; don't reset */ 3874 /* Fill the cache with physical values we inherited; don't reset */
3959 ret = wm8994_bulk_read(codec->control_data, 0, 3875 ret = wm8994_bulk_read(codec->control_data, 0,
@@ -3989,25 +3905,25 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3989 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET, 3905 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
3990 wm8994_mic_irq, "Mic 1 detect", wm8994); 3906 wm8994_mic_irq, "Mic 1 detect", wm8994);
3991 if (ret != 0) 3907 if (ret != 0)
3992 dev_warn(&pdev->dev, 3908 dev_warn(codec->dev,
3993 "Failed to request Mic1 detect IRQ: %d\n", ret); 3909 "Failed to request Mic1 detect IRQ: %d\n", ret);
3994 3910
3995 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, 3911 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
3996 wm8994_mic_irq, "Mic 1 short", wm8994); 3912 wm8994_mic_irq, "Mic 1 short", wm8994);
3997 if (ret != 0) 3913 if (ret != 0)
3998 dev_warn(&pdev->dev, 3914 dev_warn(codec->dev,
3999 "Failed to request Mic1 short IRQ: %d\n", ret); 3915 "Failed to request Mic1 short IRQ: %d\n", ret);
4000 3916
4001 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET, 3917 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
4002 wm8994_mic_irq, "Mic 2 detect", wm8994); 3918 wm8994_mic_irq, "Mic 2 detect", wm8994);
4003 if (ret != 0) 3919 if (ret != 0)
4004 dev_warn(&pdev->dev, 3920 dev_warn(codec->dev,
4005 "Failed to request Mic2 detect IRQ: %d\n", ret); 3921 "Failed to request Mic2 detect IRQ: %d\n", ret);
4006 3922
4007 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, 3923 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
4008 wm8994_mic_irq, "Mic 2 short", wm8994); 3924 wm8994_mic_irq, "Mic 2 short", wm8994);
4009 if (ret != 0) 3925 if (ret != 0)
4010 dev_warn(&pdev->dev, 3926 dev_warn(codec->dev,
4011 "Failed to request Mic2 short IRQ: %d\n", ret); 3927 "Failed to request Mic2 short IRQ: %d\n", ret);
4012 3928
4013 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3929 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
@@ -4038,13 +3954,8 @@ static int wm8994_codec_probe(struct platform_device *pdev)
4038 wm8994->lrclk_shared[1] = 0; 3954 wm8994->lrclk_shared[1] = 0;
4039 } 3955 }
4040 3956
4041 for (i = 0; i < ARRAY_SIZE(wm8994_dai); i++)
4042 wm8994_dai[i].dev = codec->dev;
4043
4044 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 3957 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
4045 3958
4046 wm8994_codec = codec;
4047
4048 /* Latch volume updates (right only; we always do left then right). */ 3959 /* Latch volume updates (right only; we always do left then right). */
4049 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME, 3960 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME,
4050 WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU); 3961 WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
@@ -4081,24 +3992,18 @@ static int wm8994_codec_probe(struct platform_device *pdev)
4081 3992
4082 wm8994_update_class_w(codec); 3993 wm8994_update_class_w(codec);
4083 3994
4084 ret = snd_soc_register_codec(codec); 3995 wm8994_handle_pdata(wm8994);
4085 if (ret != 0) {
4086 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
4087 goto err_irq;
4088 }
4089
4090 ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
4091 if (ret != 0) {
4092 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
4093 goto err_codec;
4094 }
4095 3996
4096 platform_set_drvdata(pdev, wm8994); 3997 wm_hubs_add_analogue_controls(codec);
3998 snd_soc_add_controls(codec, wm8994_snd_controls,
3999 ARRAY_SIZE(wm8994_snd_controls));
4000 snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
4001 ARRAY_SIZE(wm8994_dapm_widgets));
4002 wm_hubs_add_analogue_routes(codec, 0, 0);
4003 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
4097 4004
4098 return 0; 4005 return 0;
4099 4006
4100err_codec:
4101 snd_soc_unregister_codec(codec);
4102err_irq: 4007err_irq:
4103 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); 4008 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
4104 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); 4009 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
@@ -4109,31 +4014,50 @@ err:
4109 return ret; 4014 return ret;
4110} 4015}
4111 4016
4112static int __devexit wm8994_codec_remove(struct platform_device *pdev) 4017static int wm8994_codec_remove(struct snd_soc_codec *codec)
4113{ 4018{
4114 struct wm8994_priv *wm8994 = platform_get_drvdata(pdev); 4019 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
4115 struct snd_soc_codec *codec = &wm8994->codec;
4116 4020
4117 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); 4021 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
4118 snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); 4022
4119 snd_soc_unregister_codec(&wm8994->codec);
4120 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); 4023 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
4121 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); 4024 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
4122 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); 4025 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
4123 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); 4026 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
4124 kfree(wm8994); 4027 kfree(wm8994);
4125 wm8994_codec = NULL;
4126 4028
4127 return 0; 4029 return 0;
4128} 4030}
4129 4031
4032static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
4033 .probe = wm8994_codec_probe,
4034 .remove = wm8994_codec_remove,
4035 .suspend = wm8994_suspend,
4036 .resume = wm8994_resume,
4037 .read = wm8994_read,
4038 .write = wm8994_write,
4039 .set_bias_level = wm8994_set_bias_level,
4040};
4041
4042static int __devinit wm8994_probe(struct platform_device *pdev)
4043{
4044 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
4045 wm8994_dai, ARRAY_SIZE(wm8994_dai));
4046}
4047
4048static int __devexit wm8994_remove(struct platform_device *pdev)
4049{
4050 snd_soc_unregister_codec(&pdev->dev);
4051 return 0;
4052}
4053
4130static struct platform_driver wm8994_codec_driver = { 4054static struct platform_driver wm8994_codec_driver = {
4131 .driver = { 4055 .driver = {
4132 .name = "wm8994-codec", 4056 .name = "wm8994-codec",
4133 .owner = THIS_MODULE, 4057 .owner = THIS_MODULE,
4134 }, 4058 },
4135 .probe = wm8994_codec_probe, 4059 .probe = wm8994_probe,
4136 .remove = __devexit_p(wm8994_codec_remove), 4060 .remove = __devexit_p(wm8994_remove),
4137}; 4061};
4138 4062
4139static __init int wm8994_init(void) 4063static __init int wm8994_init(void)
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 2e0ca67a8df..d8dce260c43 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -11,9 +11,6 @@
11 11
12#include <sound/soc.h> 12#include <sound/soc.h>
13 13
14extern struct snd_soc_codec_device soc_codec_dev_wm8994;
15extern struct snd_soc_dai wm8994_dai[];
16
17/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */ 14/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
18#define WM8994_SYSCLK_MCLK1 1 15#define WM8994_SYSCLK_MCLK1 1
19#define WM8994_SYSCLK_MCLK2 2 16#define WM8994_SYSCLK_MCLK2 2
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 76b37ff6c26..00249d5b679 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -156,7 +156,8 @@ static struct {
156}; 156};
157 157
158struct wm9081_priv { 158struct wm9081_priv {
159 struct snd_soc_codec codec; 159 enum snd_soc_control_type control_type;
160 void *control_data;
160 u16 reg_cache[WM9081_MAX_REGISTER + 1]; 161 u16 reg_cache[WM9081_MAX_REGISTER + 1];
161 int sysclk_source; 162 int sysclk_source;
162 int mclk_rate; 163 int mclk_rate;
@@ -1212,8 +1213,8 @@ static struct snd_soc_dai_ops wm9081_dai_ops = {
1212/* We report two channels because the CODEC processes a stereo signal, even 1213/* We report two channels because the CODEC processes a stereo signal, even
1213 * though it is only capable of handling a mono output. 1214 * though it is only capable of handling a mono output.
1214 */ 1215 */
1215struct snd_soc_dai wm9081_dai = { 1216static struct snd_soc_dai_driver wm9081_dai = {
1216 .name = "WM9081", 1217 .name = "wm9081-hifi",
1217 .playback = { 1218 .playback = {
1218 .stream_name = "HiFi Playback", 1219 .stream_name = "HiFi Playback",
1219 .channels_min = 1, 1220 .channels_min = 1,
@@ -1223,34 +1224,42 @@ struct snd_soc_dai wm9081_dai = {
1223 }, 1224 },
1224 .ops = &wm9081_dai_ops, 1225 .ops = &wm9081_dai_ops,
1225}; 1226};
1226EXPORT_SYMBOL_GPL(wm9081_dai);
1227 1227
1228 1228static int wm9081_probe(struct snd_soc_codec *codec)
1229static struct snd_soc_codec *wm9081_codec;
1230
1231static int wm9081_probe(struct platform_device *pdev)
1232{ 1229{
1233 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1230 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1234 struct snd_soc_codec *codec; 1231 int ret;
1235 struct wm9081_priv *wm9081; 1232 u16 reg;
1236 int ret = 0;
1237 1233
1238 if (wm9081_codec == NULL) { 1234 codec->control_data = wm9081->control_data;
1239 dev_err(&pdev->dev, "Codec device not registered\n"); 1235 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type);
1240 return -ENODEV; 1236 if (ret != 0) {
1237 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1238 return ret;
1241 } 1239 }
1242 1240
1243 socdev->card->codec = wm9081_codec; 1241 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
1244 codec = wm9081_codec; 1242 if (reg != 0x9081) {
1245 wm9081 = snd_soc_codec_get_drvdata(codec); 1243 dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
1244 ret = -EINVAL;
1245 return ret;
1246 }
1246 1247
1247 /* register pcms */ 1248 ret = wm9081_reset(codec);
1248 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1249 if (ret < 0) { 1249 if (ret < 0) {
1250 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 1250 dev_err(codec->dev, "Failed to issue reset\n");
1251 goto pcm_err; 1251 return ret;
1252 } 1252 }
1253 1253
1254 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1255
1256 /* Enable zero cross by default */
1257 reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
1258 snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
1259 reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
1260 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
1261 reg | WM9081_SPKPGAZC);
1262
1254 snd_soc_add_controls(codec, wm9081_snd_controls, 1263 snd_soc_add_controls(codec, wm9081_snd_controls,
1255 ARRAY_SIZE(wm9081_snd_controls)); 1264 ARRAY_SIZE(wm9081_snd_controls));
1256 if (!wm9081->retune) { 1265 if (!wm9081->retune) {
@@ -1265,40 +1274,28 @@ static int wm9081_probe(struct platform_device *pdev)
1265 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 1274 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
1266 1275
1267 return ret; 1276 return ret;
1268
1269pcm_err:
1270 return ret;
1271} 1277}
1272 1278
1273static int wm9081_remove(struct platform_device *pdev) 1279static int wm9081_remove(struct snd_soc_codec *codec)
1274{ 1280{
1275 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1281 wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
1276
1277 snd_soc_free_pcms(socdev);
1278 snd_soc_dapm_free(socdev);
1279
1280 return 0; 1282 return 0;
1281} 1283}
1282 1284
1283#ifdef CONFIG_PM 1285#ifdef CONFIG_PM
1284static int wm9081_suspend(struct platform_device *pdev, pm_message_t state) 1286static int wm9081_suspend(struct snd_soc_codec *codec, pm_message_t state)
1285{ 1287{
1286 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1287 struct snd_soc_codec *codec = socdev->card->codec;
1288
1289 wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF); 1288 wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
1290 1289
1291 return 0; 1290 return 0;
1292} 1291}
1293 1292
1294static int wm9081_resume(struct platform_device *pdev) 1293static int wm9081_resume(struct snd_soc_codec *codec)
1295{ 1294{
1296 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1297 struct snd_soc_codec *codec = socdev->card->codec;
1298 u16 *reg_cache = codec->reg_cache; 1295 u16 *reg_cache = codec->reg_cache;
1299 int i; 1296 int i;
1300 1297
1301 for (i = 0; i < codec->reg_cache_size; i++) { 1298 for (i = 0; i < codec->driver->reg_cache_size; i++) {
1302 if (i == WM9081_SOFTWARE_RESET) 1299 if (i == WM9081_SOFTWARE_RESET)
1303 continue; 1300 continue;
1304 1301
@@ -1314,133 +1311,43 @@ static int wm9081_resume(struct platform_device *pdev)
1314#define wm9081_resume NULL 1311#define wm9081_resume NULL
1315#endif 1312#endif
1316 1313
1317struct snd_soc_codec_device soc_codec_dev_wm9081 = { 1314static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1318 .probe = wm9081_probe, 1315 .probe = wm9081_probe,
1319 .remove = wm9081_remove, 1316 .remove = wm9081_remove,
1320 .suspend = wm9081_suspend, 1317 .suspend = wm9081_suspend,
1321 .resume = wm9081_resume, 1318 .resume = wm9081_resume,
1319 .set_bias_level = wm9081_set_bias_level,
1320 .reg_cache_size = sizeof(wm9081_reg_defaults),
1321 .reg_word_size = sizeof(u16),
1322 .reg_cache_default = wm9081_reg_defaults,
1323 .volatile_register = wm9081_volatile_register,
1322}; 1324};
1323EXPORT_SYMBOL_GPL(soc_codec_dev_wm9081);
1324
1325static int wm9081_register(struct wm9081_priv *wm9081,
1326 enum snd_soc_control_type control)
1327{
1328 struct snd_soc_codec *codec = &wm9081->codec;
1329 int ret;
1330 u16 reg;
1331
1332 if (wm9081_codec) {
1333 dev_err(codec->dev, "Another WM9081 is registered\n");
1334 ret = -EINVAL;
1335 goto err;
1336 }
1337
1338 mutex_init(&codec->mutex);
1339 INIT_LIST_HEAD(&codec->dapm_widgets);
1340 INIT_LIST_HEAD(&codec->dapm_paths);
1341
1342 snd_soc_codec_set_drvdata(codec, wm9081);
1343 codec->name = "WM9081";
1344 codec->owner = THIS_MODULE;
1345 codec->dai = &wm9081_dai;
1346 codec->num_dai = 1;
1347 codec->reg_cache_size = ARRAY_SIZE(wm9081->reg_cache);
1348 codec->reg_cache = &wm9081->reg_cache;
1349 codec->bias_level = SND_SOC_BIAS_OFF;
1350 codec->set_bias_level = wm9081_set_bias_level;
1351 codec->volatile_register = wm9081_volatile_register;
1352
1353 memcpy(codec->reg_cache, wm9081_reg_defaults,
1354 sizeof(wm9081_reg_defaults));
1355
1356 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
1357 if (ret != 0) {
1358 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1359 goto err;
1360 }
1361
1362 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
1363 if (reg != 0x9081) {
1364 dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
1365 ret = -EINVAL;
1366 goto err;
1367 }
1368
1369 ret = wm9081_reset(codec);
1370 if (ret < 0) {
1371 dev_err(codec->dev, "Failed to issue reset\n");
1372 goto err;
1373 }
1374
1375 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1376
1377 /* Enable zero cross by default */
1378 reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
1379 snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
1380 reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
1381 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
1382 reg | WM9081_SPKPGAZC);
1383
1384 wm9081_dai.dev = codec->dev;
1385
1386 wm9081_codec = codec;
1387
1388 ret = snd_soc_register_codec(codec);
1389 if (ret != 0) {
1390 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1391 goto err;
1392 }
1393
1394 ret = snd_soc_register_dai(&wm9081_dai);
1395 if (ret != 0) {
1396 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1397 goto err_codec;
1398 }
1399
1400 return 0;
1401
1402err_codec:
1403 snd_soc_unregister_codec(codec);
1404err:
1405 kfree(wm9081);
1406 return ret;
1407}
1408
1409static void wm9081_unregister(struct wm9081_priv *wm9081)
1410{
1411 wm9081_set_bias_level(&wm9081->codec, SND_SOC_BIAS_OFF);
1412 snd_soc_unregister_dai(&wm9081_dai);
1413 snd_soc_unregister_codec(&wm9081->codec);
1414 kfree(wm9081);
1415 wm9081_codec = NULL;
1416}
1417 1325
1326#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1418static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, 1327static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1419 const struct i2c_device_id *id) 1328 const struct i2c_device_id *id)
1420{ 1329{
1421 struct wm9081_priv *wm9081; 1330 struct wm9081_priv *wm9081;
1422 struct snd_soc_codec *codec; 1331 int ret;
1423 1332
1424 wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL); 1333 wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL);
1425 if (wm9081 == NULL) 1334 if (wm9081 == NULL)
1426 return -ENOMEM; 1335 return -ENOMEM;
1427 1336
1428 codec = &wm9081->codec;
1429 codec->hw_write = (hw_write_t)i2c_master_send;
1430 wm9081->retune = i2c->dev.platform_data;
1431
1432 i2c_set_clientdata(i2c, wm9081); 1337 i2c_set_clientdata(i2c, wm9081);
1433 codec->control_data = i2c; 1338 wm9081->control_data = i2c;
1434
1435 codec->dev = &i2c->dev;
1436 1339
1437 return wm9081_register(wm9081, SND_SOC_I2C); 1340 ret = snd_soc_register_codec(&i2c->dev,
1341 &soc_codec_dev_wm9081, &wm9081_dai, 1);
1342 if (ret < 0)
1343 kfree(wm9081);
1344 return ret;
1438} 1345}
1439 1346
1440static __devexit int wm9081_i2c_remove(struct i2c_client *client) 1347static __devexit int wm9081_i2c_remove(struct i2c_client *client)
1441{ 1348{
1442 struct wm9081_priv *wm9081 = i2c_get_clientdata(client); 1349 snd_soc_unregister_codec(&client->dev);
1443 wm9081_unregister(wm9081); 1350 kfree(i2c_get_clientdata(client));
1444 return 0; 1351 return 0;
1445} 1352}
1446 1353
@@ -1452,31 +1359,34 @@ MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id);
1452 1359
1453static struct i2c_driver wm9081_i2c_driver = { 1360static struct i2c_driver wm9081_i2c_driver = {
1454 .driver = { 1361 .driver = {
1455 .name = "wm9081", 1362 .name = "wm9081-codec",
1456 .owner = THIS_MODULE, 1363 .owner = THIS_MODULE,
1457 }, 1364 },
1458 .probe = wm9081_i2c_probe, 1365 .probe = wm9081_i2c_probe,
1459 .remove = __devexit_p(wm9081_i2c_remove), 1366 .remove = __devexit_p(wm9081_i2c_remove),
1460 .id_table = wm9081_i2c_id, 1367 .id_table = wm9081_i2c_id,
1461}; 1368};
1369#endif
1462 1370
1463static int __init wm9081_modinit(void) 1371static int __init wm9081_modinit(void)
1464{ 1372{
1465 int ret; 1373 int ret = 0;
1466 1374#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1467 ret = i2c_add_driver(&wm9081_i2c_driver); 1375 ret = i2c_add_driver(&wm9081_i2c_driver);
1468 if (ret != 0) { 1376 if (ret != 0) {
1469 printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n", 1377 printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n",
1470 ret); 1378 ret);
1471 } 1379 }
1472 1380#endif
1473 return ret; 1381 return ret;
1474} 1382}
1475module_init(wm9081_modinit); 1383module_init(wm9081_modinit);
1476 1384
1477static void __exit wm9081_exit(void) 1385static void __exit wm9081_exit(void)
1478{ 1386{
1387#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1479 i2c_del_driver(&wm9081_i2c_driver); 1388 i2c_del_driver(&wm9081_i2c_driver);
1389#endif
1480} 1390}
1481module_exit(wm9081_exit); 1391module_exit(wm9081_exit);
1482 1392
diff --git a/sound/soc/codecs/wm9081.h b/sound/soc/codecs/wm9081.h
index 42d3bc75702..871cccb066d 100644
--- a/sound/soc/codecs/wm9081.h
+++ b/sound/soc/codecs/wm9081.h
@@ -15,9 +15,6 @@
15 15
16#include <sound/soc.h> 16#include <sound/soc.h>
17 17
18extern struct snd_soc_dai wm9081_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm9081;
20
21/* 18/*
22 * SYSCLK sources 19 * SYSCLK sources
23 */ 20 */
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 1592250daec..7a1825418ee 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -34,8 +34,6 @@
34 34
35#include "wm9090.h" 35#include "wm9090.h"
36 36
37static struct snd_soc_codec *wm9090_codec;
38
39static const u16 wm9090_reg_defaults[] = { 37static const u16 wm9090_reg_defaults[] = {
40 0x9093, /* R0 - Software Reset */ 38 0x9093, /* R0 - Software Reset */
41 0x0006, /* R1 - Power Management (1) */ 39 0x0006, /* R1 - Power Management (1) */
@@ -142,15 +140,10 @@ static const u16 wm9090_reg_defaults[] = {
142 140
143/* This struct is used to save the context */ 141/* This struct is used to save the context */
144struct wm9090_priv { 142struct 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; 143 struct mutex mutex;
152 u16 reg_cache[WM9090_MAX_REGISTER + 1]; 144 u16 reg_cache[WM9090_MAX_REGISTER + 1];
153 struct wm9090_platform_data pdata; 145 struct wm9090_platform_data pdata;
146 void *control_data;
154}; 147};
155 148
156static int wm9090_volatile(unsigned int reg) 149static int wm9090_volatile(unsigned int reg)
@@ -523,7 +516,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
523 case SND_SOC_BIAS_STANDBY: 516 case SND_SOC_BIAS_STANDBY:
524 if (codec->bias_level == SND_SOC_BIAS_OFF) { 517 if (codec->bias_level == SND_SOC_BIAS_OFF) {
525 /* Restore the register cache */ 518 /* Restore the register cache */
526 for (i = 1; i < codec->reg_cache_size; i++) { 519 for (i = 1; i < codec->driver->reg_cache_size; i++) {
527 if (reg_cache[i] == wm9090_reg_defaults[i]) 520 if (reg_cache[i] == wm9090_reg_defaults[i])
528 continue; 521 continue;
529 if (wm9090_volatile(i)) 522 if (wm9090_volatile(i))
@@ -556,51 +549,67 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
556 return 0; 549 return 0;
557} 550}
558 551
559static int wm9090_probe(struct platform_device *pdev) 552static int wm9090_probe(struct snd_soc_codec *codec)
560{ 553{
561 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 554 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
562 struct snd_soc_codec *codec; 555 int ret;
563 int ret = 0;
564 556
565 if (wm9090_codec == NULL) { 557 codec->control_data = wm9090->control_data;
566 dev_err(&pdev->dev, "Codec device not registered\n"); 558 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
567 return -ENODEV; 559 if (ret != 0) {
560 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
561 return ret;
568 } 562 }
569 563
570 socdev->card->codec = wm9090_codec; 564 ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET);
571 codec = wm9090_codec; 565 if (ret < 0)
572 566 return ret;
573 /* register pcms */ 567 if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) {
574 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 568 dev_err(codec->dev, "Device is not a WM9090, ID=%x\n", ret);
575 if (ret < 0) { 569 return -EINVAL;
576 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
577 goto pcm_err;
578 } 570 }
579 571
572 ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0);
573 if (ret < 0)
574 return ret;
575
576 /* Configure some defaults; they will be written out when we
577 * bring the bias up.
578 */
579 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
580 | WM9090_IN1A_ZC;
581 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
582 | WM9090_IN1B_ZC;
583 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
584 | WM9090_IN2A_ZC;
585 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
586 | WM9090_IN2B_ZC;
587 wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
588 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
589 wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
590 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
591 wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
592 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
593
594 wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
595
596 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
597
580 wm9090_add_controls(codec); 598 wm9090_add_controls(codec);
581 599
582 return 0; 600 return 0;
583
584pcm_err:
585 return ret;
586} 601}
587 602
588#ifdef CONFIG_PM 603#ifdef CONFIG_PM
589static int wm9090_suspend(struct platform_device *pdev, pm_message_t state) 604static int wm9090_suspend(struct snd_soc_codec *codec, pm_message_t state)
590{ 605{
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); 606 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
595 607
596 return 0; 608 return 0;
597} 609}
598 610
599static int wm9090_resume(struct platform_device *pdev) 611static int wm9090_resume(struct snd_soc_codec *codec)
600{ 612{
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); 613 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
605 614
606 return 0; 615 return 0;
@@ -610,29 +619,29 @@ static int wm9090_resume(struct platform_device *pdev)
610#define wm9090_resume NULL 619#define wm9090_resume NULL
611#endif 620#endif
612 621
613static int wm9090_remove(struct platform_device *pdev) 622static int wm9090_remove(struct snd_soc_codec *codec)
614{ 623{
615 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 624 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
616
617 snd_soc_free_pcms(socdev);
618 snd_soc_dapm_free(socdev);
619 625
620 return 0; 626 return 0;
621} 627}
622 628
623struct snd_soc_codec_device soc_codec_dev_wm9090 = { 629static struct snd_soc_codec_driver soc_codec_dev_wm9090 = {
624 .probe = wm9090_probe, 630 .probe = wm9090_probe,
625 .remove = wm9090_remove, 631 .remove = wm9090_remove,
626 .suspend = wm9090_suspend, 632 .suspend = wm9090_suspend,
627 .resume = wm9090_resume, 633 .resume = wm9090_resume,
634 .set_bias_level = wm9090_set_bias_level,
635 .reg_cache_size = (WM9090_MAX_REGISTER + 1),
636 .reg_word_size = sizeof(u16),
637 .reg_cache_default = wm9090_reg_defaults,
638 .volatile_register = wm9090_volatile,
628}; 639};
629EXPORT_SYMBOL_GPL(soc_codec_dev_wm9090);
630 640
631static int wm9090_i2c_probe(struct i2c_client *i2c, 641static int wm9090_i2c_probe(struct i2c_client *i2c,
632 const struct i2c_device_id *id) 642 const struct i2c_device_id *id)
633{ 643{
634 struct wm9090_priv *wm9090; 644 struct wm9090_priv *wm9090;
635 struct snd_soc_codec *codec;
636 int ret; 645 int ret;
637 646
638 wm9090 = kzalloc(sizeof(*wm9090), GFP_KERNEL); 647 wm9090 = kzalloc(sizeof(*wm9090), GFP_KERNEL);
@@ -640,102 +649,28 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
640 dev_err(&i2c->dev, "Can not allocate memory\n"); 649 dev_err(&i2c->dev, "Can not allocate memory\n");
641 return -ENOMEM; 650 return -ENOMEM;
642 } 651 }
643 codec = &wm9090->codec;
644 652
645 if (i2c->dev.platform_data) 653 if (i2c->dev.platform_data)
646 memcpy(&wm9090->pdata, i2c->dev.platform_data, 654 memcpy(&wm9090->pdata, i2c->dev.platform_data,
647 sizeof(wm9090->pdata)); 655 sizeof(wm9090->pdata));
648 656
649 wm9090_codec = codec;
650
651 i2c_set_clientdata(i2c, wm9090); 657 i2c_set_clientdata(i2c, wm9090);
658 wm9090->control_data = i2c;
659 mutex_init(&wm9090->mutex);
652 660
653 mutex_init(&codec->mutex); 661 ret = snd_soc_register_codec(&i2c->dev,
654 INIT_LIST_HEAD(&codec->dapm_widgets); 662 &soc_codec_dev_wm9090, NULL, 0);
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) 663 if (ret < 0)
688 goto err; 664 kfree(wm9090);
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; 665 return ret;
728} 666}
729 667
730static int wm9090_i2c_remove(struct i2c_client *i2c) 668static int wm9090_i2c_remove(struct i2c_client *i2c)
731{ 669{
732 struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c); 670 struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
733 struct snd_soc_codec *codec = &wm9090->codec;
734 671
735 snd_soc_unregister_codec(codec); 672 snd_soc_unregister_codec(&i2c->dev);
736 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
737 kfree(wm9090); 673 kfree(wm9090);
738 wm9090_codec = NULL;
739 674
740 return 0; 675 return 0;
741} 676}
@@ -748,7 +683,7 @@ MODULE_DEVICE_TABLE(i2c, wm9090_id);
748 683
749static struct i2c_driver wm9090_i2c_driver = { 684static struct i2c_driver wm9090_i2c_driver = {
750 .driver = { 685 .driver = {
751 .name = "wm9090", 686 .name = "wm9090-codec",
752 .owner = THIS_MODULE, 687 .owner = THIS_MODULE,
753 }, 688 },
754 .probe = wm9090_i2c_probe, 689 .probe = wm9090_i2c_probe,
diff --git a/sound/soc/codecs/wm9090.h b/sound/soc/codecs/wm9090.h
index b08eab932a5..29b9d9fc70b 100644
--- a/sound/soc/codecs/wm9090.h
+++ b/sound/soc/codecs/wm9090.h
@@ -23,8 +23,6 @@
23#ifndef __WM9090_H 23#ifndef __WM9090_H
24#define __WM9090_H 24#define __WM9090_H
25 25
26extern struct snd_soc_codec_device soc_codec_dev_wm9090;
27
28/* 26/*
29 * Register values. 27 * Register values.
30 */ 28 */
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 8793341849d..e4d8f5339c5 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -248,8 +248,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
248{ 248{
249 struct snd_pcm_runtime *runtime = substream->runtime; 249 struct snd_pcm_runtime *runtime = substream->runtime;
250 struct snd_soc_pcm_runtime *rtd = substream->private_data; 250 struct snd_soc_pcm_runtime *rtd = substream->private_data;
251 struct snd_soc_device *socdev = rtd->socdev; 251 struct snd_soc_codec *codec = rtd->codec;
252 struct snd_soc_codec *codec = socdev->card->codec;
253 int reg; 252 int reg;
254 u16 vra; 253 u16 vra;
255 254
@@ -273,9 +272,9 @@ static struct snd_soc_dai_ops wm9705_dai_ops = {
273 .prepare = ac97_prepare, 272 .prepare = ac97_prepare,
274}; 273};
275 274
276struct snd_soc_dai wm9705_dai[] = { 275static struct snd_soc_dai_driver wm9705_dai[] = {
277 { 276 {
278 .name = "AC97 HiFi", 277 .name = "wm9705-hifi",
279 .ac97_control = 1, 278 .ac97_control = 1,
280 .playback = { 279 .playback = {
281 .stream_name = "HiFi Playback", 280 .stream_name = "HiFi Playback",
@@ -294,7 +293,7 @@ struct snd_soc_dai wm9705_dai[] = {
294 .ops = &wm9705_dai_ops, 293 .ops = &wm9705_dai_ops,
295 }, 294 },
296 { 295 {
297 .name = "AC97 Aux", 296 .name = "wm9705-aux",
298 .playback = { 297 .playback = {
299 .stream_name = "Aux Playback", 298 .stream_name = "Aux Playback",
300 .channels_min = 1, 299 .channels_min = 1,
@@ -304,7 +303,6 @@ struct snd_soc_dai wm9705_dai[] = {
304 }, 303 },
305 } 304 }
306}; 305};
307EXPORT_SYMBOL_GPL(wm9705_dai);
308 306
309static int wm9705_reset(struct snd_soc_codec *codec) 307static int wm9705_reset(struct snd_soc_codec *codec)
310{ 308{
@@ -318,20 +316,15 @@ static int wm9705_reset(struct snd_soc_codec *codec)
318} 316}
319 317
320#ifdef CONFIG_PM 318#ifdef CONFIG_PM
321static int wm9705_soc_suspend(struct platform_device *pdev, pm_message_t msg) 319static int wm9705_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
322{ 320{
323 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
324 struct snd_soc_codec *codec = socdev->card->codec;
325
326 soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff); 321 soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff);
327 322
328 return 0; 323 return 0;
329} 324}
330 325
331static int wm9705_soc_resume(struct platform_device *pdev) 326static int wm9705_soc_resume(struct snd_soc_codec *codec)
332{ 327{
333 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
334 struct snd_soc_codec *codec = socdev->card->codec;
335 int i, ret; 328 int i, ret;
336 u16 *cache = codec->reg_cache; 329 u16 *cache = codec->reg_cache;
337 330
@@ -352,49 +345,18 @@ static int wm9705_soc_resume(struct platform_device *pdev)
352#define wm9705_soc_resume NULL 345#define wm9705_soc_resume NULL
353#endif 346#endif
354 347
355static int wm9705_soc_probe(struct platform_device *pdev) 348static int wm9705_soc_probe(struct snd_soc_codec *codec)
356{ 349{
357 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
358 struct snd_soc_codec *codec;
359 int ret = 0; 350 int ret = 0;
360 351
361 printk(KERN_INFO "WM9705 SoC Audio Codec\n"); 352 printk(KERN_INFO "WM9705 SoC Audio Codec\n");
362 353
363 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
364 GFP_KERNEL);
365 if (socdev->card->codec == NULL)
366 return -ENOMEM;
367 codec = socdev->card->codec;
368 mutex_init(&codec->mutex);
369
370 codec->reg_cache = kmemdup(wm9705_reg, sizeof(wm9705_reg), GFP_KERNEL);
371 if (codec->reg_cache == NULL) {
372 ret = -ENOMEM;
373 goto cache_err;
374 }
375 codec->reg_cache_size = sizeof(wm9705_reg);
376 codec->reg_cache_step = 2;
377
378 codec->name = "WM9705";
379 codec->owner = THIS_MODULE;
380 codec->dai = wm9705_dai;
381 codec->num_dai = ARRAY_SIZE(wm9705_dai);
382 codec->write = ac97_write;
383 codec->read = ac97_read;
384 INIT_LIST_HEAD(&codec->dapm_widgets);
385 INIT_LIST_HEAD(&codec->dapm_paths);
386
387 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 354 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
388 if (ret < 0) { 355 if (ret < 0) {
389 printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); 356 printk(KERN_ERR "wm9705: failed to register AC97 codec\n");
390 goto codec_err; 357 return ret;
391 } 358 }
392 359
393 /* register pcms */
394 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
395 if (ret < 0)
396 goto pcm_err;
397
398 ret = wm9705_reset(codec); 360 ret = wm9705_reset(codec);
399 if (ret) 361 if (ret)
400 goto reset_err; 362 goto reset_err;
@@ -406,40 +368,62 @@ static int wm9705_soc_probe(struct platform_device *pdev)
406 return 0; 368 return 0;
407 369
408reset_err: 370reset_err:
409 snd_soc_free_pcms(socdev);
410pcm_err:
411 snd_soc_free_ac97_codec(codec); 371 snd_soc_free_ac97_codec(codec);
412codec_err:
413 kfree(codec->reg_cache);
414cache_err:
415 kfree(socdev->card->codec);
416 socdev->card->codec = NULL;
417 return ret; 372 return ret;
418} 373}
419 374
420static int wm9705_soc_remove(struct platform_device *pdev) 375static int wm9705_soc_remove(struct snd_soc_codec *codec)
421{ 376{
422 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
423 struct snd_soc_codec *codec = socdev->card->codec;
424
425 if (codec == NULL)
426 return 0;
427
428 snd_soc_dapm_free(socdev);
429 snd_soc_free_pcms(socdev);
430 snd_soc_free_ac97_codec(codec); 377 snd_soc_free_ac97_codec(codec);
431 kfree(codec->reg_cache);
432 kfree(codec);
433 return 0; 378 return 0;
434} 379}
435 380
436struct snd_soc_codec_device soc_codec_dev_wm9705 = { 381static struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
437 .probe = wm9705_soc_probe, 382 .probe = wm9705_soc_probe,
438 .remove = wm9705_soc_remove, 383 .remove = wm9705_soc_remove,
439 .suspend = wm9705_soc_suspend, 384 .suspend = wm9705_soc_suspend,
440 .resume = wm9705_soc_resume, 385 .resume = wm9705_soc_resume,
386 .read = ac97_read,
387 .write = ac97_write,
388 .reg_cache_size = sizeof(wm9705_reg),
389 .reg_word_size = sizeof(u16),
390 .reg_cache_step = 2,
391 .reg_cache_default = wm9705_reg,
392};
393
394static __devinit int wm9705_probe(struct platform_device *pdev)
395{
396 return snd_soc_register_codec(&pdev->dev,
397 &soc_codec_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai));
398}
399
400static int __devexit wm9705_remove(struct platform_device *pdev)
401{
402 snd_soc_unregister_codec(&pdev->dev);
403 return 0;
404}
405
406static struct platform_driver wm9705_codec_driver = {
407 .driver = {
408 .name = "wm9705-codec",
409 .owner = THIS_MODULE,
410 },
411
412 .probe = wm9705_probe,
413 .remove = __devexit_p(wm9705_remove),
441}; 414};
442EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705); 415
416static int __init wm9705_init(void)
417{
418 return platform_driver_register(&wm9705_codec_driver);
419}
420module_init(wm9705_init);
421
422static void __exit wm9705_exit(void)
423{
424 platform_driver_unregister(&wm9705_codec_driver);
425}
426module_exit(wm9705_exit);
443 427
444MODULE_DESCRIPTION("ASoC WM9705 driver"); 428MODULE_DESCRIPTION("ASoC WM9705 driver");
445MODULE_AUTHOR("Ian Molton"); 429MODULE_AUTHOR("Ian Molton");
diff --git a/sound/soc/codecs/wm9705.h b/sound/soc/codecs/wm9705.h
index d380f110f9e..23ea9ce4735 100644
--- a/sound/soc/codecs/wm9705.h
+++ b/sound/soc/codecs/wm9705.h
@@ -8,7 +8,4 @@
8#define WM9705_DAI_AC97_HIFI 0 8#define WM9705_DAI_AC97_HIFI 0
9#define WM9705_DAI_AC97_AUX 1 9#define WM9705_DAI_AC97_AUX 1
10 10
11extern struct snd_soc_dai wm9705_dai[2];
12extern struct snd_soc_codec_device soc_codec_dev_wm9705;
13
14#endif 11#endif
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 28790a2ffe8..f8f37ae3091 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -478,8 +478,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
478{ 478{
479 struct snd_pcm_runtime *runtime = substream->runtime; 479 struct snd_pcm_runtime *runtime = substream->runtime;
480 struct snd_soc_pcm_runtime *rtd = substream->private_data; 480 struct snd_soc_pcm_runtime *rtd = substream->private_data;
481 struct snd_soc_device *socdev = rtd->socdev; 481 struct snd_soc_codec *codec =rtd->codec;
482 struct snd_soc_codec *codec = socdev->card->codec;
483 int reg; 482 int reg;
484 u16 vra; 483 u16 vra;
485 484
@@ -499,8 +498,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream,
499{ 498{
500 struct snd_pcm_runtime *runtime = substream->runtime; 499 struct snd_pcm_runtime *runtime = substream->runtime;
501 struct snd_soc_pcm_runtime *rtd = substream->private_data; 500 struct snd_soc_pcm_runtime *rtd = substream->private_data;
502 struct snd_soc_device *socdev = rtd->socdev; 501 struct snd_soc_codec *codec = rtd->codec;
503 struct snd_soc_codec *codec = socdev->card->codec;
504 u16 vra, xsle; 502 u16 vra, xsle;
505 503
506 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 504 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
@@ -526,9 +524,9 @@ static struct snd_soc_dai_ops wm9712_dai_ops_aux = {
526 .prepare = ac97_aux_prepare, 524 .prepare = ac97_aux_prepare,
527}; 525};
528 526
529struct snd_soc_dai wm9712_dai[] = { 527struct snd_soc_dai_driver wm9712_dai[] = {
530{ 528{
531 .name = "AC97 HiFi", 529 .name = "wm9712-hifi",
532 .ac97_control = 1, 530 .ac97_control = 1,
533 .playback = { 531 .playback = {
534 .stream_name = "HiFi Playback", 532 .stream_name = "HiFi Playback",
@@ -545,7 +543,7 @@ struct snd_soc_dai wm9712_dai[] = {
545 .ops = &wm9712_dai_ops_hifi, 543 .ops = &wm9712_dai_ops_hifi,
546}, 544},
547{ 545{
548 .name = "AC97 Aux", 546 .name = "wm9712-aux",
549 .playback = { 547 .playback = {
550 .stream_name = "Aux Playback", 548 .stream_name = "Aux Playback",
551 .channels_min = 1, 549 .channels_min = 1,
@@ -555,7 +553,6 @@ struct snd_soc_dai wm9712_dai[] = {
555 .ops = &wm9712_dai_ops_aux, 553 .ops = &wm9712_dai_ops_aux,
556} 554}
557}; 555};
558EXPORT_SYMBOL_GPL(wm9712_dai);
559 556
560static int wm9712_set_bias_level(struct snd_soc_codec *codec, 557static int wm9712_set_bias_level(struct snd_soc_codec *codec,
561 enum snd_soc_bias_level level) 558 enum snd_soc_bias_level level)
@@ -597,20 +594,15 @@ err:
597 return -EIO; 594 return -EIO;
598} 595}
599 596
600static int wm9712_soc_suspend(struct platform_device *pdev, 597static int wm9712_soc_suspend(struct snd_soc_codec *codec,
601 pm_message_t state) 598 pm_message_t state)
602{ 599{
603 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
604 struct snd_soc_codec *codec = socdev->card->codec;
605
606 wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); 600 wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF);
607 return 0; 601 return 0;
608} 602}
609 603
610static int wm9712_soc_resume(struct platform_device *pdev) 604static int wm9712_soc_resume(struct snd_soc_codec *codec)
611{ 605{
612 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
613 struct snd_soc_codec *codec = socdev->card->codec;
614 int i, ret; 606 int i, ret;
615 u16 *cache = codec->reg_cache; 607 u16 *cache = codec->reg_cache;
616 608
@@ -635,51 +627,18 @@ static int wm9712_soc_resume(struct platform_device *pdev)
635 return ret; 627 return ret;
636} 628}
637 629
638static int wm9712_soc_probe(struct platform_device *pdev) 630static int wm9712_soc_probe(struct snd_soc_codec *codec)
639{ 631{
640 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
641 struct snd_soc_codec *codec;
642 int ret = 0; 632 int ret = 0;
643 633
644 printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); 634 printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION);
645 635
646 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
647 GFP_KERNEL);
648 if (socdev->card->codec == NULL)
649 return -ENOMEM;
650 codec = socdev->card->codec;
651 mutex_init(&codec->mutex);
652
653 codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL);
654
655 if (codec->reg_cache == NULL) {
656 ret = -ENOMEM;
657 goto cache_err;
658 }
659 codec->reg_cache_size = sizeof(wm9712_reg);
660 codec->reg_cache_step = 2;
661
662 codec->name = "WM9712";
663 codec->owner = THIS_MODULE;
664 codec->dai = wm9712_dai;
665 codec->num_dai = ARRAY_SIZE(wm9712_dai);
666 codec->write = ac97_write;
667 codec->read = ac97_read;
668 codec->set_bias_level = wm9712_set_bias_level;
669 INIT_LIST_HEAD(&codec->dapm_widgets);
670 INIT_LIST_HEAD(&codec->dapm_paths);
671
672 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 636 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
673 if (ret < 0) { 637 if (ret < 0) {
674 printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); 638 printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
675 goto codec_err; 639 return ret;
676 } 640 }
677 641
678 /* register pcms */
679 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
680 if (ret < 0)
681 goto pcm_err;
682
683 ret = wm9712_reset(codec, 0); 642 ret = wm9712_reset(codec, 0);
684 if (ret < 0) { 643 if (ret < 0) {
685 printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n"); 644 printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n");
@@ -697,42 +656,63 @@ static int wm9712_soc_probe(struct platform_device *pdev)
697 return 0; 656 return 0;
698 657
699reset_err: 658reset_err:
700 snd_soc_free_pcms(socdev);
701pcm_err:
702 snd_soc_free_ac97_codec(codec); 659 snd_soc_free_ac97_codec(codec);
703
704codec_err:
705 kfree(codec->reg_cache);
706
707cache_err:
708 kfree(socdev->card->codec);
709 socdev->card->codec = NULL;
710 return ret; 660 return ret;
711} 661}
712 662
713static int wm9712_soc_remove(struct platform_device *pdev) 663static int wm9712_soc_remove(struct snd_soc_codec *codec)
714{ 664{
715 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
716 struct snd_soc_codec *codec = socdev->card->codec;
717
718 if (codec == NULL)
719 return 0;
720
721 snd_soc_dapm_free(socdev);
722 snd_soc_free_pcms(socdev);
723 snd_soc_free_ac97_codec(codec); 665 snd_soc_free_ac97_codec(codec);
724 kfree(codec->reg_cache);
725 kfree(codec);
726 return 0; 666 return 0;
727} 667}
728 668
729struct snd_soc_codec_device soc_codec_dev_wm9712 = { 669static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
730 .probe = wm9712_soc_probe, 670 .probe = wm9712_soc_probe,
731 .remove = wm9712_soc_remove, 671 .remove = wm9712_soc_remove,
732 .suspend = wm9712_soc_suspend, 672 .suspend = wm9712_soc_suspend,
733 .resume = wm9712_soc_resume, 673 .resume = wm9712_soc_resume,
674 .read = ac97_read,
675 .write = ac97_write,
676 .set_bias_level = wm9712_set_bias_level,
677 .reg_cache_size = sizeof(wm9712_reg),
678 .reg_word_size = sizeof(u16),
679 .reg_cache_step = 2,
680 .reg_cache_default = wm9712_reg,
734}; 681};
735EXPORT_SYMBOL_GPL(soc_codec_dev_wm9712); 682
683static __devinit int wm9712_probe(struct platform_device *pdev)
684{
685 return snd_soc_register_codec(&pdev->dev,
686 &soc_codec_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai));
687}
688
689static int __devexit wm9712_remove(struct platform_device *pdev)
690{
691 snd_soc_unregister_codec(&pdev->dev);
692 return 0;
693}
694
695static struct platform_driver wm9712_codec_driver = {
696 .driver = {
697 .name = "wm9712-codec",
698 .owner = THIS_MODULE,
699 },
700
701 .probe = wm9712_probe,
702 .remove = __devexit_p(wm9712_remove),
703};
704
705static int __init wm9712_init(void)
706{
707 return platform_driver_register(&wm9712_codec_driver);
708}
709module_init(wm9712_init);
710
711static void __exit wm9712_exit(void)
712{
713 platform_driver_unregister(&wm9712_codec_driver);
714}
715module_exit(wm9712_exit);
736 716
737MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver"); 717MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver");
738MODULE_AUTHOR("Liam Girdwood"); 718MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm9712.h b/sound/soc/codecs/wm9712.h
index d29e8a18ca6..fb69c3aa4ed 100644
--- a/sound/soc/codecs/wm9712.h
+++ b/sound/soc/codecs/wm9712.h
@@ -8,7 +8,4 @@
8#define WM9712_DAI_AC97_HIFI 0 8#define WM9712_DAI_AC97_HIFI 0
9#define WM9712_DAI_AC97_AUX 1 9#define WM9712_DAI_AC97_AUX 1
10 10
11extern struct snd_soc_dai wm9712_dai[2];
12extern struct snd_soc_codec_device soc_codec_dev_wm9712;
13
14#endif 11#endif
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 34e0c91092f..463917e762b 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1057,9 +1057,9 @@ static struct snd_soc_dai_ops wm9713_dai_ops_voice = {
1057 .set_tristate = wm9713_set_dai_tristate, 1057 .set_tristate = wm9713_set_dai_tristate,
1058}; 1058};
1059 1059
1060struct snd_soc_dai wm9713_dai[] = { 1060static struct snd_soc_dai_driver wm9713_dai[] = {
1061{ 1061{
1062 .name = "AC97 HiFi", 1062 .name = "wm9713-hifi",
1063 .ac97_control = 1, 1063 .ac97_control = 1,
1064 .playback = { 1064 .playback = {
1065 .stream_name = "HiFi Playback", 1065 .stream_name = "HiFi Playback",
@@ -1076,7 +1076,7 @@ struct snd_soc_dai wm9713_dai[] = {
1076 .ops = &wm9713_dai_ops_hifi, 1076 .ops = &wm9713_dai_ops_hifi,
1077 }, 1077 },
1078 { 1078 {
1079 .name = "AC97 Aux", 1079 .name = "wm9713-aux",
1080 .playback = { 1080 .playback = {
1081 .stream_name = "Aux Playback", 1081 .stream_name = "Aux Playback",
1082 .channels_min = 1, 1082 .channels_min = 1,
@@ -1086,7 +1086,7 @@ struct snd_soc_dai wm9713_dai[] = {
1086 .ops = &wm9713_dai_ops_aux, 1086 .ops = &wm9713_dai_ops_aux,
1087 }, 1087 },
1088 { 1088 {
1089 .name = "WM9713 Voice", 1089 .name = "wm9713-voice",
1090 .playback = { 1090 .playback = {
1091 .stream_name = "Voice Playback", 1091 .stream_name = "Voice Playback",
1092 .channels_min = 1, 1092 .channels_min = 1,
@@ -1103,7 +1103,6 @@ struct snd_soc_dai wm9713_dai[] = {
1103 .symmetric_rates = 1, 1103 .symmetric_rates = 1,
1104 }, 1104 },
1105}; 1105};
1106EXPORT_SYMBOL_GPL(wm9713_dai);
1107 1106
1108int wm9713_reset(struct snd_soc_codec *codec, int try_warm) 1107int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1109{ 1108{
@@ -1152,11 +1151,9 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec,
1152 return 0; 1151 return 0;
1153} 1152}
1154 1153
1155static int wm9713_soc_suspend(struct platform_device *pdev, 1154static int wm9713_soc_suspend(struct snd_soc_codec *codec,
1156 pm_message_t state) 1155 pm_message_t state)
1157{ 1156{
1158 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1159 struct snd_soc_codec *codec = socdev->card->codec;
1160 u16 reg; 1157 u16 reg;
1161 1158
1162 /* Disable everything except touchpanel - that will be handled 1159 /* Disable everything except touchpanel - that will be handled
@@ -1171,10 +1168,8 @@ static int wm9713_soc_suspend(struct platform_device *pdev,
1171 return 0; 1168 return 0;
1172} 1169}
1173 1170
1174static int wm9713_soc_resume(struct platform_device *pdev) 1171static int wm9713_soc_resume(struct snd_soc_codec *codec)
1175{ 1172{
1176 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1177 struct snd_soc_codec *codec = socdev->card->codec;
1178 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 1173 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1179 int i, ret; 1174 int i, ret;
1180 u16 *cache = codec->reg_cache; 1175 u16 *cache = codec->reg_cache;
@@ -1204,53 +1199,20 @@ static int wm9713_soc_resume(struct platform_device *pdev)
1204 return ret; 1199 return ret;
1205} 1200}
1206 1201
1207static int wm9713_soc_probe(struct platform_device *pdev) 1202static int wm9713_soc_probe(struct snd_soc_codec *codec)
1208{ 1203{
1209 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1204 struct wm9713_priv *wm9713;
1210 struct snd_soc_codec *codec;
1211 int ret = 0, reg; 1205 int ret = 0, reg;
1212 1206
1213 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), 1207 wm9713 = kzalloc(sizeof(struct wm9713_priv), GFP_KERNEL);
1214 GFP_KERNEL); 1208 if (wm9713 == NULL)
1215 if (socdev->card->codec == NULL)
1216 return -ENOMEM; 1209 return -ENOMEM;
1217 codec = socdev->card->codec; 1210 snd_soc_codec_set_drvdata(codec, wm9713);
1218 mutex_init(&codec->mutex);
1219
1220 codec->reg_cache = kmemdup(wm9713_reg, sizeof(wm9713_reg), GFP_KERNEL);
1221 if (codec->reg_cache == NULL) {
1222 ret = -ENOMEM;
1223 goto cache_err;
1224 }
1225 codec->reg_cache_size = sizeof(wm9713_reg);
1226 codec->reg_cache_step = 2;
1227
1228 snd_soc_codec_set_drvdata(codec, kzalloc(sizeof(struct wm9713_priv),
1229 GFP_KERNEL));
1230 if (snd_soc_codec_get_drvdata(codec) == NULL) {
1231 ret = -ENOMEM;
1232 goto priv_err;
1233 }
1234
1235 codec->name = "WM9713";
1236 codec->owner = THIS_MODULE;
1237 codec->dai = wm9713_dai;
1238 codec->num_dai = ARRAY_SIZE(wm9713_dai);
1239 codec->write = ac97_write;
1240 codec->read = ac97_read;
1241 codec->set_bias_level = wm9713_set_bias_level;
1242 INIT_LIST_HEAD(&codec->dapm_widgets);
1243 INIT_LIST_HEAD(&codec->dapm_paths);
1244 1211
1245 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 1212 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
1246 if (ret < 0) 1213 if (ret < 0)
1247 goto codec_err; 1214 goto codec_err;
1248 1215
1249 /* register pcms */
1250 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1251 if (ret < 0)
1252 goto pcm_err;
1253
1254 /* do a cold reset for the controller and then try 1216 /* do a cold reset for the controller and then try
1255 * a warm reset followed by an optional cold reset for codec */ 1217 * a warm reset followed by an optional cold reset for codec */
1256 wm9713_reset(codec, 0); 1218 wm9713_reset(codec, 0);
@@ -1273,46 +1235,67 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1273 return 0; 1235 return 0;
1274 1236
1275reset_err: 1237reset_err:
1276 snd_soc_free_pcms(socdev);
1277pcm_err:
1278 snd_soc_free_ac97_codec(codec); 1238 snd_soc_free_ac97_codec(codec);
1279
1280codec_err: 1239codec_err:
1281 kfree(snd_soc_codec_get_drvdata(codec)); 1240 kfree(wm9713);
1282
1283priv_err:
1284 kfree(codec->reg_cache);
1285
1286cache_err:
1287 kfree(socdev->card->codec);
1288 socdev->card->codec = NULL;
1289 return ret; 1241 return ret;
1290} 1242}
1291 1243
1292static int wm9713_soc_remove(struct platform_device *pdev) 1244static int wm9713_soc_remove(struct snd_soc_codec *codec)
1293{ 1245{
1294 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1246 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1295 struct snd_soc_codec *codec = socdev->card->codec;
1296
1297 if (codec == NULL)
1298 return 0;
1299
1300 snd_soc_dapm_free(socdev);
1301 snd_soc_free_pcms(socdev);
1302 snd_soc_free_ac97_codec(codec); 1247 snd_soc_free_ac97_codec(codec);
1303 kfree(snd_soc_codec_get_drvdata(codec)); 1248 kfree(wm9713);
1304 kfree(codec->reg_cache);
1305 kfree(codec);
1306 return 0; 1249 return 0;
1307} 1250}
1308 1251
1309struct snd_soc_codec_device soc_codec_dev_wm9713 = { 1252static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
1310 .probe = wm9713_soc_probe, 1253 .probe = wm9713_soc_probe,
1311 .remove = wm9713_soc_remove, 1254 .remove = wm9713_soc_remove,
1312 .suspend = wm9713_soc_suspend, 1255 .suspend = wm9713_soc_suspend,
1313 .resume = wm9713_soc_resume, 1256 .resume = wm9713_soc_resume,
1257 .read = ac97_read,
1258 .write = ac97_write,
1259 .set_bias_level = wm9713_set_bias_level,
1260 .reg_cache_size = sizeof(wm9713_reg),
1261 .reg_word_size = sizeof(u16),
1262 .reg_cache_step = 2,
1263 .reg_cache_default = wm9713_reg,
1264};
1265
1266static __devinit int wm9713_probe(struct platform_device *pdev)
1267{
1268 return snd_soc_register_codec(&pdev->dev,
1269 &soc_codec_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai));
1270}
1271
1272static int __devexit wm9713_remove(struct platform_device *pdev)
1273{
1274 snd_soc_unregister_codec(&pdev->dev);
1275 return 0;
1276}
1277
1278static struct platform_driver wm9713_codec_driver = {
1279 .driver = {
1280 .name = "wm9713-codec",
1281 .owner = THIS_MODULE,
1282 },
1283
1284 .probe = wm9713_probe,
1285 .remove = __devexit_p(wm9713_remove),
1314}; 1286};
1315EXPORT_SYMBOL_GPL(soc_codec_dev_wm9713); 1287
1288static int __init wm9713_init(void)
1289{
1290 return platform_driver_register(&wm9713_codec_driver);
1291}
1292module_init(wm9713_init);
1293
1294static void __exit wm9713_exit(void)
1295{
1296 platform_driver_unregister(&wm9713_codec_driver);
1297}
1298module_exit(wm9713_exit);
1316 1299
1317MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver"); 1300MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver");
1318MODULE_AUTHOR("Liam Girdwood"); 1301MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm9713.h b/sound/soc/codecs/wm9713.h
index 63b8d81756e..793da863a03 100644
--- a/sound/soc/codecs/wm9713.h
+++ b/sound/soc/codecs/wm9713.h
@@ -45,9 +45,6 @@
45#define WM9713_DAI_AC97_AUX 1 45#define WM9713_DAI_AC97_AUX 1
46#define WM9713_DAI_PCM_VOICE 2 46#define WM9713_DAI_PCM_VOICE 2
47 47
48extern struct snd_soc_codec_device soc_codec_dev_wm9713;
49extern struct snd_soc_dai wm9713_dai[3];
50
51int wm9713_reset(struct snd_soc_codec *codec, int try_warm); 48int wm9713_reset(struct snd_soc_codec *codec, int try_warm);
52 49
53#endif 50#endif
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 97f74d6a33e..2b07b17a6b2 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -28,12 +28,9 @@
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"
32#include "../codecs/spdif_transciever.h"
33#include "davinci-pcm.h" 31#include "davinci-pcm.h"
34#include "davinci-i2s.h" 32#include "davinci-i2s.h"
35#include "davinci-mcasp.h" 33#include "davinci-mcasp.h"
36#include "davinci-vcif.h"
37 34
38#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ 35#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
39 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF) 36 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
@@ -41,8 +38,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params) 38 struct snd_pcm_hw_params *params)
42{ 39{
43 struct snd_soc_pcm_runtime *rtd = substream->private_data; 40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
44 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
45 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
46 int ret = 0; 43 int ret = 0;
47 unsigned sysclk; 44 unsigned sysclk;
48 45
@@ -87,7 +84,7 @@ static int evm_spdif_hw_params(struct snd_pcm_substream *substream,
87 struct snd_pcm_hw_params *params) 84 struct snd_pcm_hw_params *params)
88{ 85{
89 struct snd_soc_pcm_runtime *rtd = substream->private_data; 86 struct snd_soc_pcm_runtime *rtd = substream->private_data;
90 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 87 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
91 88
92 /* set cpu DAI configuration */ 89 /* set cpu DAI configuration */
93 return snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT); 90 return snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
@@ -132,8 +129,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
132}; 129};
133 130
134/* Logic for a aic3x as connected on a davinci-evm */ 131/* Logic for a aic3x as connected on a davinci-evm */
135static int evm_aic3x_init(struct snd_soc_codec *codec) 132static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
136{ 133{
134 struct snd_soc_codec *codec = rtd->codec;
135
137 /* Add davinci-evm specific widgets */ 136 /* Add davinci-evm specific widgets */
138 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, 137 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
139 ARRAY_SIZE(aic3x_dapm_widgets)); 138 ARRAY_SIZE(aic3x_dapm_widgets));
@@ -161,8 +160,10 @@ static int evm_aic3x_init(struct snd_soc_codec *codec)
161static struct snd_soc_dai_link evm_dai = { 160static struct snd_soc_dai_link evm_dai = {
162 .name = "TLV320AIC3X", 161 .name = "TLV320AIC3X",
163 .stream_name = "AIC3X", 162 .stream_name = "AIC3X",
164 .cpu_dai = &davinci_i2s_dai, 163 .cpu_dai_name = "davinci-mcasp.0",
165 .codec_dai = &aic3x_dai, 164 .codec_dai_name = "tlv320aic3x-hifi",
165 .codec_name = "tlv320aic3x-codec.0-001a",
166 .platform_name = "davinci-pcm-audio",
166 .init = evm_aic3x_init, 167 .init = evm_aic3x_init,
167 .ops = &evm_ops, 168 .ops = &evm_ops,
168}; 169};
@@ -171,40 +172,49 @@ static struct snd_soc_dai_link dm365_evm_dai = {
171#ifdef CONFIG_SND_DM365_AIC3X_CODEC 172#ifdef CONFIG_SND_DM365_AIC3X_CODEC
172 .name = "TLV320AIC3X", 173 .name = "TLV320AIC3X",
173 .stream_name = "AIC3X", 174 .stream_name = "AIC3X",
174 .cpu_dai = &davinci_i2s_dai, 175 .cpu_dai_name = "davinci-i2s",
175 .codec_dai = &aic3x_dai, 176 .codec_dai_name = "tlv320aic3x-hifi",
176 .init = evm_aic3x_init, 177 .init = evm_aic3x_init,
178 .codec_name = "tlv320aic3x-codec.0-001a",
177 .ops = &evm_ops, 179 .ops = &evm_ops,
178#elif defined(CONFIG_SND_DM365_VOICE_CODEC) 180#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
179 .name = "Voice Codec - CQ93VC", 181 .name = "Voice Codec - CQ93VC",
180 .stream_name = "CQ93", 182 .stream_name = "CQ93",
181 .cpu_dai = &davinci_vcif_dai, 183 .cpu_dai_name = "davinci-vcif",
182 .codec_dai = &cq93vc_dai, 184 .codec_dai_name = "cq93vc-hifi",
185 .codec_name = "cq93vc-codec",
183#endif 186#endif
187 .platform_name = "davinci-pcm-audio",
184}; 188};
185 189
186static struct snd_soc_dai_link dm6467_evm_dai[] = { 190static struct snd_soc_dai_link dm6467_evm_dai[] = {
187 { 191 {
188 .name = "TLV320AIC3X", 192 .name = "TLV320AIC3X",
189 .stream_name = "AIC3X", 193 .stream_name = "AIC3X",
190 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_I2S_DAI], 194 .cpu_dai_name= "davinci-mcasp.0",
191 .codec_dai = &aic3x_dai, 195 .codec_dai_name = "tlv320aic3x-hifi",
196 .platform_name ="davinci-pcm-audio",
197 .codec_name = "tlv320aic3x-codec.0-001a",
192 .init = evm_aic3x_init, 198 .init = evm_aic3x_init,
193 .ops = &evm_ops, 199 .ops = &evm_ops,
194 }, 200 },
195 { 201 {
196 .name = "McASP", 202 .name = "McASP",
197 .stream_name = "spdif", 203 .stream_name = "spdif",
198 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_DIT_DAI], 204 .cpu_dai_name= "davinci-mcasp.1",
199 .codec_dai = &dit_stub_dai, 205 .codec_dai_name = "dit-hifi",
206 .codec_name = "spdif_dit",
207 .platform_name = "davinci-pcm-audio",
200 .ops = &evm_spdif_ops, 208 .ops = &evm_spdif_ops,
201 }, 209 },
202}; 210};
203static struct snd_soc_dai_link da8xx_evm_dai = { 211static struct snd_soc_dai_link da8xx_evm_dai = {
204 .name = "TLV320AIC3X", 212 .name = "TLV320AIC3X",
205 .stream_name = "AIC3X", 213 .stream_name = "AIC3X",
206 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_I2S_DAI], 214 .cpu_dai_name= "davinci-mcasp.0",
207 .codec_dai = &aic3x_dai, 215 .codec_dai_name = "tlv320aic3x-hifi",
216 .codec_name = "tlv320aic3x-codec.0-001a",
217 .platform_name = "davinci-pcm-audio",
208 .init = evm_aic3x_init, 218 .init = evm_aic3x_init,
209 .ops = &evm_ops, 219 .ops = &evm_ops,
210}; 220};
@@ -212,7 +222,6 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
212/* davinci dm6446, dm355 evm audio machine driver */ 222/* davinci dm6446, dm355 evm audio machine driver */
213static struct snd_soc_card snd_soc_card_evm = { 223static struct snd_soc_card snd_soc_card_evm = {
214 .name = "DaVinci EVM", 224 .name = "DaVinci EVM",
215 .platform = &davinci_soc_platform,
216 .dai_link = &evm_dai, 225 .dai_link = &evm_dai,
217 .num_links = 1, 226 .num_links = 1,
218}; 227};
@@ -220,16 +229,13 @@ static struct snd_soc_card snd_soc_card_evm = {
220/* davinci dm365 evm audio machine driver */ 229/* davinci dm365 evm audio machine driver */
221static struct snd_soc_card dm365_snd_soc_card_evm = { 230static struct snd_soc_card dm365_snd_soc_card_evm = {
222 .name = "DaVinci DM365 EVM", 231 .name = "DaVinci DM365 EVM",
223 .platform = &davinci_soc_platform,
224 .dai_link = &dm365_evm_dai, 232 .dai_link = &dm365_evm_dai,
225 .num_links = 1, 233 .num_links = 1,
226}; 234};
227 235
228
229/* davinci dm6467 evm audio machine driver */ 236/* davinci dm6467 evm audio machine driver */
230static struct snd_soc_card dm6467_snd_soc_card_evm = { 237static struct snd_soc_card dm6467_snd_soc_card_evm = {
231 .name = "DaVinci DM6467 EVM", 238 .name = "DaVinci DM6467 EVM",
232 .platform = &davinci_soc_platform,
233 .dai_link = dm6467_evm_dai, 239 .dai_link = dm6467_evm_dai,
234 .num_links = ARRAY_SIZE(dm6467_evm_dai), 240 .num_links = ARRAY_SIZE(dm6467_evm_dai),
235}; 241};
@@ -237,82 +243,40 @@ static struct snd_soc_card dm6467_snd_soc_card_evm = {
237static struct snd_soc_card da830_snd_soc_card = { 243static struct snd_soc_card da830_snd_soc_card = {
238 .name = "DA830/OMAP-L137 EVM", 244 .name = "DA830/OMAP-L137 EVM",
239 .dai_link = &da8xx_evm_dai, 245 .dai_link = &da8xx_evm_dai,
240 .platform = &davinci_soc_platform,
241 .num_links = 1, 246 .num_links = 1,
242}; 247};
243 248
244static struct snd_soc_card da850_snd_soc_card = { 249static struct snd_soc_card da850_snd_soc_card = {
245 .name = "DA850/OMAP-L138 EVM", 250 .name = "DA850/OMAP-L138 EVM",
246 .dai_link = &da8xx_evm_dai, 251 .dai_link = &da8xx_evm_dai,
247 .platform = &davinci_soc_platform,
248 .num_links = 1, 252 .num_links = 1,
249}; 253};
250 254
251static struct aic3x_setup_data aic3x_setup;
252
253/* evm audio subsystem */
254static struct snd_soc_device evm_snd_devdata = {
255 .card = &snd_soc_card_evm,
256 .codec_dev = &soc_codec_dev_aic3x,
257 .codec_data = &aic3x_setup,
258};
259
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 */
272static struct snd_soc_device dm6467_evm_snd_devdata = {
273 .card = &dm6467_snd_soc_card_evm,
274 .codec_dev = &soc_codec_dev_aic3x,
275 .codec_data = &aic3x_setup,
276};
277
278/* evm audio subsystem */
279static struct snd_soc_device da830_evm_snd_devdata = {
280 .card = &da830_snd_soc_card,
281 .codec_dev = &soc_codec_dev_aic3x,
282 .codec_data = &aic3x_setup,
283};
284
285static struct snd_soc_device da850_evm_snd_devdata = {
286 .card = &da850_snd_soc_card,
287 .codec_dev = &soc_codec_dev_aic3x,
288 .codec_data = &aic3x_setup,
289};
290
291static struct platform_device *evm_snd_device; 255static struct platform_device *evm_snd_device;
292 256
293static int __init evm_init(void) 257static int __init evm_init(void)
294{ 258{
295 struct snd_soc_device *evm_snd_dev_data; 259 struct snd_soc_card *evm_snd_dev_data;
296 int index; 260 int index;
297 int ret; 261 int ret;
298 262
299 if (machine_is_davinci_evm()) { 263 if (machine_is_davinci_evm()) {
300 evm_snd_dev_data = &evm_snd_devdata; 264 evm_snd_dev_data = &snd_soc_card_evm;
301 index = 0; 265 index = 0;
302 } else if (machine_is_davinci_dm355_evm()) { 266 } else if (machine_is_davinci_dm355_evm()) {
303 evm_snd_dev_data = &evm_snd_devdata; 267 evm_snd_dev_data = &snd_soc_card_evm;
304 index = 1; 268 index = 1;
305 } else if (machine_is_davinci_dm365_evm()) { 269 } else if (machine_is_davinci_dm365_evm()) {
306 evm_snd_dev_data = &dm365_evm_snd_devdata; 270 evm_snd_dev_data = &dm365_snd_soc_card_evm;
307 index = 0; 271 index = 0;
308 } else if (machine_is_davinci_dm6467_evm()) { 272 } else if (machine_is_davinci_dm6467_evm()) {
309 evm_snd_dev_data = &dm6467_evm_snd_devdata; 273 evm_snd_dev_data = &dm6467_snd_soc_card_evm;
310 index = 0; 274 index = 0;
311 } else if (machine_is_davinci_da830_evm()) { 275 } else if (machine_is_davinci_da830_evm()) {
312 evm_snd_dev_data = &da830_evm_snd_devdata; 276 evm_snd_dev_data = &da830_snd_soc_card;
313 index = 1; 277 index = 1;
314 } else if (machine_is_davinci_da850_evm()) { 278 } else if (machine_is_davinci_da850_evm()) {
315 evm_snd_dev_data = &da850_evm_snd_devdata; 279 evm_snd_dev_data = &da850_snd_soc_card;
316 index = 0; 280 index = 0;
317 } else 281 } else
318 return -EINVAL; 282 return -EINVAL;
@@ -322,7 +286,6 @@ static int __init evm_init(void)
322 return -ENOMEM; 286 return -ENOMEM;
323 287
324 platform_set_drvdata(evm_snd_device, evm_snd_dev_data); 288 platform_set_drvdata(evm_snd_device, evm_snd_dev_data);
325 evm_snd_dev_data->dev = &evm_snd_device->dev;
326 ret = platform_device_add(evm_snd_device); 289 ret = platform_device_add(evm_snd_device);
327 if (ret) 290 if (ret)
328 platform_device_put(evm_snd_device); 291 platform_device_put(evm_snd_device);
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 9e8932abf15..9f8b6c55686 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -183,8 +183,7 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
183 struct snd_pcm_substream *substream) 183 struct snd_pcm_substream *substream)
184{ 184{
185 struct snd_soc_pcm_runtime *rtd = substream->private_data; 185 struct snd_soc_pcm_runtime *rtd = substream->private_data;
186 struct snd_soc_device *socdev = rtd->socdev; 186 struct snd_soc_platform *platform = rtd->platform;
187 struct snd_soc_platform *platform = socdev->card->platform;
188 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 187 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
189 u32 spcr; 188 u32 spcr;
190 u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST; 189 u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
@@ -205,8 +204,8 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
205 if (playback) { 204 if (playback) {
206 /* Stop the DMA to avoid data loss */ 205 /* Stop the DMA to avoid data loss */
207 /* while the transmitter is out of reset to handle XSYNCERR */ 206 /* while the transmitter is out of reset to handle XSYNCERR */
208 if (platform->pcm_ops->trigger) { 207 if (platform->driver->ops->trigger) {
209 int ret = platform->pcm_ops->trigger(substream, 208 int ret = platform->driver->ops->trigger(substream,
210 SNDRV_PCM_TRIGGER_STOP); 209 SNDRV_PCM_TRIGGER_STOP);
211 if (ret < 0) 210 if (ret < 0)
212 printk(KERN_DEBUG "Playback DMA stop failed\n"); 211 printk(KERN_DEBUG "Playback DMA stop failed\n");
@@ -227,8 +226,8 @@ static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
227 toggle_clock(dev, playback); 226 toggle_clock(dev, playback);
228 227
229 /* Restart the DMA */ 228 /* Restart the DMA */
230 if (platform->pcm_ops->trigger) { 229 if (platform->driver->ops->trigger) {
231 int ret = platform->pcm_ops->trigger(substream, 230 int ret = platform->driver->ops->trigger(substream,
232 SNDRV_PCM_TRIGGER_START); 231 SNDRV_PCM_TRIGGER_START);
233 if (ret < 0) 232 if (ret < 0)
234 printk(KERN_DEBUG "Playback DMA start failed\n"); 233 printk(KERN_DEBUG "Playback DMA start failed\n");
@@ -263,7 +262,7 @@ static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
263static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 262static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
264 unsigned int fmt) 263 unsigned int fmt)
265{ 264{
266 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 265 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
267 unsigned int pcr; 266 unsigned int pcr;
268 unsigned int srgr; 267 unsigned int srgr;
269 /* Attention srgr is updated by hw_params! */ 268 /* Attention srgr is updated by hw_params! */
@@ -404,7 +403,7 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
404static int davinci_i2s_dai_set_clkdiv(struct snd_soc_dai *cpu_dai, 403static int davinci_i2s_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
405 int div_id, int div) 404 int div_id, int div)
406{ 405{
407 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 406 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
408 407
409 if (div_id != DAVINCI_MCBSP_CLKGDV) 408 if (div_id != DAVINCI_MCBSP_CLKGDV)
410 return -ENODEV; 409 return -ENODEV;
@@ -417,7 +416,7 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
417 struct snd_pcm_hw_params *params, 416 struct snd_pcm_hw_params *params,
418 struct snd_soc_dai *dai) 417 struct snd_soc_dai *dai)
419{ 418{
420 struct davinci_mcbsp_dev *dev = dai->private_data; 419 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
421 struct davinci_pcm_dma_params *dma_params = 420 struct davinci_pcm_dma_params *dma_params =
422 &dev->dma_params[substream->stream]; 421 &dev->dma_params[substream->stream];
423 struct snd_interval *i = NULL; 422 struct snd_interval *i = NULL;
@@ -427,6 +426,9 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
427 snd_pcm_format_t fmt; 426 snd_pcm_format_t fmt;
428 unsigned element_cnt = 1; 427 unsigned element_cnt = 1;
429 428
429 dai->capture_dma_data = dev->dma_params;
430 dai->playback_dma_data = dev->dma_params;
431
430 /* general line settings */ 432 /* general line settings */
431 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 433 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
432 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 434 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
@@ -569,7 +571,7 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
569static int davinci_i2s_prepare(struct snd_pcm_substream *substream, 571static int davinci_i2s_prepare(struct snd_pcm_substream *substream,
570 struct snd_soc_dai *dai) 572 struct snd_soc_dai *dai)
571{ 573{
572 struct davinci_mcbsp_dev *dev = dai->private_data; 574 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
573 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 575 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
574 davinci_mcbsp_stop(dev, playback); 576 davinci_mcbsp_stop(dev, playback);
575 if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0) { 577 if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0) {
@@ -582,7 +584,7 @@ static int davinci_i2s_prepare(struct snd_pcm_substream *substream,
582static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 584static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
583 struct snd_soc_dai *dai) 585 struct snd_soc_dai *dai)
584{ 586{
585 struct davinci_mcbsp_dev *dev = dai->private_data; 587 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
586 int ret = 0; 588 int ret = 0;
587 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 589 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
588 if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0) 590 if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0)
@@ -608,7 +610,7 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
608static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, 610static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
609 struct snd_soc_dai *dai) 611 struct snd_soc_dai *dai)
610{ 612{
611 struct davinci_mcbsp_dev *dev = dai->private_data; 613 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
612 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 614 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
613 davinci_mcbsp_stop(dev, playback); 615 davinci_mcbsp_stop(dev, playback);
614} 616}
@@ -625,9 +627,7 @@ static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
625 627
626}; 628};
627 629
628struct snd_soc_dai davinci_i2s_dai = { 630static struct snd_soc_dai_driver davinci_i2s_dai = {
629 .name = "davinci-i2s",
630 .id = 0,
631 .playback = { 631 .playback = {
632 .channels_min = 2, 632 .channels_min = 2,
633 .channels_max = 2, 633 .channels_max = 2,
@@ -641,7 +641,6 @@ struct snd_soc_dai davinci_i2s_dai = {
641 .ops = &davinci_i2s_dai_ops, 641 .ops = &davinci_i2s_dai_ops,
642 642
643}; 643};
644EXPORT_SYMBOL_GPL(davinci_i2s_dai);
645 644
646static int davinci_i2s_probe(struct platform_device *pdev) 645static int davinci_i2s_probe(struct platform_device *pdev)
647{ 646{
@@ -720,10 +719,9 @@ static int davinci_i2s_probe(struct platform_device *pdev)
720 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; 719 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
721 dev->dev = &pdev->dev; 720 dev->dev = &pdev->dev;
722 721
723 davinci_i2s_dai.private_data = dev; 722 dev_set_drvdata(&pdev->dev, dev);
724 davinci_i2s_dai.capture.dma_data = dev->dma_params; 723
725 davinci_i2s_dai.playback.dma_data = dev->dma_params; 724 ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai);
726 ret = snd_soc_register_dai(&davinci_i2s_dai);
727 if (ret != 0) 725 if (ret != 0)
728 goto err_free_mem; 726 goto err_free_mem;
729 727
@@ -739,10 +737,10 @@ err_release_region:
739 737
740static int davinci_i2s_remove(struct platform_device *pdev) 738static int davinci_i2s_remove(struct platform_device *pdev)
741{ 739{
742 struct davinci_mcbsp_dev *dev = davinci_i2s_dai.private_data; 740 struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
743 struct resource *mem; 741 struct resource *mem;
744 742
745 snd_soc_unregister_dai(&davinci_i2s_dai); 743 snd_soc_unregister_dai(&pdev->dev);
746 clk_disable(dev->clk); 744 clk_disable(dev->clk);
747 clk_put(dev->clk); 745 clk_put(dev->clk);
748 dev->clk = NULL; 746 dev->clk = NULL;
@@ -757,7 +755,7 @@ static struct platform_driver davinci_mcbsp_driver = {
757 .probe = davinci_i2s_probe, 755 .probe = davinci_i2s_probe,
758 .remove = davinci_i2s_remove, 756 .remove = davinci_i2s_remove,
759 .driver = { 757 .driver = {
760 .name = "davinci-asp", 758 .name = "davinci-i2s",
761 .owner = THIS_MODULE, 759 .owner = THIS_MODULE,
762 }, 760 },
763}; 761};
diff --git a/sound/soc/davinci/davinci-i2s.h b/sound/soc/davinci/davinci-i2s.h
index 0b1e77b8c27..48dac3e2521 100644
--- a/sound/soc/davinci/davinci-i2s.h
+++ b/sound/soc/davinci/davinci-i2s.h
@@ -17,6 +17,4 @@ enum davinci_mcbsp_div {
17 DAVINCI_MCBSP_CLKGDV, /* Sample rate generator divider */ 17 DAVINCI_MCBSP_CLKGDV, /* Sample rate generator divider */
18}; 18};
19 19
20extern struct snd_soc_dai davinci_i2s_dai;
21
22#endif 20#endif
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index b24720894af..c8e97dcbfff 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -422,7 +422,7 @@ static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
422static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, 422static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
423 unsigned int fmt) 423 unsigned int fmt)
424{ 424{
425 struct davinci_audio_dev *dev = cpu_dai->private_data; 425 struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
426 void __iomem *base = dev->base; 426 void __iomem *base = dev->base;
427 427
428 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 428 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -709,12 +709,15 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
709 struct snd_pcm_hw_params *params, 709 struct snd_pcm_hw_params *params,
710 struct snd_soc_dai *cpu_dai) 710 struct snd_soc_dai *cpu_dai)
711{ 711{
712 struct davinci_audio_dev *dev = cpu_dai->private_data; 712 struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
713 struct davinci_pcm_dma_params *dma_params = 713 struct davinci_pcm_dma_params *dma_params =
714 &dev->dma_params[substream->stream]; 714 &dev->dma_params[substream->stream];
715 int word_length; 715 int word_length;
716 u8 fifo_level; 716 u8 fifo_level;
717 717
718 cpu_dai->capture_dma_data = dev->dma_params;
719 cpu_dai->playback_dma_data = dev->dma_params;
720
718 davinci_hw_common_param(dev, substream->stream); 721 davinci_hw_common_param(dev, substream->stream);
719 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 722 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
720 fifo_level = dev->txnumevt; 723 fifo_level = dev->txnumevt;
@@ -761,8 +764,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
761static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, 764static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
762 int cmd, struct snd_soc_dai *cpu_dai) 765 int cmd, struct snd_soc_dai *cpu_dai)
763{ 766{
764 struct snd_soc_pcm_runtime *rtd = substream->private_data; 767 struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
765 struct davinci_audio_dev *dev = rtd->dai->cpu_dai->private_data;
766 int ret = 0; 768 int ret = 0;
767 769
768 switch (cmd) { 770 switch (cmd) {
@@ -804,10 +806,9 @@ static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
804 806
805}; 807};
806 808
807struct snd_soc_dai davinci_mcasp_dai[] = { 809static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
808 { 810 {
809 .name = "davinci-i2s", 811 .name = "davinci-mcasp.0",
810 .id = 0,
811 .playback = { 812 .playback = {
812 .channels_min = 2, 813 .channels_min = 2,
813 .channels_max = 2, 814 .channels_max = 2,
@@ -828,8 +829,7 @@ struct snd_soc_dai davinci_mcasp_dai[] = {
828 829
829 }, 830 },
830 { 831 {
831 .name = "davinci-dit", 832 "davinci-mcasp.1",
832 .id = 1,
833 .playback = { 833 .playback = {
834 .channels_min = 1, 834 .channels_min = 1,
835 .channels_max = 384, 835 .channels_max = 384,
@@ -840,7 +840,6 @@ struct snd_soc_dai davinci_mcasp_dai[] = {
840 }, 840 },
841 841
842}; 842};
843EXPORT_SYMBOL_GPL(davinci_mcasp_dai);
844 843
845static int davinci_mcasp_probe(struct platform_device *pdev) 844static int davinci_mcasp_probe(struct platform_device *pdev)
846{ 845{
@@ -917,11 +916,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
917 } 916 }
918 917
919 dma_data->channel = res->start; 918 dma_data->channel = res->start;
920 davinci_mcasp_dai[pdata->op_mode].private_data = dev; 919 dev_set_drvdata(&pdev->dev, dev);
921 davinci_mcasp_dai[pdata->op_mode].capture.dma_data = dev->dma_params; 920 ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]);
922 davinci_mcasp_dai[pdata->op_mode].playback.dma_data = dev->dma_params;
923 davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
924 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
925 921
926 if (ret != 0) 922 if (ret != 0)
927 goto err_release_region; 923 goto err_release_region;
@@ -937,12 +933,10 @@ err_release_data:
937 933
938static int davinci_mcasp_remove(struct platform_device *pdev) 934static int davinci_mcasp_remove(struct platform_device *pdev)
939{ 935{
940 struct snd_platform_data *pdata = pdev->dev.platform_data; 936 struct davinci_audio_dev *dev = dev_get_drvdata(&pdev->dev);
941 struct davinci_audio_dev *dev;
942 struct resource *mem; 937 struct resource *mem;
943 938
944 snd_soc_unregister_dai(&davinci_mcasp_dai[pdata->op_mode]); 939 snd_soc_unregister_dai(&pdev->dev);
945 dev = davinci_mcasp_dai[pdata->op_mode].private_data;
946 clk_disable(dev->clk); 940 clk_disable(dev->clk);
947 clk_put(dev->clk); 941 clk_put(dev->clk);
948 dev->clk = NULL; 942 dev->clk = NULL;
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index e755b5121ec..4681acc6360 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -22,8 +22,6 @@
22#include <mach/asp.h> 22#include <mach/asp.h>
23#include "davinci-pcm.h" 23#include "davinci-pcm.h"
24 24
25extern struct snd_soc_dai davinci_mcasp_dai[];
26
27#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000 25#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000
28#define DAVINCI_MCASP_I2S_DAI 0 26#define DAVINCI_MCASP_I2S_DAI 0
29#define DAVINCI_MCASP_DIT_DAI 1 27#define DAVINCI_MCASP_DIT_DAI 1
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index a7124116d2e..9d35b8c1a62 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -653,7 +653,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
653 struct davinci_pcm_dma_params *pa; 653 struct davinci_pcm_dma_params *pa;
654 struct davinci_pcm_dma_params *params; 654 struct davinci_pcm_dma_params *params;
655 655
656 pa = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 656 pa = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
657 if (!pa) 657 if (!pa)
658 return -ENODEV; 658 return -ENODEV;
659 params = &pa[substream->stream]; 659 params = &pa[substream->stream];
@@ -821,7 +821,7 @@ static int davinci_pcm_new(struct snd_card *card,
821 if (!card->dev->coherent_dma_mask) 821 if (!card->dev->coherent_dma_mask)
822 card->dev->coherent_dma_mask = 0xffffffff; 822 card->dev->coherent_dma_mask = 0xffffffff;
823 823
824 if (dai->playback.channels_min) { 824 if (dai->driver->playback.channels_min) {
825 ret = davinci_pcm_preallocate_dma_buffer(pcm, 825 ret = davinci_pcm_preallocate_dma_buffer(pcm,
826 SNDRV_PCM_STREAM_PLAYBACK, 826 SNDRV_PCM_STREAM_PLAYBACK,
827 pcm_hardware_playback.buffer_bytes_max); 827 pcm_hardware_playback.buffer_bytes_max);
@@ -829,7 +829,7 @@ static int davinci_pcm_new(struct snd_card *card,
829 return ret; 829 return ret;
830 } 830 }
831 831
832 if (dai->capture.channels_min) { 832 if (dai->driver->capture.channels_min) {
833 ret = davinci_pcm_preallocate_dma_buffer(pcm, 833 ret = davinci_pcm_preallocate_dma_buffer(pcm,
834 SNDRV_PCM_STREAM_CAPTURE, 834 SNDRV_PCM_STREAM_CAPTURE,
835 pcm_hardware_capture.buffer_bytes_max); 835 pcm_hardware_capture.buffer_bytes_max);
@@ -840,25 +840,44 @@ static int davinci_pcm_new(struct snd_card *card,
840 return 0; 840 return 0;
841} 841}
842 842
843struct snd_soc_platform davinci_soc_platform = { 843static struct snd_soc_platform_driver davinci_soc_platform = {
844 .name = "davinci-audio", 844 .ops = &davinci_pcm_ops,
845 .pcm_ops = &davinci_pcm_ops,
846 .pcm_new = davinci_pcm_new, 845 .pcm_new = davinci_pcm_new,
847 .pcm_free = davinci_pcm_free, 846 .pcm_free = davinci_pcm_free,
848}; 847};
849EXPORT_SYMBOL_GPL(davinci_soc_platform);
850 848
851static int __init davinci_soc_platform_init(void) 849static int __devinit davinci_soc_platform_probe(struct platform_device *pdev)
852{ 850{
853 return snd_soc_register_platform(&davinci_soc_platform); 851 return snd_soc_register_platform(&pdev->dev, &davinci_soc_platform);
854} 852}
855module_init(davinci_soc_platform_init);
856 853
857static void __exit davinci_soc_platform_exit(void) 854static int __devexit davinci_soc_platform_remove(struct platform_device *pdev)
858{ 855{
859 snd_soc_unregister_platform(&davinci_soc_platform); 856 snd_soc_unregister_platform(&pdev->dev);
857 return 0;
858}
859
860static struct platform_driver davinci_pcm_driver = {
861 .driver = {
862 .name = "davinci-pcm-audio",
863 .owner = THIS_MODULE,
864 },
865
866 .probe = davinci_soc_platform_probe,
867 .remove = __devexit_p(davinci_soc_platform_remove),
868};
869
870static int __init snd_davinci_pcm_init(void)
871{
872 return platform_driver_register(&davinci_pcm_driver);
873}
874module_init(snd_davinci_pcm_init);
875
876static void __exit snd_davinci_pcm_exit(void)
877{
878 platform_driver_unregister(&davinci_pcm_driver);
860} 879}
861module_exit(davinci_soc_platform_exit); 880module_exit(snd_davinci_pcm_exit);
862 881
863MODULE_AUTHOR("Vladimir Barinov"); 882MODULE_AUTHOR("Vladimir Barinov");
864MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); 883MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index b799a02333d..c0d6c9be4b4 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -28,7 +28,4 @@ struct davinci_pcm_dma_params {
28 unsigned int fifo_level; 28 unsigned int fifo_level;
29}; 29};
30 30
31
32extern struct snd_soc_platform davinci_soc_platform;
33
34#endif 31#endif
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index 40eccfe9e35..997c54f3693 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -29,7 +29,6 @@
29#include <asm/plat-sffsdr/sffsdr-fpga.h> 29#include <asm/plat-sffsdr/sffsdr-fpga.h>
30#endif 30#endif
31 31
32#include <mach/mcbsp.h>
33#include <mach/edma.h> 32#include <mach/edma.h>
34 33
35#include "../codecs/pcm3008.h" 34#include "../codecs/pcm3008.h"
@@ -48,7 +47,7 @@ static int sffsdr_hw_params(struct snd_pcm_substream *substream,
48 struct snd_pcm_hw_params *params) 47 struct snd_pcm_hw_params *params)
49{ 48{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data; 49 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
52 int fs; 51 int fs;
53 int ret = 0; 52 int ret = 0;
54 53
@@ -85,15 +84,16 @@ static struct snd_soc_ops sffsdr_ops = {
85static struct snd_soc_dai_link sffsdr_dai = { 84static struct snd_soc_dai_link sffsdr_dai = {
86 .name = "PCM3008", /* Codec name */ 85 .name = "PCM3008", /* Codec name */
87 .stream_name = "PCM3008 HiFi", 86 .stream_name = "PCM3008 HiFi",
88 .cpu_dai = &davinci_i2s_dai, 87 .cpu_dai_name = "davinci-asp.0",
89 .codec_dai = &pcm3008_dai, 88 .codec_dai_name = "pcm3008-hifi",
89 .codec_name = "pcm3008-codec",
90 .platform_name = "davinci-pcm-audio",
90 .ops = &sffsdr_ops, 91 .ops = &sffsdr_ops,
91}; 92};
92 93
93/* davinci-sffsdr audio machine driver */ 94/* davinci-sffsdr audio machine driver */
94static struct snd_soc_card snd_soc_sffsdr = { 95static struct snd_soc_card snd_soc_sffsdr = {
95 .name = "DaVinci SFFSDR", 96 .name = "DaVinci SFFSDR",
96 .platform = &davinci_soc_platform,
97 .dai_link = &sffsdr_dai, 97 .dai_link = &sffsdr_dai,
98 .num_links = 1, 98 .num_links = 1,
99}; 99};
@@ -106,11 +106,12 @@ static struct pcm3008_setup_data sffsdr_pcm3008_setup = {
106 .pdda_pin = GPIO(38), 106 .pdda_pin = GPIO(38),
107}; 107};
108 108
109/* sffsdr audio subsystem */ 109struct platform_device pcm3008_codec = {
110static struct snd_soc_device sffsdr_snd_devdata = { 110 .name = "pcm3008-codec",
111 .card = &snd_soc_sffsdr, 111 .id = 0,
112 .codec_dev = &soc_codec_dev_pcm3008, 112 .dev = {
113 .codec_data = &sffsdr_pcm3008_setup, 113 .platform_data = &sffsdr_pcm3008_setup,
114 },
114}; 115};
115 116
116static struct resource sffsdr_snd_resources[] = { 117static struct resource sffsdr_snd_resources[] = {
@@ -135,14 +136,15 @@ static int __init sffsdr_init(void)
135 if (!machine_is_sffsdr()) 136 if (!machine_is_sffsdr())
136 return -EINVAL; 137 return -EINVAL;
137 138
139 platform_device_register(&pcm3008_codec);
140
138 sffsdr_snd_device = platform_device_alloc("soc-audio", 0); 141 sffsdr_snd_device = platform_device_alloc("soc-audio", 0);
139 if (!sffsdr_snd_device) { 142 if (!sffsdr_snd_device) {
140 printk(KERN_ERR "platform device allocation failed\n"); 143 printk(KERN_ERR "platform device allocation failed\n");
141 return -ENOMEM; 144 return -ENOMEM;
142 } 145 }
143 146
144 platform_set_drvdata(sffsdr_snd_device, &sffsdr_snd_devdata); 147 platform_set_drvdata(sffsdr_snd_device, &snd_soc_sffsdr);
145 sffsdr_snd_devdata.dev = &sffsdr_snd_device->dev;
146 platform_device_add_data(sffsdr_snd_device, &sffsdr_snd_data, 148 platform_device_add_data(sffsdr_snd_device, &sffsdr_snd_data,
147 sizeof(sffsdr_snd_data)); 149 sizeof(sffsdr_snd_data));
148 150
@@ -168,6 +170,7 @@ error:
168static void __exit sffsdr_exit(void) 170static void __exit sffsdr_exit(void)
169{ 171{
170 platform_device_unregister(sffsdr_snd_device); 172 platform_device_unregister(sffsdr_snd_device);
173 platform_device_unregister(&pcm3008_codec);
171} 174}
172 175
173module_init(sffsdr_init); 176module_init(sffsdr_init);
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index 48678533da7..ea232f6a2c2 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -36,7 +36,6 @@
36 36
37#include "davinci-pcm.h" 37#include "davinci-pcm.h"
38#include "davinci-i2s.h" 38#include "davinci-i2s.h"
39#include "davinci-vcif.h"
40 39
41#define MOD_REG_BIT(val, mask, set) do { \ 40#define MOD_REG_BIT(val, mask, set) do { \
42 if (set) { \ 41 if (set) { \
@@ -55,7 +54,7 @@ static void davinci_vcif_start(struct snd_pcm_substream *substream)
55{ 54{
56 struct snd_soc_pcm_runtime *rtd = substream->private_data; 55 struct snd_soc_pcm_runtime *rtd = substream->private_data;
57 struct davinci_vcif_dev *davinci_vcif_dev = 56 struct davinci_vcif_dev *davinci_vcif_dev =
58 rtd->dai->cpu_dai->private_data; 57 snd_soc_dai_get_drvdata(rtd->cpu_dai);
59 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; 58 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
60 u32 w; 59 u32 w;
61 60
@@ -74,7 +73,7 @@ static void davinci_vcif_stop(struct snd_pcm_substream *substream)
74{ 73{
75 struct snd_soc_pcm_runtime *rtd = substream->private_data; 74 struct snd_soc_pcm_runtime *rtd = substream->private_data;
76 struct davinci_vcif_dev *davinci_vcif_dev = 75 struct davinci_vcif_dev *davinci_vcif_dev =
77 rtd->dai->cpu_dai->private_data; 76 snd_soc_dai_get_drvdata(rtd->cpu_dai);
78 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; 77 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
79 u32 w; 78 u32 w;
80 79
@@ -92,12 +91,15 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
92 struct snd_pcm_hw_params *params, 91 struct snd_pcm_hw_params *params,
93 struct snd_soc_dai *dai) 92 struct snd_soc_dai *dai)
94{ 93{
95 struct davinci_vcif_dev *davinci_vcif_dev = dai->private_data; 94 struct davinci_vcif_dev *davinci_vcif_dev = snd_soc_dai_get_drvdata(dai);
96 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; 95 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
97 struct davinci_pcm_dma_params *dma_params = 96 struct davinci_pcm_dma_params *dma_params =
98 &davinci_vcif_dev->dma_params[substream->stream]; 97 &davinci_vcif_dev->dma_params[substream->stream];
99 u32 w; 98 u32 w;
100 99
100 dai->capture_dma_data = davinci_vcif_dev->dma_params;
101 dai->playback_dma_data = davinci_vcif_dev->dma_params;
102
101 /* Restart the codec before setup */ 103 /* Restart the codec before setup */
102 davinci_vcif_stop(substream); 104 davinci_vcif_stop(substream);
103 davinci_vcif_start(substream); 105 davinci_vcif_start(substream);
@@ -179,8 +181,7 @@ static struct snd_soc_dai_ops davinci_vcif_dai_ops = {
179 .hw_params = davinci_vcif_hw_params, 181 .hw_params = davinci_vcif_hw_params,
180}; 182};
181 183
182struct snd_soc_dai davinci_vcif_dai = { 184static struct snd_soc_dai_driver davinci_vcif_dai = {
183 .name = "davinci-vcif",
184 .playback = { 185 .playback = {
185 .channels_min = 1, 186 .channels_min = 1,
186 .channels_max = 2, 187 .channels_max = 2,
@@ -194,7 +195,6 @@ struct snd_soc_dai davinci_vcif_dai = {
194 .ops = &davinci_vcif_dai_ops, 195 .ops = &davinci_vcif_dai_ops,
195 196
196}; 197};
197EXPORT_SYMBOL_GPL(davinci_vcif_dai);
198 198
199static int davinci_vcif_probe(struct platform_device *pdev) 199static int davinci_vcif_probe(struct platform_device *pdev)
200{ 200{
@@ -222,12 +222,9 @@ static int davinci_vcif_probe(struct platform_device *pdev)
222 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr = 222 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
223 davinci_vc->davinci_vcif.dma_rx_addr; 223 davinci_vc->davinci_vcif.dma_rx_addr;
224 224
225 davinci_vcif_dai.dev = &pdev->dev; 225 dev_set_drvdata(&pdev->dev, davinci_vcif_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 226
230 ret = snd_soc_register_dai(&davinci_vcif_dai); 227 ret = snd_soc_register_dai(&pdev->dev, &davinci_vcif_dai);
231 if (ret != 0) { 228 if (ret != 0) {
232 dev_err(&pdev->dev, "could not register dai\n"); 229 dev_err(&pdev->dev, "could not register dai\n");
233 goto fail; 230 goto fail;
@@ -243,7 +240,7 @@ fail:
243 240
244static int davinci_vcif_remove(struct platform_device *pdev) 241static int davinci_vcif_remove(struct platform_device *pdev)
245{ 242{
246 snd_soc_unregister_dai(&davinci_vcif_dai); 243 snd_soc_unregister_dai(&pdev->dev);
247 244
248 return 0; 245 return 0;
249} 246}
@@ -252,7 +249,7 @@ static struct platform_driver davinci_vcif_driver = {
252 .probe = davinci_vcif_probe, 249 .probe = davinci_vcif_probe,
253 .remove = davinci_vcif_remove, 250 .remove = davinci_vcif_remove,
254 .driver = { 251 .driver = {
255 .name = "davinci_vcif", 252 .name = "davinci-vcif",
256 .owner = THIS_MODULE, 253 .owner = THIS_MODULE,
257 }, 254 },
258}; 255};
diff --git a/sound/soc/davinci/davinci-vcif.h b/sound/soc/davinci/davinci-vcif.h
deleted file mode 100644
index 571c9948724..00000000000
--- a/sound/soc/davinci/davinci-vcif.h
+++ /dev/null
@@ -1,28 +0,0 @@
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/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index 00b94663218..4f487335961 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -31,7 +31,6 @@
31#include <mach/dma.h> 31#include <mach/dma.h>
32 32
33#include "ep93xx-pcm.h" 33#include "ep93xx-pcm.h"
34#include "ep93xx-i2s.h"
35 34
36#define EP93XX_I2S_TXCLKCFG 0x00 35#define EP93XX_I2S_TXCLKCFG 0x00
37#define EP93XX_I2S_RXCLKCFG 0x04 36#define EP93XX_I2S_RXCLKCFG 0x04
@@ -145,8 +144,8 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream,
145 struct snd_soc_dai *dai) 144 struct snd_soc_dai *dai)
146{ 145{
147 struct snd_soc_pcm_runtime *rtd = substream->private_data; 146 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 147 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
149 struct ep93xx_i2s_info *info = rtd->dai->cpu_dai->private_data; 148 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
150 149
151 snd_soc_dai_set_dma_data(cpu_dai, substream, 150 snd_soc_dai_set_dma_data(cpu_dai, substream,
152 &info->dma_params[substream->stream]); 151 &info->dma_params[substream->stream]);
@@ -156,8 +155,7 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream,
156static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream, 155static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream,
157 struct snd_soc_dai *dai) 156 struct snd_soc_dai *dai)
158{ 157{
159 struct snd_soc_pcm_runtime *rtd = substream->private_data; 158 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
160 struct ep93xx_i2s_info *info = rtd->dai->cpu_dai->private_data;
161 159
162 ep93xx_i2s_disable(info, substream->stream); 160 ep93xx_i2s_disable(info, substream->stream);
163} 161}
@@ -165,7 +163,7 @@ static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream,
165static int ep93xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 163static int ep93xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
166 unsigned int fmt) 164 unsigned int fmt)
167{ 165{
168 struct ep93xx_i2s_info *info = cpu_dai->private_data; 166 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai);
169 unsigned int clk_cfg, lin_ctrl; 167 unsigned int clk_cfg, lin_ctrl;
170 168
171 clk_cfg = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXCLKCFG); 169 clk_cfg = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXCLKCFG);
@@ -242,9 +240,7 @@ static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,
242 struct snd_pcm_hw_params *params, 240 struct snd_pcm_hw_params *params,
243 struct snd_soc_dai *dai) 241 struct snd_soc_dai *dai)
244{ 242{
245 struct snd_soc_pcm_runtime *rtd = substream->private_data; 243 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
246 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
247 struct ep93xx_i2s_info *info = cpu_dai->private_data;
248 unsigned word_len, div, sdiv, lrdiv; 244 unsigned word_len, div, sdiv, lrdiv;
249 int found = 0, err; 245 int found = 0, err;
250 246
@@ -302,7 +298,7 @@ out:
302static int ep93xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, 298static int ep93xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
303 unsigned int freq, int dir) 299 unsigned int freq, int dir)
304{ 300{
305 struct ep93xx_i2s_info *info = cpu_dai->private_data; 301 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai);
306 302
307 if (dir == SND_SOC_CLOCK_IN || clk_id != 0) 303 if (dir == SND_SOC_CLOCK_IN || clk_id != 0)
308 return -EINVAL; 304 return -EINVAL;
@@ -313,7 +309,7 @@ static int ep93xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
313#ifdef CONFIG_PM 309#ifdef CONFIG_PM
314static int ep93xx_i2s_suspend(struct snd_soc_dai *dai) 310static int ep93xx_i2s_suspend(struct snd_soc_dai *dai)
315{ 311{
316 struct ep93xx_i2s_info *info = dai->private_data; 312 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
317 313
318 if (!dai->active) 314 if (!dai->active)
319 return; 315 return;
@@ -324,7 +320,7 @@ static int ep93xx_i2s_suspend(struct snd_soc_dai *dai)
324 320
325static int ep93xx_i2s_resume(struct snd_soc_dai *dai) 321static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
326{ 322{
327 struct ep93xx_i2s_info *info = dai->private_data; 323 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
328 324
329 if (!dai->active) 325 if (!dai->active)
330 return; 326 return;
@@ -349,9 +345,7 @@ static struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
349 SNDRV_PCM_FMTBIT_S24_LE | \ 345 SNDRV_PCM_FMTBIT_S24_LE | \
350 SNDRV_PCM_FMTBIT_S32_LE) 346 SNDRV_PCM_FMTBIT_S32_LE)
351 347
352struct snd_soc_dai ep93xx_i2s_dai = { 348static struct snd_soc_dai_driver ep93xx_i2s_dai = {
353 .name = "ep93xx-i2s",
354 .id = 0,
355 .symmetric_rates= 1, 349 .symmetric_rates= 1,
356 .suspend = ep93xx_i2s_suspend, 350 .suspend = ep93xx_i2s_suspend,
357 .resume = ep93xx_i2s_resume, 351 .resume = ep93xx_i2s_resume,
@@ -369,7 +363,6 @@ struct snd_soc_dai ep93xx_i2s_dai = {
369 }, 363 },
370 .ops = &ep93xx_i2s_dai_ops, 364 .ops = &ep93xx_i2s_dai_ops,
371}; 365};
372EXPORT_SYMBOL_GPL(ep93xx_i2s_dai);
373 366
374static int ep93xx_i2s_probe(struct platform_device *pdev) 367static int ep93xx_i2s_probe(struct platform_device *pdev)
375{ 368{
@@ -383,8 +376,7 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
383 goto fail; 376 goto fail;
384 } 377 }
385 378
386 ep93xx_i2s_dai.dev = &pdev->dev; 379 dev_set_drvdata(&pdev->dev, info);
387 ep93xx_i2s_dai.private_data = info;
388 info->dma_params = ep93xx_i2s_dma_params; 380 info->dma_params = ep93xx_i2s_dma_params;
389 381
390 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 382 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -424,7 +416,7 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
424 goto fail_put_sclk; 416 goto fail_put_sclk;
425 } 417 }
426 418
427 err = snd_soc_register_dai(&ep93xx_i2s_dai); 419 err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai);
428 if (err) 420 if (err)
429 goto fail_put_lrclk; 421 goto fail_put_lrclk;
430 422
@@ -447,9 +439,9 @@ fail:
447 439
448static int __devexit ep93xx_i2s_remove(struct platform_device *pdev) 440static int __devexit ep93xx_i2s_remove(struct platform_device *pdev)
449{ 441{
450 struct ep93xx_i2s_info *info = ep93xx_i2s_dai.private_data; 442 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
451 443
452 snd_soc_unregister_dai(&ep93xx_i2s_dai); 444 snd_soc_unregister_dai(&pdev->dev);
453 clk_put(info->lrclk); 445 clk_put(info->lrclk);
454 clk_put(info->sclk); 446 clk_put(info->sclk);
455 clk_put(info->mclk); 447 clk_put(info->mclk);
diff --git a/sound/soc/ep93xx/ep93xx-i2s.h b/sound/soc/ep93xx/ep93xx-i2s.h
deleted file mode 100644
index 3bd4ebfaa1d..00000000000
--- a/sound/soc/ep93xx/ep93xx-i2s.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * linux/sound/soc/ep93xx-i2s.h
3 * EP93xx I2S driver
4 *
5 * Copyright (C) 2010 Ryan Mallon <ryan@bluewatersys.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
13#ifndef _EP93XX_SND_SOC_I2S_H
14#define _EP93XX_SND_SOC_I2S_H
15
16extern struct snd_soc_dai ep93xx_i2s_dai;
17
18#endif /* _EP93XX_SND_SOC_I2S_H */
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 4ba93840079..2f121ddbe4b 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -95,7 +95,7 @@ static void ep93xx_pcm_buffer_finished(void *cookie,
95static int ep93xx_pcm_open(struct snd_pcm_substream *substream) 95static int ep93xx_pcm_open(struct snd_pcm_substream *substream)
96{ 96{
97 struct snd_soc_pcm_runtime *soc_rtd = substream->private_data; 97 struct snd_soc_pcm_runtime *soc_rtd = substream->private_data;
98 struct snd_soc_dai *cpu_dai = soc_rtd->dai->cpu_dai; 98 struct snd_soc_dai *cpu_dai = soc_rtd->cpu_dai;
99 struct ep93xx_pcm_dma_params *dma_params; 99 struct ep93xx_pcm_dma_params *dma_params;
100 struct ep93xx_runtime_data *rtd; 100 struct ep93xx_runtime_data *rtd;
101 int ret; 101 int ret;
@@ -276,14 +276,14 @@ static int ep93xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
276 if (!card->dev->coherent_dma_mask) 276 if (!card->dev->coherent_dma_mask)
277 card->dev->coherent_dma_mask = 0xffffffff; 277 card->dev->coherent_dma_mask = 0xffffffff;
278 278
279 if (dai->playback.channels_min) { 279 if (dai->driver->playback.channels_min) {
280 ret = ep93xx_pcm_preallocate_dma_buffer(pcm, 280 ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
281 SNDRV_PCM_STREAM_PLAYBACK); 281 SNDRV_PCM_STREAM_PLAYBACK);
282 if (ret) 282 if (ret)
283 return ret; 283 return ret;
284 } 284 }
285 285
286 if (dai->capture.channels_min) { 286 if (dai->driver->capture.channels_min) {
287 ret = ep93xx_pcm_preallocate_dma_buffer(pcm, 287 ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
288 SNDRV_PCM_STREAM_CAPTURE); 288 SNDRV_PCM_STREAM_CAPTURE);
289 if (ret) 289 if (ret)
@@ -293,22 +293,41 @@ static int ep93xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
293 return 0; 293 return 0;
294} 294}
295 295
296struct snd_soc_platform ep93xx_soc_platform = { 296static struct snd_soc_platform_driver ep93xx_soc_platform = {
297 .name = "ep93xx-audio", 297 .ops = &ep93xx_pcm_ops,
298 .pcm_ops = &ep93xx_pcm_ops,
299 .pcm_new = &ep93xx_pcm_new, 298 .pcm_new = &ep93xx_pcm_new,
300 .pcm_free = &ep93xx_pcm_free_dma_buffers, 299 .pcm_free = &ep93xx_pcm_free_dma_buffers,
301}; 300};
302EXPORT_SYMBOL_GPL(ep93xx_soc_platform); 301
302static int __devinit ep93xx_soc_platform_probe(struct platform_device *pdev)
303{
304 return snd_soc_register_platform(&pdev->dev, &ep93xx_soc_platform);
305}
306
307static int __devexit ep93xx_soc_platform_remove(struct platform_device *pdev)
308{
309 snd_soc_unregister_platform(&pdev->dev);
310 return 0;
311}
312
313static struct platform_driver ep93xx_pcm_driver = {
314 .driver = {
315 .name = "ep93xx-pcm-audio",
316 .owner = THIS_MODULE,
317 },
318
319 .probe = ep93xx_soc_platform_probe,
320 .remove = __devexit_p(ep93xx_soc_platform_remove),
321};
303 322
304static int __init ep93xx_soc_platform_init(void) 323static int __init ep93xx_soc_platform_init(void)
305{ 324{
306 return snd_soc_register_platform(&ep93xx_soc_platform); 325 return platform_driver_register(&ep93xx_pcm_driver);
307} 326}
308 327
309static void __exit ep93xx_soc_platform_exit(void) 328static void __exit ep93xx_soc_platform_exit(void)
310{ 329{
311 snd_soc_unregister_platform(&ep93xx_soc_platform); 330 platform_driver_unregister(&ep93xx_pcm_driver);
312} 331}
313 332
314module_init(ep93xx_soc_platform_init); 333module_init(ep93xx_soc_platform_init);
diff --git a/sound/soc/ep93xx/ep93xx-pcm.h b/sound/soc/ep93xx/ep93xx-pcm.h
index 4ffdd3f62fe..111e1121ecb 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.h
+++ b/sound/soc/ep93xx/ep93xx-pcm.h
@@ -17,6 +17,4 @@ struct ep93xx_pcm_dma_params {
17 int dma_port; 17 int dma_port;
18}; 18};
19 19
20extern struct snd_soc_platform ep93xx_soc_platform;
21
22#endif /* _EP93XX_SND_SOC_PCM_H */ 20#endif /* _EP93XX_SND_SOC_PCM_H */
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
index 64955340ff7..28ab5ff772a 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -22,7 +22,6 @@
22 22
23#include "../codecs/tlv320aic23.h" 23#include "../codecs/tlv320aic23.h"
24#include "ep93xx-pcm.h" 24#include "ep93xx-pcm.h"
25#include "ep93xx-i2s.h"
26 25
27#define CODEC_CLOCK 5644800 26#define CODEC_CLOCK 5644800
28 27
@@ -30,8 +29,8 @@ static int snappercl15_hw_params(struct snd_pcm_substream *substream,
30 struct snd_pcm_hw_params *params) 29 struct snd_pcm_hw_params *params)
31{ 30{
32 struct snd_soc_pcm_runtime *rtd = substream->private_data; 31 struct snd_soc_pcm_runtime *rtd = substream->private_data;
33 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 32 struct snd_soc_dai *codec_dai = rtd->codec_dai;
34 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 33 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
35 int err; 34 int err;
36 35
37 err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 36 err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
@@ -77,8 +76,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
77 {"MICIN", NULL, "Mic Jack"}, 76 {"MICIN", NULL, "Mic Jack"},
78}; 77};
79 78
80static int snappercl15_tlv320aic23_init(struct snd_soc_codec *codec) 79static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
81{ 80{
81 struct snd_soc_codec *codec = rtd->codec;
82
82 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 83 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
83 ARRAY_SIZE(tlv320aic23_dapm_widgets)); 84 ARRAY_SIZE(tlv320aic23_dapm_widgets));
84 85
@@ -89,24 +90,20 @@ static int snappercl15_tlv320aic23_init(struct snd_soc_codec *codec)
89static struct snd_soc_dai_link snappercl15_dai = { 90static struct snd_soc_dai_link snappercl15_dai = {
90 .name = "tlv320aic23", 91 .name = "tlv320aic23",
91 .stream_name = "AIC23", 92 .stream_name = "AIC23",
92 .cpu_dai = &ep93xx_i2s_dai, 93 .cpu_dai_name = "ep93xx-i2s",
93 .codec_dai = &tlv320aic23_dai, 94 .codec_dai_name = "tlv320aic23-hifi",
95 .codec_name = "tlv320aic23-codec.0-001a",
96 .platform_name = "ep93xx-pcm-audio",
94 .init = snappercl15_tlv320aic23_init, 97 .init = snappercl15_tlv320aic23_init,
95 .ops = &snappercl15_ops, 98 .ops = &snappercl15_ops,
96}; 99};
97 100
98static struct snd_soc_card snd_soc_snappercl15 = { 101static struct snd_soc_card snd_soc_snappercl15 = {
99 .name = "Snapper CL15", 102 .name = "Snapper CL15",
100 .platform = &ep93xx_soc_platform,
101 .dai_link = &snappercl15_dai, 103 .dai_link = &snappercl15_dai,
102 .num_links = 1, 104 .num_links = 1,
103}; 105};
104 106
105static struct snd_soc_device snappercl15_snd_devdata = {
106 .card = &snd_soc_snappercl15,
107 .codec_dev = &soc_codec_dev_tlv320aic23,
108};
109
110static struct platform_device *snappercl15_snd_device; 107static struct platform_device *snappercl15_snd_device;
111 108
112static int __init snappercl15_init(void) 109static int __init snappercl15_init(void)
@@ -126,8 +123,7 @@ static int __init snappercl15_init(void)
126 if (!snappercl15_snd_device) 123 if (!snappercl15_snd_device)
127 return -ENOMEM; 124 return -ENOMEM;
128 125
129 platform_set_drvdata(snappercl15_snd_device, &snappercl15_snd_devdata); 126 platform_set_drvdata(snappercl15_snd_device, &snd_soc_snappercl15);
130 snappercl15_snd_devdata.dev = &snappercl15_snd_device->dev;
131 ret = platform_device_add(snappercl15_snd_device); 127 ret = platform_device_add(snappercl15_snd_device);
132 if (ret) 128 if (ret)
133 platform_device_put(snappercl15_snd_device); 129 platform_device_put(snappercl15_snd_device);
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 8cb65ccad35..98186870038 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -1,6 +1,3 @@
1config SND_SOC_OF_SIMPLE
2 tristate
3
4config SND_MPC52xx_DMA 1config SND_MPC52xx_DMA
5 tristate 2 tristate
6 3
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index a83a73967ec..7e472a53fcd 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -1,6 +1,3 @@
1# Simple machine driver that extracts configuration from the OF device tree
2obj-$(CONFIG_SND_SOC_OF_SIMPLE) += soc-of-simple.o
3
4# MPC8610 HPCD Machine Support 1# MPC8610 HPCD Machine Support
5snd-soc-mpc8610-hpcd-objs := mpc8610_hpcd.o 2snd-soc-mpc8610-hpcd-objs := mpc8610_hpcd.o
6obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o 3obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o
diff --git a/sound/soc/fsl/efika-audio-fabric.c b/sound/soc/fsl/efika-audio-fabric.c
index 1a5b8e0d6a3..53251e6b5bd 100644
--- a/sound/soc/fsl/efika-audio-fabric.c
+++ b/sound/soc/fsl/efika-audio-fabric.c
@@ -24,7 +24,6 @@
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/initval.h> 25#include <sound/initval.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-of-simple.h>
28 27
29#include "mpc5200_dma.h" 28#include "mpc5200_dma.h"
30#include "mpc5200_psc_ac97.h" 29#include "mpc5200_psc_ac97.h"
@@ -32,21 +31,24 @@
32 31
33#define DRV_NAME "efika-audio-fabric" 32#define DRV_NAME "efika-audio-fabric"
34 33
35static struct snd_soc_device device;
36static struct snd_soc_card card; 34static struct snd_soc_card card;
37 35
38static struct snd_soc_dai_link efika_fabric_dai[] = { 36static struct snd_soc_dai_link efika_fabric_dai[] = {
39{ 37{
40 .name = "AC97", 38 .name = "AC97",
41 .stream_name = "AC97 Analog", 39 .stream_name = "AC97 Analog",
42 .codec_dai = &stac9766_dai[STAC9766_DAI_AC97_ANALOG], 40 .codec_dai_name = "stac9766-hifi-analog",
43 .cpu_dai = &psc_ac97_dai[MPC5200_AC97_NORMAL], 41 .cpu_dai_name = "mpc5200-psc-ac97.0",
42 .platform_name = "mpc5200-pcm-audio",
43 .codec_name = "stac9766-codec",
44}, 44},
45{ 45{
46 .name = "AC97", 46 .name = "AC97",
47 .stream_name = "AC97 IEC958", 47 .stream_name = "AC97 IEC958",
48 .codec_dai = &stac9766_dai[STAC9766_DAI_AC97_DIGITAL], 48 .codec_dai_name = "stac9766-hifi-IEC958",
49 .cpu_dai = &psc_ac97_dai[MPC5200_AC97_SPDIF], 49 .cpu_dai_name = "mpc5200-psc-ac97.1",
50 .platform_name = "mpc5200-pcm-audio",
51 .codec_name = "stac9766-codec",
50}, 52},
51}; 53};
52 54
@@ -58,13 +60,10 @@ static __init int efika_fabric_init(void)
58 if (!of_machine_is_compatible("bplan,efika")) 60 if (!of_machine_is_compatible("bplan,efika"))
59 return -ENODEV; 61 return -ENODEV;
60 62
61 card.platform = &mpc5200_audio_dma_platform;
62 card.name = "Efika"; 63 card.name = "Efika";
63 card.dai_link = efika_fabric_dai; 64 card.dai_link = efika_fabric_dai;
64 card.num_links = ARRAY_SIZE(efika_fabric_dai); 65 card.num_links = ARRAY_SIZE(efika_fabric_dai);
65 66
66 device.card = &card;
67 device.codec_dev = &soc_codec_dev_stac9766;
68 67
69 pdev = platform_device_alloc("soc-audio", 1); 68 pdev = platform_device_alloc("soc-audio", 1);
70 if (!pdev) { 69 if (!pdev) {
@@ -72,8 +71,7 @@ static __init int efika_fabric_init(void)
72 return -ENODEV; 71 return -ENODEV;
73 } 72 }
74 73
75 platform_set_drvdata(pdev, &device); 74 platform_set_drvdata(pdev, &card);
76 device.dev = &pdev->dev;
77 75
78 rc = platform_device_add(pdev); 76 rc = platform_device_add(pdev);
79 if (rc) { 77 if (rc) {
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 410c7496a18..d09e1941b1f 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -3,10 +3,11 @@
3 * 3 *
4 * Author: Timur Tabi <timur@freescale.com> 4 * Author: Timur Tabi <timur@freescale.com>
5 * 5 *
6 * Copyright 2007-2008 Freescale Semiconductor, Inc. This file is licensed 6 * Copyright 2007-2010 Freescale Semiconductor, Inc.
7 * under the terms of the GNU General Public License version 2. This 7 *
8 * program is licensed "as is" without any warranty of any kind, whether 8 * This file is licensed under the terms of the GNU General Public License
9 * express or implied. 9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
10 * 11 *
11 * This driver implements ASoC support for the Elo DMA controller, which is 12 * This driver implements ASoC support for the Elo DMA controller, which is
12 * the DMA controller on Freescale 83xx, 85xx, and 86xx SOCs. In ALSA terms, 13 * the DMA controller on Freescale 83xx, 85xx, and 86xx SOCs. In ALSA terms,
@@ -20,6 +21,8 @@
20#include <linux/interrupt.h> 21#include <linux/interrupt.h>
21#include <linux/delay.h> 22#include <linux/delay.h>
22#include <linux/gfp.h> 23#include <linux/gfp.h>
24#include <linux/of_platform.h>
25#include <linux/list.h>
23 26
24#include <sound/core.h> 27#include <sound/core.h>
25#include <sound/pcm.h> 28#include <sound/pcm.h>
@@ -29,6 +32,7 @@
29#include <asm/io.h> 32#include <asm/io.h>
30 33
31#include "fsl_dma.h" 34#include "fsl_dma.h"
35#include "fsl_ssi.h" /* For the offset of stx0 and srx0 */
32 36
33/* 37/*
34 * The formats that the DMA controller supports, which is anything 38 * The formats that the DMA controller supports, which is anything
@@ -52,26 +56,16 @@
52#define FSLDMA_PCM_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \ 56#define FSLDMA_PCM_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
53 SNDRV_PCM_RATE_CONTINUOUS) 57 SNDRV_PCM_RATE_CONTINUOUS)
54 58
55/* DMA global data. This structure is used by fsl_dma_open() to determine 59struct dma_object {
56 * which DMA channels to assign to a substream. Unfortunately, ASoC V1 does 60 struct list_head list;
57 * not allow the machine driver to provide this information to the PCM 61 struct snd_soc_platform_driver dai;
58 * driver in advance, and there's no way to differentiate between the two
59 * DMA controllers. So for now, this driver only supports one SSI device
60 * using two DMA channels. We cannot support multiple DMA devices.
61 *
62 * ssi_stx_phys: bus address of SSI STX register
63 * ssi_srx_phys: bus address of SSI SRX register
64 * dma_channel: pointer to the DMA channel's registers
65 * irq: IRQ for this DMA channel
66 * assigned: set to 1 if that DMA channel is assigned to a substream
67 */
68static struct {
69 dma_addr_t ssi_stx_phys; 62 dma_addr_t ssi_stx_phys;
70 dma_addr_t ssi_srx_phys; 63 dma_addr_t ssi_srx_phys;
71 struct ccsr_dma_channel __iomem *dma_channel[2]; 64 struct ccsr_dma_channel __iomem *channel;
72 unsigned int irq[2]; 65 unsigned int irq;
73 unsigned int assigned[2]; 66 bool assigned;
74} dma_global_data; 67 char path[1];
68};
75 69
76/* 70/*
77 * The number of DMA links to use. Two is the bare minimum, but if you 71 * The number of DMA links to use. Two is the bare minimum, but if you
@@ -88,8 +82,6 @@ static struct {
88 * structure. 82 * structure.
89 * 83 *
90 * @link[]: array of link descriptors 84 * @link[]: array of link descriptors
91 * @controller_id: which DMA controller (0, 1, ...)
92 * @channel_id: which DMA channel on the controller (0, 1, 2, ...)
93 * @dma_channel: pointer to the DMA channel's registers 85 * @dma_channel: pointer to the DMA channel's registers
94 * @irq: IRQ for this DMA channel 86 * @irq: IRQ for this DMA channel
95 * @substream: pointer to the substream object, needed by the ISR 87 * @substream: pointer to the substream object, needed by the ISR
@@ -104,8 +96,6 @@ static struct {
104 */ 96 */
105struct fsl_dma_private { 97struct fsl_dma_private {
106 struct fsl_dma_link_descriptor link[NUM_DMA_LINKS]; 98 struct fsl_dma_link_descriptor link[NUM_DMA_LINKS];
107 unsigned int controller_id;
108 unsigned int channel_id;
109 struct ccsr_dma_channel __iomem *dma_channel; 99 struct ccsr_dma_channel __iomem *dma_channel;
110 unsigned int irq; 100 unsigned int irq;
111 struct snd_pcm_substream *substream; 101 struct snd_pcm_substream *substream;
@@ -212,6 +202,9 @@ static void fsl_dma_update_pointers(struct fsl_dma_private *dma_private)
212static irqreturn_t fsl_dma_isr(int irq, void *dev_id) 202static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
213{ 203{
214 struct fsl_dma_private *dma_private = dev_id; 204 struct fsl_dma_private *dma_private = dev_id;
205 struct snd_pcm_substream *substream = dma_private->substream;
206 struct snd_soc_pcm_runtime *rtd = substream->private_data;
207 struct device *dev = rtd->platform->dev;
215 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; 208 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
216 irqreturn_t ret = IRQ_NONE; 209 irqreturn_t ret = IRQ_NONE;
217 u32 sr, sr2 = 0; 210 u32 sr, sr2 = 0;
@@ -222,11 +215,8 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
222 sr = in_be32(&dma_channel->sr); 215 sr = in_be32(&dma_channel->sr);
223 216
224 if (sr & CCSR_DMA_SR_TE) { 217 if (sr & CCSR_DMA_SR_TE) {
225 dev_err(dma_private->substream->pcm->card->dev, 218 dev_err(dev, "dma transmit error\n");
226 "DMA transmit error (controller=%u channel=%u irq=%u\n", 219 fsl_dma_abort_stream(substream);
227 dma_private->controller_id,
228 dma_private->channel_id, irq);
229 fsl_dma_abort_stream(dma_private->substream);
230 sr2 |= CCSR_DMA_SR_TE; 220 sr2 |= CCSR_DMA_SR_TE;
231 ret = IRQ_HANDLED; 221 ret = IRQ_HANDLED;
232 } 222 }
@@ -235,11 +225,8 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
235 ret = IRQ_HANDLED; 225 ret = IRQ_HANDLED;
236 226
237 if (sr & CCSR_DMA_SR_PE) { 227 if (sr & CCSR_DMA_SR_PE) {
238 dev_err(dma_private->substream->pcm->card->dev, 228 dev_err(dev, "dma programming error\n");
239 "DMA%u programming error (channel=%u irq=%u)\n", 229 fsl_dma_abort_stream(substream);
240 dma_private->controller_id,
241 dma_private->channel_id, irq);
242 fsl_dma_abort_stream(dma_private->substream);
243 sr2 |= CCSR_DMA_SR_PE; 230 sr2 |= CCSR_DMA_SR_PE;
244 ret = IRQ_HANDLED; 231 ret = IRQ_HANDLED;
245 } 232 }
@@ -253,8 +240,6 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
253 ret = IRQ_HANDLED; 240 ret = IRQ_HANDLED;
254 241
255 if (sr & CCSR_DMA_SR_EOSI) { 242 if (sr & CCSR_DMA_SR_EOSI) {
256 struct snd_pcm_substream *substream = dma_private->substream;
257
258 /* Tell ALSA we completed a period. */ 243 /* Tell ALSA we completed a period. */
259 snd_pcm_period_elapsed(substream); 244 snd_pcm_period_elapsed(substream);
260 245
@@ -305,10 +290,8 @@ static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
305 fsl_dma_hardware.buffer_bytes_max, 290 fsl_dma_hardware.buffer_bytes_max,
306 &pcm->streams[0].substream->dma_buffer); 291 &pcm->streams[0].substream->dma_buffer);
307 if (ret) { 292 if (ret) {
308 dev_err(card->dev, 293 dev_err(card->dev, "can't allocate playback dma buffer\n");
309 "Can't allocate playback DMA buffer (size=%u)\n", 294 return ret;
310 fsl_dma_hardware.buffer_bytes_max);
311 return -ENOMEM;
312 } 295 }
313 296
314 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, 297 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
@@ -316,10 +299,8 @@ static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
316 &pcm->streams[1].substream->dma_buffer); 299 &pcm->streams[1].substream->dma_buffer);
317 if (ret) { 300 if (ret) {
318 snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer); 301 snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer);
319 dev_err(card->dev, 302 dev_err(card->dev, "can't allocate capture dma buffer\n");
320 "Can't allocate capture DMA buffer (size=%u)\n", 303 return ret;
321 fsl_dma_hardware.buffer_bytes_max);
322 return -ENOMEM;
323 } 304 }
324 305
325 return 0; 306 return 0;
@@ -390,6 +371,10 @@ static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
390static int fsl_dma_open(struct snd_pcm_substream *substream) 371static int fsl_dma_open(struct snd_pcm_substream *substream)
391{ 372{
392 struct snd_pcm_runtime *runtime = substream->runtime; 373 struct snd_pcm_runtime *runtime = substream->runtime;
374 struct snd_soc_pcm_runtime *rtd = substream->private_data;
375 struct device *dev = rtd->platform->dev;
376 struct dma_object *dma =
377 container_of(rtd->platform->driver, struct dma_object, dai);
393 struct fsl_dma_private *dma_private; 378 struct fsl_dma_private *dma_private;
394 struct ccsr_dma_channel __iomem *dma_channel; 379 struct ccsr_dma_channel __iomem *dma_channel;
395 dma_addr_t ld_buf_phys; 380 dma_addr_t ld_buf_phys;
@@ -407,52 +392,44 @@ static int fsl_dma_open(struct snd_pcm_substream *substream)
407 ret = snd_pcm_hw_constraint_integer(runtime, 392 ret = snd_pcm_hw_constraint_integer(runtime,
408 SNDRV_PCM_HW_PARAM_PERIODS); 393 SNDRV_PCM_HW_PARAM_PERIODS);
409 if (ret < 0) { 394 if (ret < 0) {
410 dev_err(substream->pcm->card->dev, "invalid buffer size\n"); 395 dev_err(dev, "invalid buffer size\n");
411 return ret; 396 return ret;
412 } 397 }
413 398
414 channel = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; 399 channel = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
415 400
416 if (dma_global_data.assigned[channel]) { 401 if (dma->assigned) {
417 dev_err(substream->pcm->card->dev, 402 dev_err(dev, "dma channel already assigned\n");
418 "DMA channel already assigned\n");
419 return -EBUSY; 403 return -EBUSY;
420 } 404 }
421 405
422 dma_private = dma_alloc_coherent(substream->pcm->card->dev, 406 dma_private = dma_alloc_coherent(dev, sizeof(struct fsl_dma_private),
423 sizeof(struct fsl_dma_private), &ld_buf_phys, GFP_KERNEL); 407 &ld_buf_phys, GFP_KERNEL);
424 if (!dma_private) { 408 if (!dma_private) {
425 dev_err(substream->pcm->card->dev, 409 dev_err(dev, "can't allocate dma private data\n");
426 "can't allocate DMA private data\n");
427 return -ENOMEM; 410 return -ENOMEM;
428 } 411 }
429 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 412 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
430 dma_private->ssi_sxx_phys = dma_global_data.ssi_stx_phys; 413 dma_private->ssi_sxx_phys = dma->ssi_stx_phys;
431 else 414 else
432 dma_private->ssi_sxx_phys = dma_global_data.ssi_srx_phys; 415 dma_private->ssi_sxx_phys = dma->ssi_srx_phys;
433 416
434 dma_private->dma_channel = dma_global_data.dma_channel[channel]; 417 dma_private->dma_channel = dma->channel;
435 dma_private->irq = dma_global_data.irq[channel]; 418 dma_private->irq = dma->irq;
436 dma_private->substream = substream; 419 dma_private->substream = substream;
437 dma_private->ld_buf_phys = ld_buf_phys; 420 dma_private->ld_buf_phys = ld_buf_phys;
438 dma_private->dma_buf_phys = substream->dma_buffer.addr; 421 dma_private->dma_buf_phys = substream->dma_buffer.addr;
439 422
440 /* We only support one DMA controller for now */
441 dma_private->controller_id = 0;
442 dma_private->channel_id = channel;
443
444 ret = request_irq(dma_private->irq, fsl_dma_isr, 0, "DMA", dma_private); 423 ret = request_irq(dma_private->irq, fsl_dma_isr, 0, "DMA", dma_private);
445 if (ret) { 424 if (ret) {
446 dev_err(substream->pcm->card->dev, 425 dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
447 "can't register ISR for IRQ %u (ret=%i)\n",
448 dma_private->irq, ret); 426 dma_private->irq, ret);
449 dma_free_coherent(substream->pcm->card->dev, 427 dma_free_coherent(dev, sizeof(struct fsl_dma_private),
450 sizeof(struct fsl_dma_private),
451 dma_private, dma_private->ld_buf_phys); 428 dma_private, dma_private->ld_buf_phys);
452 return ret; 429 return ret;
453 } 430 }
454 431
455 dma_global_data.assigned[channel] = 1; 432 dma->assigned = 1;
456 433
457 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 434 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
458 snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware); 435 snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware);
@@ -546,6 +523,8 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream,
546{ 523{
547 struct snd_pcm_runtime *runtime = substream->runtime; 524 struct snd_pcm_runtime *runtime = substream->runtime;
548 struct fsl_dma_private *dma_private = runtime->private_data; 525 struct fsl_dma_private *dma_private = runtime->private_data;
526 struct snd_soc_pcm_runtime *rtd = substream->private_data;
527 struct device *dev = rtd->platform->dev;
549 528
550 /* Number of bits per sample */ 529 /* Number of bits per sample */
551 unsigned int sample_size = 530 unsigned int sample_size =
@@ -606,8 +585,7 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream,
606 break; 585 break;
607 default: 586 default:
608 /* We should never get here */ 587 /* We should never get here */
609 dev_err(substream->pcm->card->dev, 588 dev_err(dev, "unsupported sample size %u\n", sample_size);
610 "unsupported sample size %u\n", sample_size);
611 return -EINVAL; 589 return -EINVAL;
612 } 590 }
613 591
@@ -689,6 +667,8 @@ static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream)
689{ 667{
690 struct snd_pcm_runtime *runtime = substream->runtime; 668 struct snd_pcm_runtime *runtime = substream->runtime;
691 struct fsl_dma_private *dma_private = runtime->private_data; 669 struct fsl_dma_private *dma_private = runtime->private_data;
670 struct snd_soc_pcm_runtime *rtd = substream->private_data;
671 struct device *dev = rtd->platform->dev;
692 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; 672 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
693 dma_addr_t position; 673 dma_addr_t position;
694 snd_pcm_uframes_t frames; 674 snd_pcm_uframes_t frames;
@@ -710,8 +690,7 @@ static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream)
710 690
711 if ((position < dma_private->dma_buf_phys) || 691 if ((position < dma_private->dma_buf_phys) ||
712 (position > dma_private->dma_buf_end)) { 692 (position > dma_private->dma_buf_end)) {
713 dev_err(substream->pcm->card->dev, 693 dev_err(dev, "dma pointer is out of range, halting stream\n");
714 "dma pointer is out of range, halting stream\n");
715 return SNDRV_PCM_POS_XRUN; 694 return SNDRV_PCM_POS_XRUN;
716 } 695 }
717 696
@@ -772,26 +751,28 @@ static int fsl_dma_close(struct snd_pcm_substream *substream)
772{ 751{
773 struct snd_pcm_runtime *runtime = substream->runtime; 752 struct snd_pcm_runtime *runtime = substream->runtime;
774 struct fsl_dma_private *dma_private = runtime->private_data; 753 struct fsl_dma_private *dma_private = runtime->private_data;
775 int dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; 754 struct snd_soc_pcm_runtime *rtd = substream->private_data;
755 struct device *dev = rtd->platform->dev;
756 struct dma_object *dma =
757 container_of(rtd->platform->driver, struct dma_object, dai);
776 758
777 if (dma_private) { 759 if (dma_private) {
778 if (dma_private->irq) 760 if (dma_private->irq)
779 free_irq(dma_private->irq, dma_private); 761 free_irq(dma_private->irq, dma_private);
780 762
781 if (dma_private->ld_buf_phys) { 763 if (dma_private->ld_buf_phys) {
782 dma_unmap_single(substream->pcm->card->dev, 764 dma_unmap_single(dev, dma_private->ld_buf_phys,
783 dma_private->ld_buf_phys, 765 sizeof(dma_private->link),
784 sizeof(dma_private->link), DMA_TO_DEVICE); 766 DMA_TO_DEVICE);
785 } 767 }
786 768
787 /* Deallocate the fsl_dma_private structure */ 769 /* Deallocate the fsl_dma_private structure */
788 dma_free_coherent(substream->pcm->card->dev, 770 dma_free_coherent(dev, sizeof(struct fsl_dma_private),
789 sizeof(struct fsl_dma_private), 771 dma_private, dma_private->ld_buf_phys);
790 dma_private, dma_private->ld_buf_phys);
791 substream->runtime->private_data = NULL; 772 substream->runtime->private_data = NULL;
792 } 773 }
793 774
794 dma_global_data.assigned[dir] = 0; 775 dma->assigned = 0;
795 776
796 return 0; 777 return 0;
797} 778}
@@ -814,6 +795,40 @@ static void fsl_dma_free_dma_buffers(struct snd_pcm *pcm)
814 } 795 }
815} 796}
816 797
798/* List of DMA nodes that we've probed */
799static LIST_HEAD(dma_list);
800
801/**
802 * find_ssi_node -- returns the SSI node that points to his DMA channel node
803 *
804 * Although this DMA driver attempts to operate independently of the other
805 * devices, it still needs to determine some information about the SSI device
806 * that it's working with. Unfortunately, the device tree does not contain
807 * a pointer from the DMA channel node to the SSI node -- the pointer goes the
808 * other way. So we need to scan the device tree for SSI nodes until we find
809 * the one that points to the given DMA channel node. It's ugly, but at least
810 * it's contained in this one function.
811 */
812static struct device_node *find_ssi_node(struct device_node *dma_channel_np)
813{
814 struct device_node *ssi_np, *np;
815
816 for_each_compatible_node(ssi_np, NULL, "fsl,mpc8610-ssi") {
817 /* Check each DMA phandle to see if it points to us. We
818 * assume that device_node pointers are a valid comparison.
819 */
820 np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0);
821 if (np == dma_channel_np)
822 return ssi_np;
823
824 np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0);
825 if (np == dma_channel_np)
826 return ssi_np;
827 }
828
829 return NULL;
830}
831
817static struct snd_pcm_ops fsl_dma_ops = { 832static struct snd_pcm_ops fsl_dma_ops = {
818 .open = fsl_dma_open, 833 .open = fsl_dma_open,
819 .close = fsl_dma_close, 834 .close = fsl_dma_close,
@@ -823,59 +838,112 @@ static struct snd_pcm_ops fsl_dma_ops = {
823 .pointer = fsl_dma_pointer, 838 .pointer = fsl_dma_pointer,
824}; 839};
825 840
826struct snd_soc_platform fsl_soc_platform = { 841static int __devinit fsl_soc_dma_probe(struct of_device *of_dev,
827 .name = "fsl-dma", 842 const struct of_device_id *match)
828 .pcm_ops = &fsl_dma_ops, 843 {
829 .pcm_new = fsl_dma_new, 844 struct dma_object *dma;
830 .pcm_free = fsl_dma_free_dma_buffers, 845 struct device_node *np = of_dev->dev.of_node;
831}; 846 struct device_node *ssi_np;
832EXPORT_SYMBOL_GPL(fsl_soc_platform); 847 struct resource res;
848 int ret;
833 849
834/** 850 /* Find the SSI node that points to us. */
835 * fsl_dma_configure: store the DMA parameters from the fabric driver. 851 ssi_np = find_ssi_node(np);
836 * 852 if (!ssi_np) {
837 * This function is called by the ASoC fabric driver to give us the DMA and 853 dev_err(&of_dev->dev, "cannot find parent SSI node\n");
838 * SSI channel information. 854 return -ENODEV;
839 * 855 }
840 * Unfortunately, ASoC V1 does make it possible to determine the DMA/SSI 856
841 * data when a substream is created, so for now we need to store this data 857 ret = of_address_to_resource(ssi_np, 0, &res);
842 * into a global variable. This means that we can only support one DMA 858 of_node_put(ssi_np);
843 * controller, and hence only one SSI. 859 if (ret) {
844 */ 860 dev_err(&of_dev->dev, "could not determine device resources\n");
845int fsl_dma_configure(struct fsl_dma_info *dma_info) 861 return ret;
862 }
863
864 dma = kzalloc(sizeof(*dma) + strlen(np->full_name), GFP_KERNEL);
865 if (!dma) {
866 dev_err(&of_dev->dev, "could not allocate dma object\n");
867 return -ENOMEM;
868 }
869
870 strcpy(dma->path, np->full_name);
871 dma->dai.ops = &fsl_dma_ops;
872 dma->dai.pcm_new = fsl_dma_new;
873 dma->dai.pcm_free = fsl_dma_free_dma_buffers;
874
875 /* Store the SSI-specific information that we need */
876 dma->ssi_stx_phys = res.start + offsetof(struct ccsr_ssi, stx0);
877 dma->ssi_srx_phys = res.start + offsetof(struct ccsr_ssi, srx0);
878
879 ret = snd_soc_register_platform(&of_dev->dev, &dma->dai);
880 if (ret) {
881 dev_err(&of_dev->dev, "could not register platform\n");
882 kfree(dma);
883 return ret;
884 }
885
886 dma->channel = of_iomap(np, 0);
887 dma->irq = irq_of_parse_and_map(np, 0);
888 list_add(&dma->list, &dma_list);
889
890 return 0;
891}
892
893static int __devexit fsl_soc_dma_remove(struct of_device *of_dev)
846{ 894{
847 static int initialized; 895 struct list_head *n, *ptr;
896 struct dma_object *dma;
848 897
849 /* We only support one DMA controller for now */ 898 list_for_each_safe(ptr, n, &dma_list) {
850 if (initialized) 899 dma = list_entry(ptr, struct dma_object, list);
851 return 0; 900 list_del_init(ptr);
901
902 snd_soc_unregister_platform(&of_dev->dev);
903 iounmap(dma->channel);
904 irq_dispose_mapping(dma->irq);
905 kfree(dma);
906 }
852 907
853 dma_global_data.ssi_stx_phys = dma_info->ssi_stx_phys; 908 return 0;
854 dma_global_data.ssi_srx_phys = dma_info->ssi_srx_phys;
855 dma_global_data.dma_channel[0] = dma_info->dma_channel[0];
856 dma_global_data.dma_channel[1] = dma_info->dma_channel[1];
857 dma_global_data.irq[0] = dma_info->dma_irq[0];
858 dma_global_data.irq[1] = dma_info->dma_irq[1];
859 dma_global_data.assigned[0] = 0;
860 dma_global_data.assigned[1] = 0;
861
862 initialized = 1;
863 return 1;
864} 909}
865EXPORT_SYMBOL_GPL(fsl_dma_configure);
866 910
867static int __init fsl_soc_platform_init(void) 911static const struct of_device_id fsl_soc_dma_ids[] = {
912 { .compatible = "fsl,ssi-dma-channel", },
913 {}
914};
915MODULE_DEVICE_TABLE(of, fsl_soc_dma_ids);
916
917static struct of_platform_driver fsl_soc_dma_driver = {
918 .driver = {
919 .name = "fsl-pcm-audio",
920 .owner = THIS_MODULE,
921 .of_match_table = fsl_soc_dma_ids,
922 },
923 .probe = fsl_soc_dma_probe,
924 .remove = __devexit_p(fsl_soc_dma_remove),
925};
926
927static int __init fsl_soc_dma_init(void)
868{ 928{
869 return snd_soc_register_platform(&fsl_soc_platform); 929 pr_info("Freescale Elo DMA ASoC PCM Driver\n");
930
931 return of_register_platform_driver(&fsl_soc_dma_driver);
870} 932}
871module_init(fsl_soc_platform_init);
872 933
873static void __exit fsl_soc_platform_exit(void) 934static void __exit fsl_soc_dma_exit(void)
874{ 935{
875 snd_soc_unregister_platform(&fsl_soc_platform); 936 of_unregister_platform_driver(&fsl_soc_dma_driver);
876} 937}
877module_exit(fsl_soc_platform_exit); 938
939/* We want the DMA driver to be initialized before the SSI driver, so that
940 * when the SSI driver calls fsl_soc_dma_dai_from_node(), the DMA driver
941 * will already have been probed. The easiest way to do that is to make the
942 * __init function called via arch_initcall().
943 */
944module_init(fsl_soc_dma_init);
945module_exit(fsl_soc_dma_exit);
878 946
879MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 947MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
880MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM module"); 948MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM Driver");
881MODULE_LICENSE("GPL"); 949MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/fsl_dma.h b/sound/soc/fsl/fsl_dma.h
index 385d4a42603..78fee97e803 100644
--- a/sound/soc/fsl/fsl_dma.h
+++ b/sound/soc/fsl/fsl_dma.h
@@ -126,24 +126,4 @@ struct fsl_dma_link_descriptor {
126 u8 res[4]; /* Reserved */ 126 u8 res[4]; /* Reserved */
127} __attribute__ ((aligned(32), packed)); 127} __attribute__ ((aligned(32), packed));
128 128
129/* DMA information needed to create a snd_soc_dai object
130 *
131 * ssi_stx_phys: bus address of SSI STX register to use
132 * ssi_srx_phys: bus address of SSI SRX register to use
133 * dma[0]: points to the DMA channel to use for playback
134 * dma[1]: points to the DMA channel to use for capture
135 * dma_irq[0]: IRQ of the DMA channel to use for playback
136 * dma_irq[1]: IRQ of the DMA channel to use for capture
137 */
138struct fsl_dma_info {
139 dma_addr_t ssi_stx_phys;
140 dma_addr_t ssi_srx_phys;
141 struct ccsr_dma_channel __iomem *dma_channel[2];
142 unsigned int dma_irq[2];
143};
144
145extern struct snd_soc_platform fsl_soc_platform;
146
147int fsl_dma_configure(struct fsl_dma_info *dma_info);
148
149#endif 129#endif
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 762c1b8e8e4..64f65910a7d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -3,10 +3,11 @@
3 * 3 *
4 * Author: Timur Tabi <timur@freescale.com> 4 * Author: Timur Tabi <timur@freescale.com>
5 * 5 *
6 * Copyright 2007-2008 Freescale Semiconductor, Inc. This file is licensed 6 * Copyright 2007-2010 Freescale Semiconductor, Inc.
7 * under the terms of the GNU General Public License version 2. This 7 *
8 * program is licensed "as is" without any warranty of any kind, whether 8 * This file is licensed under the terms of the GNU General Public License
9 * express or implied. 9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
10 */ 11 */
11 12
12#include <linux/init.h> 13#include <linux/init.h>
@@ -15,6 +16,7 @@
15#include <linux/device.h> 16#include <linux/device.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/of_platform.h>
18 20
19#include <sound/core.h> 21#include <sound/core.h>
20#include <sound/pcm.h> 22#include <sound/pcm.h>
@@ -71,33 +73,31 @@
71/** 73/**
72 * fsl_ssi_private: per-SSI private data 74 * fsl_ssi_private: per-SSI private data
73 * 75 *
74 * @name: short name for this device ("SSI0", "SSI1", etc)
75 * @ssi: pointer to the SSI's registers 76 * @ssi: pointer to the SSI's registers
76 * @ssi_phys: physical address of the SSI registers 77 * @ssi_phys: physical address of the SSI registers
77 * @irq: IRQ of this SSI 78 * @irq: IRQ of this SSI
78 * @first_stream: pointer to the stream that was opened first 79 * @first_stream: pointer to the stream that was opened first
79 * @second_stream: pointer to second stream 80 * @second_stream: pointer to second stream
80 * @dev: struct device pointer
81 * @playback: the number of playback streams opened 81 * @playback: the number of playback streams opened
82 * @capture: the number of capture streams opened 82 * @capture: the number of capture streams opened
83 * @asynchronous: 0=synchronous mode, 1=asynchronous mode 83 * @asynchronous: 0=synchronous mode, 1=asynchronous mode
84 * @cpu_dai: the CPU DAI for this device 84 * @cpu_dai: the CPU DAI for this device
85 * @dev_attr: the sysfs device attribute structure 85 * @dev_attr: the sysfs device attribute structure
86 * @stats: SSI statistics 86 * @stats: SSI statistics
87 * @name: name for this device
87 */ 88 */
88struct fsl_ssi_private { 89struct fsl_ssi_private {
89 char name[8];
90 struct ccsr_ssi __iomem *ssi; 90 struct ccsr_ssi __iomem *ssi;
91 dma_addr_t ssi_phys; 91 dma_addr_t ssi_phys;
92 unsigned int irq; 92 unsigned int irq;
93 struct snd_pcm_substream *first_stream; 93 struct snd_pcm_substream *first_stream;
94 struct snd_pcm_substream *second_stream; 94 struct snd_pcm_substream *second_stream;
95 struct device *dev;
96 unsigned int playback; 95 unsigned int playback;
97 unsigned int capture; 96 unsigned int capture;
98 int asynchronous; 97 int asynchronous;
99 struct snd_soc_dai cpu_dai; 98 struct snd_soc_dai_driver cpu_dai_drv;
100 struct device_attribute dev_attr; 99 struct device_attribute dev_attr;
100 struct platform_device *pdev;
101 101
102 struct { 102 struct {
103 unsigned int rfrc; 103 unsigned int rfrc;
@@ -122,6 +122,8 @@ struct fsl_ssi_private {
122 unsigned int tfe1; 122 unsigned int tfe1;
123 unsigned int tfe0; 123 unsigned int tfe0;
124 } stats; 124 } stats;
125
126 char name[1];
125}; 127};
126 128
127/** 129/**
@@ -280,7 +282,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
280 struct snd_soc_dai *dai) 282 struct snd_soc_dai *dai)
281{ 283{
282 struct snd_soc_pcm_runtime *rtd = substream->private_data; 284 struct snd_soc_pcm_runtime *rtd = substream->private_data;
283 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 285 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
284 286
285 /* 287 /*
286 * If this is the first stream opened, then request the IRQ 288 * If this is the first stream opened, then request the IRQ
@@ -290,6 +292,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
290 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 292 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
291 int ret; 293 int ret;
292 294
295 /* The 'name' should not have any slashes in it. */
293 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, 296 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0,
294 ssi_private->name, ssi_private); 297 ssi_private->name, ssi_private);
295 if (ret < 0) { 298 if (ret < 0) {
@@ -422,7 +425,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
422static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, 425static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
423 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) 426 struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai)
424{ 427{
425 struct fsl_ssi_private *ssi_private = cpu_dai->private_data; 428 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
426 429
427 if (substream == ssi_private->first_stream) { 430 if (substream == ssi_private->first_stream) {
428 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 431 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
@@ -458,7 +461,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
458 struct snd_soc_dai *dai) 461 struct snd_soc_dai *dai)
459{ 462{
460 struct snd_soc_pcm_runtime *rtd = substream->private_data; 463 struct snd_soc_pcm_runtime *rtd = substream->private_data;
461 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 464 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
462 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 465 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
463 466
464 switch (cmd) { 467 switch (cmd) {
@@ -497,7 +500,7 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
497 struct snd_soc_dai *dai) 500 struct snd_soc_dai *dai)
498{ 501{
499 struct snd_soc_pcm_runtime *rtd = substream->private_data; 502 struct snd_soc_pcm_runtime *rtd = substream->private_data;
500 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 503 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
501 504
502 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 505 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
503 ssi_private->playback--; 506 ssi_private->playback--;
@@ -523,56 +526,15 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
523 } 526 }
524} 527}
525 528
526/**
527 * fsl_ssi_set_sysclk: set the clock frequency and direction
528 *
529 * This function is called by the machine driver to tell us what the clock
530 * frequency and direction are.
531 *
532 * Currently, we only support operating as a clock slave (SND_SOC_CLOCK_IN),
533 * and we don't care about the frequency. Return an error if the direction
534 * is not SND_SOC_CLOCK_IN.
535 *
536 * @clk_id: reserved, should be zero
537 * @freq: the frequency of the given clock ID, currently ignored
538 * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master)
539 */
540static int fsl_ssi_set_sysclk(struct snd_soc_dai *cpu_dai,
541 int clk_id, unsigned int freq, int dir)
542{
543
544 return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL;
545}
546
547/**
548 * fsl_ssi_set_fmt: set the serial format.
549 *
550 * This function is called by the machine driver to tell us what serial
551 * format to use.
552 *
553 * Currently, we only support I2S mode. Return an error if the format is
554 * not SND_SOC_DAIFMT_I2S.
555 *
556 * @format: one of SND_SOC_DAIFMT_xxx
557 */
558static int fsl_ssi_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
559{
560 return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL;
561}
562
563/**
564 * fsl_ssi_dai_template: template CPU DAI for the SSI
565 */
566static struct snd_soc_dai_ops fsl_ssi_dai_ops = { 529static struct snd_soc_dai_ops fsl_ssi_dai_ops = {
567 .startup = fsl_ssi_startup, 530 .startup = fsl_ssi_startup,
568 .hw_params = fsl_ssi_hw_params, 531 .hw_params = fsl_ssi_hw_params,
569 .shutdown = fsl_ssi_shutdown, 532 .shutdown = fsl_ssi_shutdown,
570 .trigger = fsl_ssi_trigger, 533 .trigger = fsl_ssi_trigger,
571 .set_sysclk = fsl_ssi_set_sysclk,
572 .set_fmt = fsl_ssi_set_fmt,
573}; 534};
574 535
575static struct snd_soc_dai fsl_ssi_dai_template = { 536/* Template for the CPU dai driver structure */
537static struct snd_soc_dai_driver fsl_ssi_dai_template = {
576 .playback = { 538 .playback = {
577 /* The SSI does not support monaural audio. */ 539 /* The SSI does not support monaural audio. */
578 .channels_min = 2, 540 .channels_min = 2,
@@ -640,95 +602,176 @@ static ssize_t fsl_sysfs_ssi_show(struct device *dev,
640} 602}
641 603
642/** 604/**
643 * fsl_ssi_create_dai: create a snd_soc_dai structure 605 * Make every character in a string lower-case
644 *
645 * This function is called by the machine driver to create a snd_soc_dai
646 * structure. The function creates an ssi_private object, which contains
647 * the snd_soc_dai. It also creates the sysfs statistics device.
648 */ 606 */
649struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info) 607static void make_lowercase(char *s)
608{
609 char *p = s;
610 char c;
611
612 while ((c = *p)) {
613 if ((c >= 'A') && (c <= 'Z'))
614 *p = c + ('a' - 'A');
615 p++;
616 }
617}
618
619static int __devinit fsl_ssi_probe(struct of_device *of_dev,
620 const struct of_device_id *match)
650{ 621{
651 struct snd_soc_dai *fsl_ssi_dai;
652 struct fsl_ssi_private *ssi_private; 622 struct fsl_ssi_private *ssi_private;
653 int ret = 0; 623 int ret = 0;
654 struct device_attribute *dev_attr; 624 struct device_attribute *dev_attr;
625 struct device_node *np = of_dev->dev.of_node;
626 const char *p, *sprop;
627 struct resource res;
628 char name[64];
655 629
656 ssi_private = kzalloc(sizeof(struct fsl_ssi_private), GFP_KERNEL); 630 /* We are only interested in SSIs with a codec phandle in them, so let's
631 * make sure this SSI has one.
632 */
633 if (!of_get_property(np, "codec-handle", NULL))
634 return -ENODEV;
635
636 /* We only support the SSI in "I2S Slave" mode */
637 sprop = of_get_property(np, "fsl,mode", NULL);
638 if (!sprop || strcmp(sprop, "i2s-slave")) {
639 dev_notice(&of_dev->dev, "mode %s is unsupported\n", sprop);
640 return -ENODEV;
641 }
642
643 /* The DAI name is the last part of the full name of the node. */
644 p = strrchr(np->full_name, '/') + 1;
645 ssi_private = kzalloc(sizeof(struct fsl_ssi_private) + strlen(p),
646 GFP_KERNEL);
657 if (!ssi_private) { 647 if (!ssi_private) {
658 dev_err(ssi_info->dev, "could not allocate DAI object\n"); 648 dev_err(&of_dev->dev, "could not allocate DAI object\n");
659 return NULL; 649 return -ENOMEM;
660 } 650 }
661 memcpy(&ssi_private->cpu_dai, &fsl_ssi_dai_template,
662 sizeof(struct snd_soc_dai));
663 651
664 fsl_ssi_dai = &ssi_private->cpu_dai; 652 strcpy(ssi_private->name, p);
665 dev_attr = &ssi_private->dev_attr;
666 653
667 sprintf(ssi_private->name, "ssi%u", (u8) ssi_info->id); 654 /* Initialize this copy of the CPU DAI driver structure */
668 ssi_private->ssi = ssi_info->ssi; 655 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
669 ssi_private->ssi_phys = ssi_info->ssi_phys; 656 sizeof(fsl_ssi_dai_template));
670 ssi_private->irq = ssi_info->irq; 657 ssi_private->cpu_dai_drv.name = ssi_private->name;
671 ssi_private->dev = ssi_info->dev; 658
672 ssi_private->asynchronous = ssi_info->asynchronous; 659 /* Get the addresses and IRQ */
660 ret = of_address_to_resource(np, 0, &res);
661 if (ret) {
662 dev_err(&of_dev->dev, "could not determine device resources\n");
663 kfree(ssi_private);
664 return ret;
665 }
666 ssi_private->ssi = ioremap(res.start, 1 + res.end - res.start);
667 ssi_private->ssi_phys = res.start;
668 ssi_private->irq = irq_of_parse_and_map(np, 0);
673 669
674 dev_set_drvdata(ssi_private->dev, fsl_ssi_dai); 670 /* Are the RX and the TX clocks locked? */
671 if (of_find_property(np, "fsl,ssi-asynchronous", NULL))
672 ssi_private->asynchronous = 1;
673 else
674 ssi_private->cpu_dai_drv.symmetric_rates = 1;
675 675
676 /* Initialize the the device_attribute structure */ 676 /* Initialize the the device_attribute structure */
677 dev_attr->attr.name = "ssi-stats"; 677 dev_attr = &ssi_private->dev_attr;
678 dev_attr->attr.name = "statistics";
678 dev_attr->attr.mode = S_IRUGO; 679 dev_attr->attr.mode = S_IRUGO;
679 dev_attr->show = fsl_sysfs_ssi_show; 680 dev_attr->show = fsl_sysfs_ssi_show;
680 681
681 ret = device_create_file(ssi_private->dev, dev_attr); 682 ret = device_create_file(&of_dev->dev, dev_attr);
682 if (ret) { 683 if (ret) {
683 dev_err(ssi_info->dev, "could not create sysfs %s file\n", 684 dev_err(&of_dev->dev, "could not create sysfs %s file\n",
684 ssi_private->dev_attr.attr.name); 685 ssi_private->dev_attr.attr.name);
685 kfree(fsl_ssi_dai); 686 kfree(ssi_private);
686 return NULL; 687 return ret;
687 } 688 }
688 689
689 fsl_ssi_dai->private_data = ssi_private; 690 /* Register with ASoC */
690 fsl_ssi_dai->name = ssi_private->name; 691 dev_set_drvdata(&of_dev->dev, ssi_private);
691 fsl_ssi_dai->id = ssi_info->id;
692 fsl_ssi_dai->dev = ssi_info->dev;
693 fsl_ssi_dai->symmetric_rates = 1;
694 692
695 ret = snd_soc_register_dai(fsl_ssi_dai); 693 ret = snd_soc_register_dai(&of_dev->dev, &ssi_private->cpu_dai_drv);
696 if (ret != 0) { 694 if (ret != 0) {
697 dev_err(ssi_info->dev, "failed to register DAI: %d\n", ret); 695 dev_err(&of_dev->dev, "failed to register DAI: %d\n", ret);
698 kfree(fsl_ssi_dai); 696 kfree(ssi_private);
699 return NULL; 697 return ret;
698 }
699
700 /* Trigger the machine driver's probe function. The platform driver
701 * name of the machine driver is taken from the /model property of the
702 * device tree. We also pass the address of the CPU DAI driver
703 * structure.
704 */
705 sprop = of_get_property(of_find_node_by_path("/"), "model", NULL);
706 /* Sometimes the model name has a "fsl," prefix, so we strip that. */
707 p = strrchr(sprop, ',');
708 if (p)
709 sprop = p + 1;
710 snprintf(name, sizeof(name), "snd-soc-%s", sprop);
711 make_lowercase(name);
712
713 ssi_private->pdev =
714 platform_device_register_data(&of_dev->dev, name, 0, NULL, 0);
715 if (IS_ERR(ssi_private->pdev)) {
716 ret = PTR_ERR(ssi_private->pdev);
717 dev_err(&of_dev->dev, "failed to register platform: %d\n", ret);
718 kfree(ssi_private);
719 return ret;
700 } 720 }
701 721
702 return fsl_ssi_dai; 722 return 0;
703} 723}
704EXPORT_SYMBOL_GPL(fsl_ssi_create_dai);
705 724
706/** 725/**
707 * fsl_ssi_destroy_dai: destroy the snd_soc_dai object 726 * fsl_ssi_destroy_dai: destroy the snd_soc_dai object
708 * 727 *
709 * This function undoes the operations of fsl_ssi_create_dai() 728 * This function undoes the operations of fsl_ssi_probe()
710 */ 729 */
711void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai) 730static int fsl_ssi_remove(struct of_device *of_dev)
712{ 731{
713 struct fsl_ssi_private *ssi_private = 732 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&of_dev->dev);
714 container_of(fsl_ssi_dai, struct fsl_ssi_private, cpu_dai);
715 733
716 device_remove_file(ssi_private->dev, &ssi_private->dev_attr); 734 platform_device_unregister(ssi_private->pdev);
717 735 snd_soc_unregister_dai(&of_dev->dev);
718 snd_soc_unregister_dai(&ssi_private->cpu_dai); 736 device_remove_file(&of_dev->dev, &ssi_private->dev_attr);
719 737
720 kfree(ssi_private); 738 kfree(ssi_private);
739 dev_set_drvdata(&of_dev->dev, NULL);
740
741 return 0;
721} 742}
722EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai); 743
744static const struct of_device_id fsl_ssi_ids[] = {
745 { .compatible = "fsl,mpc8610-ssi", },
746 {}
747};
748MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
749
750static struct of_platform_driver fsl_ssi_driver = {
751 .driver = {
752 .name = "fsl-ssi-dai",
753 .owner = THIS_MODULE,
754 .of_match_table = fsl_ssi_ids,
755 },
756 .probe = fsl_ssi_probe,
757 .remove = fsl_ssi_remove,
758};
723 759
724static int __init fsl_ssi_init(void) 760static int __init fsl_ssi_init(void)
725{ 761{
726 printk(KERN_INFO "Freescale Synchronous Serial Interface (SSI) ASoC Driver\n"); 762 printk(KERN_INFO "Freescale Synchronous Serial Interface (SSI) ASoC Driver\n");
727 763
728 return 0; 764 return of_register_platform_driver(&fsl_ssi_driver);
765}
766
767static void __exit fsl_ssi_exit(void)
768{
769 of_unregister_platform_driver(&fsl_ssi_driver);
729} 770}
771
730module_init(fsl_ssi_init); 772module_init(fsl_ssi_init);
773module_exit(fsl_ssi_exit);
731 774
732MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 775MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
733MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver"); 776MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver");
734MODULE_LICENSE("GPL"); 777MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index eade01feaab..217300029b5 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -196,31 +196,5 @@ struct ccsr_ssi {
196#define CCSR_SSI_SOR_WAIT(x) (((x) & 3) << CCSR_SSI_SOR_WAIT_SHIFT) 196#define CCSR_SSI_SOR_WAIT(x) (((x) & 3) << CCSR_SSI_SOR_WAIT_SHIFT)
197#define CCSR_SSI_SOR_SYNRST 0x00000001 197#define CCSR_SSI_SOR_SYNRST 0x00000001
198 198
199/* Instantiation data for an SSI interface
200 *
201 * This structure contains all the information that the the SSI driver needs
202 * to instantiate an SSI interface with ALSA. The machine driver should
203 * create this structure, fill it in, call fsl_ssi_create_dai(), and then
204 * delete the structure.
205 *
206 * id: which SSI this is (0, 1, etc. )
207 * ssi: pointer to the SSI's registers
208 * ssi_phys: physical address of the SSI registers
209 * irq: IRQ of this SSI
210 * dev: struct device, used to create the sysfs statistics file
211 * asynchronous: 0=synchronous mode, 1=asynchronous mode
212*/
213struct fsl_ssi_info {
214 unsigned int id;
215 struct ccsr_ssi __iomem *ssi;
216 dma_addr_t ssi_phys;
217 unsigned int irq;
218 struct device *dev;
219 int asynchronous;
220};
221
222struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info);
223void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai);
224
225#endif 199#endif
226 200
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 1d4e7164e80..dce6b551cd7 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -9,6 +9,8 @@
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/of_device.h> 10#include <linux/of_device.h>
11#include <linux/slab.h> 11#include <linux/slab.h>
12#include <linux/of_device.h>
13#include <linux/of_platform.h>
12 14
13#include <sound/soc.h> 15#include <sound/soc.h>
14 16
@@ -107,7 +109,7 @@ static int psc_dma_hw_free(struct snd_pcm_substream *substream)
107static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd) 109static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
108{ 110{
109 struct snd_soc_pcm_runtime *rtd = substream->private_data; 111 struct snd_soc_pcm_runtime *rtd = substream->private_data;
110 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 112 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
111 struct snd_pcm_runtime *runtime = substream->runtime; 113 struct snd_pcm_runtime *runtime = substream->runtime;
112 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma); 114 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
113 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; 115 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
@@ -212,7 +214,7 @@ static int psc_dma_open(struct snd_pcm_substream *substream)
212{ 214{
213 struct snd_pcm_runtime *runtime = substream->runtime; 215 struct snd_pcm_runtime *runtime = substream->runtime;
214 struct snd_soc_pcm_runtime *rtd = substream->private_data; 216 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 217 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
216 struct psc_dma_stream *s; 218 struct psc_dma_stream *s;
217 int rc; 219 int rc;
218 220
@@ -239,7 +241,7 @@ static int psc_dma_open(struct snd_pcm_substream *substream)
239static int psc_dma_close(struct snd_pcm_substream *substream) 241static int psc_dma_close(struct snd_pcm_substream *substream)
240{ 242{
241 struct snd_soc_pcm_runtime *rtd = substream->private_data; 243 struct snd_soc_pcm_runtime *rtd = substream->private_data;
242 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 244 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
243 struct psc_dma_stream *s; 245 struct psc_dma_stream *s;
244 246
245 dev_dbg(psc_dma->dev, "psc_dma_close(substream=%p)\n", substream); 247 dev_dbg(psc_dma->dev, "psc_dma_close(substream=%p)\n", substream);
@@ -264,7 +266,7 @@ static snd_pcm_uframes_t
264psc_dma_pointer(struct snd_pcm_substream *substream) 266psc_dma_pointer(struct snd_pcm_substream *substream)
265{ 267{
266 struct snd_soc_pcm_runtime *rtd = substream->private_data; 268 struct snd_soc_pcm_runtime *rtd = substream->private_data;
267 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 269 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
268 struct psc_dma_stream *s; 270 struct psc_dma_stream *s;
269 dma_addr_t count; 271 dma_addr_t count;
270 272
@@ -302,11 +304,11 @@ static int psc_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
302 struct snd_pcm *pcm) 304 struct snd_pcm *pcm)
303{ 305{
304 struct snd_soc_pcm_runtime *rtd = pcm->private_data; 306 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
305 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 307 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
306 size_t size = psc_dma_hardware.buffer_bytes_max; 308 size_t size = psc_dma_hardware.buffer_bytes_max;
307 int rc = 0; 309 int rc = 0;
308 310
309 dev_dbg(rtd->socdev->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n", 311 dev_dbg(rtd->platform->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n",
310 card, dai, pcm); 312 card, dai, pcm);
311 313
312 if (!card->dev->dma_mask) 314 if (!card->dev->dma_mask)
@@ -328,8 +330,8 @@ static int psc_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
328 goto capture_alloc_err; 330 goto capture_alloc_err;
329 } 331 }
330 332
331 if (rtd->socdev->card->codec->ac97) 333 if (rtd->codec->ac97)
332 rtd->socdev->card->codec->ac97->private_data = psc_dma; 334 rtd->codec->ac97->private_data = psc_dma;
333 335
334 return 0; 336 return 0;
335 337
@@ -349,7 +351,7 @@ static void psc_dma_free(struct snd_pcm *pcm)
349 struct snd_pcm_substream *substream; 351 struct snd_pcm_substream *substream;
350 int stream; 352 int stream;
351 353
352 dev_dbg(rtd->socdev->dev, "psc_dma_free(pcm=%p)\n", pcm); 354 dev_dbg(rtd->platform->dev, "psc_dma_free(pcm=%p)\n", pcm);
353 355
354 for (stream = 0; stream < 2; stream++) { 356 for (stream = 0; stream < 2; stream++) {
355 substream = pcm->streams[stream].substream; 357 substream = pcm->streams[stream].substream;
@@ -361,15 +363,14 @@ static void psc_dma_free(struct snd_pcm *pcm)
361 } 363 }
362} 364}
363 365
364struct snd_soc_platform mpc5200_audio_dma_platform = { 366static struct snd_soc_platform_driver mpc5200_audio_dma_platform = {
365 .name = "mpc5200-psc-audio", 367 .ops = &psc_dma_ops,
366 .pcm_ops = &psc_dma_ops,
367 .pcm_new = &psc_dma_new, 368 .pcm_new = &psc_dma_new,
368 .pcm_free = &psc_dma_free, 369 .pcm_free = &psc_dma_free,
369}; 370};
370EXPORT_SYMBOL_GPL(mpc5200_audio_dma_platform);
371 371
372int mpc5200_audio_dma_create(struct of_device *op) 372static int mpc5200_hpcd_probe(struct of_device *op,
373 const struct of_device_id *match)
373{ 374{
374 phys_addr_t fifo; 375 phys_addr_t fifo;
375 struct psc_dma *psc_dma; 376 struct psc_dma *psc_dma;
@@ -475,7 +476,7 @@ int mpc5200_audio_dma_create(struct of_device *op)
475 dev_set_drvdata(&op->dev, psc_dma); 476 dev_set_drvdata(&op->dev, psc_dma);
476 477
477 /* Tell the ASoC OF helpers about it */ 478 /* Tell the ASoC OF helpers about it */
478 return snd_soc_register_platform(&mpc5200_audio_dma_platform); 479 return snd_soc_register_platform(&op->dev, &mpc5200_audio_dma_platform);
479out_irq: 480out_irq:
480 free_irq(psc_dma->irq, psc_dma); 481 free_irq(psc_dma->irq, psc_dma);
481 free_irq(psc_dma->capture.irq, &psc_dma->capture); 482 free_irq(psc_dma->capture.irq, &psc_dma->capture);
@@ -486,15 +487,14 @@ out_unmap:
486 iounmap(regs); 487 iounmap(regs);
487 return ret; 488 return ret;
488} 489}
489EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create);
490 490
491int mpc5200_audio_dma_destroy(struct of_device *op) 491static int mpc5200_hpcd_remove(struct of_device *op)
492{ 492{
493 struct psc_dma *psc_dma = dev_get_drvdata(&op->dev); 493 struct psc_dma *psc_dma = dev_get_drvdata(&op->dev);
494 494
495 dev_dbg(&op->dev, "mpc5200_audio_dma_destroy()\n"); 495 dev_dbg(&op->dev, "mpc5200_audio_dma_destroy()\n");
496 496
497 snd_soc_unregister_platform(&mpc5200_audio_dma_platform); 497 snd_soc_unregister_platform(&op->dev);
498 498
499 bcom_gen_bd_rx_release(psc_dma->capture.bcom_task); 499 bcom_gen_bd_rx_release(psc_dma->capture.bcom_task);
500 bcom_gen_bd_tx_release(psc_dma->playback.bcom_task); 500 bcom_gen_bd_tx_release(psc_dma->playback.bcom_task);
@@ -510,7 +510,35 @@ int mpc5200_audio_dma_destroy(struct of_device *op)
510 510
511 return 0; 511 return 0;
512} 512}
513EXPORT_SYMBOL_GPL(mpc5200_audio_dma_destroy); 513
514static struct of_device_id mpc5200_hpcd_match[] = {
515 {
516 .compatible = "fsl,mpc5200-pcm",
517 },
518 {}
519};
520MODULE_DEVICE_TABLE(of, mpc5200_hpcd_match);
521
522static struct of_platform_driver mpc5200_hpcd_of_driver = {
523 .owner = THIS_MODULE,
524 .name = "mpc5200-pcm-audio",
525 .match_table = mpc5200_hpcd_match,
526 .probe = mpc5200_hpcd_probe,
527 .remove = mpc5200_hpcd_remove,
528};
529
530static int __init mpc5200_hpcd_init(void)
531{
532 return of_register_platform_driver(&mpc5200_hpcd_of_driver);
533}
534
535static void __exit mpc5200_hpcd_exit(void)
536{
537 of_unregister_platform_driver(&mpc5200_hpcd_of_driver);
538}
539
540module_init(mpc5200_hpcd_init);
541module_exit(mpc5200_hpcd_exit);
514 542
515MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>"); 543MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
516MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver"); 544MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver");
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h
index 22208b373fb..7472531bc2a 100644
--- a/sound/soc/fsl/mpc5200_dma.h
+++ b/sound/soc/fsl/mpc5200_dma.h
@@ -81,9 +81,4 @@ to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma)
81 return &psc_dma->playback; 81 return &psc_dma->playback;
82} 82}
83 83
84int mpc5200_audio_dma_create(struct of_device *op);
85int mpc5200_audio_dma_destroy(struct of_device *op);
86
87extern struct snd_soc_platform mpc5200_audio_dma_platform;
88
89#endif /* __SOUND_SOC_FSL_MPC5200_DMA_H__ */ 84#endif /* __SOUND_SOC_FSL_MPC5200_DMA_H__ */
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index e2ee220bfb7..11706c128c0 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -129,7 +129,7 @@ static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
129 struct snd_pcm_hw_params *params, 129 struct snd_pcm_hw_params *params,
130 struct snd_soc_dai *cpu_dai) 130 struct snd_soc_dai *cpu_dai)
131{ 131{
132 struct psc_dma *psc_dma = cpu_dai->private_data; 132 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
133 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma); 133 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
134 134
135 dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i" 135 dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
@@ -152,7 +152,7 @@ static int psc_ac97_hw_digital_params(struct snd_pcm_substream *substream,
152 struct snd_pcm_hw_params *params, 152 struct snd_pcm_hw_params *params,
153 struct snd_soc_dai *cpu_dai) 153 struct snd_soc_dai *cpu_dai)
154{ 154{
155 struct psc_dma *psc_dma = cpu_dai->private_data; 155 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
156 156
157 dev_dbg(psc_dma->dev, "%s(substream=%p)\n", __func__, substream); 157 dev_dbg(psc_dma->dev, "%s(substream=%p)\n", __func__, substream);
158 158
@@ -167,8 +167,7 @@ static int psc_ac97_hw_digital_params(struct snd_pcm_substream *substream,
167static int psc_ac97_trigger(struct snd_pcm_substream *substream, int cmd, 167static int psc_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
168 struct snd_soc_dai *dai) 168 struct snd_soc_dai *dai)
169{ 169{
170 struct snd_soc_pcm_runtime *rtd = substream->private_data; 170 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(dai);
171 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
172 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma); 171 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
173 172
174 switch (cmd) { 173 switch (cmd) {
@@ -193,10 +192,9 @@ static int psc_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
193 return 0; 192 return 0;
194} 193}
195 194
196static int psc_ac97_probe(struct platform_device *pdev, 195static int psc_ac97_probe(struct snd_soc_dai *cpu_dai)
197 struct snd_soc_dai *cpu_dai)
198{ 196{
199 struct psc_dma *psc_dma = cpu_dai->private_data; 197 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
200 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; 198 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
201 199
202 /* Go */ 200 /* Go */
@@ -223,9 +221,8 @@ static struct snd_soc_dai_ops psc_ac97_digital_ops = {
223 .hw_params = psc_ac97_hw_digital_params, 221 .hw_params = psc_ac97_hw_digital_params,
224}; 222};
225 223
226struct snd_soc_dai psc_ac97_dai[] = { 224static struct snd_soc_dai_driver psc_ac97_dai[] = {
227{ 225{
228 .name = "AC97",
229 .ac97_control = 1, 226 .ac97_control = 1,
230 .probe = psc_ac97_probe, 227 .probe = psc_ac97_probe,
231 .playback = { 228 .playback = {
@@ -243,7 +240,6 @@ struct snd_soc_dai psc_ac97_dai[] = {
243 .ops = &psc_ac97_analog_ops, 240 .ops = &psc_ac97_analog_ops,
244}, 241},
245{ 242{
246 .name = "SPDIF",
247 .ac97_control = 1, 243 .ac97_control = 1,
248 .playback = { 244 .playback = {
249 .channels_min = 1, 245 .channels_min = 1,
@@ -254,7 +250,6 @@ struct snd_soc_dai psc_ac97_dai[] = {
254 }, 250 },
255 .ops = &psc_ac97_digital_ops, 251 .ops = &psc_ac97_digital_ops,
256} }; 252} };
257EXPORT_SYMBOL_GPL(psc_ac97_dai);
258 253
259 254
260 255
@@ -266,18 +261,11 @@ EXPORT_SYMBOL_GPL(psc_ac97_dai);
266static int __devinit psc_ac97_of_probe(struct of_device *op, 261static int __devinit psc_ac97_of_probe(struct of_device *op,
267 const struct of_device_id *match) 262 const struct of_device_id *match)
268{ 263{
269 int rc, i; 264 int rc;
270 struct snd_ac97 ac97; 265 struct snd_ac97 ac97;
271 struct mpc52xx_psc __iomem *regs; 266 struct mpc52xx_psc __iomem *regs;
272 267
273 rc = mpc5200_audio_dma_create(op); 268 rc = snd_soc_register_dais(&op->dev, psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
274 if (rc != 0)
275 return rc;
276
277 for (i = 0; i < ARRAY_SIZE(psc_ac97_dai); i++)
278 psc_ac97_dai[i].dev = &op->dev;
279
280 rc = snd_soc_register_dais(psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
281 if (rc != 0) { 269 if (rc != 0) {
282 dev_err(&op->dev, "Failed to register DAI\n"); 270 dev_err(&op->dev, "Failed to register DAI\n");
283 return rc; 271 return rc;
@@ -287,9 +275,6 @@ static int __devinit psc_ac97_of_probe(struct of_device *op,
287 regs = psc_dma->psc_regs; 275 regs = psc_dma->psc_regs;
288 ac97.private_data = psc_dma; 276 ac97.private_data = psc_dma;
289 277
290 for (i = 0; i < ARRAY_SIZE(psc_ac97_dai); i++)
291 psc_ac97_dai[i].private_data = psc_dma;
292
293 psc_dma->imr = 0; 278 psc_dma->imr = 0;
294 out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr); 279 out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr);
295 280
@@ -305,7 +290,8 @@ static int __devinit psc_ac97_of_probe(struct of_device *op,
305 290
306static int __devexit psc_ac97_of_remove(struct of_device *op) 291static int __devexit psc_ac97_of_remove(struct of_device *op)
307{ 292{
308 return mpc5200_audio_dma_destroy(op); 293 snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai));
294 return 0;
309} 295}
310 296
311/* Match table for of_platform binding */ 297/* Match table for of_platform binding */
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.h b/sound/soc/fsl/mpc5200_psc_ac97.h
index 4bc18c35c36..e881e784b27 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.h
+++ b/sound/soc/fsl/mpc5200_psc_ac97.h
@@ -7,8 +7,6 @@
7#ifndef __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__ 7#ifndef __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__
8#define __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__ 8#define __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__
9 9
10extern struct snd_soc_dai psc_ac97_dai[];
11
12#define MPC5200_AC97_NORMAL 0 10#define MPC5200_AC97_NORMAL 0
13#define MPC5200_AC97_SPDIF 1 11#define MPC5200_AC97_SPDIF 1
14 12
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 676841cbae9..5b9f2c73f03 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -40,7 +40,7 @@ static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
40 struct snd_soc_dai *dai) 40 struct snd_soc_dai *dai)
41{ 41{
42 struct snd_soc_pcm_runtime *rtd = substream->private_data; 42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
43 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 43 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
44 u32 mode; 44 u32 mode;
45 45
46 dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i" 46 dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
@@ -88,7 +88,7 @@ static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
88static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, 88static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
89 int clk_id, unsigned int freq, int dir) 89 int clk_id, unsigned int freq, int dir)
90{ 90{
91 struct psc_dma *psc_dma = cpu_dai->private_data; 91 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
92 dev_dbg(psc_dma->dev, "psc_i2s_set_sysclk(cpu_dai=%p, dir=%i)\n", 92 dev_dbg(psc_dma->dev, "psc_i2s_set_sysclk(cpu_dai=%p, dir=%i)\n",
93 cpu_dai, dir); 93 cpu_dai, dir);
94 return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL; 94 return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL;
@@ -107,7 +107,7 @@ static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
107 */ 107 */
108static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format) 108static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
109{ 109{
110 struct psc_dma *psc_dma = cpu_dai->private_data; 110 struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(cpu_dai);
111 dev_dbg(psc_dma->dev, "psc_i2s_set_fmt(cpu_dai=%p, format=%i)\n", 111 dev_dbg(psc_dma->dev, "psc_i2s_set_fmt(cpu_dai=%p, format=%i)\n",
112 cpu_dai, format); 112 cpu_dai, format);
113 return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL; 113 return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL;
@@ -129,8 +129,7 @@ static struct snd_soc_dai_ops psc_i2s_dai_ops = {
129 .set_fmt = psc_i2s_set_fmt, 129 .set_fmt = psc_i2s_set_fmt,
130}; 130};
131 131
132struct snd_soc_dai psc_i2s_dai[] = {{ 132static struct snd_soc_dai_driver psc_i2s_dai[] = {{
133 .name = "I2S",
134 .playback = { 133 .playback = {
135 .channels_min = 2, 134 .channels_min = 2,
136 .channels_max = 2, 135 .channels_max = 2,
@@ -145,7 +144,6 @@ struct snd_soc_dai psc_i2s_dai[] = {{
145 }, 144 },
146 .ops = &psc_i2s_dai_ops, 145 .ops = &psc_i2s_dai_ops,
147} }; 146} };
148EXPORT_SYMBOL_GPL(psc_i2s_dai);
149 147
150/* --------------------------------------------------------------------- 148/* ---------------------------------------------------------------------
151 * OF platform bus binding code: 149 * OF platform bus binding code:
@@ -159,11 +157,7 @@ static int __devinit psc_i2s_of_probe(struct of_device *op,
159 struct psc_dma *psc_dma; 157 struct psc_dma *psc_dma;
160 struct mpc52xx_psc __iomem *regs; 158 struct mpc52xx_psc __iomem *regs;
161 159
162 rc = mpc5200_audio_dma_create(op); 160 rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
163 if (rc != 0)
164 return rc;
165
166 rc = snd_soc_register_dais(psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
167 if (rc != 0) { 161 if (rc != 0) {
168 pr_err("Failed to register DAI\n"); 162 pr_err("Failed to register DAI\n");
169 return 0; 163 return 0;
@@ -207,7 +201,8 @@ static int __devinit psc_i2s_of_probe(struct of_device *op,
207 201
208static int __devexit psc_i2s_of_remove(struct of_device *op) 202static int __devexit psc_i2s_of_remove(struct of_device *op)
209{ 203{
210 return mpc5200_audio_dma_destroy(op); 204 snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai));
205 return 0;
211} 206}
212 207
213/* Match table for of_platform binding */ 208/* Match table for of_platform binding */
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 6a2764ee820..5ba823213ab 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -1,85 +1,96 @@
1/** 1/**
2 * Freescale MPC8610HPCD ALSA SoC Fabric driver 2 * Freescale MPC8610HPCD ALSA SoC Machine driver
3 * 3 *
4 * Author: Timur Tabi <timur@freescale.com> 4 * Author: Timur Tabi <timur@freescale.com>
5 * 5 *
6 * Copyright 2007-2008 Freescale Semiconductor, Inc. This file is licensed 6 * Copyright 2007-2010 Freescale Semiconductor, Inc.
7 * under the terms of the GNU General Public License version 2. This 7 *
8 * program is licensed "as is" without any warranty of any kind, whether 8 * This file is licensed under the terms of the GNU General Public License
9 * express or implied. 9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
10 */ 11 */
11 12
12#include <linux/slab.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/of_device.h> 15#include <linux/of_device.h>
16#include <linux/of_platform.h>
17#include <sound/soc.h> 16#include <sound/soc.h>
18#include <asm/immap_86xx.h> 17#include <asm/immap_86xx.h>
19 18
20#include "../codecs/cs4270.h"
21#include "fsl_dma.h" 19#include "fsl_dma.h"
22#include "fsl_ssi.h" 20#include "fsl_ssi.h"
23 21
22/* There's only one global utilities register */
23static phys_addr_t guts_phys;
24
25#define DAI_NAME_SIZE 32
26
24/** 27/**
25 * mpc8610_hpcd_data: fabric-specific ASoC device data 28 * mpc8610_hpcd_data: machine-specific ASoC device data
26 * 29 *
27 * This structure contains data for a single sound platform device on an 30 * This structure contains data for a single sound platform device on an
28 * MPC8610 HPCD. Some of the data is taken from the device tree. 31 * MPC8610 HPCD. Some of the data is taken from the device tree.
29 */ 32 */
30struct mpc8610_hpcd_data { 33struct mpc8610_hpcd_data {
31 struct snd_soc_device sound_devdata; 34 struct snd_soc_dai_link dai[2];
32 struct snd_soc_dai_link dai; 35 struct snd_soc_card card;
33 struct snd_soc_card machine;
34 unsigned int dai_format; 36 unsigned int dai_format;
35 unsigned int codec_clk_direction; 37 unsigned int codec_clk_direction;
36 unsigned int cpu_clk_direction; 38 unsigned int cpu_clk_direction;
37 unsigned int clk_frequency; 39 unsigned int clk_frequency;
38 struct ccsr_guts __iomem *guts; 40 unsigned int ssi_id; /* 0 = SSI1, 1 = SSI2, etc */
39 struct ccsr_ssi __iomem *ssi; 41 unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */
40 unsigned int ssi_id; /* 0 = SSI1, 1 = SSI2, etc */
41 unsigned int ssi_irq;
42 unsigned int dma_id; /* 0 = DMA1, 1 = DMA2, etc */
43 unsigned int dma_irq[2];
44 struct ccsr_dma_channel __iomem *dma[2];
45 unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/ 42 unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/
43 char codec_dai_name[DAI_NAME_SIZE];
44 char codec_name[DAI_NAME_SIZE];
45 char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */
46}; 46};
47 47
48/** 48/**
49 * mpc8610_hpcd_machine_probe: initalize the board 49 * mpc8610_hpcd_machine_probe: initialize the board
50 * 50 *
51 * This function is called when platform_device_add() is called. It is used 51 * This function is used to initialize the board-specific hardware.
52 * to initialize the board-specific hardware.
53 * 52 *
54 * Here we program the DMACR and PMUXCR registers. 53 * Here we program the DMACR and PMUXCR registers.
55 */ 54 */
56static int mpc8610_hpcd_machine_probe(struct platform_device *sound_device) 55static int mpc8610_hpcd_machine_probe(struct platform_device *sound_device)
57{ 56{
57 struct snd_soc_card *card = platform_get_drvdata(sound_device);
58 struct mpc8610_hpcd_data *machine_data = 58 struct mpc8610_hpcd_data *machine_data =
59 sound_device->dev.platform_data; 59 container_of(card, struct mpc8610_hpcd_data, card);
60 struct ccsr_guts __iomem *guts;
60 61
61 /* Program the signal routing between the SSI and the DMA */ 62 guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
62 guts_set_dmacr(machine_data->guts, machine_data->dma_id, 63 if (!guts) {
63 machine_data->dma_channel_id[0], CCSR_GUTS_DMACR_DEV_SSI); 64 dev_err(card->dev, "could not map global utilities\n");
64 guts_set_dmacr(machine_data->guts, machine_data->dma_id, 65 return -ENOMEM;
65 machine_data->dma_channel_id[1], CCSR_GUTS_DMACR_DEV_SSI); 66 }
66 67
67 guts_set_pmuxcr_dma(machine_data->guts, machine_data->dma_id, 68 /* Program the signal routing between the SSI and the DMA */
68 machine_data->dma_channel_id[0], 0); 69 guts_set_dmacr(guts, machine_data->dma_id[0],
69 guts_set_pmuxcr_dma(machine_data->guts, machine_data->dma_id, 70 machine_data->dma_channel_id[0],
70 machine_data->dma_channel_id[1], 0); 71 CCSR_GUTS_DMACR_DEV_SSI);
72 guts_set_dmacr(guts, machine_data->dma_id[1],
73 machine_data->dma_channel_id[1],
74 CCSR_GUTS_DMACR_DEV_SSI);
75
76 guts_set_pmuxcr_dma(guts, machine_data->dma_id[0],
77 machine_data->dma_channel_id[0], 0);
78 guts_set_pmuxcr_dma(guts, machine_data->dma_id[1],
79 machine_data->dma_channel_id[1], 0);
71 80
72 switch (machine_data->ssi_id) { 81 switch (machine_data->ssi_id) {
73 case 0: 82 case 0:
74 clrsetbits_be32(&machine_data->guts->pmuxcr, 83 clrsetbits_be32(&guts->pmuxcr,
75 CCSR_GUTS_PMUXCR_SSI1_MASK, CCSR_GUTS_PMUXCR_SSI1_SSI); 84 CCSR_GUTS_PMUXCR_SSI1_MASK, CCSR_GUTS_PMUXCR_SSI1_SSI);
76 break; 85 break;
77 case 1: 86 case 1:
78 clrsetbits_be32(&machine_data->guts->pmuxcr, 87 clrsetbits_be32(&guts->pmuxcr,
79 CCSR_GUTS_PMUXCR_SSI2_MASK, CCSR_GUTS_PMUXCR_SSI2_SSI); 88 CCSR_GUTS_PMUXCR_SSI2_MASK, CCSR_GUTS_PMUXCR_SSI2_SSI);
80 break; 89 break;
81 } 90 }
82 91
92 iounmap(guts);
93
83 return 0; 94 return 0;
84} 95}
85 96
@@ -93,38 +104,15 @@ static int mpc8610_hpcd_machine_probe(struct platform_device *sound_device)
93static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream) 104static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream)
94{ 105{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data; 106 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
97 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
98 struct mpc8610_hpcd_data *machine_data = 107 struct mpc8610_hpcd_data *machine_data =
99 rtd->socdev->dev->platform_data; 108 container_of(rtd->card, struct mpc8610_hpcd_data, card);
109 struct device *dev = rtd->card->dev;
100 int ret = 0; 110 int ret = 0;
101 111
102 /* Tell the CPU driver what the serial protocol is. */
103 ret = snd_soc_dai_set_fmt(cpu_dai, machine_data->dai_format);
104 if (ret < 0) {
105 dev_err(substream->pcm->card->dev,
106 "could not set CPU driver audio format\n");
107 return ret;
108 }
109
110 /* Tell the codec driver what the serial protocol is. */ 112 /* Tell the codec driver what the serial protocol is. */
111 ret = snd_soc_dai_set_fmt(codec_dai, machine_data->dai_format); 113 ret = snd_soc_dai_set_fmt(rtd->codec_dai, machine_data->dai_format);
112 if (ret < 0) { 114 if (ret < 0) {
113 dev_err(substream->pcm->card->dev, 115 dev_err(dev, "could not set codec driver audio format\n");
114 "could not set codec driver audio format\n");
115 return ret;
116 }
117
118 /*
119 * Tell the CPU driver what the clock frequency is, and whether it's a
120 * slave or master.
121 */
122 ret = snd_soc_dai_set_sysclk(cpu_dai, 0,
123 machine_data->clk_frequency,
124 machine_data->cpu_clk_direction);
125 if (ret < 0) {
126 dev_err(substream->pcm->card->dev,
127 "could not set CPU driver clock parameters\n");
128 return ret; 116 return ret;
129 } 117 }
130 118
@@ -132,12 +120,11 @@ static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream)
132 * Tell the codec driver what the MCLK frequency is, and whether it's 120 * Tell the codec driver what the MCLK frequency is, and whether it's
133 * a slave or master. 121 * a slave or master.
134 */ 122 */
135 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 123 ret = snd_soc_dai_set_sysclk(rtd->codec_dai, 0,
136 machine_data->clk_frequency, 124 machine_data->clk_frequency,
137 machine_data->codec_clk_direction); 125 machine_data->codec_clk_direction);
138 if (ret < 0) { 126 if (ret < 0) {
139 dev_err(substream->pcm->card->dev, 127 dev_err(dev, "could not set codec driver clock params\n");
140 "could not set codec driver clock params\n");
141 return ret; 128 return ret;
142 } 129 }
143 130
@@ -150,116 +137,254 @@ static int mpc8610_hpcd_startup(struct snd_pcm_substream *substream)
150 * This function is called to remove the sound device for one SSI. We 137 * This function is called to remove the sound device for one SSI. We
151 * de-program the DMACR and PMUXCR register. 138 * de-program the DMACR and PMUXCR register.
152 */ 139 */
153int mpc8610_hpcd_machine_remove(struct platform_device *sound_device) 140static int mpc8610_hpcd_machine_remove(struct platform_device *sound_device)
154{ 141{
142 struct snd_soc_card *card = platform_get_drvdata(sound_device);
155 struct mpc8610_hpcd_data *machine_data = 143 struct mpc8610_hpcd_data *machine_data =
156 sound_device->dev.platform_data; 144 container_of(card, struct mpc8610_hpcd_data, card);
145 struct ccsr_guts __iomem *guts;
146
147 guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
148 if (!guts) {
149 dev_err(card->dev, "could not map global utilities\n");
150 return -ENOMEM;
151 }
157 152
158 /* Restore the signal routing */ 153 /* Restore the signal routing */
159 154
160 guts_set_dmacr(machine_data->guts, machine_data->dma_id, 155 guts_set_dmacr(guts, machine_data->dma_id[0],
161 machine_data->dma_channel_id[0], 0); 156 machine_data->dma_channel_id[0], 0);
162 guts_set_dmacr(machine_data->guts, machine_data->dma_id, 157 guts_set_dmacr(guts, machine_data->dma_id[1],
163 machine_data->dma_channel_id[1], 0); 158 machine_data->dma_channel_id[1], 0);
164 159
165 switch (machine_data->ssi_id) { 160 switch (machine_data->ssi_id) {
166 case 0: 161 case 0:
167 clrsetbits_be32(&machine_data->guts->pmuxcr, 162 clrsetbits_be32(&guts->pmuxcr,
168 CCSR_GUTS_PMUXCR_SSI1_MASK, CCSR_GUTS_PMUXCR_SSI1_LA); 163 CCSR_GUTS_PMUXCR_SSI1_MASK, CCSR_GUTS_PMUXCR_SSI1_LA);
169 break; 164 break;
170 case 1: 165 case 1:
171 clrsetbits_be32(&machine_data->guts->pmuxcr, 166 clrsetbits_be32(&guts->pmuxcr,
172 CCSR_GUTS_PMUXCR_SSI2_MASK, CCSR_GUTS_PMUXCR_SSI2_LA); 167 CCSR_GUTS_PMUXCR_SSI2_MASK, CCSR_GUTS_PMUXCR_SSI2_LA);
173 break; 168 break;
174 } 169 }
175 170
171 iounmap(guts);
172
176 return 0; 173 return 0;
177} 174}
178 175
179/** 176/**
180 * mpc8610_hpcd_ops: ASoC fabric driver operations 177 * mpc8610_hpcd_ops: ASoC machine driver operations
181 */ 178 */
182static struct snd_soc_ops mpc8610_hpcd_ops = { 179static struct snd_soc_ops mpc8610_hpcd_ops = {
183 .startup = mpc8610_hpcd_startup, 180 .startup = mpc8610_hpcd_startup,
184}; 181};
185 182
186/** 183/**
187 * mpc8610_hpcd_probe: OF probe function for the fabric driver 184 * get_node_by_phandle_name - get a node by its phandle name
188 * 185 *
189 * This function gets called when an SSI node is found in the device tree. 186 * This function takes a node, the name of a property in that node, and a
187 * compatible string. Assuming the property is a phandle to another node,
188 * it returns that node, (optionally) if that node is compatible.
190 * 189 *
191 * Although this is a fabric driver, the SSI node is the "master" node with 190 * If the property is not a phandle, or the node it points to is not compatible
192 * respect to audio hardware connections. Therefore, we create a new ASoC 191 * with the specific string, then NULL is returned.
193 * device for each new SSI node that has a codec attached. 192 */
193static struct device_node *get_node_by_phandle_name(struct device_node *np,
194 const char *name,
195 const char *compatible)
196{
197 const phandle *ph;
198 int len;
199
200 ph = of_get_property(np, name, &len);
201 if (!ph || (len != sizeof(phandle)))
202 return NULL;
203
204 np = of_find_node_by_phandle(*ph);
205 if (!np)
206 return NULL;
207
208 if (compatible && !of_device_is_compatible(np, compatible)) {
209 of_node_put(np);
210 return NULL;
211 }
212
213 return np;
214}
215
216/**
217 * get_parent_cell_index -- return the cell-index of the parent of a node
194 * 218 *
195 * FIXME: Currently, we only support one DMA controller, so if there are 219 * Return the value of the cell-index property of the parent of the given
196 * multiple SSI nodes with codecs, only the first will be supported. 220 * node. This is used for DMA channel nodes that need to know the DMA ID
221 * of the controller they are on.
222 */
223static int get_parent_cell_index(struct device_node *np)
224{
225 struct device_node *parent = of_get_parent(np);
226 const u32 *iprop;
227
228 if (!parent)
229 return -1;
230
231 iprop = of_get_property(parent, "cell-index", NULL);
232 of_node_put(parent);
233
234 if (!iprop)
235 return -1;
236
237 return *iprop;
238}
239
240/**
241 * codec_node_dev_name - determine the dev_name for a codec node
197 * 242 *
198 * FIXME: Even if we did support multiple DMA controllers, we have no 243 * This function determines the dev_name for an I2C node. This is the name
199 * mechanism for assigning DMA controllers and channels to the individual 244 * that would be returned by dev_name() if this device_node were part of a
200 * SSI devices. We also probably aren't compatible with the generic Elo DMA 245 * 'struct device' It's ugly and hackish, but it works.
201 * device driver. 246 *
247 * The dev_name for such devices include the bus number and I2C address. For
248 * example, "cs4270-codec.0-004f".
202 */ 249 */
203static int mpc8610_hpcd_probe(struct of_device *ofdev, 250static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
204 const struct of_device_id *match)
205{ 251{
206 struct device_node *np = ofdev->dev.of_node;
207 struct device_node *codec_np = NULL;
208 struct device_node *guts_np = NULL;
209 struct device_node *dma_np = NULL;
210 struct device_node *dma_channel_np = NULL;
211 const phandle *codec_ph;
212 const char *sprop;
213 const u32 *iprop; 252 const u32 *iprop;
253 int bus, addr;
254 char temp[DAI_NAME_SIZE];
255
256 of_modalias_node(np, temp, DAI_NAME_SIZE);
257
258 iprop = of_get_property(np, "reg", NULL);
259 if (!iprop)
260 return -EINVAL;
261
262 addr = *iprop;
263
264 bus = get_parent_cell_index(np);
265 if (bus < 0)
266 return bus;
267
268 snprintf(buf, len, "%s-codec.%u-%04x", temp, bus, addr);
269
270 return 0;
271}
272
273static int get_dma_channel(struct device_node *ssi_np,
274 const char *compatible,
275 struct snd_soc_dai_link *dai,
276 unsigned int *dma_channel_id,
277 unsigned int *dma_id)
278{
214 struct resource res; 279 struct resource res;
280 struct device_node *dma_channel_np;
281 const u32 *iprop;
282 int ret;
283
284 dma_channel_np = get_node_by_phandle_name(ssi_np, compatible,
285 "fsl,ssi-dma-channel");
286 if (!dma_channel_np)
287 return -EINVAL;
288
289 /* Determine the dev_name for the device_node. This code mimics the
290 * behavior of of_device_make_bus_id(). We need this because ASoC uses
291 * the dev_name() of the device to match the platform (DMA) device with
292 * the CPU (SSI) device. It's all ugly and hackish, but it works (for
293 * now).
294 *
295 * dai->platform name should already point to an allocated buffer.
296 */
297 ret = of_address_to_resource(dma_channel_np, 0, &res);
298 if (ret)
299 return ret;
300 snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
301 (unsigned long long) res.start, dma_channel_np->name);
302
303 iprop = of_get_property(dma_channel_np, "cell-index", NULL);
304 if (!iprop) {
305 of_node_put(dma_channel_np);
306 return -EINVAL;
307 }
308
309 *dma_channel_id = *iprop;
310 *dma_id = get_parent_cell_index(dma_channel_np);
311 of_node_put(dma_channel_np);
312
313 return 0;
314}
315
316/**
317 * mpc8610_hpcd_probe: platform probe function for the machine driver
318 *
319 * Although this is a machine driver, the SSI node is the "master" node with
320 * respect to audio hardware connections. Therefore, we create a new ASoC
321 * device for each new SSI node that has a codec attached.
322 */
323static int mpc8610_hpcd_probe(struct platform_device *pdev)
324{
325 struct device *dev = pdev->dev.parent;
326 /* of_dev is the OF device for the SSI node that probed us */
327 struct of_device *of_dev = container_of(dev, struct of_device, dev);
328 struct device_node *np = of_dev->dev.of_node;
329 struct device_node *codec_np = NULL;
215 struct platform_device *sound_device = NULL; 330 struct platform_device *sound_device = NULL;
216 struct mpc8610_hpcd_data *machine_data; 331 struct mpc8610_hpcd_data *machine_data;
217 struct fsl_ssi_info ssi_info;
218 struct fsl_dma_info dma_info;
219 int ret = -ENODEV; 332 int ret = -ENODEV;
220 unsigned int playback_dma_channel; 333 const char *sprop;
221 unsigned int capture_dma_channel; 334 const u32 *iprop;
335
336 /* We are only interested in SSIs with a codec phandle in them,
337 * so let's make sure this SSI has one. The MPC8610 HPCD only
338 * knows about the CS4270 codec, so reject anything else.
339 */
340 codec_np = get_node_by_phandle_name(np, "codec-handle",
341 "cirrus,cs4270");
342 if (!codec_np) {
343 dev_err(dev, "invalid codec node\n");
344 return -EINVAL;
345 }
222 346
223 machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL); 347 machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL);
224 if (!machine_data) 348 if (!machine_data)
225 return -ENOMEM; 349 return -ENOMEM;
226 350
227 memset(&ssi_info, 0, sizeof(ssi_info)); 351 machine_data->dai[0].cpu_dai_name = dev_name(&of_dev->dev);
228 memset(&dma_info, 0, sizeof(dma_info)); 352 machine_data->dai[0].ops = &mpc8610_hpcd_ops;
229 353
230 ssi_info.dev = &ofdev->dev; 354 /* Determine the codec name, it will be used as the codec DAI name */
231 355 ret = codec_node_dev_name(codec_np, machine_data->codec_name,
232 /* 356 DAI_NAME_SIZE);
233 * We are only interested in SSIs with a codec phandle in them, so let's 357 if (ret) {
234 * make sure this SSI has one. 358 dev_err(&pdev->dev, "invalid codec node %s\n",
235 */ 359 codec_np->full_name);
236 codec_ph = of_get_property(np, "codec-handle", NULL); 360 ret = -EINVAL;
237 if (!codec_ph)
238 goto error; 361 goto error;
362 }
363 machine_data->dai[0].codec_name = machine_data->codec_name;
239 364
240 codec_np = of_find_node_by_phandle(*codec_ph); 365 /* The DAI name from the codec (snd_soc_dai_driver.name) */
241 if (!codec_np) 366 machine_data->dai[0].codec_dai_name = "cs4270-hifi";
242 goto error;
243 367
244 /* The MPC8610 HPCD only knows about the CS4270 codec, so reject 368 /* We register two DAIs per SSI, one for playback and the other for
245 anything else. */ 369 * capture. Currently, we only support codecs that have one DAI for
246 if (!of_device_is_compatible(codec_np, "cirrus,cs4270")) 370 * both playback and capture.
247 goto error; 371 */
372 memcpy(&machine_data->dai[1], &machine_data->dai[0],
373 sizeof(struct snd_soc_dai_link));
248 374
249 /* Get the device ID */ 375 /* Get the device ID */
250 iprop = of_get_property(np, "cell-index", NULL); 376 iprop = of_get_property(np, "cell-index", NULL);
251 if (!iprop) { 377 if (!iprop) {
252 dev_err(&ofdev->dev, "cell-index property not found\n"); 378 dev_err(&pdev->dev, "cell-index property not found\n");
253 ret = -EINVAL; 379 ret = -EINVAL;
254 goto error; 380 goto error;
255 } 381 }
256 machine_data->ssi_id = *iprop; 382 machine_data->ssi_id = *iprop;
257 ssi_info.id = *iprop;
258 383
259 /* Get the serial format and clock direction. */ 384 /* Get the serial format and clock direction. */
260 sprop = of_get_property(np, "fsl,mode", NULL); 385 sprop = of_get_property(np, "fsl,mode", NULL);
261 if (!sprop) { 386 if (!sprop) {
262 dev_err(&ofdev->dev, "fsl,mode property not found\n"); 387 dev_err(&pdev->dev, "fsl,mode property not found\n");
263 ret = -EINVAL; 388 ret = -EINVAL;
264 goto error; 389 goto error;
265 } 390 }
@@ -269,15 +394,14 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
269 machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; 394 machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT;
270 machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; 395 machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN;
271 396
272 /* 397 /* In i2s-slave mode, the codec has its own clock source, so we
273 * In i2s-slave mode, the codec has its own clock source, so we
274 * need to get the frequency from the device tree and pass it to 398 * need to get the frequency from the device tree and pass it to
275 * the codec driver. 399 * the codec driver.
276 */ 400 */
277 iprop = of_get_property(codec_np, "clock-frequency", NULL); 401 iprop = of_get_property(codec_np, "clock-frequency", NULL);
278 if (!iprop || !*iprop) { 402 if (!iprop || !*iprop) {
279 dev_err(&ofdev->dev, "codec bus-frequency property " 403 dev_err(&pdev->dev, "codec bus-frequency "
280 "is missing or invalid\n"); 404 "property is missing or invalid\n");
281 ret = -EINVAL; 405 ret = -EINVAL;
282 goto error; 406 goto error;
283 } 407 }
@@ -311,317 +435,153 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
311 machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; 435 machine_data->codec_clk_direction = SND_SOC_CLOCK_IN;
312 machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; 436 machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT;
313 } else { 437 } else {
314 dev_err(&ofdev->dev, 438 dev_err(&pdev->dev,
315 "unrecognized fsl,mode property \"%s\"\n", sprop); 439 "unrecognized fsl,mode property '%s'\n", sprop);
316 ret = -EINVAL; 440 ret = -EINVAL;
317 goto error; 441 goto error;
318 } 442 }
319 443
320 if (!machine_data->clk_frequency) { 444 if (!machine_data->clk_frequency) {
321 dev_err(&ofdev->dev, "unknown clock frequency\n"); 445 dev_err(&pdev->dev, "unknown clock frequency\n");
322 ret = -EINVAL; 446 ret = -EINVAL;
323 goto error; 447 goto error;
324 } 448 }
325 449
326 /* Read the SSI information from the device tree */ 450 /* Find the playback DMA channel to use. */
327 ret = of_address_to_resource(np, 0, &res); 451 machine_data->dai[0].platform_name = machine_data->platform_name[0];
452 ret = get_dma_channel(np, "fsl,playback-dma", &machine_data->dai[0],
453 &machine_data->dma_channel_id[0],
454 &machine_data->dma_id[0]);
328 if (ret) { 455 if (ret) {
329 dev_err(&ofdev->dev, "could not obtain SSI address\n"); 456 dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n");
330 goto error;
331 }
332 if (!res.start) {
333 dev_err(&ofdev->dev, "invalid SSI address\n");
334 goto error;
335 }
336 ssi_info.ssi_phys = res.start;
337
338 machine_data->ssi = ioremap(ssi_info.ssi_phys, sizeof(struct ccsr_ssi));
339 if (!machine_data->ssi) {
340 dev_err(&ofdev->dev, "could not map SSI address %x\n",
341 ssi_info.ssi_phys);
342 ret = -EINVAL;
343 goto error;
344 }
345 ssi_info.ssi = machine_data->ssi;
346
347
348 /* Get the IRQ of the SSI */
349 machine_data->ssi_irq = irq_of_parse_and_map(np, 0);
350 if (!machine_data->ssi_irq) {
351 dev_err(&ofdev->dev, "could not get SSI IRQ\n");
352 ret = -EINVAL;
353 goto error;
354 }
355 ssi_info.irq = machine_data->ssi_irq;
356
357 /* Do we want to use asynchronous mode? */
358 ssi_info.asynchronous =
359 of_find_property(np, "fsl,ssi-asynchronous", NULL) ? 1 : 0;
360 if (ssi_info.asynchronous)
361 dev_info(&ofdev->dev, "using asynchronous mode\n");
362
363 /* Map the global utilities registers. */
364 guts_np = of_find_compatible_node(NULL, NULL, "fsl,mpc8610-guts");
365 if (!guts_np) {
366 dev_err(&ofdev->dev, "could not obtain address of GUTS\n");
367 ret = -EINVAL;
368 goto error;
369 }
370 machine_data->guts = of_iomap(guts_np, 0);
371 of_node_put(guts_np);
372 if (!machine_data->guts) {
373 dev_err(&ofdev->dev, "could not map GUTS\n");
374 ret = -EINVAL;
375 goto error;
376 }
377
378 /* Find the DMA channels to use. Both SSIs need to use the same DMA
379 * controller, so let's use DMA#1.
380 */
381 for_each_compatible_node(dma_np, NULL, "fsl,mpc8610-dma") {
382 iprop = of_get_property(dma_np, "cell-index", NULL);
383 if (iprop && (*iprop == 0)) {
384 of_node_put(dma_np);
385 break;
386 }
387 }
388 if (!dma_np) {
389 dev_err(&ofdev->dev, "could not find DMA node\n");
390 ret = -EINVAL;
391 goto error;
392 }
393 machine_data->dma_id = *iprop;
394
395 /* SSI1 needs to use DMA Channels 0 and 1, and SSI2 needs to use DMA
396 * channels 2 and 3. This is just how the MPC8610 is wired
397 * internally.
398 */
399 playback_dma_channel = (machine_data->ssi_id == 0) ? 0 : 2;
400 capture_dma_channel = (machine_data->ssi_id == 0) ? 1 : 3;
401
402 /*
403 * Find the DMA channels to use.
404 */
405 while ((dma_channel_np = of_get_next_child(dma_np, dma_channel_np))) {
406 iprop = of_get_property(dma_channel_np, "cell-index", NULL);
407 if (iprop && (*iprop == playback_dma_channel)) {
408 /* dma_channel[0] and dma_irq[0] are for playback */
409 dma_info.dma_channel[0] = of_iomap(dma_channel_np, 0);
410 dma_info.dma_irq[0] =
411 irq_of_parse_and_map(dma_channel_np, 0);
412 machine_data->dma_channel_id[0] = *iprop;
413 continue;
414 }
415 if (iprop && (*iprop == capture_dma_channel)) {
416 /* dma_channel[1] and dma_irq[1] are for capture */
417 dma_info.dma_channel[1] = of_iomap(dma_channel_np, 0);
418 dma_info.dma_irq[1] =
419 irq_of_parse_and_map(dma_channel_np, 0);
420 machine_data->dma_channel_id[1] = *iprop;
421 continue;
422 }
423 }
424 if (!dma_info.dma_channel[0] || !dma_info.dma_channel[1] ||
425 !dma_info.dma_irq[0] || !dma_info.dma_irq[1]) {
426 dev_err(&ofdev->dev, "could not find DMA channels\n");
427 ret = -EINVAL;
428 goto error; 457 goto error;
429 } 458 }
430 459
431 dma_info.ssi_stx_phys = ssi_info.ssi_phys + 460 /* Find the capture DMA channel to use. */
432 offsetof(struct ccsr_ssi, stx0); 461 machine_data->dai[1].platform_name = machine_data->platform_name[1];
433 dma_info.ssi_srx_phys = ssi_info.ssi_phys + 462 ret = get_dma_channel(np, "fsl,capture-dma", &machine_data->dai[1],
434 offsetof(struct ccsr_ssi, srx0); 463 &machine_data->dma_channel_id[1],
435 464 &machine_data->dma_id[1]);
436 /* We have the DMA information, so tell the DMA driver what it is */ 465 if (ret) {
437 if (!fsl_dma_configure(&dma_info)) { 466 dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n");
438 dev_err(&ofdev->dev, "could not instantiate DMA device\n");
439 ret = -EBUSY;
440 goto error; 467 goto error;
441 } 468 }
442 469
443 /* 470 /* Initialize our DAI data structure. */
444 * Initialize our DAI data structure. We should probably get this 471 machine_data->dai[0].stream_name = "playback";
445 * information from the device tree. 472 machine_data->dai[1].stream_name = "capture";
446 */ 473 machine_data->dai[0].name = machine_data->dai[0].stream_name;
447 machine_data->dai.name = "CS4270"; 474 machine_data->dai[1].name = machine_data->dai[1].stream_name;
448 machine_data->dai.stream_name = "CS4270";
449
450 machine_data->dai.cpu_dai = fsl_ssi_create_dai(&ssi_info);
451 machine_data->dai.codec_dai = &cs4270_dai; /* The codec_dai we want */
452 machine_data->dai.ops = &mpc8610_hpcd_ops;
453 475
454 machine_data->machine.probe = mpc8610_hpcd_machine_probe; 476 machine_data->card.probe = mpc8610_hpcd_machine_probe;
455 machine_data->machine.remove = mpc8610_hpcd_machine_remove; 477 machine_data->card.remove = mpc8610_hpcd_machine_remove;
456 machine_data->machine.name = "MPC8610 HPCD"; 478 machine_data->card.name = pdev->name; /* The platform driver name */
457 machine_data->machine.num_links = 1; 479 machine_data->card.num_links = 2;
458 machine_data->machine.dai_link = &machine_data->dai; 480 machine_data->card.dai_link = machine_data->dai;
459 481
460 /* Allocate a new audio platform device structure */ 482 /* Allocate a new audio platform device structure */
461 sound_device = platform_device_alloc("soc-audio", -1); 483 sound_device = platform_device_alloc("soc-audio", -1);
462 if (!sound_device) { 484 if (!sound_device) {
463 dev_err(&ofdev->dev, "platform device allocation failed\n"); 485 dev_err(&pdev->dev, "platform device alloc failed\n");
464 ret = -ENOMEM; 486 ret = -ENOMEM;
465 goto error; 487 goto error;
466 } 488 }
467 489
468 machine_data->sound_devdata.card = &machine_data->machine; 490 /* Associate the card data with the sound device */
469 machine_data->sound_devdata.codec_dev = &soc_codec_device_cs4270; 491 platform_set_drvdata(sound_device, &machine_data->card);
470 machine_data->machine.platform = &fsl_soc_platform;
471
472 sound_device->dev.platform_data = machine_data;
473
474 492
475 /* Set the platform device and ASoC device to point to each other */ 493 /* Register with ASoC */
476 platform_set_drvdata(sound_device, &machine_data->sound_devdata);
477
478 machine_data->sound_devdata.dev = &sound_device->dev;
479
480
481 /* Tell ASoC to probe us. This will call mpc8610_hpcd_machine.probe(),
482 if it exists. */
483 ret = platform_device_add(sound_device); 494 ret = platform_device_add(sound_device);
484
485 if (ret) { 495 if (ret) {
486 dev_err(&ofdev->dev, "platform device add failed\n"); 496 dev_err(&pdev->dev, "platform device add failed\n");
487 goto error; 497 goto error;
488 } 498 }
489 499
490 dev_set_drvdata(&ofdev->dev, sound_device); 500 of_node_put(codec_np);
491 501
492 return 0; 502 return 0;
493 503
494error: 504error:
495 of_node_put(codec_np); 505 of_node_put(codec_np);
496 of_node_put(guts_np);
497 of_node_put(dma_np);
498 of_node_put(dma_channel_np);
499 506
500 if (sound_device) 507 if (sound_device)
501 platform_device_unregister(sound_device); 508 platform_device_unregister(sound_device);
502 509
503 if (machine_data->dai.cpu_dai)
504 fsl_ssi_destroy_dai(machine_data->dai.cpu_dai);
505
506 if (ssi_info.ssi)
507 iounmap(ssi_info.ssi);
508
509 if (ssi_info.irq)
510 irq_dispose_mapping(ssi_info.irq);
511
512 if (dma_info.dma_channel[0])
513 iounmap(dma_info.dma_channel[0]);
514
515 if (dma_info.dma_channel[1])
516 iounmap(dma_info.dma_channel[1]);
517
518 if (dma_info.dma_irq[0])
519 irq_dispose_mapping(dma_info.dma_irq[0]);
520
521 if (dma_info.dma_irq[1])
522 irq_dispose_mapping(dma_info.dma_irq[1]);
523
524 if (machine_data->guts)
525 iounmap(machine_data->guts);
526
527 kfree(machine_data); 510 kfree(machine_data);
528 511
529 return ret; 512 return ret;
530} 513}
531 514
532/** 515/**
533 * mpc8610_hpcd_remove: remove the OF device 516 * mpc8610_hpcd_remove: remove the platform device
534 * 517 *
535 * This function is called when the OF device is removed. 518 * This function is called when the platform device is removed.
536 */ 519 */
537static int mpc8610_hpcd_remove(struct of_device *ofdev) 520static int __devexit mpc8610_hpcd_remove(struct platform_device *pdev)
538{ 521{
539 struct platform_device *sound_device = dev_get_drvdata(&ofdev->dev); 522 struct platform_device *sound_device = dev_get_drvdata(&pdev->dev);
523 struct snd_soc_card *card = platform_get_drvdata(sound_device);
540 struct mpc8610_hpcd_data *machine_data = 524 struct mpc8610_hpcd_data *machine_data =
541 sound_device->dev.platform_data; 525 container_of(card, struct mpc8610_hpcd_data, card);
542 526
543 platform_device_unregister(sound_device); 527 platform_device_unregister(sound_device);
544 528
545 if (machine_data->dai.cpu_dai)
546 fsl_ssi_destroy_dai(machine_data->dai.cpu_dai);
547
548 if (machine_data->ssi)
549 iounmap(machine_data->ssi);
550
551 if (machine_data->dma[0])
552 iounmap(machine_data->dma[0]);
553
554 if (machine_data->dma[1])
555 iounmap(machine_data->dma[1]);
556
557 if (machine_data->dma_irq[0])
558 irq_dispose_mapping(machine_data->dma_irq[0]);
559
560 if (machine_data->dma_irq[1])
561 irq_dispose_mapping(machine_data->dma_irq[1]);
562
563 if (machine_data->guts)
564 iounmap(machine_data->guts);
565
566 kfree(machine_data); 529 kfree(machine_data);
567 sound_device->dev.platform_data = NULL; 530 sound_device->dev.platform_data = NULL;
568 531
569 dev_set_drvdata(&ofdev->dev, NULL); 532 dev_set_drvdata(&pdev->dev, NULL);
570 533
571 return 0; 534 return 0;
572} 535}
573 536
574static struct of_device_id mpc8610_hpcd_match[] = { 537static struct platform_driver mpc8610_hpcd_driver = {
575 { 538 .probe = mpc8610_hpcd_probe,
576 .compatible = "fsl,mpc8610-ssi", 539 .remove = __devexit_p(mpc8610_hpcd_remove),
577 },
578 {}
579};
580MODULE_DEVICE_TABLE(of, mpc8610_hpcd_match);
581
582static struct of_platform_driver mpc8610_hpcd_of_driver = {
583 .driver = { 540 .driver = {
584 .name = "mpc8610_hpcd", 541 /* The name must match the 'model' property in the device tree,
542 * in lowercase letters.
543 */
544 .name = "snd-soc-mpc8610hpcd",
585 .owner = THIS_MODULE, 545 .owner = THIS_MODULE,
586 .of_match_table = mpc8610_hpcd_match,
587 }, 546 },
588 .probe = mpc8610_hpcd_probe,
589 .remove = mpc8610_hpcd_remove,
590}; 547};
591 548
592/** 549/**
593 * mpc8610_hpcd_init: fabric driver initialization. 550 * mpc8610_hpcd_init: machine driver initialization.
594 * 551 *
595 * This function is called when this module is loaded. 552 * This function is called when this module is loaded.
596 */ 553 */
597static int __init mpc8610_hpcd_init(void) 554static int __init mpc8610_hpcd_init(void)
598{ 555{
599 int ret; 556 struct device_node *guts_np;
600 557 struct resource res;
601 printk(KERN_INFO "Freescale MPC8610 HPCD ALSA SoC fabric driver\n");
602 558
603 ret = of_register_platform_driver(&mpc8610_hpcd_of_driver); 559 pr_info("Freescale MPC8610 HPCD ALSA SoC machine driver\n");
604 560
605 if (ret) 561 /* Get the physical address of the global utilities registers */
606 printk(KERN_ERR 562 guts_np = of_find_compatible_node(NULL, NULL, "fsl,mpc8610-guts");
607 "mpc8610-hpcd: failed to register platform driver\n"); 563 if (of_address_to_resource(guts_np, 0, &res)) {
564 pr_err("mpc8610-hpcd: missing/invalid global utilities node\n");
565 return -EINVAL;
566 }
567 guts_phys = res.start;
608 568
609 return ret; 569 return platform_driver_register(&mpc8610_hpcd_driver);
610} 570}
611 571
612/** 572/**
613 * mpc8610_hpcd_exit: fabric driver exit 573 * mpc8610_hpcd_exit: machine driver exit
614 * 574 *
615 * This function is called when this driver is unloaded. 575 * This function is called when this driver is unloaded.
616 */ 576 */
617static void __exit mpc8610_hpcd_exit(void) 577static void __exit mpc8610_hpcd_exit(void)
618{ 578{
619 of_unregister_platform_driver(&mpc8610_hpcd_of_driver); 579 platform_driver_unregister(&mpc8610_hpcd_driver);
620} 580}
621 581
622module_init(mpc8610_hpcd_init); 582module_init(mpc8610_hpcd_init);
623module_exit(mpc8610_hpcd_exit); 583module_exit(mpc8610_hpcd_exit);
624 584
625MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 585MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
626MODULE_DESCRIPTION("Freescale MPC8610 HPCD ALSA SoC fabric driver"); 586MODULE_DESCRIPTION("Freescale MPC8610 HPCD ALSA SoC machine driver");
627MODULE_LICENSE("GPL"); 587MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index 6644cba7cbf..fe15bb26e48 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -32,21 +32,24 @@
32 32
33#define DRV_NAME "pcm030-audio-fabric" 33#define DRV_NAME "pcm030-audio-fabric"
34 34
35static struct snd_soc_device device;
36static struct snd_soc_card card; 35static struct snd_soc_card card;
37 36
38static struct snd_soc_dai_link pcm030_fabric_dai[] = { 37static struct snd_soc_dai_link pcm030_fabric_dai[] = {
39{ 38{
40 .name = "AC97", 39 .name = "AC97",
41 .stream_name = "AC97 Analog", 40 .stream_name = "AC97 Analog",
42 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 41 .codec_dai_name = "wm9712-hifi",
43 .cpu_dai = &psc_ac97_dai[MPC5200_AC97_NORMAL], 42 .cpu_dai_name = "mpc5200-psc-ac97.0",
43 .platform_name = "mpc5200-pcm-audio",
44 .codec_name = "wm9712-codec",
44}, 45},
45{ 46{
46 .name = "AC97", 47 .name = "AC97",
47 .stream_name = "AC97 IEC958", 48 .stream_name = "AC97 IEC958",
48 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 49 .codec_dai_name = "wm9712-aux",
49 .cpu_dai = &psc_ac97_dai[MPC5200_AC97_SPDIF], 50 .cpu_dai_name = "mpc5200-psc-ac97.1",
51 .platform_name = "mpc5200-pcm-audio",
52 ..codec_name = "wm9712-codec",
50}, 53},
51}; 54};
52 55
@@ -58,22 +61,18 @@ static __init int pcm030_fabric_init(void)
58 if (!of_machine_is_compatible("phytec,pcm030")) 61 if (!of_machine_is_compatible("phytec,pcm030"))
59 return -ENODEV; 62 return -ENODEV;
60 63
61 card.platform = &mpc5200_audio_dma_platform; 64
62 card.name = "pcm030"; 65 card.name = "pcm030";
63 card.dai_link = pcm030_fabric_dai; 66 card.dai_link = pcm030_fabric_dai;
64 card.num_links = ARRAY_SIZE(pcm030_fabric_dai); 67 card.num_links = ARRAY_SIZE(pcm030_fabric_dai);
65 68
66 device.card = &card;
67 device.codec_dev = &soc_codec_dev_wm9712;
68
69 pdev = platform_device_alloc("soc-audio", 1); 69 pdev = platform_device_alloc("soc-audio", 1);
70 if (!pdev) { 70 if (!pdev) {
71 pr_err("pcm030_fabric_init: platform_device_alloc() failed\n"); 71 pr_err("pcm030_fabric_init: platform_device_alloc() failed\n");
72 return -ENODEV; 72 return -ENODEV;
73 } 73 }
74 74
75 platform_set_drvdata(pdev, &device); 75 platform_set_drvdata(pdev, &card);
76 device.dev = &pdev->dev;
77 76
78 rc = platform_device_add(pdev); 77 rc = platform_device_add(pdev);
79 if (rc) { 78 if (rc) {
diff --git a/sound/soc/fsl/soc-of-simple.c b/sound/soc/fsl/soc-of-simple.c
deleted file mode 100644
index 3bc13fd8909..00000000000
--- a/sound/soc/fsl/soc-of-simple.c
+++ /dev/null
@@ -1,172 +0,0 @@
1/*
2 * OF helpers for ALSA SoC Layer
3 *
4 * Copyright (C) 2008, Secret Lab Technologies Ltd.
5 */
6
7#include <linux/module.h>
8#include <linux/moduleparam.h>
9#include <linux/init.h>
10#include <linux/delay.h>
11#include <linux/pm.h>
12#include <linux/bitops.h>
13#include <linux/platform_device.h>
14#include <linux/of.h>
15#include <linux/slab.h>
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/pcm_params.h>
19#include <sound/soc.h>
20#include <sound/soc-of-simple.h>
21#include <sound/initval.h>
22
23MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
24MODULE_LICENSE("GPL");
25MODULE_DESCRIPTION("ALSA SoC OpenFirmware bindings");
26
27static DEFINE_MUTEX(of_snd_soc_mutex);
28static LIST_HEAD(of_snd_soc_device_list);
29static int of_snd_soc_next_index;
30
31struct of_snd_soc_device {
32 int id;
33 struct list_head list;
34 struct snd_soc_device device;
35 struct snd_soc_card card;
36 struct snd_soc_dai_link dai_link;
37 struct platform_device *pdev;
38 struct device_node *platform_node;
39 struct device_node *codec_node;
40};
41
42static struct snd_soc_ops of_snd_soc_ops = {
43};
44
45static struct of_snd_soc_device *
46of_snd_soc_get_device(struct device_node *codec_node)
47{
48 struct of_snd_soc_device *of_soc;
49
50 list_for_each_entry(of_soc, &of_snd_soc_device_list, list) {
51 if (of_soc->codec_node == codec_node)
52 return of_soc;
53 }
54
55 of_soc = kzalloc(sizeof(struct of_snd_soc_device), GFP_KERNEL);
56 if (!of_soc)
57 return NULL;
58
59 /* Initialize the structure and add it to the global list */
60 of_soc->codec_node = codec_node;
61 of_soc->id = of_snd_soc_next_index++;
62 of_soc->card.dai_link = &of_soc->dai_link;
63 of_soc->card.num_links = 1;
64 of_soc->device.card = &of_soc->card;
65 of_soc->dai_link.ops = &of_snd_soc_ops;
66 list_add(&of_soc->list, &of_snd_soc_device_list);
67
68 return of_soc;
69}
70
71static void of_snd_soc_register_device(struct of_snd_soc_device *of_soc)
72{
73 struct platform_device *pdev;
74 int rc;
75
76 /* Only register the device if both the codec and platform have
77 * been registered */
78 if ((!of_soc->device.codec_data) || (!of_soc->platform_node))
79 return;
80
81 pr_info("platform<-->codec match achieved; registering machine\n");
82
83 pdev = platform_device_alloc("soc-audio", of_soc->id);
84 if (!pdev) {
85 pr_err("of_soc: platform_device_alloc() failed\n");
86 return;
87 }
88
89 pdev->dev.platform_data = of_soc;
90 platform_set_drvdata(pdev, &of_soc->device);
91 of_soc->device.dev = &pdev->dev;
92
93 /* The ASoC device is complete; register it */
94 rc = platform_device_add(pdev);
95 if (rc) {
96 pr_err("of_soc: platform_device_add() failed\n");
97 return;
98 }
99
100}
101
102int of_snd_soc_register_codec(struct snd_soc_codec_device *codec_dev,
103 void *codec_data, struct snd_soc_dai *dai,
104 struct device_node *node)
105{
106 struct of_snd_soc_device *of_soc;
107 int rc = 0;
108
109 pr_info("registering ASoC codec driver: %s\n", node->full_name);
110
111 mutex_lock(&of_snd_soc_mutex);
112 of_soc = of_snd_soc_get_device(node);
113 if (!of_soc) {
114 rc = -ENOMEM;
115 goto out;
116 }
117
118 /* Store the codec data */
119 of_soc->device.codec_data = codec_data;
120 of_soc->device.codec_dev = codec_dev;
121 of_soc->dai_link.name = (char *)node->name;
122 of_soc->dai_link.stream_name = (char *)node->name;
123 of_soc->dai_link.codec_dai = dai;
124
125 /* Now try to register the SoC device */
126 of_snd_soc_register_device(of_soc);
127
128 out:
129 mutex_unlock(&of_snd_soc_mutex);
130 return rc;
131}
132EXPORT_SYMBOL_GPL(of_snd_soc_register_codec);
133
134int of_snd_soc_register_platform(struct snd_soc_platform *platform,
135 struct device_node *node,
136 struct snd_soc_dai *cpu_dai)
137{
138 struct of_snd_soc_device *of_soc;
139 struct device_node *codec_node;
140 const phandle *handle;
141 int len, rc = 0;
142
143 pr_info("registering ASoC platform driver: %s\n", node->full_name);
144
145 handle = of_get_property(node, "codec-handle", &len);
146 if (!handle || len < sizeof(handle))
147 return -ENODEV;
148 codec_node = of_find_node_by_phandle(*handle);
149 if (!codec_node)
150 return -ENODEV;
151 pr_info("looking for codec: %s\n", codec_node->full_name);
152
153 mutex_lock(&of_snd_soc_mutex);
154 of_soc = of_snd_soc_get_device(codec_node);
155 if (!of_soc) {
156 rc = -ENOMEM;
157 goto out;
158 }
159
160 of_soc->platform_node = node;
161 of_soc->dai_link.cpu_dai = cpu_dai;
162 of_soc->card.platform = platform;
163 of_soc->card.name = of_soc->dai_link.cpu_dai->name;
164
165 /* Now try to register the SoC device */
166 of_snd_soc_register_device(of_soc);
167
168 out:
169 mutex_unlock(&of_snd_soc_mutex);
170 return rc;
171}
172EXPORT_SYMBOL_GPL(of_snd_soc_register_platform);
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 52dac5e3874..66ba26393c1 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -8,12 +8,24 @@ menuconfig SND_IMX_SOC
8 Say Y or M if you want to add support for codecs attached to 8 Say Y or M if you want to add support for codecs attached to
9 the i.MX SSI interface. 9 the i.MX SSI interface.
10 10
11
11if SND_IMX_SOC 12if SND_IMX_SOC
12 13
14config SND_MXC_SOC_SSI
15 tristate
16
17config SND_MXC_SOC_FIQ
18 tristate
19
20config SND_MXC_SOC_MX2
21 tristate
22
13config SND_MXC_SOC_WM1133_EV1 23config SND_MXC_SOC_WM1133_EV1
14 tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted" 24 tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted"
15 depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL 25 depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
16 select SND_SOC_WM8350 26 select SND_SOC_WM8350
27 select SND_MXC_SOC_SSI
28 select SND_MXC_SOC_FIQ
17 help 29 help
18 Enable support for audio on the i.MX31ADS with the WM1133-EV1 30 Enable support for audio on the i.MX31ADS with the WM1133-EV1
19 PMIC board with WM8835x fitted. 31 PMIC board with WM8835x fitted.
@@ -22,6 +34,8 @@ config SND_SOC_PHYCORE_AC97
22 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" 34 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
23 depends on MACH_PCM043 || MACH_PCA100 35 depends on MACH_PCM043 || MACH_PCA100
24 select SND_SOC_WM9712 36 select SND_SOC_WM9712
37 select SND_MXC_SOC_SSI
38 select SND_MXC_SOC_FIQ
25 help 39 help
26 Say Y if you want to add support for SoC audio on Phytec phyCORE 40 Say Y if you want to add support for SoC audio on Phytec phyCORE
27 and phyCARD boards in AC97 mode 41 and phyCARD boards in AC97 mode
@@ -30,6 +44,8 @@ config SND_SOC_EUKREA_TLV320
30 tristate "Eukrea TLV320" 44 tristate "Eukrea TLV320"
31 depends on MACH_EUKREA_MBIMX27_BASEBOARD || MACH_EUKREA_MBIMXSD_BASEBOARD 45 depends on MACH_EUKREA_MBIMX27_BASEBOARD || MACH_EUKREA_MBIMXSD_BASEBOARD
32 select SND_SOC_TLV320AIC23 46 select SND_SOC_TLV320AIC23
47 select SND_MXC_SOC_SSI
48 select SND_MXC_SOC_FIQ
33 help 49 help
34 Enable I2S based access to the TLV320AIC23B codec attached 50 Enable I2S based access to the TLV320AIC23B codec attached
35 to the SSI interface 51 to the SSI interface
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index 7bc57baf2b0..b67fc02a4ec 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -1,11 +1,11 @@
1# i.MX Platform Support 1# i.MX Platform Support
2snd-soc-imx-objs := imx-ssi.o imx-pcm-fiq.o 2snd-soc-imx-objs := imx-ssi.o
3 3snd-soc-imx-fiq-objs := imx-pcm-fiq.o
4ifdef CONFIG_MACH_MX27 4snd-soc-imx-mx2-objs := imx-pcm-dma-mx2.o
5snd-soc-imx-objs += imx-pcm-dma-mx2.o
6endif
7 5
8obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o 6obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o
7obj-$(CONFIG_SND_MXC_SOC_FIQ) += snd-soc-imx-fiq.o
8obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.o
9 9
10# i.MX Machine Support 10# i.MX Machine Support
11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o 11snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
index f15dfbdc47e..807f736ee29 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/imx/eukrea-tlv320.c
@@ -79,22 +79,19 @@ static struct snd_soc_ops eukrea_tlv320_snd_ops = {
79static struct snd_soc_dai_link eukrea_tlv320_dai = { 79static struct snd_soc_dai_link eukrea_tlv320_dai = {
80 .name = "tlv320aic23", 80 .name = "tlv320aic23",
81 .stream_name = "TLV320AIC23", 81 .stream_name = "TLV320AIC23",
82 .codec_dai = &tlv320aic23_dai, 82 .codec_dai = "tlv320aic23-hifi",
83 .platform_name = "imx-pcm-audio.0",
84 .codec_name = "tlv320aic23-codec.0-001a",
85 .cpu_dai = "imx-ssi-dai.0",
83 .ops = &eukrea_tlv320_snd_ops, 86 .ops = &eukrea_tlv320_snd_ops,
84}; 87};
85 88
86static struct snd_soc_card eukrea_tlv320 = { 89static struct snd_soc_card eukrea_tlv320 = {
87 .name = "cpuimx-audio", 90 .name = "cpuimx-audio",
88 .platform = &imx_soc_platform,
89 .dai_link = &eukrea_tlv320_dai, 91 .dai_link = &eukrea_tlv320_dai,
90 .num_links = 1, 92 .num_links = 1,
91}; 93};
92 94
93static struct snd_soc_device eukrea_tlv320_snd_devdata = {
94 .card = &eukrea_tlv320,
95 .codec_dev = &soc_codec_dev_tlv320aic23,
96};
97
98static struct platform_device *eukrea_tlv320_snd_device; 95static struct platform_device *eukrea_tlv320_snd_device;
99 96
100static int __init eukrea_tlv320_init(void) 97static int __init eukrea_tlv320_init(void)
@@ -110,10 +107,7 @@ static int __init eukrea_tlv320_init(void)
110 if (!eukrea_tlv320_snd_device) 107 if (!eukrea_tlv320_snd_device)
111 return -ENOMEM; 108 return -ENOMEM;
112 109
113 eukrea_tlv320_dai.cpu_dai = &imx_ssi_pcm_dai[0]; 110 platform_set_drvdata(eukrea_tlv320_snd_device, &eukrea_tlv320);
114
115 platform_set_drvdata(eukrea_tlv320_snd_device, &eukrea_tlv320_snd_devdata);
116 eukrea_tlv320_snd_devdata.dev = &eukrea_tlv320_snd_device->dev;
117 ret = platform_device_add(eukrea_tlv320_snd_device); 111 ret = platform_device_add(eukrea_tlv320_snd_device);
118 112
119 if (ret) { 113 if (ret) {
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 0a595da4811..fd493ee1428 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -103,7 +103,7 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
103 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 103 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
104 int ret; 104 int ret;
105 105
106 dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 106 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
107 107
108 iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); 108 iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
109 if (iprtd->dma < 0) { 109 if (iprtd->dma < 0) {
@@ -213,7 +213,7 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
213 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 213 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
214 int err; 214 int err;
215 215
216 dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 216 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
217 217
218 iprtd->substream = substream; 218 iprtd->substream = substream;
219 iprtd->buf = (unsigned int *)substream->dma_buffer.area; 219 iprtd->buf = (unsigned int *)substream->dma_buffer.area;
@@ -318,19 +318,42 @@ static struct snd_pcm_ops imx_pcm_ops = {
318 .mmap = snd_imx_pcm_mmap, 318 .mmap = snd_imx_pcm_mmap,
319}; 319};
320 320
321static struct snd_soc_platform imx_soc_platform_dma = { 321static struct snd_soc_platform_driver imx_soc_platform_mx2 = {
322 .name = "imx-audio", 322 .ops = &imx_pcm_ops,
323 .pcm_ops = &imx_pcm_ops,
324 .pcm_new = imx_pcm_new, 323 .pcm_new = imx_pcm_new,
325 .pcm_free = imx_pcm_free, 324 .pcm_free = imx_pcm_free,
326}; 325};
327 326
328struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev, 327static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
329 struct imx_ssi *ssi)
330{ 328{
331 ssi->dma_params_tx.burstsize = DMA_TXFIFO_BURST; 329 return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
332 ssi->dma_params_rx.burstsize = DMA_RXFIFO_BURST; 330}
331
332static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
333{
334 snd_soc_unregister_platform(&pdev->dev);
335 return 0;
336}
337
338static struct platform_driver imx_pcm_driver = {
339 .driver = {
340 .name = "imx-pcm-audio",
341 .owner = THIS_MODULE,
342 },
333 343
334 return &imx_soc_platform_dma; 344 .probe = imx_soc_platform_probe,
345 .remove = __devexit_p(imx_soc_platform_remove),
346};
347
348static int __init snd_imx_pcm_init(void)
349{
350 return platform_driver_register(&imx_pcm_driver);
351}
352module_init(snd_imx_pcm_init);
353
354static void __exit snd_imx_pcm_exit(void)
355{
356 platform_driver_unregister(&imx_pcm_driver);
335} 357}
358module_exit(snd_imx_pcm_exit);
336 359
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
index b2bf27282cd..413b78da248 100644
--- a/sound/soc/imx/imx-pcm-fiq.c
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -236,6 +236,8 @@ static struct snd_pcm_ops imx_pcm_ops = {
236 .mmap = snd_imx_pcm_mmap, 236 .mmap = snd_imx_pcm_mmap,
237}; 237};
238 238
239static int ssi_irq = 0;
240
239static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai, 241static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
240 struct snd_pcm *pcm) 242 struct snd_pcm *pcm)
241{ 243{
@@ -245,7 +247,7 @@ static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
245 if (ret) 247 if (ret)
246 return ret; 248 return ret;
247 249
248 if (dai->playback.channels_min) { 250 if (dai->driver->playback.channels_min) {
249 struct snd_pcm_substream *substream = 251 struct snd_pcm_substream *substream =
250 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 252 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
251 struct snd_dma_buffer *buf = &substream->dma_buffer; 253 struct snd_dma_buffer *buf = &substream->dma_buffer;
@@ -253,7 +255,7 @@ static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
253 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area; 255 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area;
254 } 256 }
255 257
256 if (dai->capture.channels_min) { 258 if (dai->driver->capture.channels_min) {
257 struct snd_pcm_substream *substream = 259 struct snd_pcm_substream *substream =
258 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 260 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
259 struct snd_dma_buffer *buf = &substream->dma_buffer; 261 struct snd_dma_buffer *buf = &substream->dma_buffer;
@@ -267,24 +269,32 @@ static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
267 return 0; 269 return 0;
268} 270}
269 271
270static struct snd_soc_platform imx_soc_platform_fiq = { 272static void imx_pcm_fiq_free(struct snd_pcm *pcm)
271 .pcm_ops = &imx_pcm_ops, 273{
274 mxc_set_irq_fiq(ssi_irq, 0);
275 release_fiq(&fh);
276 imx_pcm_free(pcm);
277}
278
279static struct snd_soc_platform_driver imx_soc_platform_fiq = {
280 .ops = &imx_pcm_ops,
272 .pcm_new = imx_pcm_fiq_new, 281 .pcm_new = imx_pcm_fiq_new,
273 .pcm_free = imx_pcm_free, 282 .pcm_free = imx_pcm_fiq_free,
274}; 283};
275 284
276struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev, 285static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
277 struct imx_ssi *ssi)
278{ 286{
279 int ret = 0; 287 struct imx_ssi *ssi = platform_get_drvdata(pdev);
288 int ret;
280 289
281 ret = claim_fiq(&fh); 290 ret = claim_fiq(&fh);
282 if (ret) { 291 if (ret) {
283 dev_err(&pdev->dev, "failed to claim fiq: %d", ret); 292 dev_err(&pdev->dev, "failed to claim fiq: %d", ret);
284 return ERR_PTR(ret); 293 return ret;
285 } 294 }
286 295
287 mxc_set_irq_fiq(ssi->irq, 1); 296 mxc_set_irq_fiq(ssi->irq, 1);
297 ssi_irq = ssi->irq;
288 298
289 imx_pcm_fiq = ssi->irq; 299 imx_pcm_fiq = ssi->irq;
290 300
@@ -293,13 +303,43 @@ struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
293 ssi->dma_params_tx.burstsize = 4; 303 ssi->dma_params_tx.burstsize = 4;
294 ssi->dma_params_rx.burstsize = 6; 304 ssi->dma_params_rx.burstsize = 6;
295 305
296 return &imx_soc_platform_fiq; 306 ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
307 if (ret)
308 goto failed_register;
309
310 return 0;
311
312failed_register:
313 mxc_set_irq_fiq(ssi_irq, 0);
314 release_fiq(&fh);
315
316 return ret;
297} 317}
298 318
299void imx_ssi_fiq_exit(struct platform_device *pdev, 319static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
300 struct imx_ssi *ssi)
301{ 320{
302 mxc_set_irq_fiq(ssi->irq, 0); 321 snd_soc_unregister_platform(&pdev->dev);
303 release_fiq(&fh); 322 return 0;
304} 323}
305 324
325static struct platform_driver imx_pcm_driver = {
326 .driver = {
327 .name = "imx-fiq-pcm-audio",
328 .owner = THIS_MODULE,
329 },
330
331 .probe = imx_soc_platform_probe,
332 .remove = __devexit_p(imx_soc_platform_remove),
333};
334
335static int __init snd_imx_pcm_init(void)
336{
337 return platform_driver_register(&imx_pcm_driver);
338}
339module_init(snd_imx_pcm_init);
340
341static void __exit snd_imx_pcm_exit(void)
342{
343 platform_driver_unregister(&imx_pcm_driver);
344}
345module_exit(snd_imx_pcm_exit);
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 50f51624c53..02a3e7c799d 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -61,7 +61,7 @@
61static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, 61static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
62 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 62 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
63{ 63{
64 struct imx_ssi *ssi = cpu_dai->private_data; 64 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
65 u32 sccr; 65 u32 sccr;
66 66
67 sccr = readl(ssi->base + SSI_STCCR); 67 sccr = readl(ssi->base + SSI_STCCR);
@@ -86,7 +86,7 @@ static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
86 */ 86 */
87static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) 87static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
88{ 88{
89 struct imx_ssi *ssi = cpu_dai->private_data; 89 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
90 u32 strcr = 0, scr; 90 u32 strcr = 0, scr;
91 91
92 scr = readl(ssi->base + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET); 92 scr = readl(ssi->base + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET);
@@ -164,7 +164,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
164static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, 164static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
165 int clk_id, unsigned int freq, int dir) 165 int clk_id, unsigned int freq, int dir)
166{ 166{
167 struct imx_ssi *ssi = cpu_dai->private_data; 167 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
168 u32 scr; 168 u32 scr;
169 169
170 scr = readl(ssi->base + SSI_SCR); 170 scr = readl(ssi->base + SSI_SCR);
@@ -192,7 +192,7 @@ static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
192static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, 192static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
193 int div_id, int div) 193 int div_id, int div)
194{ 194{
195 struct imx_ssi *ssi = cpu_dai->private_data; 195 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
196 u32 stccr, srccr; 196 u32 stccr, srccr;
197 197
198 stccr = readl(ssi->base + SSI_STCCR); 198 stccr = readl(ssi->base + SSI_STCCR);
@@ -241,7 +241,7 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
241 struct snd_pcm_hw_params *params, 241 struct snd_pcm_hw_params *params,
242 struct snd_soc_dai *cpu_dai) 242 struct snd_soc_dai *cpu_dai)
243{ 243{
244 struct imx_ssi *ssi = cpu_dai->private_data; 244 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
245 struct imx_pcm_dma_params *dma_data; 245 struct imx_pcm_dma_params *dma_data;
246 u32 reg, sccr; 246 u32 reg, sccr;
247 247
@@ -279,9 +279,7 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
279static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd, 279static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
280 struct snd_soc_dai *dai) 280 struct snd_soc_dai *dai)
281{ 281{
282 struct snd_soc_pcm_runtime *rtd = substream->private_data; 282 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(dai);
283 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
284 struct imx_ssi *ssi = cpu_dai->private_data;
285 unsigned int sier_bits, sier; 283 unsigned int sier_bits, sier;
286 unsigned int scr; 284 unsigned int scr;
287 285
@@ -350,22 +348,6 @@ static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
350 .trigger = imx_ssi_trigger, 348 .trigger = imx_ssi_trigger,
351}; 349};
352 350
353static struct snd_soc_dai imx_ssi_dai = {
354 .playback = {
355 .channels_min = 2,
356 .channels_max = 2,
357 .rates = SNDRV_PCM_RATE_8000_96000,
358 .formats = SNDRV_PCM_FMTBIT_S16_LE,
359 },
360 .capture = {
361 .channels_min = 2,
362 .channels_max = 2,
363 .rates = SNDRV_PCM_RATE_8000_96000,
364 .formats = SNDRV_PCM_FMTBIT_S16_LE,
365 },
366 .ops = &imx_ssi_pcm_dai_ops,
367};
368
369int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, 351int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
370 struct vm_area_struct *vma) 352 struct vm_area_struct *vma)
371{ 353{
@@ -381,6 +363,7 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
381 runtime->dma_bytes); 363 runtime->dma_bytes);
382 return ret; 364 return ret;
383} 365}
366EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap);
384 367
385static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 368static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
386{ 369{
@@ -412,14 +395,14 @@ int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
412 card->dev->dma_mask = &imx_pcm_dmamask; 395 card->dev->dma_mask = &imx_pcm_dmamask;
413 if (!card->dev->coherent_dma_mask) 396 if (!card->dev->coherent_dma_mask)
414 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 397 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
415 if (dai->playback.channels_min) { 398 if (dai->driver->playback.channels_min) {
416 ret = imx_pcm_preallocate_dma_buffer(pcm, 399 ret = imx_pcm_preallocate_dma_buffer(pcm,
417 SNDRV_PCM_STREAM_PLAYBACK); 400 SNDRV_PCM_STREAM_PLAYBACK);
418 if (ret) 401 if (ret)
419 goto out; 402 goto out;
420 } 403 }
421 404
422 if (dai->capture.channels_min) { 405 if (dai->driver->capture.channels_min) {
423 ret = imx_pcm_preallocate_dma_buffer(pcm, 406 ret = imx_pcm_preallocate_dma_buffer(pcm,
424 SNDRV_PCM_STREAM_CAPTURE); 407 SNDRV_PCM_STREAM_CAPTURE);
425 if (ret) 408 if (ret)
@@ -429,6 +412,7 @@ int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
429out: 412out:
430 return ret; 413 return ret;
431} 414}
415EXPORT_SYMBOL_GPL(imx_pcm_new);
432 416
433void imx_pcm_free(struct snd_pcm *pcm) 417void imx_pcm_free(struct snd_pcm *pcm)
434{ 418{
@@ -450,14 +434,40 @@ void imx_pcm_free(struct snd_pcm *pcm)
450 buf->area = NULL; 434 buf->area = NULL;
451 } 435 }
452} 436}
437EXPORT_SYMBOL_GPL(imx_pcm_free);
453 438
454struct snd_soc_platform imx_soc_platform = { 439static struct snd_soc_dai_driver imx_ssi_dai = {
455 .name = "imx-audio", 440 .playback = {
441 .channels_min = 2,
442 .channels_max = 2,
443 .rates = SNDRV_PCM_RATE_8000_96000,
444 .formats = SNDRV_PCM_FMTBIT_S16_LE,
445 },
446 .capture = {
447 .channels_min = 2,
448 .channels_max = 2,
449 .rates = SNDRV_PCM_RATE_8000_96000,
450 .formats = SNDRV_PCM_FMTBIT_S16_LE,
451 },
452 .ops = &imx_ssi_pcm_dai_ops,
456}; 453};
457EXPORT_SYMBOL_GPL(imx_soc_platform);
458 454
459static struct snd_soc_dai imx_ac97_dai = { 455static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
460 .name = "AC97", 456{
457 struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
458 uint32_t val;
459
460 snd_soc_dai_set_drvdata(dai, ssi);
461
462 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
463 SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
464 writel(val, ssi->base + SSI_SFCSR);
465
466 return 0;
467}
468
469static struct snd_soc_dai_driver imx_ac97_dai = {
470 .probe = imx_ssi_dai_probe,
461 .ac97_control = 1, 471 .ac97_control = 1,
462 .playback = { 472 .playback = {
463 .stream_name = "AC97 Playback", 473 .stream_name = "AC97 Playback",
@@ -577,25 +587,18 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
577}; 587};
578EXPORT_SYMBOL_GPL(soc_ac97_ops); 588EXPORT_SYMBOL_GPL(soc_ac97_ops);
579 589
580struct snd_soc_dai imx_ssi_pcm_dai[2];
581EXPORT_SYMBOL_GPL(imx_ssi_pcm_dai);
582
583static int imx_ssi_probe(struct platform_device *pdev) 590static int imx_ssi_probe(struct platform_device *pdev)
584{ 591{
585 struct resource *res; 592 struct resource *res;
586 struct imx_ssi *ssi; 593 struct imx_ssi *ssi;
587 struct imx_ssi_platform_data *pdata = pdev->dev.platform_data; 594 struct imx_ssi_platform_data *pdata = pdev->dev.platform_data;
588 struct snd_soc_platform *platform;
589 int ret = 0; 595 int ret = 0;
590 unsigned int val; 596 struct snd_soc_dai_driver *dai;
591 struct snd_soc_dai *dai = &imx_ssi_pcm_dai[pdev->id];
592
593 if (dai->id >= ARRAY_SIZE(imx_ssi_pcm_dai))
594 return -EINVAL;
595 597
596 ssi = kzalloc(sizeof(*ssi), GFP_KERNEL); 598 ssi = kzalloc(sizeof(*ssi), GFP_KERNEL);
597 if (!ssi) 599 if (!ssi)
598 return -ENOMEM; 600 return -ENOMEM;
601 dev_set_drvdata(&pdev->dev, ssi);
599 602
600 if (pdata) { 603 if (pdata) {
601 ssi->ac97_reset = pdata->ac97_reset; 604 ssi->ac97_reset = pdata->ac97_reset;
@@ -640,9 +643,9 @@ static int imx_ssi_probe(struct platform_device *pdev)
640 } 643 }
641 ac97_ssi = ssi; 644 ac97_ssi = ssi;
642 setup_channel_to_ac97(ssi); 645 setup_channel_to_ac97(ssi);
643 memcpy(dai, &imx_ac97_dai, sizeof(imx_ac97_dai)); 646 dai = &imx_ac97_dai;
644 } else 647 } else
645 memcpy(dai, &imx_ssi_dai, sizeof(imx_ssi_dai)); 648 dai = &imx_ssi_dai;
646 649
647 writel(0x0, ssi->base + SSI_SIER); 650 writel(0x0, ssi->base + SSI_SIER);
648 651
@@ -657,37 +660,36 @@ static int imx_ssi_probe(struct platform_device *pdev)
657 if (res) 660 if (res)
658 ssi->dma_params_rx.dma = res->start; 661 ssi->dma_params_rx.dma = res->start;
659 662
660 dai->id = pdev->id;
661 dai->dev = &pdev->dev;
662 dai->name = kasprintf(GFP_KERNEL, "imx-ssi.%d", pdev->id);
663 dai->private_data = ssi;
664
665 if ((cpu_is_mx27() || cpu_is_mx21()) && 663 if ((cpu_is_mx27() || cpu_is_mx21()) &&
666 !(ssi->flags & IMX_SSI_USE_AC97) && 664 !(ssi->flags & IMX_SSI_USE_AC97) &&
667 (ssi->flags & IMX_SSI_DMA)) { 665 (ssi->flags & IMX_SSI_DMA)) {
668 ssi->flags |= IMX_SSI_DMA; 666 ssi->flags |= IMX_SSI_DMA;
669 platform = imx_ssi_dma_mx2_init(pdev, ssi); 667 }
670 } else
671 platform = imx_ssi_fiq_init(pdev, ssi);
672
673 imx_soc_platform.pcm_ops = platform->pcm_ops;
674 imx_soc_platform.pcm_new = platform->pcm_new;
675 imx_soc_platform.pcm_free = platform->pcm_free;
676 668
677 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) | 669 platform_set_drvdata(pdev, ssi);
678 SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
679 writel(val, ssi->base + SSI_SFCSR);
680 670
681 ret = snd_soc_register_dai(dai); 671 ret = snd_soc_register_dai(&pdev->dev, dai);
682 if (ret) { 672 if (ret) {
683 dev_err(&pdev->dev, "register DAI failed\n"); 673 dev_err(&pdev->dev, "register DAI failed\n");
684 goto failed_register; 674 goto failed_register;
685 } 675 }
686 676
687 platform_set_drvdata(pdev, ssi); 677 ssi->soc_platform_pdev = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
678 if (!ssi->soc_platform_pdev)
679 goto failed_pdev_alloc;
680 platform_set_drvdata(ssi->soc_platform_pdev, ssi);
681 ret = platform_device_add(ssi->soc_platform_pdev);
682 if (ret) {
683 dev_err(&pdev->dev, "failed to add platform device\n");
684 goto failed_pdev_add;
685 }
688 686
689 return 0; 687 return 0;
690 688
689failed_pdev_add:
690 platform_device_put(ssi->soc_platform_pdev);
691failed_pdev_alloc:
692 snd_soc_unregister_dai(&pdev->dev);
691failed_register: 693failed_register:
692failed_ac97: 694failed_ac97:
693 iounmap(ssi->base); 695 iounmap(ssi->base);
@@ -706,16 +708,15 @@ static int __devexit imx_ssi_remove(struct platform_device *pdev)
706{ 708{
707 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 709 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
708 struct imx_ssi *ssi = platform_get_drvdata(pdev); 710 struct imx_ssi *ssi = platform_get_drvdata(pdev);
709 struct snd_soc_dai *dai = &imx_ssi_pcm_dai[pdev->id];
710 711
711 snd_soc_unregister_dai(dai); 712 platform_device_del(ssi->soc_platform_pdev);
713 platform_device_put(ssi->soc_platform_pdev);
714
715 snd_soc_unregister_dai(&pdev->dev);
712 716
713 if (ssi->flags & IMX_SSI_USE_AC97) 717 if (ssi->flags & IMX_SSI_USE_AC97)
714 ac97_ssi = NULL; 718 ac97_ssi = NULL;
715 719
716 if (!(ssi->flags & IMX_SSI_DMA))
717 imx_ssi_fiq_exit(pdev, ssi);
718
719 iounmap(ssi->base); 720 iounmap(ssi->base);
720 release_mem_region(res->start, resource_size(res)); 721 release_mem_region(res->start, resource_size(res));
721 clk_disable(ssi->clk); 722 clk_disable(ssi->clk);
@@ -730,34 +731,19 @@ static struct platform_driver imx_ssi_driver = {
730 .remove = __devexit_p(imx_ssi_remove), 731 .remove = __devexit_p(imx_ssi_remove),
731 732
732 .driver = { 733 .driver = {
733 .name = DRV_NAME, 734 .name = "imx-ssi-dai",
734 .owner = THIS_MODULE, 735 .owner = THIS_MODULE,
735 }, 736 },
736}; 737};
737 738
738static int __init imx_ssi_init(void) 739static int __init imx_ssi_init(void)
739{ 740{
740 int ret; 741 return platform_driver_register(&imx_ssi_driver);
741
742 ret = snd_soc_register_platform(&imx_soc_platform);
743 if (ret) {
744 pr_err("failed to register soc platform: %d\n", ret);
745 return ret;
746 }
747
748 ret = platform_driver_register(&imx_ssi_driver);
749 if (ret) {
750 snd_soc_unregister_platform(&imx_soc_platform);
751 return ret;
752 }
753
754 return 0;
755} 742}
756 743
757static void __exit imx_ssi_exit(void) 744static void __exit imx_ssi_exit(void)
758{ 745{
759 platform_driver_unregister(&imx_ssi_driver); 746 platform_driver_unregister(&imx_ssi_driver);
760 snd_soc_unregister_platform(&imx_soc_platform);
761} 747}
762 748
763module_init(imx_ssi_init); 749module_init(imx_ssi_init);
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
index 55f26ebcd8c..53b780d9b2b 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/imx/imx-ssi.h
@@ -183,9 +183,6 @@
183#define IMX_SSI_RX_DIV_PSR 4 183#define IMX_SSI_RX_DIV_PSR 4
184#define IMX_SSI_RX_DIV_PM 5 184#define IMX_SSI_RX_DIV_PM 5
185 185
186extern struct snd_soc_dai imx_ssi_pcm_dai[2];
187extern struct snd_soc_platform imx_soc_platform;
188
189#define DRV_NAME "imx-ssi" 186#define DRV_NAME "imx-ssi"
190 187
191struct imx_pcm_dma_params { 188struct imx_pcm_dma_params {
@@ -197,7 +194,7 @@ struct imx_pcm_dma_params {
197struct imx_ssi { 194struct imx_ssi {
198 struct platform_device *ac97_dev; 195 struct platform_device *ac97_dev;
199 196
200 struct snd_soc_device imx_ac97; 197 struct snd_soc_dai *imx_ac97;
201 struct clk *clk; 198 struct clk *clk;
202 void __iomem *base; 199 void __iomem *base;
203 int irq; 200 int irq;
@@ -213,6 +210,8 @@ struct imx_ssi {
213 struct imx_pcm_dma_params dma_params_tx; 210 struct imx_pcm_dma_params dma_params_tx;
214 211
215 int enabled; 212 int enabled;
213
214 struct platform_device *soc_platform_pdev;
216}; 215};
217 216
218struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev, 217struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
index a8307d55c70..65f0f99ca6d 100644
--- a/sound/soc/imx/phycore-ac97.c
+++ b/sound/soc/imx/phycore-ac97.c
@@ -32,23 +32,20 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
32 { 32 {
33 .name = "HiFi", 33 .name = "HiFi",
34 .stream_name = "HiFi", 34 .stream_name = "HiFi",
35 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 35 .codec_dai_name = "wm9712-hifi",
36 .codec_name = "wm9712-codec",
37 .cpu_dai_name = "imx-ssi-dai.0",
38 .platform_name = "imx-fiq-pcm-audio.0",
36 .ops = &imx_phycore_hifi_ops, 39 .ops = &imx_phycore_hifi_ops,
37 }, 40 },
38}; 41};
39 42
40static struct snd_soc_card imx_phycore = { 43static struct snd_soc_card imx_phycore = {
41 .name = "PhyCORE-audio", 44 .name = "PhyCORE-audio",
42 .platform = &imx_soc_platform,
43 .dai_link = imx_phycore_dai_ac97, 45 .dai_link = imx_phycore_dai_ac97,
44 .num_links = ARRAY_SIZE(imx_phycore_dai_ac97), 46 .num_links = ARRAY_SIZE(imx_phycore_dai_ac97),
45}; 47};
46 48
47static struct snd_soc_device imx_phycore_snd_devdata = {
48 .card = &imx_phycore,
49 .codec_dev = &soc_codec_dev_wm9712,
50};
51
52static struct platform_device *imx_phycore_snd_device; 49static struct platform_device *imx_phycore_snd_device;
53 50
54static int __init imx_phycore_init(void) 51static int __init imx_phycore_init(void)
@@ -63,10 +60,12 @@ static int __init imx_phycore_init(void)
63 if (!imx_phycore_snd_device) 60 if (!imx_phycore_snd_device)
64 return -ENOMEM; 61 return -ENOMEM;
65 62
66 imx_phycore_dai_ac97[0].cpu_dai = &imx_ssi_pcm_dai[0]; 63 platform_set_drvdata(imx_phycore_snd_device, &imx_phycore);
64 ret = platform_device_add(imx_phycore_snd_device);
67 65
68 platform_set_drvdata(imx_phycore_snd_device, &imx_phycore_snd_devdata); 66 imx_phycore_snd_device = platform_device_alloc("wm9712-codec", -1);
69 imx_phycore_snd_devdata.dev = &imx_phycore_snd_device->dev; 67 if (!imx_phycore_snd_device)
68 return -ENOMEM;
70 ret = platform_device_add(imx_phycore_snd_device); 69 ret = platform_device_add(imx_phycore_snd_device);
71 70
72 if (ret) { 71 if (ret) {
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c
index a6e7d949763..74068636c1d 100644
--- a/sound/soc/imx/wm1133-ev1.c
+++ b/sound/soc/imx/wm1133-ev1.c
@@ -82,8 +82,8 @@ static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream,
82 struct snd_pcm_hw_params *params) 82 struct snd_pcm_hw_params *params)
83{ 83{
84 struct snd_soc_pcm_runtime *rtd = substream->private_data; 84 struct snd_soc_pcm_runtime *rtd = substream->private_data;
85 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 85 struct snd_soc_dai *codec_dai = rtd->codec_dai;
86 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 86 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
87 int i, found = 0; 87 int i, found = 0;
88 snd_pcm_format_t format = params_format(params); 88 snd_pcm_format_t format = params_format(params);
89 unsigned int rate = params_rate(params); 89 unsigned int rate = params_rate(params);
@@ -210,9 +210,9 @@ static struct snd_soc_jack_pin mic_jack_pins[] = {
210 { .pin = "Mic2 Jack", .mask = SND_JACK_MICROPHONE }, 210 { .pin = "Mic2 Jack", .mask = SND_JACK_MICROPHONE },
211}; 211};
212 212
213static int wm1133_ev1_init(struct snd_soc_codec *codec) 213static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
214{ 214{
215 struct snd_soc_card *card = codec->socdev->card; 215 struct snd_soc_codec *codec = rtd->codec;
216 216
217 snd_soc_dapm_new_controls(codec, wm1133_ev1_widgets, 217 snd_soc_dapm_new_controls(codec, wm1133_ev1_widgets,
218 ARRAY_SIZE(wm1133_ev1_widgets)); 218 ARRAY_SIZE(wm1133_ev1_widgets));
@@ -221,13 +221,13 @@ static int wm1133_ev1_init(struct snd_soc_codec *codec)
221 ARRAY_SIZE(wm1133_ev1_map)); 221 ARRAY_SIZE(wm1133_ev1_map));
222 222
223 /* Headphone jack detection */ 223 /* Headphone jack detection */
224 snd_soc_jack_new(card, "Headphone", SND_JACK_HEADPHONE, &hp_jack); 224 snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack);
225 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), 225 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
226 hp_jack_pins); 226 hp_jack_pins);
227 wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE); 227 wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
228 228
229 /* Microphone jack detection */ 229 /* Microphone jack detection */
230 snd_soc_jack_new(card, "Microphone", 230 snd_soc_jack_new(codec, "Microphone",
231 SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack); 231 SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack);
232 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins), 232 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
233 mic_jack_pins); 233 mic_jack_pins);
@@ -243,8 +243,10 @@ static int wm1133_ev1_init(struct snd_soc_codec *codec)
243static struct snd_soc_dai_link wm1133_ev1_dai = { 243static struct snd_soc_dai_link wm1133_ev1_dai = {
244 .name = "WM1133-EV1", 244 .name = "WM1133-EV1",
245 .stream_name = "Audio", 245 .stream_name = "Audio",
246 .cpu_dai = &imx_ssi_pcm_dai[0], 246 .cpu_dai_name = "imx-ssi-dai.0",
247 .codec_dai = &wm8350_dai, 247 .codec_dai_name = "wm8350-hifi",
248 .platform_name = "imx-fiq-pcm-audio.0",
249 .codec_name = "wm8350-codec.0-0x1a",
248 .init = wm1133_ev1_init, 250 .init = wm1133_ev1_init,
249 .ops = &wm1133_ev1_ops, 251 .ops = &wm1133_ev1_ops,
250 .symmetric_rates = 1, 252 .symmetric_rates = 1,
@@ -252,16 +254,10 @@ static struct snd_soc_dai_link wm1133_ev1_dai = {
252 254
253static struct snd_soc_card wm1133_ev1 = { 255static struct snd_soc_card wm1133_ev1 = {
254 .name = "WM1133-EV1", 256 .name = "WM1133-EV1",
255 .platform = &imx_soc_platform,
256 .dai_link = &wm1133_ev1_dai, 257 .dai_link = &wm1133_ev1_dai,
257 .num_links = 1, 258 .num_links = 1,
258}; 259};
259 260
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; 261static struct platform_device *wm1133_ev1_snd_device;
266 262
267static int __init wm1133_ev1_audio_init(void) 263static int __init wm1133_ev1_audio_init(void)
@@ -286,8 +282,7 @@ static int __init wm1133_ev1_audio_init(void)
286 if (!wm1133_ev1_snd_device) 282 if (!wm1133_ev1_snd_device)
287 return -ENOMEM; 283 return -ENOMEM;
288 284
289 platform_set_drvdata(wm1133_ev1_snd_device, &wm1133_ev1_snd_devdata); 285 platform_set_drvdata(wm1133_ev1_snd_device, &wm1133_ev1);
290 wm1133_ev1_snd_devdata.dev = &wm1133_ev1_snd_device->dev;
291 ret = platform_device_add(wm1133_ev1_snd_device); 286 ret = platform_device_add(wm1133_ev1_snd_device);
292 287
293 if (ret) 288 if (ret)
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index eb518f0c5e0..f3cffd18340 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -106,15 +106,10 @@ static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
106 writel(value, i2s->base + reg); 106 writel(value, i2s->base + reg);
107} 107}
108 108
109static inline struct jz4740_i2s *jz4740_dai_to_i2s(struct snd_soc_dai *dai)
110{
111 return dai->private_data;
112}
113
114static int jz4740_i2s_startup(struct snd_pcm_substream *substream, 109static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
115 struct snd_soc_dai *dai) 110 struct snd_soc_dai *dai)
116{ 111{
117 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); 112 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
118 uint32_t conf, ctrl; 113 uint32_t conf, ctrl;
119 114
120 if (dai->active) 115 if (dai->active)
@@ -136,7 +131,7 @@ static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
136static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream, 131static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream,
137 struct snd_soc_dai *dai) 132 struct snd_soc_dai *dai)
138{ 133{
139 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); 134 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
140 uint32_t conf; 135 uint32_t conf;
141 136
142 if (!dai->active) 137 if (!dai->active)
@@ -152,7 +147,7 @@ static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream,
152static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 147static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
153 struct snd_soc_dai *dai) 148 struct snd_soc_dai *dai)
154{ 149{
155 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); 150 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
156 151
157 uint32_t ctrl; 152 uint32_t ctrl;
158 uint32_t mask; 153 uint32_t mask;
@@ -186,7 +181,7 @@ static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
186 181
187static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 182static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
188{ 183{
189 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); 184 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
190 185
191 uint32_t format = 0; 186 uint32_t format = 0;
192 uint32_t conf; 187 uint32_t conf;
@@ -238,7 +233,7 @@ static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
238static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, 233static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 234 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
240{ 235{
241 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); 236 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
242 enum jz4740_dma_width dma_width; 237 enum jz4740_dma_width dma_width;
243 struct jz4740_pcm_config *pcm_config; 238 struct jz4740_pcm_config *pcm_config;
244 unsigned int sample_size; 239 unsigned int sample_size;
@@ -288,7 +283,7 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
288static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, 283static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
289 unsigned int freq, int dir) 284 unsigned int freq, int dir)
290{ 285{
291 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); 286 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
292 struct clk *parent; 287 struct clk *parent;
293 int ret = 0; 288 int ret = 0;
294 289
@@ -312,7 +307,7 @@ static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
312 307
313static int jz4740_i2s_suspend(struct snd_soc_dai *dai) 308static int jz4740_i2s_suspend(struct snd_soc_dai *dai)
314{ 309{
315 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); 310 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
316 uint32_t conf; 311 uint32_t conf;
317 312
318 if (dai->active) { 313 if (dai->active) {
@@ -330,7 +325,7 @@ static int jz4740_i2s_suspend(struct snd_soc_dai *dai)
330 325
331static int jz4740_i2s_resume(struct snd_soc_dai *dai) 326static int jz4740_i2s_resume(struct snd_soc_dai *dai)
332{ 327{
333 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); 328 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
334 uint32_t conf; 329 uint32_t conf;
335 330
336 clk_enable(i2s->clk_aic); 331 clk_enable(i2s->clk_aic);
@@ -346,11 +341,38 @@ static int jz4740_i2s_resume(struct snd_soc_dai *dai)
346 return 0; 341 return 0;
347} 342}
348 343
349static int jz4740_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai) 344static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
350{ 345{
351 struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai); 346 struct jz4740_dma_config *dma_config;
347
348 /* Playback */
349 dma_config = &i2s->pcm_config_playback.dma_config;
350 dma_config->src_width = JZ4740_DMA_WIDTH_32BIT,
351 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
352 dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT;
353 dma_config->flags = JZ4740_DMA_SRC_AUTOINC;
354 dma_config->mode = JZ4740_DMA_MODE_SINGLE;
355 i2s->pcm_config_playback.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO;
356
357 /* Capture */
358 dma_config = &i2s->pcm_config_capture.dma_config;
359 dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT,
360 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
361 dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE;
362 dma_config->flags = JZ4740_DMA_DST_AUTOINC;
363 dma_config->mode = JZ4740_DMA_MODE_SINGLE;
364 i2s->pcm_config_capture.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO;
365}
366
367static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
368{
369 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
352 uint32_t conf; 370 uint32_t conf;
353 371
372 clk_enable(i2s->clk_aic);
373
374 jz4740_i2c_init_pcm_config(i2s);
375
354 conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | 376 conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
355 (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | 377 (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
356 JZ_AIC_CONF_OVERFLOW_PLAY_LAST | 378 JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
@@ -363,6 +385,14 @@ static int jz4740_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *da
363 return 0; 385 return 0;
364} 386}
365 387
388static int jz4740_i2s_dai_remove(struct snd_soc_dai *dai)
389{
390 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
391
392 clk_disable(i2s->clk_aic);
393 return 0;
394}
395
366static struct snd_soc_dai_ops jz4740_i2s_dai_ops = { 396static struct snd_soc_dai_ops jz4740_i2s_dai_ops = {
367 .startup = jz4740_i2s_startup, 397 .startup = jz4740_i2s_startup,
368 .shutdown = jz4740_i2s_shutdown, 398 .shutdown = jz4740_i2s_shutdown,
@@ -375,9 +405,9 @@ static struct snd_soc_dai_ops jz4740_i2s_dai_ops = {
375#define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ 405#define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
376 SNDRV_PCM_FMTBIT_S16_LE) 406 SNDRV_PCM_FMTBIT_S16_LE)
377 407
378struct snd_soc_dai jz4740_i2s_dai = { 408static struct snd_soc_dai_driver jz4740_i2s_dai = {
379 .name = "jz4740-i2s", 409 .probe = jz4740_i2s_dai_probe,
380 .probe = jz4740_i2s_probe, 410 .remove = jz4740_i2s_dai_remove,
381 .playback = { 411 .playback = {
382 .channels_min = 1, 412 .channels_min = 1,
383 .channels_max = 2, 413 .channels_max = 2,
@@ -395,30 +425,6 @@ struct snd_soc_dai jz4740_i2s_dai = {
395 .suspend = jz4740_i2s_suspend, 425 .suspend = jz4740_i2s_suspend,
396 .resume = jz4740_i2s_resume, 426 .resume = jz4740_i2s_resume,
397}; 427};
398EXPORT_SYMBOL_GPL(jz4740_i2s_dai);
399
400static void __devinit jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
401{
402 struct jz4740_dma_config *dma_config;
403
404 /* Playback */
405 dma_config = &i2s->pcm_config_playback.dma_config;
406 dma_config->src_width = JZ4740_DMA_WIDTH_32BIT,
407 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
408 dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT;
409 dma_config->flags = JZ4740_DMA_SRC_AUTOINC;
410 dma_config->mode = JZ4740_DMA_MODE_SINGLE;
411 i2s->pcm_config_playback.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO;
412
413 /* Capture */
414 dma_config = &i2s->pcm_config_capture.dma_config;
415 dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT,
416 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
417 dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE;
418 dma_config->flags = JZ4740_DMA_DST_AUTOINC;
419 dma_config->mode = JZ4740_DMA_MODE_SINGLE;
420 i2s->pcm_config_capture.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO;
421}
422 428
423static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev) 429static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev)
424{ 430{
@@ -463,24 +469,17 @@ static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev)
463 goto err_clk_put_aic; 469 goto err_clk_put_aic;
464 } 470 }
465 471
466 clk_enable(i2s->clk_aic); 472 platform_set_drvdata(pdev, i2s);
467 473 ret = snd_soc_register_dai(&pdev->dev, &jz4740_i2s_dai);
468 jz4740_i2c_init_pcm_config(i2s);
469
470 jz4740_i2s_dai.private_data = i2s;
471 ret = snd_soc_register_dai(&jz4740_i2s_dai);
472 474
473 if (ret) { 475 if (ret) {
474 dev_err(&pdev->dev, "Failed to register DAI\n"); 476 dev_err(&pdev->dev, "Failed to register DAI\n");
475 goto err_clk_put_i2s; 477 goto err_clk_put_i2s;
476 } 478 }
477 479
478 platform_set_drvdata(pdev, i2s);
479
480 return 0; 480 return 0;
481 481
482err_clk_put_i2s: 482err_clk_put_i2s:
483 clk_disable(i2s->clk_aic);
484 clk_put(i2s->clk_i2s); 483 clk_put(i2s->clk_i2s);
485err_clk_put_aic: 484err_clk_put_aic:
486 clk_put(i2s->clk_aic); 485 clk_put(i2s->clk_aic);
@@ -498,9 +497,8 @@ static int __devexit jz4740_i2s_dev_remove(struct platform_device *pdev)
498{ 497{
499 struct jz4740_i2s *i2s = platform_get_drvdata(pdev); 498 struct jz4740_i2s *i2s = platform_get_drvdata(pdev);
500 499
501 snd_soc_unregister_dai(&jz4740_i2s_dai); 500 snd_soc_unregister_dai(&pdev->dev);
502 501
503 clk_disable(i2s->clk_aic);
504 clk_put(i2s->clk_i2s); 502 clk_put(i2s->clk_i2s);
505 clk_put(i2s->clk_aic); 503 clk_put(i2s->clk_aic);
506 504
diff --git a/sound/soc/jz4740/jz4740-i2s.h b/sound/soc/jz4740/jz4740-i2s.h
index da22ed88a58..5e49339d8b9 100644
--- a/sound/soc/jz4740/jz4740-i2s.h
+++ b/sound/soc/jz4740/jz4740-i2s.h
@@ -13,6 +13,4 @@
13 13
14#define JZ4740_I2S_BIT_CLK 0 14#define JZ4740_I2S_BIT_CLK 0
15 15
16extern struct snd_soc_dai jz4740_i2s_dai;
17
18#endif 16#endif
diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c
index ee68d850c8d..fb1483f7c96 100644
--- a/sound/soc/jz4740/jz4740-pcm.c
+++ b/sound/soc/jz4740/jz4740-pcm.c
@@ -109,7 +109,7 @@ static int jz4740_pcm_hw_params(struct snd_pcm_substream *substream,
109 struct snd_soc_pcm_runtime *rtd = substream->private_data; 109 struct snd_soc_pcm_runtime *rtd = substream->private_data;
110 struct jz4740_pcm_config *config; 110 struct jz4740_pcm_config *config;
111 111
112 config = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 112 config = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
113 113
114 if (!config) 114 if (!config)
115 return 0; 115 return 0;
@@ -310,14 +310,14 @@ int jz4740_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
310 if (!card->dev->coherent_dma_mask) 310 if (!card->dev->coherent_dma_mask)
311 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 311 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
312 312
313 if (dai->playback.channels_min) { 313 if (dai->driver->playback.channels_min) {
314 ret = jz4740_pcm_preallocate_dma_buffer(pcm, 314 ret = jz4740_pcm_preallocate_dma_buffer(pcm,
315 SNDRV_PCM_STREAM_PLAYBACK); 315 SNDRV_PCM_STREAM_PLAYBACK);
316 if (ret) 316 if (ret)
317 goto err; 317 goto err;
318 } 318 }
319 319
320 if (dai->capture.channels_min) { 320 if (dai->driver->capture.channels_min) {
321 ret = jz4740_pcm_preallocate_dma_buffer(pcm, 321 ret = jz4740_pcm_preallocate_dma_buffer(pcm,
322 SNDRV_PCM_STREAM_CAPTURE); 322 SNDRV_PCM_STREAM_CAPTURE);
323 if (ret) 323 if (ret)
@@ -328,22 +328,20 @@ err:
328 return ret; 328 return ret;
329} 329}
330 330
331struct snd_soc_platform jz4740_soc_platform = { 331static struct snd_soc_platform_driver jz4740_soc_platform = {
332 .name = "jz4740-pcm", 332 .ops = &jz4740_pcm_ops,
333 .pcm_ops = &jz4740_pcm_ops,
334 .pcm_new = jz4740_pcm_new, 333 .pcm_new = jz4740_pcm_new,
335 .pcm_free = jz4740_pcm_free, 334 .pcm_free = jz4740_pcm_free,
336}; 335};
337EXPORT_SYMBOL_GPL(jz4740_soc_platform);
338 336
339static int __devinit jz4740_pcm_probe(struct platform_device *pdev) 337static int __devinit jz4740_pcm_probe(struct platform_device *pdev)
340{ 338{
341 return snd_soc_register_platform(&jz4740_soc_platform); 339 return snd_soc_register_platform(&pdev->dev, &jz4740_soc_platform);
342} 340}
343 341
344static int __devexit jz4740_pcm_remove(struct platform_device *pdev) 342static int __devexit jz4740_pcm_remove(struct platform_device *pdev)
345{ 343{
346 snd_soc_unregister_platform(&jz4740_soc_platform); 344 snd_soc_unregister_platform(&pdev->dev);
347 return 0; 345 return 0;
348} 346}
349 347
@@ -351,7 +349,7 @@ static struct platform_driver jz4740_pcm_driver = {
351 .probe = jz4740_pcm_probe, 349 .probe = jz4740_pcm_probe,
352 .remove = __devexit_p(jz4740_pcm_remove), 350 .remove = __devexit_p(jz4740_pcm_remove),
353 .driver = { 351 .driver = {
354 .name = "jz4740-pcm", 352 .name = "jz4740-pcm-audio",
355 .owner = THIS_MODULE, 353 .owner = THIS_MODULE,
356 }, 354 },
357}; 355};
diff --git a/sound/soc/jz4740/jz4740-pcm.h b/sound/soc/jz4740/jz4740-pcm.h
index e3f221e2779..1220cbb4382 100644
--- a/sound/soc/jz4740/jz4740-pcm.h
+++ b/sound/soc/jz4740/jz4740-pcm.h
@@ -11,8 +11,6 @@
11#include <linux/dma-mapping.h> 11#include <linux/dma-mapping.h>
12#include <asm/mach-jz4740/dma.h> 12#include <asm/mach-jz4740/dma.h>
13 13
14/* platform data */
15extern struct snd_soc_platform jz4740_soc_platform;
16 14
17struct jz4740_pcm_config { 15struct jz4740_pcm_config {
18 struct jz4740_dma_config dma_config; 16 struct jz4740_dma_config dma_config;
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
index f15f4918f15..78dabebe8fd 100644
--- a/sound/soc/jz4740/qi_lb60.c
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -60,10 +60,11 @@ static const struct snd_soc_dapm_route qi_lb60_routes[] = {
60 SND_SOC_DAIFMT_NB_NF | \ 60 SND_SOC_DAIFMT_NB_NF | \
61 SND_SOC_DAIFMT_CBM_CFM) 61 SND_SOC_DAIFMT_CBM_CFM)
62 62
63static int qi_lb60_codec_init(struct snd_soc_codec *codec) 63static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
64{ 64{
65 struct snd_soc_codec *codec = rtd->codec;
66 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
65 int ret; 67 int ret;
66 struct snd_soc_dai *cpu_dai = codec->socdev->card->dai_link->cpu_dai;
67 68
68 snd_soc_dapm_nc_pin(codec, "LIN"); 69 snd_soc_dapm_nc_pin(codec, "LIN");
69 snd_soc_dapm_nc_pin(codec, "RIN"); 70 snd_soc_dapm_nc_pin(codec, "RIN");
@@ -84,8 +85,10 @@ static int qi_lb60_codec_init(struct snd_soc_codec *codec)
84static struct snd_soc_dai_link qi_lb60_dai = { 85static struct snd_soc_dai_link qi_lb60_dai = {
85 .name = "jz4740", 86 .name = "jz4740",
86 .stream_name = "jz4740", 87 .stream_name = "jz4740",
87 .cpu_dai = &jz4740_i2s_dai, 88 .cpu_dai_name = "jz4740-i2s",
88 .codec_dai = &jz4740_codec_dai, 89 .platform_name = "jz4740-pmc-audio",
90 .codec_dai_name = "jz4740-hifi",
91 .codec_name = "jz4740-codec",
89 .init = qi_lb60_codec_init, 92 .init = qi_lb60_codec_init,
90}; 93};
91 94
@@ -93,12 +96,6 @@ static struct snd_soc_card qi_lb60 = {
93 .name = "QI LB60", 96 .name = "QI LB60",
94 .dai_link = &qi_lb60_dai, 97 .dai_link = &qi_lb60_dai,
95 .num_links = 1, 98 .num_links = 1,
96 .platform = &jz4740_soc_platform,
97};
98
99static struct snd_soc_device qi_lb60_snd_devdata = {
100 .card = &qi_lb60,
101 .codec_dev = &soc_codec_dev_jz4740_codec,
102}; 99};
103 100
104static struct platform_device *qi_lb60_snd_device; 101static struct platform_device *qi_lb60_snd_device;
@@ -129,8 +126,7 @@ static int __init qi_lb60_init(void)
129 gpio_direction_output(QI_LB60_SND_GPIO, 0); 126 gpio_direction_output(QI_LB60_SND_GPIO, 0);
130 gpio_direction_output(QI_LB60_AMP_GPIO, 0); 127 gpio_direction_output(QI_LB60_AMP_GPIO, 0);
131 128
132 platform_set_drvdata(qi_lb60_snd_device, &qi_lb60_snd_devdata); 129 platform_set_drvdata(qi_lb60_snd_device, &qi_lb60);
133 qi_lb60_snd_devdata.dev = &qi_lb60_snd_device->dev;
134 130
135 ret = platform_device_add(qi_lb60_snd_device); 131 ret = platform_device_add(qi_lb60_snd_device);
136 if (ret) { 132 if (ret) {
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index a30205be3e2..693049d42d2 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -18,7 +18,6 @@
18#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
19#include <linux/mbus.h> 19#include <linux/mbus.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include "kirkwood-dma.h"
22#include "kirkwood.h" 21#include "kirkwood.h"
23 22
24#define KIRKWOOD_RATES \ 23#define KIRKWOOD_RATES \
@@ -123,9 +122,10 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream)
123 int err; 122 int err;
124 struct snd_pcm_runtime *runtime = substream->runtime; 123 struct snd_pcm_runtime *runtime = substream->runtime;
125 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 124 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
126 struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai; 125 struct snd_soc_platform *platform = soc_runtime->platform;
126 struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
127 struct kirkwood_dma_data *priv; 127 struct kirkwood_dma_data *priv;
128 struct kirkwood_dma_priv *prdata = cpu_dai->private_data; 128 struct kirkwood_dma_priv *prdata = snd_soc_platform_get_drvdata(platform);
129 unsigned long addr; 129 unsigned long addr;
130 130
131 priv = snd_soc_dai_get_dma_data(cpu_dai, substream); 131 priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
@@ -151,7 +151,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream)
151 if (err < 0) 151 if (err < 0)
152 return err; 152 return err;
153 153
154 if (soc_runtime->dai->cpu_dai->private_data == NULL) { 154 if (prdata == NULL) {
155 prdata = kzalloc(sizeof(struct kirkwood_dma_priv), GFP_KERNEL); 155 prdata = kzalloc(sizeof(struct kirkwood_dma_priv), GFP_KERNEL);
156 if (prdata == NULL) 156 if (prdata == NULL)
157 return -ENOMEM; 157 return -ENOMEM;
@@ -165,7 +165,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream)
165 return -EBUSY; 165 return -EBUSY;
166 } 166 }
167 167
168 soc_runtime->dai->cpu_dai->private_data = prdata; 168 snd_soc_platform_set_drvdata(platform, prdata);
169 169
170 /* 170 /*
171 * Enable Error interrupts. We're only ack'ing them but 171 * Enable Error interrupts. We're only ack'ing them but
@@ -191,8 +191,9 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream)
191static int kirkwood_dma_close(struct snd_pcm_substream *substream) 191static int kirkwood_dma_close(struct snd_pcm_substream *substream)
192{ 192{
193 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 193 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
194 struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai; 194 struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
195 struct kirkwood_dma_priv *prdata = cpu_dai->private_data; 195 struct snd_soc_platform *platform = soc_runtime->platform;
196 struct kirkwood_dma_priv *prdata = snd_soc_platform_get_drvdata(platform);
196 struct kirkwood_dma_data *priv; 197 struct kirkwood_dma_data *priv;
197 198
198 priv = snd_soc_dai_get_dma_data(cpu_dai, substream); 199 priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
@@ -209,7 +210,7 @@ static int kirkwood_dma_close(struct snd_pcm_substream *substream)
209 writel(0, priv->io + KIRKWOOD_ERR_MASK); 210 writel(0, priv->io + KIRKWOOD_ERR_MASK);
210 free_irq(priv->irq, prdata); 211 free_irq(priv->irq, prdata);
211 kfree(prdata); 212 kfree(prdata);
212 soc_runtime->dai->cpu_dai->private_data = NULL; 213 snd_soc_platform_set_drvdata(platform, NULL);
213 } 214 }
214 215
215 return 0; 216 return 0;
@@ -236,7 +237,7 @@ static int kirkwood_dma_prepare(struct snd_pcm_substream *substream)
236{ 237{
237 struct snd_pcm_runtime *runtime = substream->runtime; 238 struct snd_pcm_runtime *runtime = substream->runtime;
238 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 239 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
239 struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai; 240 struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
240 struct kirkwood_dma_data *priv; 241 struct kirkwood_dma_data *priv;
241 unsigned long size, count; 242 unsigned long size, count;
242 243
@@ -265,7 +266,7 @@ static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream
265 *substream) 266 *substream)
266{ 267{
267 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 268 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
268 struct snd_soc_dai *cpu_dai = soc_runtime->dai->cpu_dai; 269 struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
269 struct kirkwood_dma_data *priv; 270 struct kirkwood_dma_data *priv;
270 snd_pcm_uframes_t count; 271 snd_pcm_uframes_t count;
271 272
@@ -320,14 +321,14 @@ static int kirkwood_dma_new(struct snd_card *card,
320 if (!card->dev->coherent_dma_mask) 321 if (!card->dev->coherent_dma_mask)
321 card->dev->coherent_dma_mask = 0xffffffff; 322 card->dev->coherent_dma_mask = 0xffffffff;
322 323
323 if (dai->playback.channels_min) { 324 if (dai->driver->playback.channels_min) {
324 ret = kirkwood_dma_preallocate_dma_buffer(pcm, 325 ret = kirkwood_dma_preallocate_dma_buffer(pcm,
325 SNDRV_PCM_STREAM_PLAYBACK); 326 SNDRV_PCM_STREAM_PLAYBACK);
326 if (ret) 327 if (ret)
327 return ret; 328 return ret;
328 } 329 }
329 330
330 if (dai->capture.channels_min) { 331 if (dai->driver->capture.channels_min) {
331 ret = kirkwood_dma_preallocate_dma_buffer(pcm, 332 ret = kirkwood_dma_preallocate_dma_buffer(pcm,
332 SNDRV_PCM_STREAM_CAPTURE); 333 SNDRV_PCM_STREAM_CAPTURE);
333 if (ret) 334 if (ret)
@@ -357,25 +358,44 @@ static void kirkwood_dma_free_dma_buffers(struct snd_pcm *pcm)
357 } 358 }
358} 359}
359 360
360struct snd_soc_platform kirkwood_soc_platform = { 361static struct snd_soc_platform_driver kirkwood_soc_platform = {
361 .name = "kirkwood-dma", 362 .ops = &kirkwood_dma_ops,
362 .pcm_ops = &kirkwood_dma_ops,
363 .pcm_new = kirkwood_dma_new, 363 .pcm_new = kirkwood_dma_new,
364 .pcm_free = kirkwood_dma_free_dma_buffers, 364 .pcm_free = kirkwood_dma_free_dma_buffers,
365}; 365};
366EXPORT_SYMBOL_GPL(kirkwood_soc_platform);
367 366
368static int __init kirkwood_soc_platform_init(void) 367static int __devinit kirkwood_soc_platform_probe(struct platform_device *pdev)
369{ 368{
370 return snd_soc_register_platform(&kirkwood_soc_platform); 369 return snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform);
371} 370}
372module_init(kirkwood_soc_platform_init);
373 371
374static void __exit kirkwood_soc_platform_exit(void) 372static int __devexit kirkwood_soc_platform_remove(struct platform_device *pdev)
375{ 373{
376 snd_soc_unregister_platform(&kirkwood_soc_platform); 374 snd_soc_unregister_platform(&pdev->dev);
375 return 0;
376}
377
378static struct platform_driver kirkwood_pcm_driver = {
379 .driver = {
380 .name = "kirkwood-pcm-audio",
381 .owner = THIS_MODULE,
382 },
383
384 .probe = kirkwood_soc_platform_probe,
385 .remove = __devexit_p(kirkwood_soc_platform_remove),
386};
387
388static int __init kirkwood_pcm_init(void)
389{
390 return platform_driver_register(&kirkwood_pcm_driver);
391}
392module_init(kirkwood_pcm_init);
393
394static void __exit kirkwood_pcm_exit(void)
395{
396 platform_driver_unregister(&kirkwood_pcm_driver);
377} 397}
378module_exit(kirkwood_soc_platform_exit); 398module_exit(kirkwood_pcm_exit);
379 399
380MODULE_AUTHOR("Arnaud Patard <apatard@mandriva.com>"); 400MODULE_AUTHOR("Arnaud Patard <apatard@mandriva.com>");
381MODULE_DESCRIPTION("Marvell Kirkwood Audio DMA module"); 401MODULE_DESCRIPTION("Marvell Kirkwood Audio DMA module");
diff --git a/sound/soc/kirkwood/kirkwood-dma.h b/sound/soc/kirkwood/kirkwood-dma.h
deleted file mode 100644
index ba4454cd34f..00000000000
--- a/sound/soc/kirkwood/kirkwood-dma.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * kirkwood-dma.h
3 *
4 * (c) 2010 Arnaud Patard <apatard@mandriva.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#ifndef _KIRKWOOD_DMA_H
13#define _KIRKWOOD_DMA_H
14
15extern struct snd_soc_platform kirkwood_soc_platform;
16
17#endif
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 981ffc2a13c..9b62cba4f59 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -20,7 +20,6 @@
20#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <plat/audio.h> 22#include <plat/audio.h>
23#include "kirkwood-i2s.h"
24#include "kirkwood.h" 23#include "kirkwood.h"
25 24
26#define DRV_NAME "kirkwood-i2s" 25#define DRV_NAME "kirkwood-i2s"
@@ -33,13 +32,10 @@
33 SNDRV_PCM_FMTBIT_S24_LE | \ 32 SNDRV_PCM_FMTBIT_S24_LE | \
34 SNDRV_PCM_FMTBIT_S32_LE) 33 SNDRV_PCM_FMTBIT_S32_LE)
35 34
36
37struct snd_soc_dai kirkwood_i2s_dai;
38static struct kirkwood_dma_data *priv;
39
40static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai, 35static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
41 unsigned int fmt) 36 unsigned int fmt)
42{ 37{
38 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(cpu_dai);
43 unsigned long mask; 39 unsigned long mask;
44 unsigned long value; 40 unsigned long value;
45 41
@@ -101,10 +97,20 @@ static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate)
101 } while (value == 0); 97 } while (value == 0);
102} 98}
103 99
100static int kirkwood_i2s_startup(struct snd_pcm_substream *substream,
101 struct snd_soc_dai *dai)
102{
103 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
104
105 snd_soc_dai_set_dma_data(dai, substream, priv);
106 return 0;
107}
108
104static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream, 109static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
105 struct snd_pcm_hw_params *params, 110 struct snd_pcm_hw_params *params,
106 struct snd_soc_dai *dai) 111 struct snd_soc_dai *dai)
107{ 112{
113 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
108 unsigned int i2s_reg, reg; 114 unsigned int i2s_reg, reg;
109 unsigned long i2s_value, value; 115 unsigned long i2s_value, value;
110 116
@@ -171,6 +177,7 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
171static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, 177static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
172 int cmd, struct snd_soc_dai *dai) 178 int cmd, struct snd_soc_dai *dai)
173{ 179{
180 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
174 unsigned long value; 181 unsigned long value;
175 182
176 /* 183 /*
@@ -244,6 +251,7 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
244static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream, 251static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
245 int cmd, struct snd_soc_dai *dai) 252 int cmd, struct snd_soc_dai *dai)
246{ 253{
254 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
247 unsigned long value; 255 unsigned long value;
248 256
249 value = readl(priv->io + KIRKWOOD_RECCTL); 257 value = readl(priv->io + KIRKWOOD_RECCTL);
@@ -323,9 +331,9 @@ static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
323 return 0; 331 return 0;
324} 332}
325 333
326static int kirkwood_i2s_probe(struct platform_device *pdev, 334static int kirkwood_i2s_probe(struct snd_soc_dai *dai)
327 struct snd_soc_dai *dai)
328{ 335{
336 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
329 unsigned long value; 337 unsigned long value;
330 unsigned int reg_data; 338 unsigned int reg_data;
331 339
@@ -359,21 +367,20 @@ static int kirkwood_i2s_probe(struct platform_device *pdev,
359 367
360} 368}
361 369
362static void kirkwood_i2s_remove(struct platform_device *pdev, 370static int kirkwood_i2s_remove(struct snd_soc_dai *dai)
363 struct snd_soc_dai *dai)
364{ 371{
372 return 0;
365} 373}
366 374
367static struct snd_soc_dai_ops kirkwood_i2s_dai_ops = { 375static struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
376 .startup = kirkwood_i2s_startup,
368 .trigger = kirkwood_i2s_trigger, 377 .trigger = kirkwood_i2s_trigger,
369 .hw_params = kirkwood_i2s_hw_params, 378 .hw_params = kirkwood_i2s_hw_params,
370 .set_fmt = kirkwood_i2s_set_fmt, 379 .set_fmt = kirkwood_i2s_set_fmt,
371}; 380};
372 381
373 382
374struct snd_soc_dai kirkwood_i2s_dai = { 383static struct snd_soc_dai_driver kirkwood_i2s_dai = {
375 .name = DRV_NAME,
376 .id = 0,
377 .probe = kirkwood_i2s_probe, 384 .probe = kirkwood_i2s_probe,
378 .remove = kirkwood_i2s_remove, 385 .remove = kirkwood_i2s_remove,
379 .playback = { 386 .playback = {
@@ -388,13 +395,13 @@ struct snd_soc_dai kirkwood_i2s_dai = {
388 .formats = KIRKWOOD_I2S_FORMATS,}, 395 .formats = KIRKWOOD_I2S_FORMATS,},
389 .ops = &kirkwood_i2s_dai_ops, 396 .ops = &kirkwood_i2s_dai_ops,
390}; 397};
391EXPORT_SYMBOL_GPL(kirkwood_i2s_dai);
392 398
393static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev) 399static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
394{ 400{
395 struct resource *mem; 401 struct resource *mem;
396 struct kirkwood_asoc_platform_data *data = 402 struct kirkwood_asoc_platform_data *data =
397 pdev->dev.platform_data; 403 pdev->dev.platform_data;
404 struct kirkwood_dma_data *priv;
398 int err; 405 int err;
399 406
400 priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL); 407 priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL);
@@ -403,6 +410,7 @@ static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
403 err = -ENOMEM; 410 err = -ENOMEM;
404 goto error; 411 goto error;
405 } 412 }
413 dev_set_drvdata(&pdev->dev, priv);
406 414
407 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 415 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
408 if (!mem) { 416 if (!mem) {
@@ -441,10 +449,7 @@ static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
441 priv->dram = data->dram; 449 priv->dram = data->dram;
442 priv->burst = data->burst; 450 priv->burst = data->burst;
443 451
444 kirkwood_i2s_dai.capture.dma_data = priv; 452 return snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai);
445 kirkwood_i2s_dai.playback.dma_data = priv;
446
447 return snd_soc_register_dai(&kirkwood_i2s_dai);
448 453
449err_ioremap: 454err_ioremap:
450 iounmap(priv->io); 455 iounmap(priv->io);
@@ -458,12 +463,13 @@ error:
458 463
459static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev) 464static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev)
460{ 465{
461 if (priv) { 466 struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
462 iounmap(priv->io); 467
463 release_mem_region(priv->mem->start, SZ_16K); 468 snd_soc_unregister_dai(&pdev->dev);
464 kfree(priv); 469 iounmap(priv->io);
465 } 470 release_mem_region(priv->mem->start, SZ_16K);
466 snd_soc_unregister_dai(&kirkwood_i2s_dai); 471 kfree(priv);
472
467 return 0; 473 return 0;
468} 474}
469 475
diff --git a/sound/soc/kirkwood/kirkwood-i2s.h b/sound/soc/kirkwood/kirkwood-i2s.h
deleted file mode 100644
index c5595c616d7..00000000000
--- a/sound/soc/kirkwood/kirkwood-i2s.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * kirkwood-i2s.h
3 *
4 * (c) 2010 Arnaud Patard <apatard@mandriva.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#ifndef _KIRKWOOD_I2S_H
13#define _KIRKWOOD_I2S_H
14
15extern struct snd_soc_dai kirkwood_i2s_dai;
16
17#endif
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
index 0353d06bc41..cc1a1e277ed 100644
--- a/sound/soc/kirkwood/kirkwood-openrd.c
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -18,16 +18,14 @@
18#include <mach/kirkwood.h> 18#include <mach/kirkwood.h>
19#include <plat/audio.h> 19#include <plat/audio.h>
20#include <asm/mach-types.h> 20#include <asm/mach-types.h>
21#include "kirkwood-i2s.h"
22#include "kirkwood-dma.h"
23#include "../codecs/cs42l51.h" 21#include "../codecs/cs42l51.h"
24 22
25static int openrd_client_hw_params(struct snd_pcm_substream *substream, 23static int openrd_client_hw_params(struct snd_pcm_substream *substream,
26 struct snd_pcm_hw_params *params) 24 struct snd_pcm_hw_params *params)
27{ 25{
28 struct snd_soc_pcm_runtime *rtd = substream->private_data; 26 struct snd_soc_pcm_runtime *rtd = substream->private_data;
29 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 27 struct snd_soc_dai *codec_dai = rtd->codec_dai;
30 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 28 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
31 int ret; 29 int ret;
32 unsigned int freq, fmt; 30 unsigned int freq, fmt;
33 31
@@ -66,8 +64,10 @@ static struct snd_soc_dai_link openrd_client_dai[] = {
66{ 64{
67 .name = "CS42L51", 65 .name = "CS42L51",
68 .stream_name = "CS42L51 HiFi", 66 .stream_name = "CS42L51 HiFi",
69 .cpu_dai = &kirkwood_i2s_dai, 67 .cpu_dai_name = "kirkwood-i2s",
70 .codec_dai = &cs42l51_dai, 68 .platform_name = "kirkwood-pcm-audio",
69 .codec_dai_name = "cs42l51_hifi",
70 .codec_name = "cs42l51-codec.0-004a",
71 .ops = &openrd_client_ops, 71 .ops = &openrd_client_ops,
72}, 72},
73}; 73};
@@ -75,16 +75,10 @@ static struct snd_soc_dai_link openrd_client_dai[] = {
75 75
76static struct snd_soc_card openrd_client = { 76static struct snd_soc_card openrd_client = {
77 .name = "OpenRD Client", 77 .name = "OpenRD Client",
78 .platform = &kirkwood_soc_platform,
79 .dai_link = openrd_client_dai, 78 .dai_link = openrd_client_dai,
80 .num_links = ARRAY_SIZE(openrd_client_dai), 79 .num_links = ARRAY_SIZE(openrd_client_dai),
81}; 80};
82 81
83static struct snd_soc_device openrd_client_snd_devdata = {
84 .card = &openrd_client,
85 .codec_dev = &soc_codec_device_cs42l51,
86};
87
88static struct platform_device *openrd_client_snd_device; 82static struct platform_device *openrd_client_snd_device;
89 83
90static int __init openrd_client_init(void) 84static int __init openrd_client_init(void)
@@ -99,8 +93,7 @@ static int __init openrd_client_init(void)
99 return -ENOMEM; 93 return -ENOMEM;
100 94
101 platform_set_drvdata(openrd_client_snd_device, 95 platform_set_drvdata(openrd_client_snd_device,
102 &openrd_client_snd_devdata); 96 &openrd_client);
103 openrd_client_snd_devdata.dev = &openrd_client_snd_device->dev;
104 97
105 ret = platform_device_add(openrd_client_snd_device); 98 ret = platform_device_add(openrd_client_snd_device);
106 if (ret) { 99 if (ret) {
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
index caa7c901bc2..02b64a17dec 100644
--- a/sound/soc/nuc900/nuc900-ac97.c
+++ b/sound/soc/nuc900/nuc900-ac97.c
@@ -297,8 +297,7 @@ static struct snd_soc_dai_ops nuc900_ac97_dai_ops = {
297 .trigger = nuc900_ac97_trigger, 297 .trigger = nuc900_ac97_trigger,
298}; 298};
299 299
300struct snd_soc_dai nuc900_ac97_dai = { 300static struct snd_soc_dai_driver nuc900_ac97_dai = {
301 .name = "nuc900-ac97",
302 .probe = nuc900_ac97_probe, 301 .probe = nuc900_ac97_probe,
303 .remove = nuc900_ac97_remove, 302 .remove = nuc900_ac97_remove,
304 .ac97_control = 1, 303 .ac97_control = 1,
@@ -316,7 +315,6 @@ struct snd_soc_dai nuc900_ac97_dai = {
316 }, 315 },
317 .ops = &nuc900_ac97_dai_ops, 316 .ops = &nuc900_ac97_dai_ops,
318} 317}
319EXPORT_SYMBOL_GPL(nuc900_ac97_dai);
320 318
321static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev) 319static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev)
322{ 320{
@@ -365,9 +363,7 @@ static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev)
365 363
366 nuc900_ac97_data = nuc900_audio; 364 nuc900_ac97_data = nuc900_audio;
367 365
368 nuc900_audio->dev = nuc900_ac97_dai.dev = &pdev->dev; 366 ret = snd_soc_register_dai(&pdev->dev, &nuc900_ac97_dai);
369
370 ret = snd_soc_register_dai(&nuc900_ac97_dai);
371 if (ret) 367 if (ret)
372 goto out3; 368 goto out3;
373 369
@@ -390,7 +386,7 @@ out0:
390static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev) 386static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev)
391{ 387{
392 388
393 snd_soc_unregister_dai(&nuc900_ac97_dai); 389 snd_soc_unregister_dai(&pdev->dev);
394 390
395 clk_put(nuc900_ac97_data->clk); 391 clk_put(nuc900_ac97_data->clk);
396 iounmap(nuc900_ac97_data->mmio); 392 iounmap(nuc900_ac97_data->mmio);
@@ -404,7 +400,7 @@ static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev)
404 400
405static struct platform_driver nuc900_ac97_driver = { 401static struct platform_driver nuc900_ac97_driver = {
406 .driver = { 402 .driver = {
407 .name = "nuc900-audio", 403 .name = "nuc900-ac97",
408 .owner = THIS_MODULE, 404 .owner = THIS_MODULE,
409 }, 405 },
410 .probe = nuc900_ac97_drvprobe, 406 .probe = nuc900_ac97_drvprobe,
diff --git a/sound/soc/nuc900/nuc900-audio.c b/sound/soc/nuc900/nuc900-audio.c
index 72e6f518f7b..161f5b667d7 100644
--- a/sound/soc/nuc900/nuc900-audio.c
+++ b/sound/soc/nuc900/nuc900-audio.c
@@ -20,26 +20,21 @@
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/soc-dapm.h> 21#include <sound/soc-dapm.h>
22 22
23#include "../codecs/ac97.h"
24#include "nuc900-audio.h" 23#include "nuc900-audio.h"
25 24
26static struct snd_soc_dai_link nuc900evb_ac97_dai = { 25static struct snd_soc_dai_link nuc900evb_ac97_dai = {
27 .name = "AC97", 26 .name = "AC97",
28 .stream_name = "AC97 HiFi", 27 .stream_name = "AC97 HiFi",
29 .cpu_dai = &nuc900_ac97_dai, 28 .cpu_dai_name = "nuc900-ac97",
30 .codec_dai = &ac97_dai, 29 .codec_dai_name = "ac97-hifi",
30 .codec_name = "ac97-codec",
31 .platform_name = "nuc900-pcm-audio",
31}; 32};
32 33
33static struct snd_soc_card nuc900evb_audio_machine = { 34static struct snd_soc_card nuc900evb_audio_machine = {
34 .name = "NUC900EVB_AC97", 35 .name = "NUC900EVB_AC97",
35 .dai_link = &nuc900evb_ac97_dai, 36 .dai_link = &nuc900evb_ac97_dai,
36 .num_links = 1, 37 .num_links = 1,
37 .platform = &nuc900_soc_platform,
38};
39
40static struct snd_soc_device nuc900evb_ac97_devdata = {
41 .card = &nuc900evb_audio_machine,
42 .codec_dev = &soc_codec_dev_ac97,
43}; 38};
44 39
45static struct platform_device *nuc900evb_asoc_dev; 40static struct platform_device *nuc900evb_asoc_dev;
@@ -54,9 +49,8 @@ static int __init nuc900evb_audio_init(void)
54 goto out; 49 goto out;
55 50
56 /* nuc900 board audio device */ 51 /* nuc900 board audio device */
57 platform_set_drvdata(nuc900evb_asoc_dev, &nuc900evb_ac97_devdata); 52 platform_set_drvdata(nuc900evb_asoc_dev, &nuc900evb_audio_machine);
58 53
59 nuc900evb_ac97_devdata.dev = &nuc900evb_asoc_dev->dev;
60 ret = platform_device_add(nuc900evb_asoc_dev); 54 ret = platform_device_add(nuc900evb_asoc_dev);
61 55
62 if (ret) { 56 if (ret) {
diff --git a/sound/soc/nuc900/nuc900-audio.h b/sound/soc/nuc900/nuc900-audio.h
index 3038f519729..aeed8ead2b2 100644
--- a/sound/soc/nuc900/nuc900-audio.h
+++ b/sound/soc/nuc900/nuc900-audio.h
@@ -110,8 +110,4 @@ struct nuc900_audio {
110 110
111}; 111};
112 112
113extern struct nuc900_audio *nuc900_ac97_data;
114extern struct snd_soc_dai nuc900_ac97_dai;
115extern struct snd_soc_platform nuc900_soc_platform;
116
117#endif /*end _NUC900_AUDIO_H */ 113#endif /*end _NUC900_AUDIO_H */
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index e81e803b3a6..195d1ac9477 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -328,26 +328,44 @@ static int nuc900_dma_new(struct snd_card *card,
328 return 0; 328 return 0;
329} 329}
330 330
331struct snd_soc_platform nuc900_soc_platform = { 331static struct snd_soc_platform_driver nuc900_soc_platform = {
332 .name = "nuc900-dma", 332 .ops = &nuc900_dma_ops,
333 .pcm_ops = &nuc900_dma_ops,
334 .pcm_new = nuc900_dma_new, 333 .pcm_new = nuc900_dma_new,
335 .pcm_free = nuc900_dma_free_dma_buffers, 334 .pcm_free = nuc900_dma_free_dma_buffers,
336} 335}
337EXPORT_SYMBOL_GPL(nuc900_soc_platform);
338 336
339static int __init nuc900_soc_platform_init(void) 337static int __devinit nuc900_soc_platform_probe(struct platform_device *pdev)
340{ 338{
341 return snd_soc_register_platform(&nuc900_soc_platform); 339 return snd_soc_register_platform(&pdev->dev, &nuc900_soc_platform);
342} 340}
343 341
344static void __exit nuc900_soc_platform_exit(void) 342static int __devexit nuc900_soc_platform_remove(struct platform_device *pdev)
345{ 343{
346 snd_soc_unregister_platform(&nuc900_soc_platform); 344 snd_soc_unregister_platform(&pdev->dev);
345 return 0;
347} 346}
348 347
349module_init(nuc900_soc_platform_init); 348static struct platform_driver nuc900_pcm_driver = {
350module_exit(nuc900_soc_platform_exit); 349 .driver = {
350 .name = "nuc900-pcm-audio",
351 .owner = THIS_MODULE,
352 },
353
354 .probe = nuc900_soc_platform_probe,
355 .remove = __devexit_p(nuc900_soc_platform_remove),
356};
357
358static int __init nuc900_pcm_init(void)
359{
360 return platform_driver_register(&nuc900_pcm_driver);
361}
362module_init(nuc900_pcm_init);
363
364static void __exit nuc900_pcm_exit(void)
365{
366 platform_driver_unregister(&nuc900_pcm_driver);
367}
368module_exit(nuc900_pcm_exit);
351 369
352MODULE_AUTHOR("Wan ZongShun, <mcuos.com@gmail.com>"); 370MODULE_AUTHOR("Wan ZongShun, <mcuos.com@gmail.com>");
353MODULE_DESCRIPTION("nuc900 Audio DMA module"); 371MODULE_DESCRIPTION("nuc900 Audio DMA module");
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index 135901b2ea1..68bd902ccd4 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -40,8 +40,8 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
40 struct snd_pcm_hw_params *params) 40 struct snd_pcm_hw_params *params)
41{ 41{
42 struct snd_soc_pcm_runtime *rtd = substream->private_data; 42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
43 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 43 struct snd_soc_dai *codec_dai = rtd->codec_dai;
44 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 44 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
45 int ret; 45 int ret;
46 46
47 /* Set codec DAI configuration */ 47 /* Set codec DAI configuration */
@@ -111,8 +111,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
111 {"MICIN", NULL, "Mic In"}, 111 {"MICIN", NULL, "Mic In"},
112}; 112};
113 113
114static int am3517evm_aic23_init(struct snd_soc_codec *codec) 114static int am3517evm_aic23_init(struct snd_soc_pcm_runtime *rtd)
115{ 115{
116 struct snd_soc_codec *codec = rtd->codec;
117
116 /* Add am3517-evm specific widgets */ 118 /* Add am3517-evm specific widgets */
117 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 119 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
118 ARRAY_SIZE(tlv320aic23_dapm_widgets)); 120 ARRAY_SIZE(tlv320aic23_dapm_widgets));
@@ -134,8 +136,10 @@ static int am3517evm_aic23_init(struct snd_soc_codec *codec)
134static struct snd_soc_dai_link am3517evm_dai = { 136static struct snd_soc_dai_link am3517evm_dai = {
135 .name = "TLV320AIC23", 137 .name = "TLV320AIC23",
136 .stream_name = "AIC23", 138 .stream_name = "AIC23",
137 .cpu_dai = &omap_mcbsp_dai[0], 139 .cpu_dai_name ="omap-mcbsp-dai.0",
138 .codec_dai = &tlv320aic23_dai, 140 .codec_dai_name = "tlv320aic23-hifi",
141 .platform_name = "omap-pcm-audio",
142 .codec_name = "tlv320aic23-codec",
139 .init = am3517evm_aic23_init, 143 .init = am3517evm_aic23_init,
140 .ops = &am3517evm_ops, 144 .ops = &am3517evm_ops,
141}; 145};
@@ -143,17 +147,10 @@ static struct snd_soc_dai_link am3517evm_dai = {
143/* Audio machine driver */ 147/* Audio machine driver */
144static struct snd_soc_card snd_soc_am3517evm = { 148static struct snd_soc_card snd_soc_am3517evm = {
145 .name = "am3517evm", 149 .name = "am3517evm",
146 .platform = &omap_soc_platform,
147 .dai_link = &am3517evm_dai, 150 .dai_link = &am3517evm_dai,
148 .num_links = 1, 151 .num_links = 1,
149}; 152};
150 153
151/* Audio subsystem */
152static struct snd_soc_device am3517evm_snd_devdata = {
153 .card = &snd_soc_am3517evm,
154 .codec_dev = &soc_codec_dev_tlv320aic23,
155};
156
157static struct platform_device *am3517evm_snd_device; 154static struct platform_device *am3517evm_snd_device;
158 155
159static int __init am3517evm_soc_init(void) 156static int __init am3517evm_soc_init(void)
@@ -172,9 +169,7 @@ static int __init am3517evm_soc_init(void)
172 return -ENOMEM; 169 return -ENOMEM;
173 } 170 }
174 171
175 platform_set_drvdata(am3517evm_snd_device, &am3517evm_snd_devdata); 172 platform_set_drvdata(am3517evm_snd_device, &snd_soc_am3517evm);
176 am3517evm_snd_devdata.dev = &am3517evm_snd_device->dev;
177 *(unsigned int *)am3517evm_dai.cpu_dai->private_data = 0; /* McBSP1 */
178 173
179 ret = platform_device_add(am3517evm_snd_device); 174 ret = platform_device_add(am3517evm_snd_device);
180 if (ret) 175 if (ret)
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index b0f618e4484..9d88efa06e3 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -99,7 +99,7 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
99 int pin, changed = 0; 99 int pin, changed = 0;
100 100
101 /* Refuse any mode changes if we are not able to control the codec. */ 101 /* Refuse any mode changes if we are not able to control the codec. */
102 if (!codec->control_data) 102 if (!codec->hw_write)
103 return -EUNATCH; 103 return -EUNATCH;
104 104
105 if (ucontrol->value.enumerated.item[0] >= control->max) 105 if (ucontrol->value.enumerated.item[0] >= control->max)
@@ -268,10 +268,32 @@ static void cx81801_timeout(unsigned long data)
268 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0); 268 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0);
269} 269}
270 270
271/*
272 * Used for passing a codec structure pointer
273 * from the board initialization code to the tty line discipline.
274 */
275static struct snd_soc_codec *cx20442_codec;
276
271/* Line discipline .open() */ 277/* Line discipline .open() */
272static int cx81801_open(struct tty_struct *tty) 278static int cx81801_open(struct tty_struct *tty)
273{ 279{
274 return v253_ops.open(tty); 280 int ret;
281
282 if (!cx20442_codec)
283 return -ENODEV;
284
285 /*
286 * Pass the codec structure pointer for use by other ldisc callbacks,
287 * both the card and the codec specific parts.
288 */
289 tty->disc_data = cx20442_codec;
290
291 ret = v253_ops.open(tty);
292
293 if (ret < 0)
294 tty->disc_data = NULL;
295
296 return ret;
275} 297}
276 298
277/* Line discipline .close() */ 299/* Line discipline .close() */
@@ -281,11 +303,14 @@ static void cx81801_close(struct tty_struct *tty)
281 303
282 del_timer_sync(&cx81801_timer); 304 del_timer_sync(&cx81801_timer);
283 305
284 v253_ops.close(tty);
285
286 /* Prevent the hook switch from further changing the DAPM pins */ 306 /* Prevent the hook switch from further changing the DAPM pins */
287 INIT_LIST_HEAD(&ams_delta_hook_switch.pins); 307 INIT_LIST_HEAD(&ams_delta_hook_switch.pins);
288 308
309 if (!codec)
310 return;
311
312 v253_ops.close(tty);
313
289 /* Revert back to default audio input/output constellation */ 314 /* Revert back to default audio input/output constellation */
290 snd_soc_dapm_disable_pin(codec, "Mouthpiece"); 315 snd_soc_dapm_disable_pin(codec, "Mouthpiece");
291 snd_soc_dapm_enable_pin(codec, "Earpiece"); 316 snd_soc_dapm_enable_pin(codec, "Earpiece");
@@ -310,7 +335,10 @@ static void cx81801_receive(struct tty_struct *tty,
310 const unsigned char *c; 335 const unsigned char *c;
311 int apply, ret; 336 int apply, ret;
312 337
313 if (!codec->control_data) { 338 if (!codec)
339 return;
340
341 if (!codec->hw_write) {
314 /* First modem response, complete setup procedure */ 342 /* First modem response, complete setup procedure */
315 343
316 /* Initialize timer used for config pulse generation */ 344 /* Initialize timer used for config pulse generation */
@@ -323,7 +351,7 @@ static void cx81801_receive(struct tty_struct *tty,
323 ARRAY_SIZE(ams_delta_hook_switch_pins), 351 ARRAY_SIZE(ams_delta_hook_switch_pins),
324 ams_delta_hook_switch_pins); 352 ams_delta_hook_switch_pins);
325 if (ret) 353 if (ret)
326 dev_warn(codec->socdev->card->dev, 354 dev_warn(codec->dev,
327 "Failed to link hook switch to DAPM pins, " 355 "Failed to link hook switch to DAPM pins, "
328 "will continue with hook switch unlinked.\n"); 356 "will continue with hook switch unlinked.\n");
329 357
@@ -383,7 +411,7 @@ static int ams_delta_hw_params(struct snd_pcm_substream *substream,
383 struct snd_soc_pcm_runtime *rtd = substream->private_data; 411 struct snd_soc_pcm_runtime *rtd = substream->private_data;
384 412
385 /* Set cpu DAI configuration */ 413 /* Set cpu DAI configuration */
386 return snd_soc_dai_set_fmt(rtd->dai->cpu_dai, 414 return snd_soc_dai_set_fmt(rtd->cpu_dai,
387 SND_SOC_DAIFMT_DSP_A | 415 SND_SOC_DAIFMT_DSP_A |
388 SND_SOC_DAIFMT_NB_NF | 416 SND_SOC_DAIFMT_NB_NF |
389 SND_SOC_DAIFMT_CBM_CFM); 417 SND_SOC_DAIFMT_CBM_CFM);
@@ -398,7 +426,7 @@ static struct snd_soc_ops ams_delta_ops = {
398static int ams_delta_set_bias_level(struct snd_soc_card *card, 426static int ams_delta_set_bias_level(struct snd_soc_card *card,
399 enum snd_soc_bias_level level) 427 enum snd_soc_bias_level level)
400{ 428{
401 struct snd_soc_codec *codec = card->codec; 429 struct snd_soc_codec *codec = card->rtd->codec;
402 430
403 switch (level) { 431 switch (level) {
404 case SND_SOC_BIAS_ON: 432 case SND_SOC_BIAS_ON:
@@ -461,18 +489,22 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream)
461 * Card initialization 489 * Card initialization
462 */ 490 */
463 491
464static int ams_delta_cx20442_init(struct snd_soc_codec *codec) 492static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
465{ 493{
466 struct snd_soc_dai *codec_dai = codec->dai; 494 struct snd_soc_codec *codec = rtd->codec;
467 struct snd_soc_card *card = codec->socdev->card; 495 struct snd_soc_dai *codec_dai = rtd->codec_dai;
496 struct snd_soc_card *card = rtd->card;
468 int ret; 497 int ret;
469 /* Codec is ready, now add/activate board specific controls */ 498 /* Codec is ready, now add/activate board specific controls */
470 499
500 /* Store a pointer to the codec structure for tty ldisc use */
501 cx20442_codec = codec;
502
471 /* Set up digital mute if not provided by the codec */ 503 /* Set up digital mute if not provided by the codec */
472 if (!codec_dai->ops) { 504 if (!codec_dai->driver->ops) {
473 codec_dai->ops = &ams_delta_dai_ops; 505 codec_dai->driver->ops = &ams_delta_dai_ops;
474 } else if (!codec_dai->ops->digital_mute) { 506 } else if (!codec_dai->driver->ops->digital_mute) {
475 codec_dai->ops->digital_mute = ams_delta_digital_mute; 507 codec_dai->driver->ops->digital_mute = ams_delta_digital_mute;
476 } else { 508 } else {
477 ams_delta_ops.startup = ams_delta_startup; 509 ams_delta_ops.startup = ams_delta_startup;
478 ams_delta_ops.shutdown = ams_delta_shutdown; 510 ams_delta_ops.shutdown = ams_delta_shutdown;
@@ -483,7 +515,7 @@ static int ams_delta_cx20442_init(struct snd_soc_codec *codec)
483 515
484 /* Add hook switch - can be used to control the codec from userspace 516 /* Add hook switch - can be used to control the codec from userspace
485 * even if line discipline fails */ 517 * even if line discipline fails */
486 ret = snd_soc_jack_new(card, "hook_switch", 518 ret = snd_soc_jack_new(rtd->codec, "hook_switch",
487 SND_JACK_HEADSET, &ams_delta_hook_switch); 519 SND_JACK_HEADSET, &ams_delta_hook_switch);
488 if (ret) 520 if (ret)
489 dev_warn(card->dev, 521 dev_warn(card->dev,
@@ -551,27 +583,22 @@ static int ams_delta_cx20442_init(struct snd_soc_codec *codec)
551static struct snd_soc_dai_link ams_delta_dai_link = { 583static struct snd_soc_dai_link ams_delta_dai_link = {
552 .name = "CX20442", 584 .name = "CX20442",
553 .stream_name = "CX20442", 585 .stream_name = "CX20442",
554 .cpu_dai = &omap_mcbsp_dai[0], 586 .cpu_dai_name ="omap-mcbsp-dai.0",
555 .codec_dai = &cx20442_dai, 587 .codec_dai_name = "cx20442-hifi",
556 .init = ams_delta_cx20442_init, 588 .init = ams_delta_cx20442_init,
589 .platform_name = "omap-pcm-audio",
590 .codec_name = "cx20442-codec",
557 .ops = &ams_delta_ops, 591 .ops = &ams_delta_ops,
558}; 592};
559 593
560/* Audio card driver */ 594/* Audio card driver */
561static struct snd_soc_card ams_delta_audio_card = { 595static struct snd_soc_card ams_delta_audio_card = {
562 .name = "AMS_DELTA", 596 .name = "AMS_DELTA",
563 .platform = &omap_soc_platform,
564 .dai_link = &ams_delta_dai_link, 597 .dai_link = &ams_delta_dai_link,
565 .num_links = 1, 598 .num_links = 1,
566 .set_bias_level = ams_delta_set_bias_level, 599 .set_bias_level = ams_delta_set_bias_level,
567}; 600};
568 601
569/* Audio subsystem */
570static struct snd_soc_device ams_delta_snd_soc_device = {
571 .card = &ams_delta_audio_card,
572 .codec_dev = &cx20442_codec_dev,
573};
574
575/* Module init/exit */ 602/* Module init/exit */
576static struct platform_device *ams_delta_audio_platform_device; 603static struct platform_device *ams_delta_audio_platform_device;
577static struct platform_device *cx20442_platform_device; 604static struct platform_device *cx20442_platform_device;
@@ -589,9 +616,7 @@ static int __init ams_delta_module_init(void)
589 return -ENOMEM; 616 return -ENOMEM;
590 617
591 platform_set_drvdata(ams_delta_audio_platform_device, 618 platform_set_drvdata(ams_delta_audio_platform_device,
592 &ams_delta_snd_soc_device); 619 &ams_delta_audio_card);
593 ams_delta_snd_soc_device.dev = &ams_delta_audio_platform_device->dev;
594 *(unsigned int *)ams_delta_dai_link.cpu_dai->private_data = OMAP_MCBSP1;
595 620
596 ret = platform_device_add(ams_delta_audio_platform_device); 621 ret = platform_device_add(ams_delta_audio_platform_device);
597 if (ret) 622 if (ret)
@@ -601,8 +626,8 @@ static int __init ams_delta_module_init(void)
601 * Codec platform device could be registered from elsewhere (board?), 626 * Codec platform device could be registered from elsewhere (board?),
602 * but I do it here as it makes sense only if used with the card. 627 * but I do it here as it makes sense only if used with the card.
603 */ 628 */
604 cx20442_platform_device = platform_device_register_simple("cx20442", 629 cx20442_platform_device =
605 -1, NULL, 0); 630 platform_device_register_simple("cx20442-codec", -1, NULL, 0);
606 return 0; 631 return 0;
607err: 632err:
608 platform_device_put(ams_delta_audio_platform_device); 633 platform_device_put(ams_delta_audio_platform_device);
@@ -612,19 +637,6 @@ module_init(ams_delta_module_init);
612 637
613static void __exit ams_delta_module_exit(void) 638static void __exit ams_delta_module_exit(void)
614{ 639{
615 struct snd_soc_codec *codec;
616 struct tty_struct *tty;
617
618 if (ams_delta_audio_card.codec) {
619 codec = ams_delta_audio_card.codec;
620
621 if (codec->control_data) {
622 tty = codec->control_data;
623
624 tty_hangup(tty);
625 }
626 }
627
628 if (tty_unregister_ldisc(N_V253) != 0) 640 if (tty_unregister_ldisc(N_V253) != 0)
629 dev_warn(&ams_delta_audio_platform_device->dev, 641 dev_warn(&ams_delta_audio_platform_device->dev,
630 "failed to unregister V253 line discipline\n"); 642 "failed to unregister V253 line discipline\n");
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
index 3583c429f9b..d296cfcc672 100644
--- a/sound/soc/omap/igep0020.c
+++ b/sound/soc/omap/igep0020.c
@@ -33,14 +33,13 @@
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37 36
38static int igep2_hw_params(struct snd_pcm_substream *substream, 37static int igep2_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params) 38 struct snd_pcm_hw_params *params)
40{ 39{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data; 40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 int ret; 43 int ret;
45 44
46 /* Set codec DAI configuration */ 45 /* Set codec DAI configuration */
@@ -82,25 +81,20 @@ static struct snd_soc_ops igep2_ops = {
82static struct snd_soc_dai_link igep2_dai = { 81static struct snd_soc_dai_link igep2_dai = {
83 .name = "TWL4030", 82 .name = "TWL4030",
84 .stream_name = "TWL4030", 83 .stream_name = "TWL4030",
85 .cpu_dai = &omap_mcbsp_dai[0], 84 .cpu_dai_name = "omap-mcbsp-dai.1",
86 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], 85 .codec_dai_name = "twl4030-hifi",
86 .platform_name = "omap-pcm-audio",
87 .codec_name = "twl4030-codec",
87 .ops = &igep2_ops, 88 .ops = &igep2_ops,
88}; 89};
89 90
90/* Audio machine driver */ 91/* Audio machine driver */
91static struct snd_soc_card snd_soc_card_igep2 = { 92static struct snd_soc_card snd_soc_card_igep2 = {
92 .name = "igep2", 93 .name = "igep2",
93 .platform = &omap_soc_platform,
94 .dai_link = &igep2_dai, 94 .dai_link = &igep2_dai,
95 .num_links = 1, 95 .num_links = 1,
96}; 96};
97 97
98/* Audio subsystem */
99static struct snd_soc_device igep2_snd_devdata = {
100 .card = &snd_soc_card_igep2,
101 .codec_dev = &soc_codec_dev_twl4030,
102};
103
104static struct platform_device *igep2_snd_device; 98static struct platform_device *igep2_snd_device;
105 99
106static int __init igep2_soc_init(void) 100static int __init igep2_soc_init(void)
@@ -119,9 +113,7 @@ static int __init igep2_soc_init(void)
119 return -ENOMEM; 113 return -ENOMEM;
120 } 114 }
121 115
122 platform_set_drvdata(igep2_snd_device, &igep2_snd_devdata); 116 platform_set_drvdata(igep2_snd_device, &snd_soc_card_igep2);
123 igep2_snd_devdata.dev = &igep2_snd_device->dev;
124 *(unsigned int *)igep2_dai.cpu_dai->private_data = 1; /* McBSP2 */
125 117
126 ret = platform_device_add(igep2_snd_device); 118 ret = platform_device_add(igep2_snd_device);
127 if (ret) 119 if (ret)
diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c
index 90b8bf71c89..928f0370745 100644
--- a/sound/soc/omap/mcpdm.c
+++ b/sound/soc/omap/mcpdm.c
@@ -402,7 +402,7 @@ int omap_mcpdm_set_offset(int offset1, int offset2)
402 return 0; 402 return 0;
403} 403}
404 404
405static int __devinit omap_mcpdm_probe(struct platform_device *pdev) 405int __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;
@@ -449,7 +449,7 @@ exit:
449 return ret; 449 return ret;
450} 450}
451 451
452static int __devexit omap_mcpdm_remove(struct platform_device *pdev) 452int __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
@@ -468,18 +468,3 @@ static int __devexit omap_mcpdm_remove(struct platform_device *pdev)
468 return 0; 468 return 0;
469} 469}
470 470
471static struct platform_driver omap_mcpdm_driver = {
472 .probe = omap_mcpdm_probe,
473 .remove = __devexit_p(omap_mcpdm_remove),
474 .driver = {
475 .name = "omap-mcpdm",
476 },
477};
478
479static struct platform_device *omap_mcpdm_device;
480
481static int __init omap_mcpdm_init(void)
482{
483 return platform_driver_register(&omap_mcpdm_driver);
484}
485arch_initcall(omap_mcpdm_init);
diff --git a/sound/soc/omap/mcpdm.h b/sound/soc/omap/mcpdm.h
index 7bb326ef088..df3e16fb51f 100644
--- a/sound/soc/omap/mcpdm.h
+++ b/sound/soc/omap/mcpdm.h
@@ -149,3 +149,5 @@ extern int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink);
149extern int omap_mcpdm_request(void); 149extern int omap_mcpdm_request(void);
150extern void omap_mcpdm_free(void); 150extern void omap_mcpdm_free(void);
151extern int omap_mcpdm_set_offset(int offset1, int offset2); 151extern int omap_mcpdm_set_offset(int offset1, int offset2);
152int __devinit omap_mcpdm_probe(struct platform_device *pdev);
153int __devexit omap_mcpdm_remove(struct platform_device *pdev);
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 08e09d72790..a3b6d897ad8 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -97,7 +97,7 @@ static int n810_startup(struct snd_pcm_substream *substream)
97{ 97{
98 struct snd_pcm_runtime *runtime = substream->runtime; 98 struct snd_pcm_runtime *runtime = substream->runtime;
99 struct snd_soc_pcm_runtime *rtd = substream->private_data; 99 struct snd_soc_pcm_runtime *rtd = substream->private_data;
100 struct snd_soc_codec *codec = rtd->socdev->card->codec; 100 struct snd_soc_codec *codec = rtd->codec;
101 101
102 snd_pcm_hw_constraint_minmax(runtime, 102 snd_pcm_hw_constraint_minmax(runtime,
103 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); 103 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
@@ -115,8 +115,8 @@ static int n810_hw_params(struct snd_pcm_substream *substream,
115 struct snd_pcm_hw_params *params) 115 struct snd_pcm_hw_params *params)
116{ 116{
117 struct snd_soc_pcm_runtime *rtd = substream->private_data; 117 struct snd_soc_pcm_runtime *rtd = substream->private_data;
118 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 118 struct snd_soc_dai *codec_dai = rtd->codec_dai;
119 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 119 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
120 int err; 120 int err;
121 121
122 /* Set codec DAI configuration */ 122 /* Set codec DAI configuration */
@@ -271,8 +271,9 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = {
271 n810_get_input, n810_set_input), 271 n810_get_input, n810_set_input),
272}; 272};
273 273
274static int n810_aic33_init(struct snd_soc_codec *codec) 274static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
275{ 275{
276 struct snd_soc_codec *codec = rtd->codec;
276 int err; 277 int err;
277 278
278 /* Not connected */ 279 /* Not connected */
@@ -307,8 +308,10 @@ static int n810_aic33_init(struct snd_soc_codec *codec)
307static struct snd_soc_dai_link n810_dai = { 308static struct snd_soc_dai_link n810_dai = {
308 .name = "TLV320AIC33", 309 .name = "TLV320AIC33",
309 .stream_name = "AIC33", 310 .stream_name = "AIC33",
310 .cpu_dai = &omap_mcbsp_dai[0], 311 .cpu_dai_name = "omap-mcbsp-dai.1",
311 .codec_dai = &aic3x_dai, 312 .platform_name = "omap-pcm-audio",
313 .codec_name = "tlv320aic3x-codec.2-0018",
314 .codec_dai_name = "tlv320aic3x-hifi",
312 .init = n810_aic33_init, 315 .init = n810_aic33_init,
313 .ops = &n810_ops, 316 .ops = &n810_ops,
314}; 317};
@@ -316,33 +319,12 @@ static struct snd_soc_dai_link n810_dai = {
316/* Audio machine driver */ 319/* Audio machine driver */
317static struct snd_soc_card snd_soc_n810 = { 320static struct snd_soc_card snd_soc_n810 = {
318 .name = "N810", 321 .name = "N810",
319 .platform = &omap_soc_platform,
320 .dai_link = &n810_dai, 322 .dai_link = &n810_dai,
321 .num_links = 1, 323 .num_links = 1,
322}; 324};
323 325
324/* Audio private data */
325static struct aic3x_setup_data n810_aic33_setup = {
326 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
327 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
328};
329
330/* Audio subsystem */
331static struct snd_soc_device n810_snd_devdata = {
332 .card = &snd_soc_n810,
333 .codec_dev = &soc_codec_dev_aic3x,
334 .codec_data = &n810_aic33_setup,
335};
336
337static struct platform_device *n810_snd_device; 326static struct platform_device *n810_snd_device;
338 327
339/* temporary i2c device creation until this can be moved into the machine
340 * support file.
341*/
342static struct i2c_board_info i2c_device[] = {
343 { I2C_BOARD_INFO("tlv320aic3x", 0x1b), }
344};
345
346static int __init n810_soc_init(void) 328static int __init n810_soc_init(void)
347{ 329{
348 int err; 330 int err;
@@ -351,15 +333,11 @@ static int __init n810_soc_init(void)
351 if (!(machine_is_nokia_n810() || machine_is_nokia_n810_wimax())) 333 if (!(machine_is_nokia_n810() || machine_is_nokia_n810_wimax()))
352 return -ENODEV; 334 return -ENODEV;
353 335
354 i2c_register_board_info(1, i2c_device, ARRAY_SIZE(i2c_device));
355
356 n810_snd_device = platform_device_alloc("soc-audio", -1); 336 n810_snd_device = platform_device_alloc("soc-audio", -1);
357 if (!n810_snd_device) 337 if (!n810_snd_device)
358 return -ENOMEM; 338 return -ENOMEM;
359 339
360 platform_set_drvdata(n810_snd_device, &n810_snd_devdata); 340 platform_set_drvdata(n810_snd_device, &snd_soc_n810);
361 n810_snd_devdata.dev = &n810_snd_device->dev;
362 *(unsigned int *)n810_dai.cpu_dai->private_data = 1; /* McBSP2 */
363 err = platform_device_add(n810_snd_device); 341 err = platform_device_add(n810_snd_device);
364 if (err) 342 if (err)
365 goto err1; 343 goto err1;
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 86f213905e2..7ba5690118f 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -62,8 +62,6 @@ struct omap_mcbsp_data {
62 int wlen; 62 int wlen;
63}; 63};
64 64
65#define to_mcbsp(priv) container_of((priv), struct omap_mcbsp_data, bus_id)
66
67static struct omap_mcbsp_data mcbsp_data[NUM_LINKS]; 65static struct omap_mcbsp_data mcbsp_data[NUM_LINKS];
68 66
69/* 67/*
@@ -153,13 +151,13 @@ static const unsigned long omap34xx_mcbsp_port[][2] = {};
153static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) 151static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
154{ 152{
155 struct snd_soc_pcm_runtime *rtd = substream->private_data; 153 struct snd_soc_pcm_runtime *rtd = substream->private_data;
156 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 154 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
157 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 155 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
158 struct omap_pcm_dma_data *dma_data; 156 struct omap_pcm_dma_data *dma_data;
159 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id); 157 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id);
160 int words; 158 int words;
161 159
162 dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 160 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
163 161
164 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ 162 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
165 if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) 163 if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
@@ -203,11 +201,9 @@ static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params,
203} 201}
204 202
205static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, 203static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai) 204 struct snd_soc_dai *cpu_dai)
207{ 205{
208 struct snd_soc_pcm_runtime *rtd = substream->private_data; 206 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
209 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
210 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
211 int bus_id = mcbsp_data->bus_id; 207 int bus_id = mcbsp_data->bus_id;
212 int err = 0; 208 int err = 0;
213 209
@@ -249,11 +245,9 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
249} 245}
250 246
251static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream, 247static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
252 struct snd_soc_dai *dai) 248 struct snd_soc_dai *cpu_dai)
253{ 249{
254 struct snd_soc_pcm_runtime *rtd = substream->private_data; 250 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
255 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
256 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
257 251
258 if (!cpu_dai->active) { 252 if (!cpu_dai->active) {
259 omap_mcbsp_free(mcbsp_data->bus_id); 253 omap_mcbsp_free(mcbsp_data->bus_id);
@@ -262,11 +256,9 @@ static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
262} 256}
263 257
264static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, 258static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
265 struct snd_soc_dai *dai) 259 struct snd_soc_dai *cpu_dai)
266{ 260{
267 struct snd_soc_pcm_runtime *rtd = substream->private_data; 261 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
268 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
269 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
270 int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 262 int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
271 263
272 switch (cmd) { 264 switch (cmd) {
@@ -295,8 +287,8 @@ static snd_pcm_sframes_t omap_mcbsp_dai_delay(
295 struct snd_soc_dai *dai) 287 struct snd_soc_dai *dai)
296{ 288{
297 struct snd_soc_pcm_runtime *rtd = substream->private_data; 289 struct snd_soc_pcm_runtime *rtd = substream->private_data;
298 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 290 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
299 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 291 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
300 u16 fifo_use; 292 u16 fifo_use;
301 snd_pcm_sframes_t delay; 293 snd_pcm_sframes_t delay;
302 294
@@ -317,11 +309,9 @@ static snd_pcm_sframes_t omap_mcbsp_dai_delay(
317 309
318static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, 310static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
319 struct snd_pcm_hw_params *params, 311 struct snd_pcm_hw_params *params,
320 struct snd_soc_dai *dai) 312 struct snd_soc_dai *cpu_dai)
321{ 313{
322 struct snd_soc_pcm_runtime *rtd = substream->private_data; 314 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
323 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
324 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
325 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 315 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
326 struct omap_pcm_dma_data *dma_data; 316 struct omap_pcm_dma_data *dma_data;
327 int dma, bus_id = mcbsp_data->bus_id; 317 int dma, bus_id = mcbsp_data->bus_id;
@@ -496,7 +486,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
496static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, 486static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
497 unsigned int fmt) 487 unsigned int fmt)
498{ 488{
499 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 489 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
500 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 490 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
501 unsigned int temp_fmt = fmt; 491 unsigned int temp_fmt = fmt;
502 492
@@ -596,7 +586,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
596static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai, 586static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
597 int div_id, int div) 587 int div_id, int div)
598{ 588{
599 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 589 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
600 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 590 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
601 591
602 if (div_id != OMAP_MCBSP_CLKGDV) 592 if (div_id != OMAP_MCBSP_CLKGDV)
@@ -699,7 +689,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
699 int clk_id, unsigned int freq, 689 int clk_id, unsigned int freq,
700 int dir) 690 int dir)
701{ 691{
702 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 692 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai);
703 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 693 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
704 int err = 0; 694 int err = 0;
705 695
@@ -733,7 +723,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
733 return err; 723 return err;
734} 724}
735 725
736static struct snd_soc_dai_ops omap_mcbsp_dai_ops = { 726static struct snd_soc_dai_ops mcbsp_dai_ops = {
737 .startup = omap_mcbsp_dai_startup, 727 .startup = omap_mcbsp_dai_startup,
738 .shutdown = omap_mcbsp_dai_shutdown, 728 .shutdown = omap_mcbsp_dai_shutdown,
739 .trigger = omap_mcbsp_dai_trigger, 729 .trigger = omap_mcbsp_dai_trigger,
@@ -744,42 +734,31 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = {
744 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, 734 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk,
745}; 735};
746 736
747#define OMAP_MCBSP_DAI_BUILDER(link_id) \ 737static int mcbsp_dai_probe(struct snd_soc_dai *dai)
748{ \ 738{
749 .name = "omap-mcbsp-dai-"#link_id, \ 739 mcbsp_data[dai->id].bus_id = dai->id;
750 .id = (link_id), \ 740 snd_soc_dai_set_drvdata(dai, &mcbsp_data[dai->id].bus_id);
751 .playback = { \ 741 return 0;
752 .channels_min = 1, \
753 .channels_max = 16, \
754 .rates = OMAP_MCBSP_RATES, \
755 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
756 SNDRV_PCM_FMTBIT_S32_LE, \
757 }, \
758 .capture = { \
759 .channels_min = 1, \
760 .channels_max = 16, \
761 .rates = OMAP_MCBSP_RATES, \
762 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
763 SNDRV_PCM_FMTBIT_S32_LE, \
764 }, \
765 .ops = &omap_mcbsp_dai_ops, \
766 .private_data = &mcbsp_data[(link_id)].bus_id, \
767} 742}
768 743
769struct snd_soc_dai omap_mcbsp_dai[] = { 744static struct snd_soc_dai_driver omap_mcbsp_dai =
770 OMAP_MCBSP_DAI_BUILDER(0), 745{
771 OMAP_MCBSP_DAI_BUILDER(1), 746 .probe = mcbsp_dai_probe,
772#if NUM_LINKS >= 3 747 .playback = {
773 OMAP_MCBSP_DAI_BUILDER(2), 748 .channels_min = 1,
774#endif 749 .channels_max = 16,
775#if NUM_LINKS == 5 750 .rates = OMAP_MCBSP_RATES,
776 OMAP_MCBSP_DAI_BUILDER(3), 751 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
777 OMAP_MCBSP_DAI_BUILDER(4), 752 },
778#endif 753 .capture = {
754 .channels_min = 1,
755 .channels_max = 16,
756 .rates = OMAP_MCBSP_RATES,
757 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
758 },
759 .ops = &mcbsp_dai_ops,
779}; 760};
780 761
781EXPORT_SYMBOL_GPL(omap_mcbsp_dai);
782
783int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol, 762int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
784 struct snd_ctl_elem_info *uinfo) 763 struct snd_ctl_elem_info *uinfo)
785{ 764{
@@ -910,16 +889,36 @@ int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id)
910} 889}
911EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls); 890EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
912 891
892static __devinit int asoc_mcbsp_probe(struct platform_device *pdev)
893{
894 return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai);
895}
896
897static int __devexit asoc_mcbsp_remove(struct platform_device *pdev)
898{
899 snd_soc_unregister_dai(&pdev->dev);
900 return 0;
901}
902
903static struct platform_driver asoc_mcbsp_driver = {
904 .driver = {
905 .name = "omap-mcbsp-dai",
906 .owner = THIS_MODULE,
907 },
908
909 .probe = asoc_mcbsp_probe,
910 .remove = __devexit_p(asoc_mcbsp_remove),
911};
912
913static int __init snd_omap_mcbsp_init(void) 913static int __init snd_omap_mcbsp_init(void)
914{ 914{
915 return snd_soc_register_dais(omap_mcbsp_dai, 915 return platform_driver_register(&asoc_mcbsp_driver);
916 ARRAY_SIZE(omap_mcbsp_dai));
917} 916}
918module_init(snd_omap_mcbsp_init); 917module_init(snd_omap_mcbsp_init);
919 918
920static void __exit snd_omap_mcbsp_exit(void) 919static void __exit snd_omap_mcbsp_exit(void)
921{ 920{
922 snd_soc_unregister_dais(omap_mcbsp_dai, ARRAY_SIZE(omap_mcbsp_dai)); 921 platform_driver_unregister(&asoc_mcbsp_driver);
923} 922}
924module_exit(snd_omap_mcbsp_exit); 923module_exit(snd_omap_mcbsp_exit);
925 924
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index 6c363e5f438..ffdcc5abb7b 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -55,8 +55,6 @@ enum omap_mcbsp_div {
55#define NUM_LINKS 5 55#define NUM_LINKS 5
56#endif 56#endif
57 57
58extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS];
59
60int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id); 58int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id);
61 59
62#endif 60#endif
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index b7f4f7e015f..f161c2f5ed3 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -36,7 +36,6 @@
36#include <plat/dma.h> 36#include <plat/dma.h>
37#include <plat/mcbsp.h> 37#include <plat/mcbsp.h>
38#include "mcpdm.h" 38#include "mcpdm.h"
39#include "omap-mcpdm.h"
40#include "omap-pcm.h" 39#include "omap-pcm.h"
41 40
42struct omap_mcpdm_data { 41struct omap_mcpdm_data {
@@ -89,11 +88,9 @@ static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
89static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, 88static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
90 struct snd_soc_dai *dai) 89 struct snd_soc_dai *dai)
91{ 90{
92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
94 int err = 0; 91 int err = 0;
95 92
96 if (!cpu_dai->active) 93 if (!dai->active)
97 err = omap_mcpdm_request(); 94 err = omap_mcpdm_request();
98 95
99 return err; 96 return err;
@@ -102,19 +99,14 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
102static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, 99static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
103 struct snd_soc_dai *dai) 100 struct snd_soc_dai *dai)
104{ 101{
105 struct snd_soc_pcm_runtime *rtd = substream->private_data; 102 if (!dai->active)
106 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
107
108 if (!cpu_dai->active)
109 omap_mcpdm_free(); 103 omap_mcpdm_free();
110} 104}
111 105
112static int omap_mcpdm_dai_trigger(struct snd_pcm_substream *substream, int cmd, 106static int omap_mcpdm_dai_trigger(struct snd_pcm_substream *substream, int cmd,
113 struct snd_soc_dai *dai) 107 struct snd_soc_dai *dai)
114{ 108{
115 struct snd_soc_pcm_runtime *rtd = substream->private_data; 109 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai);
116 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
117 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
118 int stream = substream->stream; 110 int stream = substream->stream;
119 int err = 0; 111 int err = 0;
120 112
@@ -143,14 +135,12 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params, 135 struct snd_pcm_hw_params *params,
144 struct snd_soc_dai *dai) 136 struct snd_soc_dai *dai)
145{ 137{
146 struct snd_soc_pcm_runtime *rtd = substream->private_data; 138 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai);
147 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
148 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
149 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links; 139 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
150 int stream = substream->stream; 140 int stream = substream->stream;
151 int channels, err, link_mask = 0; 141 int channels, err, link_mask = 0;
152 142
153 snd_soc_dai_set_dma_data(cpu_dai, substream, 143 snd_soc_dai_set_dma_data(dai, substream,
154 &omap_mcpdm_dai_dma_params[stream]); 144 &omap_mcpdm_dai_dma_params[stream]);
155 145
156 channels = params_channels(params); 146 channels = params_channels(params);
@@ -189,9 +179,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
189static int omap_mcpdm_dai_hw_free(struct snd_pcm_substream *substream, 179static int omap_mcpdm_dai_hw_free(struct snd_pcm_substream *substream,
190 struct snd_soc_dai *dai) 180 struct snd_soc_dai *dai)
191{ 181{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data; 182 struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai);
193 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
194 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
195 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links; 183 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
196 int stream = substream->stream; 184 int stream = substream->stream;
197 int err; 185 int err;
@@ -215,9 +203,14 @@ static struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
215#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 203#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
216#define OMAP_MCPDM_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) 204#define OMAP_MCPDM_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
217 205
218struct snd_soc_dai omap_mcpdm_dai = { 206static int omap_mcpdm_dai_probe(struct snd_soc_dai *dai)
219 .name = "omap-mcpdm", 207{
220 .id = -1, 208 snd_soc_dai_set_drvdata(dai, &mcpdm_data);
209 return 0;
210}
211
212static struct snd_soc_dai_driver omap_mcpdm_dai = {
213 .probe = omap_mcpdm_dai_probe,
221 .playback = { 214 .playback = {
222 .channels_min = 1, 215 .channels_min = 1,
223 .channels_max = 4, 216 .channels_max = 4,
@@ -231,19 +224,47 @@ struct snd_soc_dai omap_mcpdm_dai = {
231 .formats = OMAP_MCPDM_FORMATS, 224 .formats = OMAP_MCPDM_FORMATS,
232 }, 225 },
233 .ops = &omap_mcpdm_dai_ops, 226 .ops = &omap_mcpdm_dai_ops,
234 .private_data = &mcpdm_data,
235}; 227};
236EXPORT_SYMBOL_GPL(omap_mcpdm_dai); 228
229static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
230{
231 int ret;
232
233 ret = omap_mcpdm_probe(pdev);
234 if (ret < 0)
235 return ret;
236 ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
237 if (ret < 0)
238 omap_mcpdm_remove(pdev);
239 return ret;
240}
241
242static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
243{
244 snd_soc_unregister_dai(&pdev->dev);
245 omap_mcpdm_remove(pdev);
246 return 0;
247}
248
249static struct platform_driver asoc_mcpdm_driver = {
250 .driver = {
251 .name = "omap-mcpdm-dai",
252 .owner = THIS_MODULE,
253 },
254
255 .probe = asoc_mcpdm_probe,
256 .remove = __devexit_p(asoc_mcpdm_remove),
257};
237 258
238static int __init snd_omap_mcpdm_init(void) 259static int __init snd_omap_mcpdm_init(void)
239{ 260{
240 return snd_soc_register_dai(&omap_mcpdm_dai); 261 return platform_driver_register(&asoc_mcpdm_driver);
241} 262}
242module_init(snd_omap_mcpdm_init); 263module_init(snd_omap_mcpdm_init);
243 264
244static void __exit snd_omap_mcpdm_exit(void) 265static void __exit snd_omap_mcpdm_exit(void)
245{ 266{
246 snd_soc_unregister_dai(&omap_mcpdm_dai); 267 platform_driver_unregister(&asoc_mcpdm_driver);
247} 268}
248module_exit(snd_omap_mcpdm_exit); 269module_exit(snd_omap_mcpdm_exit);
249 270
diff --git a/sound/soc/omap/omap-mcpdm.h b/sound/soc/omap/omap-mcpdm.h
deleted file mode 100644
index 73b80d55934..00000000000
--- a/sound/soc/omap/omap-mcpdm.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * omap-mcpdm.h
3 *
4 * Copyright (C) 2009 Texas Instruments
5 *
6 * Contact: Misael Lopez Cruz <x0052729@ti.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
24#ifndef __OMAP_MCPDM_H__
25#define __OMAP_MCPDM_H__
26
27extern struct snd_soc_dai omap_mcpdm_dai;
28
29#endif /* End of __OMAP_MCPDM_H__ */
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 1e521904ea6..8caeb8d305c 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -101,9 +101,10 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
101 struct snd_soc_pcm_runtime *rtd = substream->private_data; 101 struct snd_soc_pcm_runtime *rtd = substream->private_data;
102 struct omap_runtime_data *prtd = runtime->private_data; 102 struct omap_runtime_data *prtd = runtime->private_data;
103 struct omap_pcm_dma_data *dma_data; 103 struct omap_pcm_dma_data *dma_data;
104
104 int err = 0; 105 int err = 0;
105 106
106 dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 107 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
107 108
108 /* return if this is a bufferless transfer e.g. 109 /* return if this is a bufferless transfer e.g.
109 * codec <--> BT codec or GSM modem -- lg FIXME */ 110 * codec <--> BT codec or GSM modem -- lg FIXME */
@@ -374,14 +375,14 @@ static int omap_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
374 if (!card->dev->coherent_dma_mask) 375 if (!card->dev->coherent_dma_mask)
375 card->dev->coherent_dma_mask = DMA_BIT_MASK(64); 376 card->dev->coherent_dma_mask = DMA_BIT_MASK(64);
376 377
377 if (dai->playback.channels_min) { 378 if (dai->driver->playback.channels_min) {
378 ret = omap_pcm_preallocate_dma_buffer(pcm, 379 ret = omap_pcm_preallocate_dma_buffer(pcm,
379 SNDRV_PCM_STREAM_PLAYBACK); 380 SNDRV_PCM_STREAM_PLAYBACK);
380 if (ret) 381 if (ret)
381 goto out; 382 goto out;
382 } 383 }
383 384
384 if (dai->capture.channels_min) { 385 if (dai->driver->capture.channels_min) {
385 ret = omap_pcm_preallocate_dma_buffer(pcm, 386 ret = omap_pcm_preallocate_dma_buffer(pcm,
386 SNDRV_PCM_STREAM_CAPTURE); 387 SNDRV_PCM_STREAM_CAPTURE);
387 if (ret) 388 if (ret)
@@ -392,25 +393,45 @@ out:
392 return ret; 393 return ret;
393} 394}
394 395
395struct snd_soc_platform omap_soc_platform = { 396static struct snd_soc_platform_driver omap_soc_platform = {
396 .name = "omap-pcm-audio", 397 .ops = &omap_pcm_ops,
397 .pcm_ops = &omap_pcm_ops,
398 .pcm_new = omap_pcm_new, 398 .pcm_new = omap_pcm_new,
399 .pcm_free = omap_pcm_free_dma_buffers, 399 .pcm_free = omap_pcm_free_dma_buffers,
400}; 400};
401EXPORT_SYMBOL_GPL(omap_soc_platform);
402 401
403static int __init omap_soc_platform_init(void) 402static __devinit int omap_pcm_probe(struct platform_device *pdev)
403{
404 return snd_soc_register_platform(&pdev->dev,
405 &omap_soc_platform);
406}
407
408static int __devexit omap_pcm_remove(struct platform_device *pdev)
409{
410 snd_soc_unregister_platform(&pdev->dev);
411 return 0;
412}
413
414static struct platform_driver omap_pcm_driver = {
415 .driver = {
416 .name = "omap-pcm-audio",
417 .owner = THIS_MODULE,
418 },
419
420 .probe = omap_pcm_probe,
421 .remove = __devexit_p(omap_pcm_remove),
422};
423
424static int __init snd_omap_pcm_init(void)
404{ 425{
405 return snd_soc_register_platform(&omap_soc_platform); 426 return platform_driver_register(&omap_pcm_driver);
406} 427}
407module_init(omap_soc_platform_init); 428module_init(snd_omap_pcm_init);
408 429
409static void __exit omap_soc_platform_exit(void) 430static void __exit snd_omap_pcm_exit(void)
410{ 431{
411 snd_soc_unregister_platform(&omap_soc_platform); 432 platform_driver_unregister(&omap_pcm_driver);
412} 433}
413module_exit(omap_soc_platform_exit); 434module_exit(snd_omap_pcm_exit);
414 435
415MODULE_AUTHOR("Jarkko Nikula <jhnikula@gmail.com>"); 436MODULE_AUTHOR("Jarkko Nikula <jhnikula@gmail.com>");
416MODULE_DESCRIPTION("OMAP PCM DMA module"); 437MODULE_DESCRIPTION("OMAP PCM DMA module");
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index b19975d2690..fea0515331f 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -35,6 +35,4 @@ struct omap_pcm_dma_data {
35 int packet_size; /* packet size only in PACKET mode */ 35 int packet_size; /* packet size only in PACKET mode */
36}; 36};
37 37
38extern struct snd_soc_platform omap_soc_platform;
39
40#endif 38#endif
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c
index c7adea38274..38cd1894623 100644
--- a/sound/soc/omap/omap2evm.c
+++ b/sound/soc/omap/omap2evm.c
@@ -35,15 +35,13 @@
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
38#include "../codecs/twl4030.h"
39 38
40static int omap2evm_hw_params(struct snd_pcm_substream *substream, 39static int omap2evm_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params, 40 struct snd_pcm_hw_params *params)
42 struct snd_soc_dai *dai)
43{ 41{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data; 42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 43 struct snd_soc_dai *codec_dai = rtd->codec_dai;
46 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 44 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
47 int ret; 45 int ret;
48 46
49 /* Set codec DAI configuration */ 47 /* Set codec DAI configuration */
@@ -85,25 +83,20 @@ static struct snd_soc_ops omap2evm_ops = {
85static struct snd_soc_dai_link omap2evm_dai = { 83static struct snd_soc_dai_link omap2evm_dai = {
86 .name = "TWL4030", 84 .name = "TWL4030",
87 .stream_name = "TWL4030", 85 .stream_name = "TWL4030",
88 .cpu_dai = &omap_mcbsp_dai[0], 86 .cpu_dai_name = "omap-mcbsp-dai.1",
89 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], 87 .codec_dai_name = "twl4030-hifi",
88 .platform_name = "omap-pcm-audio",
89 .codec_name = "twl4030-codec",
90 .ops = &omap2evm_ops, 90 .ops = &omap2evm_ops,
91}; 91};
92 92
93/* Audio machine driver */ 93/* Audio machine driver */
94static struct snd_soc_card snd_soc_omap2evm = { 94static struct snd_soc_card snd_soc_omap2evm = {
95 .name = "omap2evm", 95 .name = "omap2evm",
96 .platform = &omap_soc_platform,
97 .dai_link = &omap2evm_dai, 96 .dai_link = &omap2evm_dai,
98 .num_links = 1, 97 .num_links = 1,
99}; 98};
100 99
101/* Audio subsystem */
102static struct snd_soc_device omap2evm_snd_devdata = {
103 .card = &snd_soc_omap2evm,
104 .codec_dev = &soc_codec_dev_twl4030,
105};
106
107static struct platform_device *omap2evm_snd_device; 100static struct platform_device *omap2evm_snd_device;
108 101
109static int __init omap2evm_soc_init(void) 102static int __init omap2evm_soc_init(void)
@@ -122,9 +115,7 @@ static int __init omap2evm_soc_init(void)
122 return -ENOMEM; 115 return -ENOMEM;
123 } 116 }
124 117
125 platform_set_drvdata(omap2evm_snd_device, &omap2evm_snd_devdata); 118 platform_set_drvdata(omap2evm_snd_device, &snd_soc_omap2evm);
126 omap2evm_snd_devdata.dev = &omap2evm_snd_device->dev;
127 *(unsigned int *)omap2evm_dai.cpu_dai->private_data = 1; /* McBSP2 */
128 119
129 ret = platform_device_add(omap2evm_snd_device); 120 ret = platform_device_add(omap2evm_snd_device);
130 if (ret) 121 if (ret)
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
index 240e0975dd6..7c11e1afe9e 100644
--- a/sound/soc/omap/omap3beagle.c
+++ b/sound/soc/omap/omap3beagle.c
@@ -33,14 +33,13 @@
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37 36
38static int omap3beagle_hw_params(struct snd_pcm_substream *substream, 37static int omap3beagle_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params) 38 struct snd_pcm_hw_params *params)
40{ 39{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data; 40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 unsigned int fmt; 43 unsigned int fmt;
45 int ret; 44 int ret;
46 45
@@ -92,25 +91,21 @@ static struct snd_soc_ops omap3beagle_ops = {
92static struct snd_soc_dai_link omap3beagle_dai = { 91static struct snd_soc_dai_link omap3beagle_dai = {
93 .name = "TWL4030", 92 .name = "TWL4030",
94 .stream_name = "TWL4030", 93 .stream_name = "TWL4030",
95 .cpu_dai = &omap_mcbsp_dai[0], 94 .cpu_dai_name = "omap-mcbsp-dai.1",
96 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], 95 .platform_name = "omap-pcm-audio",
96 .codec_dai_name = "twl4030-hifi",
97 .codec_name = "twl4030-codec",
97 .ops = &omap3beagle_ops, 98 .ops = &omap3beagle_ops,
98}; 99};
99 100
100/* Audio machine driver */ 101/* Audio machine driver */
101static struct snd_soc_card snd_soc_omap3beagle = { 102static struct snd_soc_card snd_soc_omap3beagle = {
102 .name = "omap3beagle", 103 .name = "omap3beagle",
103 .platform = &omap_soc_platform, 104 .owner = THIS_MODULE,
104 .dai_link = &omap3beagle_dai, 105 .dai_link = &omap3beagle_dai,
105 .num_links = 1, 106 .num_links = 1,
106}; 107};
107 108
108/* Audio subsystem */
109static struct snd_soc_device omap3beagle_snd_devdata = {
110 .card = &snd_soc_omap3beagle,
111 .codec_dev = &soc_codec_dev_twl4030,
112};
113
114static struct platform_device *omap3beagle_snd_device; 109static struct platform_device *omap3beagle_snd_device;
115 110
116static int __init omap3beagle_soc_init(void) 111static int __init omap3beagle_soc_init(void)
@@ -129,9 +124,7 @@ static int __init omap3beagle_soc_init(void)
129 return -ENOMEM; 124 return -ENOMEM;
130 } 125 }
131 126
132 platform_set_drvdata(omap3beagle_snd_device, &omap3beagle_snd_devdata); 127 platform_set_drvdata(omap3beagle_snd_device, &snd_soc_omap3beagle);
133 omap3beagle_snd_devdata.dev = &omap3beagle_snd_device->dev;
134 *(unsigned int *)omap3beagle_dai.cpu_dai->private_data = 1; /* McBSP2 */
135 128
136 ret = platform_device_add(omap3beagle_snd_device); 129 ret = platform_device_add(omap3beagle_snd_device);
137 if (ret) 130 if (ret)
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index dfcb344092e..1ac5babef00 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -31,14 +31,13 @@
31 31
32#include "omap-mcbsp.h" 32#include "omap-mcbsp.h"
33#include "omap-pcm.h" 33#include "omap-pcm.h"
34#include "../codecs/twl4030.h"
35 34
36static int omap3evm_hw_params(struct snd_pcm_substream *substream, 35static int omap3evm_hw_params(struct snd_pcm_substream *substream,
37 struct snd_pcm_hw_params *params) 36 struct snd_pcm_hw_params *params)
38{ 37{
39 struct snd_soc_pcm_runtime *rtd = substream->private_data; 38 struct snd_soc_pcm_runtime *rtd = substream->private_data;
40 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 39 struct snd_soc_dai *codec_dai = rtd->codec_dai;
41 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 40 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
42 int ret; 41 int ret;
43 42
44 /* Set codec DAI configuration */ 43 /* Set codec DAI configuration */
@@ -80,32 +79,20 @@ static struct snd_soc_ops omap3evm_ops = {
80static struct snd_soc_dai_link omap3evm_dai = { 79static struct snd_soc_dai_link omap3evm_dai = {
81 .name = "TWL4030", 80 .name = "TWL4030",
82 .stream_name = "TWL4030", 81 .stream_name = "TWL4030",
83 .cpu_dai = &omap_mcbsp_dai[0], 82 .cpu_dai_name = "omap-mcbsp-dai.1",
84 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], 83 .codec_dai_name = "twl4030-hifi",
84 .platform_name = "omap-pcm-audio",
85 .codec_name = "twl4030-codec",
85 .ops = &omap3evm_ops, 86 .ops = &omap3evm_ops,
86}; 87};
87 88
88/* Audio machine driver */ 89/* Audio machine driver */
89static struct snd_soc_card snd_soc_omap3evm = { 90static struct snd_soc_card snd_soc_omap3evm = {
90 .name = "omap3evm", 91 .name = "omap3evm",
91 .platform = &omap_soc_platform,
92 .dai_link = &omap3evm_dai, 92 .dai_link = &omap3evm_dai,
93 .num_links = 1, 93 .num_links = 1,
94}; 94};
95 95
96/* twl4030 setup */
97static struct twl4030_setup_data twl4030_setup = {
98 .ramp_delay_value = 4,
99 .sysclk = 26000,
100};
101
102/* Audio subsystem */
103static struct snd_soc_device omap3evm_snd_devdata = {
104 .card = &snd_soc_omap3evm,
105 .codec_dev = &soc_codec_dev_twl4030,
106 .codec_data = &twl4030_setup,
107};
108
109static struct platform_device *omap3evm_snd_device; 96static struct platform_device *omap3evm_snd_device;
110 97
111static int __init omap3evm_soc_init(void) 98static int __init omap3evm_soc_init(void)
@@ -124,10 +111,7 @@ static int __init omap3evm_soc_init(void)
124 return -ENOMEM; 111 return -ENOMEM;
125 } 112 }
126 113
127 platform_set_drvdata(omap3evm_snd_device, &omap3evm_snd_devdata); 114 platform_set_drvdata(omap3evm_snd_device, &snd_soc_omap3evm);
128 omap3evm_snd_devdata.dev = &omap3evm_snd_device->dev;
129 *(unsigned int *)omap3evm_dai.cpu_dai->private_data = 1;
130
131 ret = platform_device_add(omap3evm_snd_device); 115 ret = platform_device_add(omap3evm_snd_device);
132 if (ret) 116 if (ret)
133 goto err1; 117 goto err1;
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 9eecac135bb..dbd9d96b5f9 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -31,10 +31,10 @@
31#include <sound/soc-dapm.h> 31#include <sound/soc-dapm.h>
32 32
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34#include <plat/mcbsp.h>
34 35
35#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
36#include "omap-pcm.h" 37#include "omap-pcm.h"
37#include "../codecs/twl4030.h"
38 38
39#define OMAP3_PANDORA_DAC_POWER_GPIO 118 39#define OMAP3_PANDORA_DAC_POWER_GPIO 118
40#define OMAP3_PANDORA_AMP_POWER_GPIO 14 40#define OMAP3_PANDORA_AMP_POWER_GPIO 14
@@ -47,8 +47,8 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream,
47 struct snd_pcm_hw_params *params) 47 struct snd_pcm_hw_params *params)
48{ 48{
49 struct snd_soc_pcm_runtime *rtd = substream->private_data; 49 struct snd_soc_pcm_runtime *rtd = substream->private_data;
50 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 50 struct snd_soc_dai *codec_dai = rtd->codec_dai;
51 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 51 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
52 int fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 52 int fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
53 SND_SOC_DAIFMT_CBS_CFS; 53 SND_SOC_DAIFMT_CBS_CFS;
54 int ret; 54 int ret;
@@ -167,8 +167,9 @@ static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
167 {"Mic Bias 2", NULL, "Mic (external)"}, 167 {"Mic Bias 2", NULL, "Mic (external)"},
168}; 168};
169 169
170static int omap3pandora_out_init(struct snd_soc_codec *codec) 170static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd)
171{ 171{
172 struct snd_soc_codec *codec = rtd->codec;
172 int ret; 173 int ret;
173 174
174 /* All TWL4030 output pins are floating */ 175 /* All TWL4030 output pins are floating */
@@ -194,8 +195,9 @@ static int omap3pandora_out_init(struct snd_soc_codec *codec)
194 return snd_soc_dapm_sync(codec); 195 return snd_soc_dapm_sync(codec);
195} 196}
196 197
197static int omap3pandora_in_init(struct snd_soc_codec *codec) 198static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
198{ 199{
200 struct snd_soc_codec *codec = rtd->codec;
199 int ret; 201 int ret;
200 202
201 /* Not comnnected */ 203 /* Not comnnected */
@@ -224,15 +226,19 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
224 { 226 {
225 .name = "PCM1773", 227 .name = "PCM1773",
226 .stream_name = "HiFi Out", 228 .stream_name = "HiFi Out",
227 .cpu_dai = &omap_mcbsp_dai[0], 229 .cpu_dai_name = "omap-mcbsp-dai.1",
228 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], 230 .codec_dai_name = "twl4030-hifi",
231 .platform_name = "omap-pcm-audio",
232 .codec_name = "twl4030-codec",
229 .ops = &omap3pandora_ops, 233 .ops = &omap3pandora_ops,
230 .init = omap3pandora_out_init, 234 .init = omap3pandora_out_init,
231 }, { 235 }, {
232 .name = "TWL4030", 236 .name = "TWL4030",
233 .stream_name = "Line/Mic In", 237 .stream_name = "Line/Mic In",
234 .cpu_dai = &omap_mcbsp_dai[1], 238 .cpu_dai_name = "omap-mcbsp-dai.3",
235 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], 239 .codec_dai_name = "twl4030-hifi",
240 .platform_name = "omap-pcm-audio",
241 .codec_name = "twl4030-codec",
236 .ops = &omap3pandora_ops, 242 .ops = &omap3pandora_ops,
237 .init = omap3pandora_in_init, 243 .init = omap3pandora_in_init,
238 } 244 }
@@ -241,17 +247,10 @@ static struct snd_soc_dai_link omap3pandora_dai[] = {
241/* SoC card */ 247/* SoC card */
242static struct snd_soc_card snd_soc_card_omap3pandora = { 248static struct snd_soc_card snd_soc_card_omap3pandora = {
243 .name = "omap3pandora", 249 .name = "omap3pandora",
244 .platform = &omap_soc_platform,
245 .dai_link = omap3pandora_dai, 250 .dai_link = omap3pandora_dai,
246 .num_links = ARRAY_SIZE(omap3pandora_dai), 251 .num_links = ARRAY_SIZE(omap3pandora_dai),
247}; 252};
248 253
249/* Audio subsystem */
250static struct snd_soc_device omap3pandora_snd_data = {
251 .card = &snd_soc_card_omap3pandora,
252 .codec_dev = &soc_codec_dev_twl4030,
253};
254
255static struct platform_device *omap3pandora_snd_device; 254static struct platform_device *omap3pandora_snd_device;
256 255
257static int __init omap3pandora_soc_init(void) 256static int __init omap3pandora_soc_init(void)
@@ -294,10 +293,7 @@ static int __init omap3pandora_soc_init(void)
294 goto fail1; 293 goto fail1;
295 } 294 }
296 295
297 platform_set_drvdata(omap3pandora_snd_device, &omap3pandora_snd_data); 296 platform_set_drvdata(omap3pandora_snd_device, &snd_soc_card_omap3pandora);
298 omap3pandora_snd_data.dev = &omap3pandora_snd_device->dev;
299 *(unsigned int *)omap_mcbsp_dai[0].private_data = 1; /* McBSP2 */
300 *(unsigned int *)omap_mcbsp_dai[1].private_data = 3; /* McBSP4 */
301 297
302 ret = platform_device_add(omap3pandora_snd_device); 298 ret = platform_device_add(omap3pandora_snd_device);
303 if (ret) { 299 if (ret) {
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index 498ca2e0351..f0e66255642 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -55,8 +55,8 @@ static int osk_hw_params(struct snd_pcm_substream *substream,
55 struct snd_pcm_hw_params *params) 55 struct snd_pcm_hw_params *params)
56{ 56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data; 57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 58 struct snd_soc_dai *codec_dai = rtd->codec_dai;
59 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 59 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
60 int err; 60 int err;
61 61
62 /* Set codec DAI configuration */ 62 /* Set codec DAI configuration */
@@ -113,8 +113,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
113 {"MICIN", NULL, "Mic Jack"}, 113 {"MICIN", NULL, "Mic Jack"},
114}; 114};
115 115
116static int osk_tlv320aic23_init(struct snd_soc_codec *codec) 116static int osk_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
117{ 117{
118 struct snd_soc_codec *codec = rtd->codec;
118 119
119 /* Add osk5912 specific widgets */ 120 /* Add osk5912 specific widgets */
120 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 121 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
@@ -136,8 +137,10 @@ static int osk_tlv320aic23_init(struct snd_soc_codec *codec)
136static struct snd_soc_dai_link osk_dai = { 137static struct snd_soc_dai_link osk_dai = {
137 .name = "TLV320AIC23", 138 .name = "TLV320AIC23",
138 .stream_name = "AIC23", 139 .stream_name = "AIC23",
139 .cpu_dai = &omap_mcbsp_dai[0], 140 .cpu_dai_name = "omap-mcbsp-dai.0",
140 .codec_dai = &tlv320aic23_dai, 141 .codec_dai_name = "tlv320aic23-hifi",
142 .platform_name = "omap-pcm-audio",
143 .codec_name = "tlv320aic23-codec",
141 .init = osk_tlv320aic23_init, 144 .init = osk_tlv320aic23_init,
142 .ops = &osk_ops, 145 .ops = &osk_ops,
143}; 146};
@@ -145,17 +148,10 @@ static struct snd_soc_dai_link osk_dai = {
145/* Audio machine driver */ 148/* Audio machine driver */
146static struct snd_soc_card snd_soc_card_osk = { 149static struct snd_soc_card snd_soc_card_osk = {
147 .name = "OSK5912", 150 .name = "OSK5912",
148 .platform = &omap_soc_platform,
149 .dai_link = &osk_dai, 151 .dai_link = &osk_dai,
150 .num_links = 1, 152 .num_links = 1,
151}; 153};
152 154
153/* Audio subsystem */
154static struct snd_soc_device osk_snd_devdata = {
155 .card = &snd_soc_card_osk,
156 .codec_dev = &soc_codec_dev_tlv320aic23,
157};
158
159static struct platform_device *osk_snd_device; 155static struct platform_device *osk_snd_device;
160 156
161static int __init osk_soc_init(void) 157static int __init osk_soc_init(void)
@@ -171,9 +167,7 @@ static int __init osk_soc_init(void)
171 if (!osk_snd_device) 167 if (!osk_snd_device)
172 return -ENOMEM; 168 return -ENOMEM;
173 169
174 platform_set_drvdata(osk_snd_device, &osk_snd_devdata); 170 platform_set_drvdata(osk_snd_device, &snd_soc_card_osk);
175 osk_snd_devdata.dev = &osk_snd_device->dev;
176 *(unsigned int *)osk_dai.cpu_dai->private_data = 0; /* McBSP1 */
177 err = platform_device_add(osk_snd_device); 171 err = platform_device_add(osk_snd_device);
178 if (err) 172 if (err)
179 goto err1; 173 goto err1;
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index c25f5276ad6..e95a607937d 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -33,14 +33,13 @@
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37 36
38static int overo_hw_params(struct snd_pcm_substream *substream, 37static int overo_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params) 38 struct snd_pcm_hw_params *params)
40{ 39{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data; 40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 int ret; 43 int ret;
45 44
46 /* Set codec DAI configuration */ 45 /* Set codec DAI configuration */
@@ -82,25 +81,20 @@ static struct snd_soc_ops overo_ops = {
82static struct snd_soc_dai_link overo_dai = { 81static struct snd_soc_dai_link overo_dai = {
83 .name = "TWL4030", 82 .name = "TWL4030",
84 .stream_name = "TWL4030", 83 .stream_name = "TWL4030",
85 .cpu_dai = &omap_mcbsp_dai[0], 84 .cpu_dai_name = "omap-mcbsp-dai.1",
86 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], 85 .codec_dai_name = "twl4030-hifi",
86 .platform_name = "omap-pcm-audio",
87 .codec_name = "twl4030-codec",
87 .ops = &overo_ops, 88 .ops = &overo_ops,
88}; 89};
89 90
90/* Audio machine driver */ 91/* Audio machine driver */
91static struct snd_soc_card snd_soc_card_overo = { 92static struct snd_soc_card snd_soc_card_overo = {
92 .name = "overo", 93 .name = "overo",
93 .platform = &omap_soc_platform,
94 .dai_link = &overo_dai, 94 .dai_link = &overo_dai,
95 .num_links = 1, 95 .num_links = 1,
96}; 96};
97 97
98/* Audio subsystem */
99static struct snd_soc_device overo_snd_devdata = {
100 .card = &snd_soc_card_overo,
101 .codec_dev = &soc_codec_dev_twl4030,
102};
103
104static struct platform_device *overo_snd_device; 98static struct platform_device *overo_snd_device;
105 99
106static int __init overo_soc_init(void) 100static int __init overo_soc_init(void)
@@ -119,9 +113,7 @@ static int __init overo_soc_init(void)
119 return -ENOMEM; 113 return -ENOMEM;
120 } 114 }
121 115
122 platform_set_drvdata(overo_snd_device, &overo_snd_devdata); 116 platform_set_drvdata(overo_snd_device, &snd_soc_card_overo);
123 overo_snd_devdata.dev = &overo_snd_device->dev;
124 *(unsigned int *)overo_dai.cpu_dai->private_data = 1; /* McBSP2 */
125 117
126 ret = platform_device_add(overo_snd_device); 118 ret = platform_device_add(overo_snd_device);
127 if (ret) 119 if (ret)
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 88052d29617..d1d8098923c 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -31,6 +31,7 @@
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <sound/soc-dapm.h> 33#include <sound/soc-dapm.h>
34#include <plat/mcbsp.h>
34 35
35#include <asm/mach-types.h> 36#include <asm/mach-types.h>
36 37
@@ -76,7 +77,7 @@ static int rx51_startup(struct snd_pcm_substream *substream)
76{ 77{
77 struct snd_pcm_runtime *runtime = substream->runtime; 78 struct snd_pcm_runtime *runtime = substream->runtime;
78 struct snd_soc_pcm_runtime *rtd = substream->private_data; 79 struct snd_soc_pcm_runtime *rtd = substream->private_data;
79 struct snd_soc_codec *codec = rtd->socdev->card->codec; 80 struct snd_soc_codec *codec = rtd->codec;
80 81
81 snd_pcm_hw_constraint_minmax(runtime, 82 snd_pcm_hw_constraint_minmax(runtime,
82 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); 83 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
@@ -89,8 +90,8 @@ static int rx51_hw_params(struct snd_pcm_substream *substream,
89 struct snd_pcm_hw_params *params) 90 struct snd_pcm_hw_params *params)
90{ 91{
91 struct snd_soc_pcm_runtime *rtd = substream->private_data; 92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
92 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 93 struct snd_soc_dai *codec_dai = rtd->codec_dai;
93 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 94 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
94 int err; 95 int err;
95 96
96 /* Set codec DAI configuration */ 97 /* Set codec DAI configuration */
@@ -240,9 +241,9 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
240 rx51_get_jack, rx51_set_jack), 241 rx51_get_jack, rx51_set_jack),
241}; 242};
242 243
243static int rx51_aic34_init(struct snd_soc_codec *codec) 244static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
244{ 245{
245 struct snd_soc_card *card = codec->socdev->card; 246 struct snd_soc_codec *codec = rtd->codec;
246 int err; 247 int err;
247 248
248 /* Set up NC codec pins */ 249 /* Set up NC codec pins */
@@ -266,7 +267,7 @@ static int rx51_aic34_init(struct snd_soc_codec *codec)
266 snd_soc_dapm_sync(codec); 267 snd_soc_dapm_sync(codec);
267 268
268 /* AV jack detection */ 269 /* AV jack detection */
269 err = snd_soc_jack_new(card, "AV Jack", 270 err = snd_soc_jack_new(codec, "AV Jack",
270 SND_JACK_VIDEOOUT, &rx51_av_jack); 271 SND_JACK_VIDEOOUT, &rx51_av_jack);
271 if (err) 272 if (err)
272 return err; 273 return err;
@@ -282,32 +283,20 @@ static struct snd_soc_dai_link rx51_dai[] = {
282 { 283 {
283 .name = "TLV320AIC34", 284 .name = "TLV320AIC34",
284 .stream_name = "AIC34", 285 .stream_name = "AIC34",
285 .cpu_dai = &omap_mcbsp_dai[0], 286 .cpu_dai_name = "omap-mcbsp-dai.1",
286 .codec_dai = &aic3x_dai, 287 .codec_dai_name = "tlv320aic3x-hifi",
288 .platform_name = "omap-pcm-audio",
289 .codec_name = "tlv320aic3x-codec.2-0018",
287 .init = rx51_aic34_init, 290 .init = rx51_aic34_init,
288 .ops = &rx51_ops, 291 .ops = &rx51_ops,
289 }, 292 },
290}; 293};
291 294
292/* Audio private data */
293static struct aic3x_setup_data rx51_aic34_setup = {
294 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
295 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
296};
297
298/* Audio card */ 295/* Audio card */
299static struct snd_soc_card rx51_sound_card = { 296static struct snd_soc_card rx51_sound_card = {
300 .name = "RX-51", 297 .name = "RX-51",
301 .dai_link = rx51_dai, 298 .dai_link = rx51_dai,
302 .num_links = ARRAY_SIZE(rx51_dai), 299 .num_links = ARRAY_SIZE(rx51_dai),
303 .platform = &omap_soc_platform,
304};
305
306/* Audio subsystem */
307static struct snd_soc_device rx51_snd_devdata = {
308 .card = &rx51_sound_card,
309 .codec_dev = &soc_codec_dev_aic3x,
310 .codec_data = &rx51_aic34_setup,
311}; 300};
312 301
313static struct platform_device *rx51_snd_device; 302static struct platform_device *rx51_snd_device;
@@ -330,9 +319,7 @@ static int __init rx51_soc_init(void)
330 goto err1; 319 goto err1;
331 } 320 }
332 321
333 platform_set_drvdata(rx51_snd_device, &rx51_snd_devdata); 322 platform_set_drvdata(rx51_snd_device, &rx51_sound_card);
334 rx51_snd_devdata.dev = &rx51_snd_device->dev;
335 *(unsigned int *)rx51_dai[0].cpu_dai->private_data = 1; /* McBSP2 */
336 323
337 err = platform_device_add(rx51_snd_device); 324 err = platform_device_add(rx51_snd_device);
338 if (err) 325 if (err)
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 3c85c0f9282..76ce77b9184 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -36,9 +36,11 @@
36#include <mach/gpio.h> 36#include <mach/gpio.h>
37#include <plat/mcbsp.h> 37#include <plat/mcbsp.h>
38 38
39/* Register descriptions for twl4030 codec part */
40#include <linux/mfd/twl4030-codec.h>
41
39#include "omap-mcbsp.h" 42#include "omap-mcbsp.h"
40#include "omap-pcm.h" 43#include "omap-pcm.h"
41#include "../codecs/twl4030.h"
42 44
43/* TWL4030 PMBR1 Register */ 45/* TWL4030 PMBR1 Register */
44#define TWL4030_INTBR_PMBR1 0x0D 46#define TWL4030_INTBR_PMBR1 0x0D
@@ -51,8 +53,8 @@ static int sdp3430_hw_params(struct snd_pcm_substream *substream,
51 struct snd_pcm_hw_params *params) 53 struct snd_pcm_hw_params *params)
52{ 54{
53 struct snd_soc_pcm_runtime *rtd = substream->private_data; 55 struct snd_soc_pcm_runtime *rtd = substream->private_data;
54 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 56 struct snd_soc_dai *codec_dai = rtd->codec_dai;
55 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 57 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
56 int ret; 58 int ret;
57 59
58 /* Set codec DAI configuration */ 60 /* Set codec DAI configuration */
@@ -94,8 +96,8 @@ static int sdp3430_hw_voice_params(struct snd_pcm_substream *substream,
94 struct snd_pcm_hw_params *params) 96 struct snd_pcm_hw_params *params)
95{ 97{
96 struct snd_soc_pcm_runtime *rtd = substream->private_data; 98 struct snd_soc_pcm_runtime *rtd = substream->private_data;
97 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 99 struct snd_soc_dai *codec_dai = rtd->codec_dai;
98 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 100 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
99 int ret; 101 int ret;
100 102
101 /* Set codec DAI configuration */ 103 /* Set codec DAI configuration */
@@ -186,8 +188,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
186 {"Headset Stereophone", NULL, "HSOR"}, 188 {"Headset Stereophone", NULL, "HSOR"},
187}; 189};
188 190
189static int sdp3430_twl4030_init(struct snd_soc_codec *codec) 191static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd)
190{ 192{
193 struct snd_soc_codec *codec = rtd->codec;
191 int ret; 194 int ret;
192 195
193 /* Add SDP3430 specific widgets */ 196 /* Add SDP3430 specific widgets */
@@ -225,7 +228,7 @@ static int sdp3430_twl4030_init(struct snd_soc_codec *codec)
225 return ret; 228 return ret;
226 229
227 /* Headset jack detection */ 230 /* Headset jack detection */
228 ret = snd_soc_jack_new(&snd_soc_sdp3430, "Headset Jack", 231 ret = snd_soc_jack_new(codec, "Headset Jack",
229 SND_JACK_HEADSET, &hs_jack); 232 SND_JACK_HEADSET, &hs_jack);
230 if (ret) 233 if (ret)
231 return ret; 234 return ret;
@@ -241,14 +244,15 @@ static int sdp3430_twl4030_init(struct snd_soc_codec *codec)
241 return ret; 244 return ret;
242} 245}
243 246
244static int sdp3430_twl4030_voice_init(struct snd_soc_codec *codec) 247static int sdp3430_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd)
245{ 248{
249 struct snd_soc_codec *codec = rtd->codec;
246 unsigned short reg; 250 unsigned short reg;
247 251
248 /* Enable voice interface */ 252 /* Enable voice interface */
249 reg = codec->read(codec, TWL4030_REG_VOICE_IF); 253 reg = codec->driver->read(codec, TWL4030_REG_VOICE_IF);
250 reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN; 254 reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN;
251 codec->write(codec, TWL4030_REG_VOICE_IF, reg); 255 codec->driver->write(codec, TWL4030_REG_VOICE_IF, reg);
252 256
253 return 0; 257 return 0;
254} 258}
@@ -259,16 +263,20 @@ static struct snd_soc_dai_link sdp3430_dai[] = {
259 { 263 {
260 .name = "TWL4030 I2S", 264 .name = "TWL4030 I2S",
261 .stream_name = "TWL4030 Audio", 265 .stream_name = "TWL4030 Audio",
262 .cpu_dai = &omap_mcbsp_dai[0], 266 .cpu_dai_name = "omap-mcbsp-dai.1",
263 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], 267 .codec_dai_name = "twl4030-hifi",
268 .platform_name = "omap-pcm-audio",
269 .codec_name = "twl4030-codec",
264 .init = sdp3430_twl4030_init, 270 .init = sdp3430_twl4030_init,
265 .ops = &sdp3430_ops, 271 .ops = &sdp3430_ops,
266 }, 272 },
267 { 273 {
268 .name = "TWL4030 PCM", 274 .name = "TWL4030 PCM",
269 .stream_name = "TWL4030 Voice", 275 .stream_name = "TWL4030 Voice",
270 .cpu_dai = &omap_mcbsp_dai[1], 276 .cpu_dai_name = "omap-mcbsp-dai.2",
271 .codec_dai = &twl4030_dai[TWL4030_DAI_VOICE], 277 .codec_dai_name = "twl4030-voice",
278 .platform_name = "omap-pcm-audio",
279 .codec_name = "twl4030-codec",
272 .init = sdp3430_twl4030_voice_init, 280 .init = sdp3430_twl4030_voice_init,
273 .ops = &sdp3430_voice_ops, 281 .ops = &sdp3430_voice_ops,
274 }, 282 },
@@ -277,25 +285,10 @@ static struct snd_soc_dai_link sdp3430_dai[] = {
277/* Audio machine driver */ 285/* Audio machine driver */
278static struct snd_soc_card snd_soc_sdp3430 = { 286static struct snd_soc_card snd_soc_sdp3430 = {
279 .name = "SDP3430", 287 .name = "SDP3430",
280 .platform = &omap_soc_platform,
281 .dai_link = sdp3430_dai, 288 .dai_link = sdp3430_dai,
282 .num_links = ARRAY_SIZE(sdp3430_dai), 289 .num_links = ARRAY_SIZE(sdp3430_dai),
283}; 290};
284 291
285/* twl4030 setup */
286static struct twl4030_setup_data twl4030_setup = {
287 .ramp_delay_value = 3,
288 .sysclk = 26000,
289 .hs_extmute = 1,
290};
291
292/* Audio subsystem */
293static struct snd_soc_device sdp3430_snd_devdata = {
294 .card = &snd_soc_sdp3430,
295 .codec_dev = &soc_codec_dev_twl4030,
296 .codec_data = &twl4030_setup,
297};
298
299static struct platform_device *sdp3430_snd_device; 292static struct platform_device *sdp3430_snd_device;
300 293
301static int __init sdp3430_soc_init(void) 294static int __init sdp3430_soc_init(void)
@@ -315,10 +308,7 @@ static int __init sdp3430_soc_init(void)
315 return -ENOMEM; 308 return -ENOMEM;
316 } 309 }
317 310
318 platform_set_drvdata(sdp3430_snd_device, &sdp3430_snd_devdata); 311 platform_set_drvdata(sdp3430_snd_device, &snd_soc_sdp3430);
319 sdp3430_snd_devdata.dev = &sdp3430_snd_device->dev;
320 *(unsigned int *)sdp3430_dai[0].cpu_dai->private_data = 1; /* McBSP2 */
321 *(unsigned int *)sdp3430_dai[1].cpu_dai->private_data = 2; /* McBSP3 */
322 312
323 /* Set TWL4030 GPIO6 as EXTMUTE signal */ 313 /* Set TWL4030 GPIO6 as EXTMUTE signal */
324 twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux, 314 twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux,
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
index 4ebbde6b565..62f6a622d79 100644
--- a/sound/soc/omap/sdp4430.c
+++ b/sound/soc/omap/sdp4430.c
@@ -31,7 +31,6 @@
31#include <plat/mux.h> 31#include <plat/mux.h>
32 32
33#include "mcpdm.h" 33#include "mcpdm.h"
34#include "omap-mcpdm.h"
35#include "omap-pcm.h" 34#include "omap-pcm.h"
36#include "../codecs/twl6040.h" 35#include "../codecs/twl6040.h"
37 36
@@ -41,7 +40,7 @@ static int sdp4430_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params) 40 struct snd_pcm_hw_params *params)
42{ 41{
43 struct snd_soc_pcm_runtime *rtd = substream->private_data; 42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
44 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 43 struct snd_soc_dai *codec_dai = rtd->codec_dai;
45 int clk_id, freq; 44 int clk_id, freq;
46 int ret; 45 int ret;
47 46
@@ -60,6 +59,7 @@ static int sdp4430_hw_params(struct snd_pcm_substream *substream,
60 printk(KERN_ERR "can't set codec system clock\n"); 59 printk(KERN_ERR "can't set codec system clock\n");
61 return ret; 60 return ret;
62 } 61 }
62 return ret;
63} 63}
64 64
65static struct snd_soc_ops sdp4430_ops = { 65static struct snd_soc_ops sdp4430_ops = {
@@ -126,8 +126,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
126 {"Earphone Spk", NULL, "EP"}, 126 {"Earphone Spk", NULL, "EP"},
127}; 127};
128 128
129static int sdp4430_twl6040_init(struct snd_soc_codec *codec) 129static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
130{ 130{
131 struct snd_soc_codec *codec = rtd->codec;
131 int ret; 132 int ret;
132 133
133 /* Add SDP4430 specific controls */ 134 /* Add SDP4430 specific controls */
@@ -164,8 +165,10 @@ static int sdp4430_twl6040_init(struct snd_soc_codec *codec)
164static struct snd_soc_dai_link sdp4430_dai = { 165static struct snd_soc_dai_link sdp4430_dai = {
165 .name = "TWL6040", 166 .name = "TWL6040",
166 .stream_name = "TWL6040", 167 .stream_name = "TWL6040",
167 .cpu_dai = &omap_mcpdm_dai, 168 .cpu_dai_name ="omap-mcpdm-dai",
168 .codec_dai = &twl6040_dai, 169 .codec_dai_name = "twl6040-hifi",
170 .platform_name = "omap-pcm-audio",
171 .codec_name = "twl6040-codec",
169 .init = sdp4430_twl6040_init, 172 .init = sdp4430_twl6040_init,
170 .ops = &sdp4430_ops, 173 .ops = &sdp4430_ops,
171}; 174};
@@ -173,17 +176,10 @@ static struct snd_soc_dai_link sdp4430_dai = {
173/* Audio machine driver */ 176/* Audio machine driver */
174static struct snd_soc_card snd_soc_sdp4430 = { 177static struct snd_soc_card snd_soc_sdp4430 = {
175 .name = "SDP4430", 178 .name = "SDP4430",
176 .platform = &omap_soc_platform,
177 .dai_link = &sdp4430_dai, 179 .dai_link = &sdp4430_dai,
178 .num_links = 1, 180 .num_links = 1,
179}; 181};
180 182
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; 183static struct platform_device *sdp4430_snd_device;
188 184
189static int __init sdp4430_soc_init(void) 185static int __init sdp4430_soc_init(void)
@@ -202,8 +198,7 @@ static int __init sdp4430_soc_init(void)
202 return -ENOMEM; 198 return -ENOMEM;
203 } 199 }
204 200
205 platform_set_drvdata(sdp4430_snd_device, &sdp4430_snd_devdata); 201 platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430);
206 sdp4430_snd_devdata.dev = &sdp4430_snd_device->dev;
207 202
208 ret = platform_device_add(sdp4430_snd_device); 203 ret = platform_device_add(sdp4430_snd_device);
209 if (ret) 204 if (ret)
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 50a94ee76ec..338dc9552bd 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -29,21 +29,23 @@
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/gpio.h> 31#include <mach/gpio.h>
32#include <mach/board-zoom.h>
32#include <plat/mcbsp.h> 33#include <plat/mcbsp.h>
33 34
35/* Register descriptions for twl4030 codec part */
36#include <linux/mfd/twl4030-codec.h>
37
34#include "omap-mcbsp.h" 38#include "omap-mcbsp.h"
35#include "omap-pcm.h" 39#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37 40
38#define ZOOM2_HEADSET_MUX_GPIO (OMAP_MAX_GPIO_LINES + 15) 41#define ZOOM2_HEADSET_MUX_GPIO (OMAP_MAX_GPIO_LINES + 15)
39#define ZOOM2_HEADSET_EXTMUTE_GPIO 153
40 42
41static int zoom2_hw_params(struct snd_pcm_substream *substream, 43static int zoom2_hw_params(struct snd_pcm_substream *substream,
42 struct snd_pcm_hw_params *params) 44 struct snd_pcm_hw_params *params)
43{ 45{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data; 46 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 47 struct snd_soc_dai *codec_dai = rtd->codec_dai;
46 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 48 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
47 int ret; 49 int ret;
48 50
49 /* Set codec DAI configuration */ 51 /* Set codec DAI configuration */
@@ -85,8 +87,8 @@ static int zoom2_hw_voice_params(struct snd_pcm_substream *substream,
85 struct snd_pcm_hw_params *params) 87 struct snd_pcm_hw_params *params)
86{ 88{
87 struct snd_soc_pcm_runtime *rtd = substream->private_data; 89 struct snd_soc_pcm_runtime *rtd = substream->private_data;
88 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 90 struct snd_soc_dai *codec_dai = rtd->codec_dai;
89 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 91 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
90 int ret; 92 int ret;
91 93
92 /* Set codec DAI configuration */ 94 /* Set codec DAI configuration */
@@ -157,8 +159,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
157 {"Aux In", NULL, "AUXR"}, 159 {"Aux In", NULL, "AUXR"},
158}; 160};
159 161
160static int zoom2_twl4030_init(struct snd_soc_codec *codec) 162static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd)
161{ 163{
164 struct snd_soc_codec *codec = rtd->codec;
162 int ret; 165 int ret;
163 166
164 /* Add Zoom2 specific widgets */ 167 /* Add Zoom2 specific widgets */
@@ -192,14 +195,15 @@ static int zoom2_twl4030_init(struct snd_soc_codec *codec)
192 return ret; 195 return ret;
193} 196}
194 197
195static int zoom2_twl4030_voice_init(struct snd_soc_codec *codec) 198static int zoom2_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd)
196{ 199{
200 struct snd_soc_codec *codec = rtd->codec;
197 unsigned short reg; 201 unsigned short reg;
198 202
199 /* Enable voice interface */ 203 /* Enable voice interface */
200 reg = codec->read(codec, TWL4030_REG_VOICE_IF); 204 reg = codec->driver->read(codec, TWL4030_REG_VOICE_IF);
201 reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN; 205 reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN;
202 codec->write(codec, TWL4030_REG_VOICE_IF, reg); 206 codec->driver->write(codec, TWL4030_REG_VOICE_IF, reg);
203 207
204 return 0; 208 return 0;
205} 209}
@@ -209,16 +213,20 @@ static struct snd_soc_dai_link zoom2_dai[] = {
209 { 213 {
210 .name = "TWL4030 I2S", 214 .name = "TWL4030 I2S",
211 .stream_name = "TWL4030 Audio", 215 .stream_name = "TWL4030 Audio",
212 .cpu_dai = &omap_mcbsp_dai[0], 216 .cpu_dai_name = "omap-mcbsp-dai.1",
213 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], 217 .codec_dai_name = "twl4030-hifi",
218 .platform_name = "omap-pcm-audio",
219 .codec_name = "twl4030-codec",
214 .init = zoom2_twl4030_init, 220 .init = zoom2_twl4030_init,
215 .ops = &zoom2_ops, 221 .ops = &zoom2_ops,
216 }, 222 },
217 { 223 {
218 .name = "TWL4030 PCM", 224 .name = "TWL4030 PCM",
219 .stream_name = "TWL4030 Voice", 225 .stream_name = "TWL4030 Voice",
220 .cpu_dai = &omap_mcbsp_dai[1], 226 .cpu_dai_name = "omap-mcbsp-dai.2",
221 .codec_dai = &twl4030_dai[TWL4030_DAI_VOICE], 227 .codec_dai_name = "twl4030-voice",
228 .platform_name = "omap-pcm-audio",
229 .codec_name = "twl4030-codec",
222 .init = zoom2_twl4030_voice_init, 230 .init = zoom2_twl4030_voice_init,
223 .ops = &zoom2_voice_ops, 231 .ops = &zoom2_voice_ops,
224 }, 232 },
@@ -227,32 +235,10 @@ static struct snd_soc_dai_link zoom2_dai[] = {
227/* Audio machine driver */ 235/* Audio machine driver */
228static struct snd_soc_card snd_soc_zoom2 = { 236static struct snd_soc_card snd_soc_zoom2 = {
229 .name = "Zoom2", 237 .name = "Zoom2",
230 .platform = &omap_soc_platform,
231 .dai_link = zoom2_dai, 238 .dai_link = zoom2_dai,
232 .num_links = ARRAY_SIZE(zoom2_dai), 239 .num_links = ARRAY_SIZE(zoom2_dai),
233}; 240};
234 241
235/* EXTMUTE callback function */
236void zoom2_set_hs_extmute(int mute)
237{
238 gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute);
239}
240
241/* twl4030 setup */
242static struct twl4030_setup_data twl4030_setup = {
243 .ramp_delay_value = 3, /* 161 ms */
244 .sysclk = 26000,
245 .hs_extmute = 1,
246 .set_hs_extmute = zoom2_set_hs_extmute,
247};
248
249/* Audio subsystem */
250static struct snd_soc_device zoom2_snd_devdata = {
251 .card = &snd_soc_zoom2,
252 .codec_dev = &soc_codec_dev_twl4030,
253 .codec_data = &twl4030_setup,
254};
255
256static struct platform_device *zoom2_snd_device; 242static struct platform_device *zoom2_snd_device;
257 243
258static int __init zoom2_soc_init(void) 244static int __init zoom2_soc_init(void)
@@ -271,11 +257,7 @@ static int __init zoom2_soc_init(void)
271 return -ENOMEM; 257 return -ENOMEM;
272 } 258 }
273 259
274 platform_set_drvdata(zoom2_snd_device, &zoom2_snd_devdata); 260 platform_set_drvdata(zoom2_snd_device, &snd_soc_zoom2);
275 zoom2_snd_devdata.dev = &zoom2_snd_device->dev;
276 *(unsigned int *)zoom2_dai[0].cpu_dai->private_data = 1; /* McBSP2 */
277 *(unsigned int *)zoom2_dai[1].cpu_dai->private_data = 2; /* McBSP3 */
278
279 ret = platform_device_add(zoom2_snd_device); 261 ret = platform_device_add(zoom2_snd_device);
280 if (ret) 262 if (ret)
281 goto err1; 263 goto err1;
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index fefe1a57f31..11c6a495f97 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -99,7 +99,7 @@ static void corgi_ext_control(struct snd_soc_codec *codec)
99static int corgi_startup(struct snd_pcm_substream *substream) 99static int corgi_startup(struct snd_pcm_substream *substream)
100{ 100{
101 struct snd_soc_pcm_runtime *rtd = substream->private_data; 101 struct snd_soc_pcm_runtime *rtd = substream->private_data;
102 struct snd_soc_codec *codec = rtd->socdev->card->codec; 102 struct snd_soc_codec *codec = rtd->codec;
103 103
104 /* check the jack status at stream startup */ 104 /* check the jack status at stream startup */
105 corgi_ext_control(codec); 105 corgi_ext_control(codec);
@@ -118,8 +118,8 @@ static int corgi_hw_params(struct snd_pcm_substream *substream,
118 struct snd_pcm_hw_params *params) 118 struct snd_pcm_hw_params *params)
119{ 119{
120 struct snd_soc_pcm_runtime *rtd = substream->private_data; 120 struct snd_soc_pcm_runtime *rtd = substream->private_data;
121 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 121 struct snd_soc_dai *codec_dai = rtd->codec_dai;
122 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 122 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
123 unsigned int clk = 0; 123 unsigned int clk = 0;
124 int ret = 0; 124 int ret = 0;
125 125
@@ -272,8 +272,9 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = {
272/* 272/*
273 * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device 273 * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device
274 */ 274 */
275static int corgi_wm8731_init(struct snd_soc_codec *codec) 275static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
276{ 276{
277 struct snd_soc_codec *codec = rtd->codec;
277 int err; 278 int err;
278 279
279 snd_soc_dapm_nc_pin(codec, "LLINEIN"); 280 snd_soc_dapm_nc_pin(codec, "LLINEIN");
@@ -300,8 +301,10 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec)
300static struct snd_soc_dai_link corgi_dai = { 301static struct snd_soc_dai_link corgi_dai = {
301 .name = "WM8731", 302 .name = "WM8731",
302 .stream_name = "WM8731", 303 .stream_name = "WM8731",
303 .cpu_dai = &pxa_i2s_dai, 304 .cpu_dai_name = "pxa-is2-dai",
304 .codec_dai = &wm8731_dai, 305 .codec_dai_name = "wm8731-hifi",
306 .platform_name = "pxa-pcm-audio",
307 .codec_name = "wm8731-codec-0.001a",
305 .init = corgi_wm8731_init, 308 .init = corgi_wm8731_init,
306 .ops = &corgi_ops, 309 .ops = &corgi_ops,
307}; 310};
@@ -309,17 +312,10 @@ static struct snd_soc_dai_link corgi_dai = {
309/* corgi audio machine driver */ 312/* corgi audio machine driver */
310static struct snd_soc_card snd_soc_corgi = { 313static struct snd_soc_card snd_soc_corgi = {
311 .name = "Corgi", 314 .name = "Corgi",
312 .platform = &pxa2xx_soc_platform,
313 .dai_link = &corgi_dai, 315 .dai_link = &corgi_dai,
314 .num_links = 1, 316 .num_links = 1,
315}; 317};
316 318
317/* corgi audio subsystem */
318static struct snd_soc_device corgi_snd_devdata = {
319 .card = &snd_soc_corgi,
320 .codec_dev = &soc_codec_dev_wm8731,
321};
322
323static struct platform_device *corgi_snd_device; 319static struct platform_device *corgi_snd_device;
324 320
325static int __init corgi_init(void) 321static int __init corgi_init(void)
@@ -334,8 +330,7 @@ static int __init corgi_init(void)
334 if (!corgi_snd_device) 330 if (!corgi_snd_device)
335 return -ENOMEM; 331 return -ENOMEM;
336 332
337 platform_set_drvdata(corgi_snd_device, &corgi_snd_devdata); 333 platform_set_drvdata(corgi_snd_device, &snd_soc_corgi);
338 corgi_snd_devdata.dev = &corgi_snd_device->dev;
339 ret = platform_device_add(corgi_snd_device); 334 ret = platform_device_add(corgi_snd_device);
340 335
341 if (ret) 336 if (ret)
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index 7cd2f89d7b1..f614607b205 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -24,7 +24,6 @@
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25 25
26#include "../codecs/wm9705.h" 26#include "../codecs/wm9705.h"
27#include "pxa2xx-pcm.h"
28#include "pxa2xx-ac97.h" 27#include "pxa2xx-ac97.h"
29 28
30 29
@@ -90,8 +89,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
90 {"Mic Amp", NULL, "Mic (Internal)"}, 89 {"Mic Amp", NULL, "Mic (Internal)"},
91}; 90};
92 91
93static int e740_ac97_init(struct snd_soc_codec *codec) 92static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd)
94{ 93{
94 struct snd_soc_codec *codec = rtd->codec;
95
95 snd_soc_dapm_nc_pin(codec, "HPOUTL"); 96 snd_soc_dapm_nc_pin(codec, "HPOUTL");
96 snd_soc_dapm_nc_pin(codec, "HPOUTR"); 97 snd_soc_dapm_nc_pin(codec, "HPOUTR");
97 snd_soc_dapm_nc_pin(codec, "PHONE"); 98 snd_soc_dapm_nc_pin(codec, "PHONE");
@@ -116,30 +117,28 @@ static struct snd_soc_dai_link e740_dai[] = {
116 { 117 {
117 .name = "AC97", 118 .name = "AC97",
118 .stream_name = "AC97 HiFi", 119 .stream_name = "AC97 HiFi",
119 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 120 .cpu_dai_name = "pxa-ac97.0",
120 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI], 121 .codec_dai_name = "wm9705-hifi",
122 .platform_name = "pxa-pcm-audio",
123 .codec_name = "wm9705-codec",
121 .init = e740_ac97_init, 124 .init = e740_ac97_init,
122 }, 125 },
123 { 126 {
124 .name = "AC97 Aux", 127 .name = "AC97 Aux",
125 .stream_name = "AC97 Aux", 128 .stream_name = "AC97 Aux",
126 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 129 .cpu_dai_name = "pxa-ac97.1",
127 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX], 130 .codec_dai_name = "wm9705-aux",
131 .platform_name = "pxa-pcm-audio",
132 .codec_name = "wm9705-codec",
128 }, 133 },
129}; 134};
130 135
131static struct snd_soc_card e740 = { 136static struct snd_soc_card e740 = {
132 .name = "Toshiba e740", 137 .name = "Toshiba e740",
133 .platform = &pxa2xx_soc_platform,
134 .dai_link = e740_dai, 138 .dai_link = e740_dai,
135 .num_links = ARRAY_SIZE(e740_dai), 139 .num_links = ARRAY_SIZE(e740_dai),
136}; 140};
137 141
138static struct snd_soc_device e740_snd_devdata = {
139 .card = &e740,
140 .codec_dev = &soc_codec_dev_wm9705,
141};
142
143static struct platform_device *e740_snd_device; 142static struct platform_device *e740_snd_device;
144 143
145static int __init e740_init(void) 144static int __init e740_init(void)
@@ -178,8 +177,7 @@ static int __init e740_init(void)
178 goto free_apwr_gpio; 177 goto free_apwr_gpio;
179 } 178 }
180 179
181 platform_set_drvdata(e740_snd_device, &e740_snd_devdata); 180 platform_set_drvdata(e740_snd_device, &e740);
182 e740_snd_devdata.dev = &e740_snd_device->dev;
183 ret = platform_device_add(e740_snd_device); 181 ret = platform_device_add(e740_snd_device);
184 182
185 if (!ret) 183 if (!ret)
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 8dceccc5e05..4c143803a75 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -24,7 +24,6 @@
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25 25
26#include "../codecs/wm9705.h" 26#include "../codecs/wm9705.h"
27#include "pxa2xx-pcm.h"
28#include "pxa2xx-ac97.h" 27#include "pxa2xx-ac97.h"
29 28
30static int e750_spk_amp_event(struct snd_soc_dapm_widget *w, 29static int e750_spk_amp_event(struct snd_soc_dapm_widget *w,
@@ -72,8 +71,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
72 {"MIC1", NULL, "Mic (Internal)"}, 71 {"MIC1", NULL, "Mic (Internal)"},
73}; 72};
74 73
75static int e750_ac97_init(struct snd_soc_codec *codec) 74static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd)
76{ 75{
76 struct snd_soc_codec *codec = rtd->codec;
77
77 snd_soc_dapm_nc_pin(codec, "LOUT"); 78 snd_soc_dapm_nc_pin(codec, "LOUT");
78 snd_soc_dapm_nc_pin(codec, "ROUT"); 79 snd_soc_dapm_nc_pin(codec, "ROUT");
79 snd_soc_dapm_nc_pin(codec, "PHONE"); 80 snd_soc_dapm_nc_pin(codec, "PHONE");
@@ -98,31 +99,29 @@ static struct snd_soc_dai_link e750_dai[] = {
98 { 99 {
99 .name = "AC97", 100 .name = "AC97",
100 .stream_name = "AC97 HiFi", 101 .stream_name = "AC97 HiFi",
101 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 102 .cpu_dai_name = "pxa-ac97.0",
102 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI], 103 .codec_dai_name = "wm9705-hifi",
104 .platform_name = "pxa-pcm-audio",
105 .codec_name = "wm9705-codec",
103 .init = e750_ac97_init, 106 .init = e750_ac97_init,
104 /* use ops to check startup state */ 107 /* use ops to check startup state */
105 }, 108 },
106 { 109 {
107 .name = "AC97 Aux", 110 .name = "AC97 Aux",
108 .stream_name = "AC97 Aux", 111 .stream_name = "AC97 Aux",
109 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 112 .cpu_dai_name = "pxa-ac97.1",
110 .codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX], 113 .codec_dai_name ="wm9705-aux",
114 .platform_name = "pxa-pcm-audio",
115 .codec_name = "wm9705-codec",
111 }, 116 },
112}; 117};
113 118
114static struct snd_soc_card e750 = { 119static struct snd_soc_card e750 = {
115 .name = "Toshiba e750", 120 .name = "Toshiba e750",
116 .platform = &pxa2xx_soc_platform,
117 .dai_link = e750_dai, 121 .dai_link = e750_dai,
118 .num_links = ARRAY_SIZE(e750_dai), 122 .num_links = ARRAY_SIZE(e750_dai),
119}; 123};
120 124
121static struct snd_soc_device e750_snd_devdata = {
122 .card = &e750,
123 .codec_dev = &soc_codec_dev_wm9705,
124};
125
126static struct platform_device *e750_snd_device; 125static struct platform_device *e750_snd_device;
127 126
128static int __init e750_init(void) 127static int __init e750_init(void)
@@ -154,8 +153,7 @@ static int __init e750_init(void)
154 goto free_spk_amp_gpio; 153 goto free_spk_amp_gpio;
155 } 154 }
156 155
157 platform_set_drvdata(e750_snd_device, &e750_snd_devdata); 156 platform_set_drvdata(e750_snd_device, &e750);
158 e750_snd_devdata.dev = &e750_snd_device->dev;
159 ret = platform_device_add(e750_snd_device); 157 ret = platform_device_add(e750_snd_device);
160 158
161 if (!ret) 159 if (!ret)
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index bc019cdce42..d42e5fe832c 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -23,7 +23,6 @@
23#include <mach/eseries-gpio.h> 23#include <mach/eseries-gpio.h>
24 24
25#include "../codecs/wm9712.h" 25#include "../codecs/wm9712.h"
26#include "pxa2xx-pcm.h"
27#include "pxa2xx-ac97.h" 26#include "pxa2xx-ac97.h"
28 27
29static int e800_spk_amp_event(struct snd_soc_dapm_widget *w, 28static int e800_spk_amp_event(struct snd_soc_dapm_widget *w,
@@ -73,8 +72,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
73 {"MIC2", NULL, "Mic (Internal2)"}, 72 {"MIC2", NULL, "Mic (Internal2)"},
74}; 73};
75 74
76static int e800_ac97_init(struct snd_soc_codec *codec) 75static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd)
77{ 76{
77 struct snd_soc_codec *codec = rtd->codec;
78
78 snd_soc_dapm_new_controls(codec, e800_dapm_widgets, 79 snd_soc_dapm_new_controls(codec, e800_dapm_widgets,
79 ARRAY_SIZE(e800_dapm_widgets)); 80 ARRAY_SIZE(e800_dapm_widgets));
80 81
@@ -88,30 +89,28 @@ static struct snd_soc_dai_link e800_dai[] = {
88 { 89 {
89 .name = "AC97", 90 .name = "AC97",
90 .stream_name = "AC97 HiFi", 91 .stream_name = "AC97 HiFi",
91 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 92 .cpu_dai_name = "pxa-ac97.0",
92 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 93 .codec_dai_name = "wm9712-hifi",
94 .platform_name = "pxa-pcm-audio",
95 .codec_name = "wm9712-codec",
93 .init = e800_ac97_init, 96 .init = e800_ac97_init,
94 }, 97 },
95 { 98 {
96 .name = "AC97 Aux", 99 .name = "AC97 Aux",
97 .stream_name = "AC97 Aux", 100 .stream_name = "AC97 Aux",
98 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 101 .cpu_dai_name = "pxa-ac97.1",
99 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 102 .codec_dai_name ="wm9712-aux",
103 .platform_name = "pxa-pcm-audio",
104 .codec_name = "wm9712-codec",
100 }, 105 },
101}; 106};
102 107
103static struct snd_soc_card e800 = { 108static struct snd_soc_card e800 = {
104 .name = "Toshiba e800", 109 .name = "Toshiba e800",
105 .platform = &pxa2xx_soc_platform,
106 .dai_link = e800_dai, 110 .dai_link = e800_dai,
107 .num_links = ARRAY_SIZE(e800_dai), 111 .num_links = ARRAY_SIZE(e800_dai),
108}; 112};
109 113
110static struct snd_soc_device e800_snd_devdata = {
111 .card = &e800,
112 .codec_dev = &soc_codec_dev_wm9712,
113};
114
115static struct platform_device *e800_snd_device; 114static struct platform_device *e800_snd_device;
116 115
117static int __init e800_init(void) 116static int __init e800_init(void)
@@ -141,8 +140,7 @@ static int __init e800_init(void)
141 if (!e800_snd_device) 140 if (!e800_snd_device)
142 return -ENOMEM; 141 return -ENOMEM;
143 142
144 platform_set_drvdata(e800_snd_device, &e800_snd_devdata); 143 platform_set_drvdata(e800_snd_device, &e800);
145 e800_snd_devdata.dev = &e800_snd_device->dev;
146 ret = platform_device_add(e800_snd_device); 144 ret = platform_device_add(e800_snd_device);
147 145
148 if (!ret) 146 if (!ret)
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index f4756e4025f..7046128b2a4 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -39,29 +39,27 @@ static struct snd_soc_dai_link em_x270_dai[] = {
39 { 39 {
40 .name = "AC97", 40 .name = "AC97",
41 .stream_name = "AC97 HiFi", 41 .stream_name = "AC97 HiFi",
42 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 42 .cpu_dai_name = "pxa-ac97.0",
43 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 43 .codec_dai_name = "wm9712-hifi",
44 .platform_name = "pxa-pcm-audio",
45 .codec_name = "wm9712-codec",
44 }, 46 },
45 { 47 {
46 .name = "AC97 Aux", 48 .name = "AC97 Aux",
47 .stream_name = "AC97 Aux", 49 .stream_name = "AC97 Aux",
48 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 50 .cpu_dai_name = "pxa-ac97.1",
49 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 51 .codec_dai_name ="wm9712-aux",
52 .platform_name = "pxa-pcm-audio",
53 .codec_name = "wm9712-codec",
50 }, 54 },
51}; 55};
52 56
53static struct snd_soc_card em_x270 = { 57static struct snd_soc_card em_x270 = {
54 .name = "EM-X270", 58 .name = "EM-X270",
55 .platform = &pxa2xx_soc_platform,
56 .dai_link = em_x270_dai, 59 .dai_link = em_x270_dai,
57 .num_links = ARRAY_SIZE(em_x270_dai), 60 .num_links = ARRAY_SIZE(em_x270_dai),
58}; 61};
59 62
60static struct snd_soc_device em_x270_snd_devdata = {
61 .card = &em_x270,
62 .codec_dev = &soc_codec_dev_wm9712,
63};
64
65static struct platform_device *em_x270_snd_device; 63static struct platform_device *em_x270_snd_device;
66 64
67static int __init em_x270_init(void) 65static int __init em_x270_init(void)
@@ -76,8 +74,7 @@ static int __init em_x270_init(void)
76 if (!em_x270_snd_device) 74 if (!em_x270_snd_device)
77 return -ENOMEM; 75 return -ENOMEM;
78 76
79 platform_set_drvdata(em_x270_snd_device, &em_x270_snd_devdata); 77 platform_set_drvdata(em_x270_snd_device, &em_x270);
80 em_x270_snd_devdata.dev = &em_x270_snd_device->dev;
81 ret = platform_device_add(em_x270_snd_device); 78 ret = platform_device_add(em_x270_snd_device);
82 79
83 if (ret) 80 if (ret)
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
index 405587a0116..03765fc5ac7 100644
--- a/sound/soc/pxa/imote2.c
+++ b/sound/soc/pxa/imote2.c
@@ -6,14 +6,13 @@
6 6
7#include "../codecs/wm8940.h" 7#include "../codecs/wm8940.h"
8#include "pxa2xx-i2s.h" 8#include "pxa2xx-i2s.h"
9#include "pxa2xx-pcm.h"
10 9
11static int imote2_asoc_hw_params(struct snd_pcm_substream *substream, 10static int imote2_asoc_hw_params(struct snd_pcm_substream *substream,
12 struct snd_pcm_hw_params *params) 11 struct snd_pcm_hw_params *params)
13{ 12{
14 struct snd_soc_pcm_runtime *rtd = substream->private_data; 13 struct snd_soc_pcm_runtime *rtd = substream->private_data;
15 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 14 struct snd_soc_dai *codec_dai = rtd->codec_dai;
16 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 15 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
17 unsigned int clk = 0; 16 unsigned int clk = 0;
18 int ret; 17 int ret;
19 18
@@ -64,23 +63,19 @@ static struct snd_soc_ops imote2_asoc_ops = {
64static struct snd_soc_dai_link imote2_dai = { 63static struct snd_soc_dai_link imote2_dai = {
65 .name = "WM8940", 64 .name = "WM8940",
66 .stream_name = "WM8940", 65 .stream_name = "WM8940",
67 .cpu_dai = &pxa_i2s_dai, 66 .cpu_dai_name = "pxa-i2s",
68 .codec_dai = &wm8940_dai, 67 .codec_dai_name = "wm8940-hifi",
68 .platform_name = "pxa-pcm-audio",
69 .codec_name = "wm8940-codec.0-0034",
69 .ops = &imote2_asoc_ops, 70 .ops = &imote2_asoc_ops,
70}; 71};
71 72
72static struct snd_soc_card snd_soc_imote2 = { 73static struct snd_soc_card snd_soc_imote2 = {
73 .name = "Imote2", 74 .name = "Imote2",
74 .platform = &pxa2xx_soc_platform,
75 .dai_link = &imote2_dai, 75 .dai_link = &imote2_dai,
76 .num_links = 1, 76 .num_links = 1,
77}; 77};
78 78
79static struct snd_soc_device imote2_snd_devdata = {
80 .card = &snd_soc_imote2,
81 .codec_dev = &soc_codec_dev_wm8940,
82};
83
84static struct platform_device *imote2_snd_device; 79static struct platform_device *imote2_snd_device;
85 80
86static int __init imote2_asoc_init(void) 81static int __init imote2_asoc_init(void)
@@ -93,8 +88,7 @@ static int __init imote2_asoc_init(void)
93 if (!imote2_snd_device) 88 if (!imote2_snd_device)
94 return -ENOMEM; 89 return -ENOMEM;
95 90
96 platform_set_drvdata(imote2_snd_device, &imote2_snd_devdata); 91 platform_set_drvdata(imote2_snd_device, &snd_soc_imote2);
97 imote2_snd_devdata.dev = &imote2_snd_device->dev;
98 ret = platform_device_add(imote2_snd_device); 92 ret = platform_device_add(imote2_snd_device);
99 if (ret) 93 if (ret)
100 platform_device_put(imote2_snd_device); 94 platform_device_put(imote2_snd_device);
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 4c8d99a8d38..608bc3dd835 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -32,7 +32,6 @@
32#include <mach/magician.h> 32#include <mach/magician.h>
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34#include "../codecs/uda1380.h" 34#include "../codecs/uda1380.h"
35#include "pxa2xx-pcm.h"
36#include "pxa2xx-i2s.h" 35#include "pxa2xx-i2s.h"
37#include "pxa-ssp.h" 36#include "pxa-ssp.h"
38 37
@@ -71,7 +70,7 @@ static void magician_ext_control(struct snd_soc_codec *codec)
71static int magician_startup(struct snd_pcm_substream *substream) 70static int magician_startup(struct snd_pcm_substream *substream)
72{ 71{
73 struct snd_soc_pcm_runtime *rtd = substream->private_data; 72 struct snd_soc_pcm_runtime *rtd = substream->private_data;
74 struct snd_soc_codec *codec = rtd->socdev->card->codec; 73 struct snd_soc_codec *codec = rtd->codec;
75 74
76 /* check the jack status at stream startup */ 75 /* check the jack status at stream startup */
77 magician_ext_control(codec); 76 magician_ext_control(codec);
@@ -86,8 +85,8 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
86 struct snd_pcm_hw_params *params) 85 struct snd_pcm_hw_params *params)
87{ 86{
88 struct snd_soc_pcm_runtime *rtd = substream->private_data; 87 struct snd_soc_pcm_runtime *rtd = substream->private_data;
89 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 88 struct snd_soc_dai *codec_dai = rtd->codec_dai;
90 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 89 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
91 unsigned int acps, acds, width, rate; 90 unsigned int acps, acds, width, rate;
92 unsigned int div4 = PXA_SSP_CLK_SCDB_4; 91 unsigned int div4 = PXA_SSP_CLK_SCDB_4;
93 int ret = 0; 92 int ret = 0;
@@ -227,8 +226,8 @@ static int magician_capture_hw_params(struct snd_pcm_substream *substream,
227 struct snd_pcm_hw_params *params) 226 struct snd_pcm_hw_params *params)
228{ 227{
229 struct snd_soc_pcm_runtime *rtd = substream->private_data; 228 struct snd_soc_pcm_runtime *rtd = substream->private_data;
230 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 229 struct snd_soc_dai *codec_dai = rtd->codec_dai;
231 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 230 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
232 int ret = 0; 231 int ret = 0;
233 232
234 /* set codec DAI configuration */ 233 /* set codec DAI configuration */
@@ -393,8 +392,9 @@ static const struct snd_kcontrol_new uda1380_magician_controls[] = {
393/* 392/*
394 * Logic for a uda1380 as connected on a HTC Magician 393 * Logic for a uda1380 as connected on a HTC Magician
395 */ 394 */
396static int magician_uda1380_init(struct snd_soc_codec *codec) 395static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
397{ 396{
397 struct snd_soc_codec *codec = rtd->codec;
398 int err; 398 int err;
399 399
400 /* NC codec pins */ 400 /* NC codec pins */
@@ -427,16 +427,20 @@ static struct snd_soc_dai_link magician_dai[] = {
427{ 427{
428 .name = "uda1380", 428 .name = "uda1380",
429 .stream_name = "UDA1380 Playback", 429 .stream_name = "UDA1380 Playback",
430 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1], 430 .cpu_dai_name = "pxa-ssp-dai.0",
431 .codec_dai = &uda1380_dai[UDA1380_DAI_PLAYBACK], 431 .codec_dai_name = "uda1380-hifi-playback",
432 .platform_name = "pxa-pcm-audio",
433 .codec_name = "uda1380-codec.0-0018",
432 .init = magician_uda1380_init, 434 .init = magician_uda1380_init,
433 .ops = &magician_playback_ops, 435 .ops = &magician_playback_ops,
434}, 436},
435{ 437{
436 .name = "uda1380", 438 .name = "uda1380",
437 .stream_name = "UDA1380 Capture", 439 .stream_name = "UDA1380 Capture",
438 .cpu_dai = &pxa_i2s_dai, 440 .cpu_dai_name = "pxa-i2s",
439 .codec_dai = &uda1380_dai[UDA1380_DAI_CAPTURE], 441 .codec_dai_name = "uda1380-hifi-capture",
442 .platform_name = "pxa-pcm-audio",
443 .codec_name = "uda1380-codec.0-0018",
440 .ops = &magician_capture_ops, 444 .ops = &magician_capture_ops,
441} 445}
442}; 446};
@@ -446,13 +450,7 @@ static struct snd_soc_card snd_soc_card_magician = {
446 .name = "Magician", 450 .name = "Magician",
447 .dai_link = magician_dai, 451 .dai_link = magician_dai,
448 .num_links = ARRAY_SIZE(magician_dai), 452 .num_links = ARRAY_SIZE(magician_dai),
449 .platform = &pxa2xx_soc_platform,
450};
451 453
452/* magician audio subsystem */
453static struct snd_soc_device magician_snd_devdata = {
454 .card = &snd_soc_card_magician,
455 .codec_dev = &soc_codec_dev_uda1380,
456}; 454};
457 455
458static struct platform_device *magician_snd_device; 456static struct platform_device *magician_snd_device;
@@ -514,8 +512,7 @@ static int __init magician_init(void)
514 goto err_pdev; 512 goto err_pdev;
515 } 513 }
516 514
517 platform_set_drvdata(magician_snd_device, &magician_snd_devdata); 515 platform_set_drvdata(magician_snd_device, &snd_soc_card_magician);
518 magician_snd_devdata.dev = &magician_snd_device->dev;
519 ret = platform_device_add(magician_snd_device); 516 ret = platform_device_add(magician_snd_device);
520 if (ret) { 517 if (ret) {
521 platform_device_put(magician_snd_device); 518 platform_device_put(magician_snd_device);
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 19eda8bbfda..f284cc54bc8 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -54,7 +54,6 @@
54#include <sound/initval.h> 54#include <sound/initval.h>
55#include <sound/ac97_codec.h> 55#include <sound/ac97_codec.h>
56 56
57#include "pxa2xx-pcm.h"
58#include "pxa2xx-ac97.h" 57#include "pxa2xx-ac97.h"
59#include "../codecs/wm9713.h" 58#include "../codecs/wm9713.h"
60 59
@@ -128,8 +127,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
128 {"Rear Speaker", NULL, "SPKR"}, 127 {"Rear Speaker", NULL, "SPKR"},
129}; 128};
130 129
131static int mioa701_wm9713_init(struct snd_soc_codec *codec) 130static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
132{ 131{
132 struct snd_soc_codec *codec = rtd->codec;
133 unsigned short reg; 133 unsigned short reg;
134 134
135 /* Add mioa701 specific widgets */ 135 /* Add mioa701 specific widgets */
@@ -139,12 +139,12 @@ static int mioa701_wm9713_init(struct snd_soc_codec *codec)
139 snd_soc_dapm_add_routes(codec, ARRAY_AND_SIZE(audio_map)); 139 snd_soc_dapm_add_routes(codec, ARRAY_AND_SIZE(audio_map));
140 140
141 /* Prepare GPIO8 for rear speaker amplifier */ 141 /* Prepare GPIO8 for rear speaker amplifier */
142 reg = codec->read(codec, AC97_GPIO_CFG); 142 reg = codec->driver->read(codec, AC97_GPIO_CFG);
143 codec->write(codec, AC97_GPIO_CFG, reg | 0x0100); 143 codec->driver->write(codec, AC97_GPIO_CFG, reg | 0x0100);
144 144
145 /* Prepare MIC input */ 145 /* Prepare MIC input */
146 reg = codec->read(codec, AC97_3D_CONTROL); 146 reg = codec->driver->read(codec, AC97_3D_CONTROL);
147 codec->write(codec, AC97_3D_CONTROL, reg | 0xc000); 147 codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000);
148 148
149 snd_soc_dapm_enable_pin(codec, "Front Speaker"); 149 snd_soc_dapm_enable_pin(codec, "Front Speaker");
150 snd_soc_dapm_enable_pin(codec, "Rear Speaker"); 150 snd_soc_dapm_enable_pin(codec, "Rear Speaker");
@@ -162,32 +162,30 @@ static struct snd_soc_dai_link mioa701_dai[] = {
162 { 162 {
163 .name = "AC97", 163 .name = "AC97",
164 .stream_name = "AC97 HiFi", 164 .stream_name = "AC97 HiFi",
165 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 165 .cpu_dai_name = "pxa-ac97.0",
166 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI], 166 .codec_dai_name = "wm9713-hifi",
167 .codec_name = "wm9713-codec",
167 .init = mioa701_wm9713_init, 168 .init = mioa701_wm9713_init,
169 .platform_name = "pxa-pcm-audio",
168 .ops = &mioa701_ops, 170 .ops = &mioa701_ops,
169 }, 171 },
170 { 172 {
171 .name = "AC97 Aux", 173 .name = "AC97 Aux",
172 .stream_name = "AC97 Aux", 174 .stream_name = "AC97 Aux",
173 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 175 .cpu_dai_name = "pxa-ac97.1",
174 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX], 176 .codec_dai_name ="wm9713-aux",
177 .codec_name = "wm9713-codec",
178 .platform_name = "pxa-pcm-audio",
175 .ops = &mioa701_ops, 179 .ops = &mioa701_ops,
176 }, 180 },
177}; 181};
178 182
179static struct snd_soc_card mioa701 = { 183static struct snd_soc_card mioa701 = {
180 .name = "MioA701", 184 .name = "MioA701",
181 .platform = &pxa2xx_soc_platform,
182 .dai_link = mioa701_dai, 185 .dai_link = mioa701_dai,
183 .num_links = ARRAY_SIZE(mioa701_dai), 186 .num_links = ARRAY_SIZE(mioa701_dai),
184}; 187};
185 188
186static struct snd_soc_device mioa701_snd_devdata = {
187 .card = &mioa701,
188 .codec_dev = &soc_codec_dev_wm9713,
189};
190
191static struct platform_device *mioa701_snd_device; 189static struct platform_device *mioa701_snd_device;
192 190
193static int mioa701_wm9713_probe(struct platform_device *pdev) 191static int mioa701_wm9713_probe(struct platform_device *pdev)
@@ -205,8 +203,7 @@ static int mioa701_wm9713_probe(struct platform_device *pdev)
205 if (!mioa701_snd_device) 203 if (!mioa701_snd_device)
206 return -ENOMEM; 204 return -ENOMEM;
207 205
208 platform_set_drvdata(mioa701_snd_device, &mioa701_snd_devdata); 206 platform_set_drvdata(mioa701_snd_device, &mioa701);
209 mioa701_snd_devdata.dev = &mioa701_snd_device->dev;
210 207
211 ret = platform_device_add(mioa701_snd_device); 208 ret = platform_device_add(mioa701_snd_device);
212 if (!ret) 209 if (!ret)
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 1f96e3227be..13f6d485d57 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -29,7 +29,6 @@
29#include <mach/palmasoc.h> 29#include <mach/palmasoc.h>
30 30
31#include "../codecs/wm9712.h" 31#include "../codecs/wm9712.h"
32#include "pxa2xx-pcm.h"
33#include "pxa2xx-ac97.h" 32#include "pxa2xx-ac97.h"
34 33
35static struct snd_soc_jack hs_jack; 34static struct snd_soc_jack hs_jack;
@@ -75,8 +74,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
75 74
76static struct snd_soc_card palm27x_asoc; 75static struct snd_soc_card palm27x_asoc;
77 76
78static int palm27x_ac97_init(struct snd_soc_codec *codec) 77static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
79{ 78{
79 struct snd_soc_codec *codec = rtd->codec;
80 int err; 80 int err;
81 81
82 /* add palm27x specific widgets */ 82 /* add palm27x specific widgets */
@@ -112,7 +112,7 @@ static int palm27x_ac97_init(struct snd_soc_codec *codec)
112 return err; 112 return err;
113 113
114 /* Jack detection API stuff */ 114 /* Jack detection API stuff */
115 err = snd_soc_jack_new(&palm27x_asoc, "Headphone Jack", 115 err = snd_soc_jack_new(codec, "Headphone Jack",
116 SND_JACK_HEADPHONE, &hs_jack); 116 SND_JACK_HEADPHONE, &hs_jack);
117 if (err) 117 if (err)
118 return err; 118 return err;
@@ -132,30 +132,28 @@ static struct snd_soc_dai_link palm27x_dai[] = {
132{ 132{
133 .name = "AC97 HiFi", 133 .name = "AC97 HiFi",
134 .stream_name = "AC97 HiFi", 134 .stream_name = "AC97 HiFi",
135 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 135 .cpu_dai_name = "pxa-ac97.0",
136 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 136 .codec_dai_name = "wm9712-hifi",
137 .codec_name = "wm9712-codec",
138 .platform_name = "pxa-pcm-audio",
137 .init = palm27x_ac97_init, 139 .init = palm27x_ac97_init,
138}, 140},
139{ 141{
140 .name = "AC97 Aux", 142 .name = "AC97 Aux",
141 .stream_name = "AC97 Aux", 143 .stream_name = "AC97 Aux",
142 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 144 .cpu_dai_name = "pxa-ac97.1",
143 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 145 .codec_dai_name = "wm9712-aux",
146 .codec_name = "wm9712-codec",
147 .platform_name = "pxa-pcm-audio",
144}, 148},
145}; 149};
146 150
147static struct snd_soc_card palm27x_asoc = { 151static struct snd_soc_card palm27x_asoc = {
148 .name = "Palm/PXA27x", 152 .name = "Palm/PXA27x",
149 .platform = &pxa2xx_soc_platform,
150 .dai_link = palm27x_dai, 153 .dai_link = palm27x_dai,
151 .num_links = ARRAY_SIZE(palm27x_dai), 154 .num_links = ARRAY_SIZE(palm27x_dai),
152}; 155};
153 156
154static struct snd_soc_device palm27x_snd_devdata = {
155 .card = &palm27x_asoc,
156 .codec_dev = &soc_codec_dev_wm9712,
157};
158
159static struct platform_device *palm27x_snd_device; 157static struct platform_device *palm27x_snd_device;
160 158
161static int palm27x_asoc_probe(struct platform_device *pdev) 159static int palm27x_asoc_probe(struct platform_device *pdev)
@@ -178,8 +176,7 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
178 if (!palm27x_snd_device) 176 if (!palm27x_snd_device)
179 return -ENOMEM; 177 return -ENOMEM;
180 178
181 platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata); 179 platform_set_drvdata(palm27x_snd_device, &palm27x_asoc);
182 palm27x_snd_devdata.dev = &palm27x_snd_device->dev;
183 ret = platform_device_add(palm27x_snd_device); 180 ret = platform_device_add(palm27x_snd_device);
184 181
185 if (ret != 0) 182 if (ret != 0)
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index c5f36e0eab5..3ba5a962ecb 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -31,7 +31,6 @@
31#include <mach/audio.h> 31#include <mach/audio.h>
32 32
33#include "../codecs/wm8731.h" 33#include "../codecs/wm8731.h"
34#include "pxa2xx-pcm.h"
35#include "pxa2xx-i2s.h" 34#include "pxa2xx-i2s.h"
36 35
37#define POODLE_HP 1 36#define POODLE_HP 1
@@ -76,7 +75,7 @@ static void poodle_ext_control(struct snd_soc_codec *codec)
76static int poodle_startup(struct snd_pcm_substream *substream) 75static int poodle_startup(struct snd_pcm_substream *substream)
77{ 76{
78 struct snd_soc_pcm_runtime *rtd = substream->private_data; 77 struct snd_soc_pcm_runtime *rtd = substream->private_data;
79 struct snd_soc_codec *codec = rtd->socdev->card->codec; 78 struct snd_soc_codec *codec = rtd->codec;
80 79
81 /* check the jack status at stream startup */ 80 /* check the jack status at stream startup */
82 poodle_ext_control(codec); 81 poodle_ext_control(codec);
@@ -97,8 +96,8 @@ static int poodle_hw_params(struct snd_pcm_substream *substream,
97 struct snd_pcm_hw_params *params) 96 struct snd_pcm_hw_params *params)
98{ 97{
99 struct snd_soc_pcm_runtime *rtd = substream->private_data; 98 struct snd_soc_pcm_runtime *rtd = substream->private_data;
100 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 99 struct snd_soc_dai *codec_dai = rtd->codec_dai;
101 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 100 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
102 unsigned int clk = 0; 101 unsigned int clk = 0;
103 int ret = 0; 102 int ret = 0;
104 103
@@ -237,8 +236,9 @@ static const struct snd_kcontrol_new wm8731_poodle_controls[] = {
237/* 236/*
238 * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device 237 * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device
239 */ 238 */
240static int poodle_wm8731_init(struct snd_soc_codec *codec) 239static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
241{ 240{
241 struct snd_soc_codec *codec = rtd->codec;
242 int err; 242 int err;
243 243
244 snd_soc_dapm_nc_pin(codec, "LLINEIN"); 244 snd_soc_dapm_nc_pin(codec, "LLINEIN");
@@ -266,8 +266,10 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec)
266static struct snd_soc_dai_link poodle_dai = { 266static struct snd_soc_dai_link poodle_dai = {
267 .name = "WM8731", 267 .name = "WM8731",
268 .stream_name = "WM8731", 268 .stream_name = "WM8731",
269 .cpu_dai = &pxa_i2s_dai, 269 .cpu_dai_name = "pxa-i2s",
270 .codec_dai = &wm8731_dai, 270 .codec_dai_name = "wm8731-hifi"
271 .platform_name = "pxa-pcm-audio",
272 .codec_name = "wm8731-codec.0-001a",
271 .init = poodle_wm8731_init, 273 .init = poodle_wm8731_init,
272 .ops = &poodle_ops, 274 .ops = &poodle_ops,
273}; 275};
@@ -275,15 +277,9 @@ static struct snd_soc_dai_link poodle_dai = {
275/* poodle audio machine driver */ 277/* poodle audio machine driver */
276static struct snd_soc_card snd_soc_poodle = { 278static struct snd_soc_card snd_soc_poodle = {
277 .name = "Poodle", 279 .name = "Poodle",
278 .platform = &pxa2xx_soc_platform,
279 .dai_link = &poodle_dai, 280 .dai_link = &poodle_dai,
280 .num_links = 1, 281 .num_links = 1,
281}; 282 .owner = THIS_MODULE,
282
283/* poodle audio subsystem */
284static struct snd_soc_device poodle_snd_devdata = {
285 .card = &snd_soc_poodle,
286 .codec_dev = &soc_codec_dev_wm8731,
287}; 283};
288 284
289static struct platform_device *poodle_snd_device; 285static struct platform_device *poodle_snd_device;
@@ -307,8 +303,7 @@ static int __init poodle_init(void)
307 if (!poodle_snd_device) 303 if (!poodle_snd_device)
308 return -ENOMEM; 304 return -ENOMEM;
309 305
310 platform_set_drvdata(poodle_snd_device, &poodle_snd_devdata); 306 platform_set_drvdata(poodle_snd_device, &snd_soc_poodle);
311 poodle_snd_devdata.dev = &poodle_snd_device->dev;
312 ret = platform_device_add(poodle_snd_device); 307 ret = platform_device_add(poodle_snd_device);
313 308
314 if (ret) 309 if (ret)
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index a1fd23e0e3d..99d80e85621 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -108,11 +108,9 @@ pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
108} 108}
109 109
110static int pxa_ssp_startup(struct snd_pcm_substream *substream, 110static int pxa_ssp_startup(struct snd_pcm_substream *substream,
111 struct snd_soc_dai *dai) 111 struct snd_soc_dai *cpu_dai)
112{ 112{
113 struct snd_soc_pcm_runtime *rtd = substream->private_data; 113 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
114 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
115 struct ssp_priv *priv = cpu_dai->private_data;
116 struct ssp_device *ssp = priv->ssp; 114 struct ssp_device *ssp = priv->ssp;
117 int ret = 0; 115 int ret = 0;
118 116
@@ -128,11 +126,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
128} 126}
129 127
130static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, 128static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
131 struct snd_soc_dai *dai) 129 struct snd_soc_dai *cpu_dai)
132{ 130{
133 struct snd_soc_pcm_runtime *rtd = substream->private_data; 131 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
134 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
135 struct ssp_priv *priv = cpu_dai->private_data;
136 struct ssp_device *ssp = priv->ssp; 132 struct ssp_device *ssp = priv->ssp;
137 133
138 if (!cpu_dai->active) { 134 if (!cpu_dai->active) {
@@ -148,7 +144,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
148 144
149static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) 145static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
150{ 146{
151 struct ssp_priv *priv = cpu_dai->private_data; 147 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
152 struct ssp_device *ssp = priv->ssp; 148 struct ssp_device *ssp = priv->ssp;
153 149
154 if (!cpu_dai->active) 150 if (!cpu_dai->active)
@@ -166,7 +162,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
166 162
167static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) 163static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
168{ 164{
169 struct ssp_priv *priv = cpu_dai->private_data; 165 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
170 struct ssp_device *ssp = priv->ssp; 166 struct ssp_device *ssp = priv->ssp;
171 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE; 167 uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
172 168
@@ -230,7 +226,7 @@ static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
230static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, 226static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
231 int clk_id, unsigned int freq, int dir) 227 int clk_id, unsigned int freq, int dir)
232{ 228{
233 struct ssp_priv *priv = cpu_dai->private_data; 229 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
234 struct ssp_device *ssp = priv->ssp; 230 struct ssp_device *ssp = priv->ssp;
235 int val; 231 int val;
236 232
@@ -287,7 +283,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
287static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, 283static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
288 int div_id, int div) 284 int div_id, int div)
289{ 285{
290 struct ssp_priv *priv = cpu_dai->private_data; 286 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
291 struct ssp_device *ssp = priv->ssp; 287 struct ssp_device *ssp = priv->ssp;
292 int val; 288 int val;
293 289
@@ -338,7 +334,7 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
338static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, 334static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
339 int source, unsigned int freq_in, unsigned int freq_out) 335 int source, unsigned int freq_in, unsigned int freq_out)
340{ 336{
341 struct ssp_priv *priv = cpu_dai->private_data; 337 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
342 struct ssp_device *ssp = priv->ssp; 338 struct ssp_device *ssp = priv->ssp;
343 u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70; 339 u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
344 340
@@ -407,7 +403,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
407static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, 403static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
408 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 404 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
409{ 405{
410 struct ssp_priv *priv = cpu_dai->private_data; 406 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
411 struct ssp_device *ssp = priv->ssp; 407 struct ssp_device *ssp = priv->ssp;
412 u32 sscr0; 408 u32 sscr0;
413 409
@@ -442,7 +438,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
442static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai, 438static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
443 int tristate) 439 int tristate)
444{ 440{
445 struct ssp_priv *priv = cpu_dai->private_data; 441 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
446 struct ssp_device *ssp = priv->ssp; 442 struct ssp_device *ssp = priv->ssp;
447 u32 sscr1; 443 u32 sscr1;
448 444
@@ -464,7 +460,7 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
464static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, 460static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
465 unsigned int fmt) 461 unsigned int fmt)
466{ 462{
467 struct ssp_priv *priv = cpu_dai->private_data; 463 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
468 struct ssp_device *ssp = priv->ssp; 464 struct ssp_device *ssp = priv->ssp;
469 u32 sscr0; 465 u32 sscr0;
470 u32 sscr1; 466 u32 sscr1;
@@ -555,11 +551,9 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
555 */ 551 */
556static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, 552static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
557 struct snd_pcm_hw_params *params, 553 struct snd_pcm_hw_params *params,
558 struct snd_soc_dai *dai) 554 struct snd_soc_dai *cpu_dai)
559{ 555{
560 struct snd_soc_pcm_runtime *rtd = substream->private_data; 556 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
561 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
562 struct ssp_priv *priv = cpu_dai->private_data;
563 struct ssp_device *ssp = priv->ssp; 557 struct ssp_device *ssp = priv->ssp;
564 int chn = params_channels(params); 558 int chn = params_channels(params);
565 u32 sscr0; 559 u32 sscr0;
@@ -568,7 +562,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
568 int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf; 562 int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
569 struct pxa2xx_pcm_dma_params *dma_data; 563 struct pxa2xx_pcm_dma_params *dma_data;
570 564
571 dma_data = snd_soc_dai_get_dma_data(dai, substream); 565 dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
572 566
573 /* generate correct DMA params */ 567 /* generate correct DMA params */
574 kfree(dma_data); 568 kfree(dma_data);
@@ -581,7 +575,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
581 ((chn == 2) && (ttsa != 1)) || (width == 32), 575 ((chn == 2) && (ttsa != 1)) || (width == 32),
582 substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 576 substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
583 577
584 snd_soc_dai_set_dma_data(dai, substream, dma_data); 578 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
585 579
586 /* we can only change the settings if the port is not in use */ 580 /* we can only change the settings if the port is not in use */
587 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) 581 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
@@ -668,12 +662,10 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
668} 662}
669 663
670static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, 664static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
671 struct snd_soc_dai *dai) 665 struct snd_soc_dai *cpu_dai)
672{ 666{
673 struct snd_soc_pcm_runtime *rtd = substream->private_data;
674 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
675 int ret = 0; 667 int ret = 0;
676 struct ssp_priv *priv = cpu_dai->private_data; 668 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
677 struct ssp_device *ssp = priv->ssp; 669 struct ssp_device *ssp = priv->ssp;
678 int val; 670 int val;
679 671
@@ -729,8 +721,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
729 return ret; 721 return ret;
730} 722}
731 723
732static int pxa_ssp_probe(struct platform_device *pdev, 724static int pxa_ssp_probe(struct snd_soc_dai *dai)
733 struct snd_soc_dai *dai)
734{ 725{
735 struct ssp_priv *priv; 726 struct ssp_priv *priv;
736 int ret; 727 int ret;
@@ -746,7 +737,7 @@ static int pxa_ssp_probe(struct platform_device *pdev,
746 } 737 }
747 738
748 priv->dai_fmt = (unsigned int) -1; 739 priv->dai_fmt = (unsigned int) -1;
749 dai->private_data = priv; 740 snd_soc_dai_set_drvdata(dai, priv);
750 741
751 return 0; 742 return 0;
752 743
@@ -755,11 +746,12 @@ err_priv:
755 return ret; 746 return ret;
756} 747}
757 748
758static void pxa_ssp_remove(struct platform_device *pdev, 749static int pxa_ssp_remove(struct snd_soc_dai *dai)
759 struct snd_soc_dai *dai)
760{ 750{
761 struct ssp_priv *priv = dai->private_data; 751 struct ssp_priv *priv = snd_soc_dai_get_drvdata(dai);
752
762 pxa_ssp_free(priv->ssp); 753 pxa_ssp_free(priv->ssp);
754 return 0;
763} 755}
764 756
765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 757#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
@@ -784,10 +776,7 @@ static struct snd_soc_dai_ops pxa_ssp_dai_ops = {
784 .set_tristate = pxa_ssp_set_dai_tristate, 776 .set_tristate = pxa_ssp_set_dai_tristate,
785}; 777};
786 778
787struct snd_soc_dai pxa_ssp_dai[] = { 779static struct snd_soc_dai_driver pxa_ssp_dai = {
788 {
789 .name = "pxa2xx-ssp1",
790 .id = 0,
791 .probe = pxa_ssp_probe, 780 .probe = pxa_ssp_probe,
792 .remove = pxa_ssp_remove, 781 .remove = pxa_ssp_remove,
793 .suspend = pxa_ssp_suspend, 782 .suspend = pxa_ssp_suspend,
@@ -805,81 +794,38 @@ struct snd_soc_dai pxa_ssp_dai[] = {
805 .formats = PXA_SSP_FORMATS, 794 .formats = PXA_SSP_FORMATS,
806 }, 795 },
807 .ops = &pxa_ssp_dai_ops, 796 .ops = &pxa_ssp_dai_ops,
797};
798
799static __devinit int asoc_ssp_probe(struct platform_device *pdev)
800{
801 return snd_soc_register_dai(&pdev->dev, &pxa_ssp_dai);
802}
803
804static int __devexit asoc_ssp_remove(struct platform_device *pdev)
805{
806 snd_soc_unregister_dai(&pdev->dev);
807 return 0;
808}
809
810static struct platform_driver asoc_ssp_driver = {
811 .driver = {
812 .name = "pxa-ssp-dai",
813 .owner = THIS_MODULE,
808 }, 814 },
809 { .name = "pxa2xx-ssp2", 815
810 .id = 1, 816 .probe = asoc_ssp_probe,
811 .probe = pxa_ssp_probe, 817 .remove = __devexit_p(asoc_ssp_remove),
812 .remove = pxa_ssp_remove,
813 .suspend = pxa_ssp_suspend,
814 .resume = pxa_ssp_resume,
815 .playback = {
816 .channels_min = 1,
817 .channels_max = 8,
818 .rates = PXA_SSP_RATES,
819 .formats = PXA_SSP_FORMATS,
820 },
821 .capture = {
822 .channels_min = 1,
823 .channels_max = 8,
824 .rates = PXA_SSP_RATES,
825 .formats = PXA_SSP_FORMATS,
826 },
827 .ops = &pxa_ssp_dai_ops,
828 },
829 {
830 .name = "pxa2xx-ssp3",
831 .id = 2,
832 .probe = pxa_ssp_probe,
833 .remove = pxa_ssp_remove,
834 .suspend = pxa_ssp_suspend,
835 .resume = pxa_ssp_resume,
836 .playback = {
837 .channels_min = 1,
838 .channels_max = 8,
839 .rates = PXA_SSP_RATES,
840 .formats = PXA_SSP_FORMATS,
841 },
842 .capture = {
843 .channels_min = 1,
844 .channels_max = 8,
845 .rates = PXA_SSP_RATES,
846 .formats = PXA_SSP_FORMATS,
847 },
848 .ops = &pxa_ssp_dai_ops,
849 },
850 {
851 .name = "pxa2xx-ssp4",
852 .id = 3,
853 .probe = pxa_ssp_probe,
854 .remove = pxa_ssp_remove,
855 .suspend = pxa_ssp_suspend,
856 .resume = pxa_ssp_resume,
857 .playback = {
858 .channels_min = 1,
859 .channels_max = 8,
860 .rates = PXA_SSP_RATES,
861 .formats = PXA_SSP_FORMATS,
862 },
863 .capture = {
864 .channels_min = 1,
865 .channels_max = 8,
866 .rates = PXA_SSP_RATES,
867 .formats = PXA_SSP_FORMATS,
868 },
869 .ops = &pxa_ssp_dai_ops,
870 },
871}; 818};
872EXPORT_SYMBOL_GPL(pxa_ssp_dai);
873 819
874static int __init pxa_ssp_init(void) 820static int __init pxa_ssp_init(void)
875{ 821{
876 return snd_soc_register_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai)); 822 return platform_driver_register(&asoc_ssp_driver);
877} 823}
878module_init(pxa_ssp_init); 824module_init(pxa_ssp_init);
879 825
880static void __exit pxa_ssp_exit(void) 826static void __exit pxa_ssp_exit(void)
881{ 827{
882 snd_soc_unregister_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai)); 828 platform_driver_unregister(&asoc_ssp_driver);
883} 829}
884module_exit(pxa_ssp_exit); 830module_exit(pxa_ssp_exit);
885 831
diff --git a/sound/soc/pxa/pxa-ssp.h b/sound/soc/pxa/pxa-ssp.h
index 91deadd5567..bc79da221c0 100644
--- a/sound/soc/pxa/pxa-ssp.h
+++ b/sound/soc/pxa/pxa-ssp.h
@@ -42,6 +42,4 @@
42 42
43#define PXA_SSP_PLL_OUT 0 43#define PXA_SSP_PLL_OUT 0
44 44
45extern struct snd_soc_dai pxa_ssp_dai[4];
46
47#endif 45#endif
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index d314115e3dd..9c2bafa112a 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -104,24 +104,21 @@ static int pxa2xx_ac97_resume(struct snd_soc_dai *dai)
104#define pxa2xx_ac97_resume NULL 104#define pxa2xx_ac97_resume NULL
105#endif 105#endif
106 106
107static int pxa2xx_ac97_probe(struct platform_device *pdev, 107static int pxa2xx_ac97_probe(struct snd_soc_dai *dai)
108 struct snd_soc_dai *dai)
109{ 108{
110 return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev)); 109 return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev));
111} 110}
112 111
113static void pxa2xx_ac97_remove(struct platform_device *pdev, 112static int pxa2xx_ac97_remove(struct snd_soc_dai *dai)
114 struct snd_soc_dai *dai)
115{ 113{
116 pxa2xx_ac97_hw_remove(to_platform_device(dai->dev)); 114 pxa2xx_ac97_hw_remove(to_platform_device(dai->dev));
115 return 0;
117} 116}
118 117
119static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 118static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
120 struct snd_pcm_hw_params *params, 119 struct snd_pcm_hw_params *params,
121 struct snd_soc_dai *dai) 120 struct snd_soc_dai *cpu_dai)
122{ 121{
123 struct snd_soc_pcm_runtime *rtd = substream->private_data;
124 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
125 struct pxa2xx_pcm_dma_params *dma_data; 122 struct pxa2xx_pcm_dma_params *dma_data;
126 123
127 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 124 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -136,10 +133,8 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
136 133
137static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, 134static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
138 struct snd_pcm_hw_params *params, 135 struct snd_pcm_hw_params *params,
139 struct snd_soc_dai *dai) 136 struct snd_soc_dai *cpu_dai)
140{ 137{
141 struct snd_soc_pcm_runtime *rtd = substream->private_data;
142 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
143 struct pxa2xx_pcm_dma_params *dma_data; 138 struct pxa2xx_pcm_dma_params *dma_data;
144 139
145 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 140 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -154,11 +149,8 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
154 149
155static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, 150static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
156 struct snd_pcm_hw_params *params, 151 struct snd_pcm_hw_params *params,
157 struct snd_soc_dai *dai) 152 struct snd_soc_dai *cpu_dai)
158{ 153{
159 struct snd_soc_pcm_runtime *rtd = substream->private_data;
160 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
161
162 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 154 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
163 return -ENODEV; 155 return -ENODEV;
164 else 156 else
@@ -188,10 +180,9 @@ static struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
188 * There is only 1 physical AC97 interface for pxa2xx, but it 180 * There is only 1 physical AC97 interface for pxa2xx, but it
189 * has extra fifo's that can be used for aux DACs and ADCs. 181 * has extra fifo's that can be used for aux DACs and ADCs.
190 */ 182 */
191struct snd_soc_dai pxa_ac97_dai[] = { 183static struct snd_soc_dai_driver pxa_ac97_dai[] = {
192{ 184{
193 .name = "pxa2xx-ac97", 185 .name = "pxa2xx-ac97",
194 .id = 0,
195 .ac97_control = 1, 186 .ac97_control = 1,
196 .probe = pxa2xx_ac97_probe, 187 .probe = pxa2xx_ac97_probe,
197 .remove = pxa2xx_ac97_remove, 188 .remove = pxa2xx_ac97_remove,
@@ -213,7 +204,6 @@ struct snd_soc_dai pxa_ac97_dai[] = {
213}, 204},
214{ 205{
215 .name = "pxa2xx-ac97-aux", 206 .name = "pxa2xx-ac97-aux",
216 .id = 1,
217 .ac97_control = 1, 207 .ac97_control = 1,
218 .playback = { 208 .playback = {
219 .stream_name = "AC97 Aux Playback", 209 .stream_name = "AC97 Aux Playback",
@@ -231,7 +221,6 @@ struct snd_soc_dai pxa_ac97_dai[] = {
231}, 221},
232{ 222{
233 .name = "pxa2xx-ac97-mic", 223 .name = "pxa2xx-ac97-mic",
234 .id = 2,
235 .ac97_control = 1, 224 .ac97_control = 1,
236 .capture = { 225 .capture = {
237 .stream_name = "AC97 Mic Capture", 226 .stream_name = "AC97 Mic Capture",
@@ -243,36 +232,26 @@ struct snd_soc_dai pxa_ac97_dai[] = {
243}, 232},
244}; 233};
245 234
246EXPORT_SYMBOL_GPL(pxa_ac97_dai);
247EXPORT_SYMBOL_GPL(soc_ac97_ops); 235EXPORT_SYMBOL_GPL(soc_ac97_ops);
248 236
249static int __devinit pxa2xx_ac97_dev_probe(struct platform_device *pdev) 237static __devinit int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
250{ 238{
251 int i; 239 if (pdev->id != -1) {
252 pxa2xx_audio_ops_t *pdata = pdev->dev.platform_data;
253
254 if (pdev->id >= 0) {
255 dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n"); 240 dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n");
256 return -ENXIO; 241 return -ENXIO;
257 } 242 }
258 243
259 for (i = 0; i < ARRAY_SIZE(pxa_ac97_dai); i++) {
260 pxa_ac97_dai[i].dev = &pdev->dev;
261 if (pdata && pdata->codec_pdata[0])
262 pxa_ac97_dai[i].ac97_pdata = pdata->codec_pdata[0];
263 }
264
265 /* Punt most of the init to the SoC probe; we may need the machine 244 /* Punt most of the init to the SoC probe; we may need the machine
266 * driver to do interesting things with the clocking to get us up 245 * driver to do interesting things with the clocking to get us up
267 * and running. 246 * and running.
268 */ 247 */
269 return snd_soc_register_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai)); 248 return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai,
249 ARRAY_SIZE(pxa_ac97_dai));
270} 250}
271 251
272static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev) 252static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev)
273{ 253{
274 snd_soc_unregister_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai)); 254 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai));
275
276 return 0; 255 return 0;
277} 256}
278 257
diff --git a/sound/soc/pxa/pxa2xx-ac97.h b/sound/soc/pxa/pxa2xx-ac97.h
index e390de8edcd..eda891e6f31 100644
--- a/sound/soc/pxa/pxa2xx-ac97.h
+++ b/sound/soc/pxa/pxa2xx-ac97.h
@@ -14,8 +14,6 @@
14#define PXA2XX_DAI_AC97_AUX 1 14#define PXA2XX_DAI_AC97_AUX 1
15#define PXA2XX_DAI_AC97_MIC 2 15#define PXA2XX_DAI_AC97_MIC 2
16 16
17extern struct snd_soc_dai pxa_ac97_dai[3];
18
19/* platform data */ 17/* platform data */
20extern struct snd_ac97_bus_ops pxa2xx_ac97_ops; 18extern struct snd_ac97_bus_ops pxa2xx_ac97_ops;
21 19
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index c1a5275721e..3b473b200a8 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -80,6 +80,7 @@ struct pxa_i2s_port {
80}; 80};
81static struct pxa_i2s_port pxa_i2s; 81static struct pxa_i2s_port pxa_i2s;
82static struct clk *clk_i2s; 82static struct clk *clk_i2s;
83static int clk_ena = 0;
83 84
84static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { 85static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
85 .name = "I2S PCM Stereo out", 86 .name = "I2S PCM Stereo out",
@@ -101,7 +102,7 @@ static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
101 struct snd_soc_dai *dai) 102 struct snd_soc_dai *dai)
102{ 103{
103 struct snd_soc_pcm_runtime *rtd = substream->private_data; 104 struct snd_soc_pcm_runtime *rtd = substream->private_data;
104 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 105 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
105 106
106 if (IS_ERR(clk_i2s)) 107 if (IS_ERR(clk_i2s))
107 return PTR_ERR(clk_i2s); 108 return PTR_ERR(clk_i2s);
@@ -162,13 +163,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
162 struct snd_pcm_hw_params *params, 163 struct snd_pcm_hw_params *params,
163 struct snd_soc_dai *dai) 164 struct snd_soc_dai *dai)
164{ 165{
165 struct snd_soc_pcm_runtime *rtd = substream->private_data;
166 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
167 struct pxa2xx_pcm_dma_params *dma_data; 166 struct pxa2xx_pcm_dma_params *dma_data;
168 167
169 BUG_ON(IS_ERR(clk_i2s)); 168 BUG_ON(IS_ERR(clk_i2s));
170 clk_enable(clk_i2s); 169 clk_enable(clk_i2s);
171 dai->private_data = dai; 170 clk_ena = 1;
172 pxa_i2s_wait(); 171 pxa_i2s_wait();
173 172
174 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 173 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -176,7 +175,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
176 else 175 else
177 dma_data = &pxa2xx_i2s_pcm_stereo_in; 176 dma_data = &pxa2xx_i2s_pcm_stereo_in;
178 177
179 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); 178 snd_soc_dai_set_dma_data(dai, substream, dma_data);
180 179
181 /* is port used by another stream */ 180 /* is port used by another stream */
182 if (!(SACR0 & SACR0_ENB)) { 181 if (!(SACR0 & SACR0_ENB)) {
@@ -259,9 +258,9 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
259 if ((SACR1 & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) { 258 if ((SACR1 & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) {
260 SACR0 &= ~SACR0_ENB; 259 SACR0 &= ~SACR0_ENB;
261 pxa_i2s_wait(); 260 pxa_i2s_wait();
262 if (dai->private_data != NULL) { 261 if (clk_ena) {
263 clk_disable(clk_i2s); 262 clk_disable(clk_i2s);
264 dai->private_data = NULL; 263 clk_ena = 0;
265 } 264 }
266 } 265 }
267} 266}
@@ -300,6 +299,35 @@ static int pxa2xx_i2s_resume(struct snd_soc_dai *dai)
300#define pxa2xx_i2s_resume NULL 299#define pxa2xx_i2s_resume NULL
301#endif 300#endif
302 301
302static int pxa2xx_i2s_probe(struct snd_soc_dai *dai)
303{
304 clk_i2s = clk_get(dai->dev, "I2SCLK");
305 if (IS_ERR(clk_i2s))
306 return PTR_ERR(clk_i2s);
307
308 /*
309 * PXA Developer's Manual:
310 * If SACR0[ENB] is toggled in the middle of a normal operation,
311 * the SACR0[RST] bit must also be set and cleared to reset all
312 * I2S controller registers.
313 */
314 SACR0 = SACR0_RST;
315 SACR0 = 0;
316 /* Make sure RPL and REC are disabled */
317 SACR1 = SACR1_DRPL | SACR1_DREC;
318 /* Along with FIFO servicing */
319 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
320
321 return 0;
322}
323
324static int pxa2xx_i2s_remove(struct snd_soc_dai *dai)
325{
326 clk_put(clk_i2s);
327 clk_i2s = ERR_PTR(-ENOENT);
328 return 0;
329}
330
303#define PXA2XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 331#define PXA2XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
304 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ 332 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
305 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) 333 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
@@ -313,9 +341,9 @@ static struct snd_soc_dai_ops pxa_i2s_dai_ops = {
313 .set_sysclk = pxa2xx_i2s_set_dai_sysclk, 341 .set_sysclk = pxa2xx_i2s_set_dai_sysclk,
314}; 342};
315 343
316struct snd_soc_dai pxa_i2s_dai = { 344static struct snd_soc_dai_driver pxa_i2s_dai = {
317 .name = "pxa2xx-i2s", 345 .probe = pxa2xx_i2s_probe,
318 .id = 0, 346 .remove = pxa2xx_i2s_remove,
319 .suspend = pxa2xx_i2s_suspend, 347 .suspend = pxa2xx_i2s_suspend,
320 .resume = pxa2xx_i2s_resume, 348 .resume = pxa2xx_i2s_resume,
321 .playback = { 349 .playback = {
@@ -332,49 +360,20 @@ struct snd_soc_dai pxa_i2s_dai = {
332 .symmetric_rates = 1, 360 .symmetric_rates = 1,
333}; 361};
334 362
335EXPORT_SYMBOL_GPL(pxa_i2s_dai); 363static int pxa2xx_i2s_drv_probe(struct platform_device *pdev)
336
337static int pxa2xx_i2s_probe(struct platform_device *dev)
338{ 364{
339 int ret; 365 return snd_soc_register_dai(&pdev->dev, &pxa_i2s_dai);
340
341 clk_i2s = clk_get(&dev->dev, "I2SCLK");
342 if (IS_ERR(clk_i2s))
343 return PTR_ERR(clk_i2s);
344
345 pxa_i2s_dai.dev = &dev->dev;
346 pxa_i2s_dai.private_data = NULL;
347 ret = snd_soc_register_dai(&pxa_i2s_dai);
348 if (ret != 0)
349 clk_put(clk_i2s);
350
351 /*
352 * PXA Developer's Manual:
353 * If SACR0[ENB] is toggled in the middle of a normal operation,
354 * the SACR0[RST] bit must also be set and cleared to reset all
355 * I2S controller registers.
356 */
357 SACR0 = SACR0_RST;
358 SACR0 = 0;
359 /* Make sure RPL and REC are disabled */
360 SACR1 = SACR1_DRPL | SACR1_DREC;
361 /* Along with FIFO servicing */
362 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
363
364 return ret;
365} 366}
366 367
367static int __devexit pxa2xx_i2s_remove(struct platform_device *dev) 368static int __devexit pxa2xx_i2s_drv_remove(struct platform_device *pdev)
368{ 369{
369 snd_soc_unregister_dai(&pxa_i2s_dai); 370 snd_soc_unregister_dai(&pdev->dev);
370 clk_put(clk_i2s);
371 clk_i2s = ERR_PTR(-ENOENT);
372 return 0; 371 return 0;
373} 372}
374 373
375static struct platform_driver pxa2xx_i2s_driver = { 374static struct platform_driver pxa2xx_i2s_driver = {
376 .probe = pxa2xx_i2s_probe, 375 .probe = pxa2xx_i2s_drv_probe,
377 .remove = __devexit_p(pxa2xx_i2s_remove), 376 .remove = __devexit_p(pxa2xx_i2s_drv_remove),
378 377
379 .driver = { 378 .driver = {
380 .name = "pxa2xx-i2s", 379 .name = "pxa2xx-i2s",
diff --git a/sound/soc/pxa/pxa2xx-i2s.h b/sound/soc/pxa/pxa2xx-i2s.h
index e2def441153..070f3c6059f 100644
--- a/sound/soc/pxa/pxa2xx-i2s.h
+++ b/sound/soc/pxa/pxa2xx-i2s.h
@@ -15,6 +15,4 @@
15/* I2S clock */ 15/* I2S clock */
16#define PXA2XX_I2S_SYSCLK 0 16#define PXA2XX_I2S_SYSCLK 0
17 17
18extern struct snd_soc_dai pxa_i2s_dai;
19
20#endif 18#endif
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index adc7e6f15f9..5127044acfe 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -28,7 +28,7 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
28 struct pxa2xx_pcm_dma_params *dma; 28 struct pxa2xx_pcm_dma_params *dma;
29 int ret; 29 int ret;
30 30
31 dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 31 dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
32 32
33 /* return if this is a bufferless transfer e.g. 33 /* return if this is a bufferless transfer e.g.
34 * codec <--> BT codec or GSM modem -- lg FIXME */ 34 * codec <--> BT codec or GSM modem -- lg FIXME */
@@ -95,14 +95,14 @@ static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
95 if (!card->dev->coherent_dma_mask) 95 if (!card->dev->coherent_dma_mask)
96 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 96 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
97 97
98 if (dai->playback.channels_min) { 98 if (dai->driver->playback.channels_min) {
99 ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, 99 ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
100 SNDRV_PCM_STREAM_PLAYBACK); 100 SNDRV_PCM_STREAM_PLAYBACK);
101 if (ret) 101 if (ret)
102 goto out; 102 goto out;
103 } 103 }
104 104
105 if (dai->capture.channels_min) { 105 if (dai->driver->capture.channels_min) {
106 ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, 106 ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
107 SNDRV_PCM_STREAM_CAPTURE); 107 SNDRV_PCM_STREAM_CAPTURE);
108 if (ret) 108 if (ret)
@@ -112,25 +112,44 @@ static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
112 return ret; 112 return ret;
113} 113}
114 114
115struct snd_soc_platform pxa2xx_soc_platform = { 115static struct snd_soc_platform_driver pxa2xx_soc_platform = {
116 .name = "pxa2xx-audio", 116 .ops = &pxa2xx_pcm_ops,
117 .pcm_ops = &pxa2xx_pcm_ops,
118 .pcm_new = pxa2xx_soc_pcm_new, 117 .pcm_new = pxa2xx_soc_pcm_new,
119 .pcm_free = pxa2xx_pcm_free_dma_buffers, 118 .pcm_free = pxa2xx_pcm_free_dma_buffers,
120}; 119};
121EXPORT_SYMBOL_GPL(pxa2xx_soc_platform);
122 120
123static int __init pxa2xx_soc_platform_init(void) 121static int __devinit pxa2xx_soc_platform_probe(struct platform_device *pdev)
124{ 122{
125 return snd_soc_register_platform(&pxa2xx_soc_platform); 123 return snd_soc_register_platform(&pdev->dev, &pxa2xx_soc_platform);
126} 124}
127module_init(pxa2xx_soc_platform_init);
128 125
129static void __exit pxa2xx_soc_platform_exit(void) 126static int __devexit pxa2xx_soc_platform_remove(struct platform_device *pdev)
130{ 127{
131 snd_soc_unregister_platform(&pxa2xx_soc_platform); 128 snd_soc_unregister_platform(&pdev->dev);
129 return 0;
130}
131
132static struct platform_driver pxa_pcm_driver = {
133 .driver = {
134 .name = "pxa-pcm-audio",
135 .owner = THIS_MODULE,
136 },
137
138 .probe = pxa2xx_soc_platform_probe,
139 .remove = __devexit_p(pxa2xx_soc_platform_remove),
140};
141
142static int __init snd_pxa_pcm_init(void)
143{
144 return platform_driver_register(&pxa_pcm_driver);
145}
146module_init(snd_pxa_pcm_init);
147
148static void __exit snd_pxa_pcm_exit(void)
149{
150 platform_driver_unregister(&pxa_pcm_driver);
132} 151}
133module_exit(pxa2xx_soc_platform_exit); 152module_exit(snd_pxa_pcm_exit);
134 153
135MODULE_AUTHOR("Nicolas Pitre"); 154MODULE_AUTHOR("Nicolas Pitre");
136MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module"); 155MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
diff --git a/sound/soc/pxa/pxa2xx-pcm.h b/sound/soc/pxa/pxa2xx-pcm.h
deleted file mode 100644
index 60c3b20aeeb..00000000000
--- a/sound/soc/pxa/pxa2xx-pcm.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * linux/sound/arm/pxa2xx-pcm.h -- ALSA PCM interface for the Intel PXA2xx chip
3 *
4 * Author: Nicolas Pitre
5 * Created: Nov 30, 2004
6 * Copyright: MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _PXA2XX_PCM_H
14#define _PXA2XX_PCM_H
15
16/* platform data */
17extern struct snd_soc_platform pxa2xx_soc_platform;
18
19#endif
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 7e3f41696c4..2cda82bc5d2 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -26,9 +26,6 @@
26 26
27#include <asm/mach-types.h> 27#include <asm/mach-types.h>
28 28
29#include "../codecs/cs4270.h"
30#include "../codecs/ak4104.h"
31#include "pxa2xx-pcm.h"
32#include "pxa-ssp.h" 29#include "pxa-ssp.h"
33 30
34#define GPIO_SPDIF_RESET (38) 31#define GPIO_SPDIF_RESET (38)
@@ -71,7 +68,7 @@ static void raumfeld_enable_audio(bool en)
71static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream) 68static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
72{ 69{
73 struct snd_soc_pcm_runtime *rtd = substream->private_data; 70 struct snd_soc_pcm_runtime *rtd = substream->private_data;
74 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 71 struct snd_soc_dai *codec_dai = rtd->codec_dai;
75 72
76 /* set freq to 0 to enable all possible codec sample rates */ 73 /* set freq to 0 to enable all possible codec sample rates */
77 return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0); 74 return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
@@ -80,7 +77,7 @@ static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
80static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream) 77static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream)
81{ 78{
82 struct snd_soc_pcm_runtime *rtd = substream->private_data; 79 struct snd_soc_pcm_runtime *rtd = substream->private_data;
83 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 80 struct snd_soc_dai *codec_dai = rtd->codec_dai;
84 81
85 /* set freq to 0 to enable all possible codec sample rates */ 82 /* set freq to 0 to enable all possible codec sample rates */
86 snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0); 83 snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
@@ -90,8 +87,8 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
90 struct snd_pcm_hw_params *params) 87 struct snd_pcm_hw_params *params)
91{ 88{
92 struct snd_soc_pcm_runtime *rtd = substream->private_data; 89 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 90 struct snd_soc_dai *codec_dai = rtd->codec_dai;
94 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 91 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
95 unsigned int fmt, clk = 0; 92 unsigned int fmt, clk = 0;
96 int ret = 0; 93 int ret = 0;
97 94
@@ -167,32 +164,14 @@ static int raumfeld_line_resume(struct platform_device *pdev)
167 return 0; 164 return 0;
168} 165}
169 166
170static struct snd_soc_dai_link raumfeld_line_dai = {
171 .name = "CS4270",
172 .stream_name = "CS4270",
173 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1],
174 .codec_dai = &cs4270_dai,
175 .ops = &raumfeld_cs4270_ops,
176};
177
178static struct snd_soc_card snd_soc_line_raumfeld = {
179 .name = "Raumfeld analog",
180 .platform = &pxa2xx_soc_platform,
181 .dai_link = &raumfeld_line_dai,
182 .suspend_post = raumfeld_line_suspend,
183 .resume_pre = raumfeld_line_resume,
184 .num_links = 1,
185};
186
187
188/* AK4104 */ 167/* AK4104 */
189 168
190static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream, 169static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
191 struct snd_pcm_hw_params *params) 170 struct snd_pcm_hw_params *params)
192{ 171{
193 struct snd_soc_pcm_runtime *rtd = substream->private_data; 172 struct snd_soc_pcm_runtime *rtd = substream->private_data;
194 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 173 struct snd_soc_dai *codec_dai = rtd->codec_dai;
195 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 174 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
196 int fmt, ret = 0, clk = 0; 175 int fmt, ret = 0, clk = 0;
197 176
198 switch (params_rate(params)) { 177 switch (params_rate(params)) {
@@ -247,34 +226,35 @@ static struct snd_soc_ops raumfeld_ak4104_ops = {
247 .hw_params = raumfeld_ak4104_hw_params, 226 .hw_params = raumfeld_ak4104_hw_params,
248}; 227};
249 228
250static struct snd_soc_dai_link raumfeld_spdif_dai = { 229static struct snd_soc_dai_link raumfeld_dai[] = {
230{
251 .name = "ak4104", 231 .name = "ak4104",
252 .stream_name = "Playback", 232 .stream_name = "Playback",
253 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP2], 233 .cpu_dai_name = "pxa-ssp-dai.1",
254 .codec_dai = &ak4104_dai, 234 .codec_dai_name = "ak4104-hifi",
235 .platform_name = "pxa-pcm-audio",
255 .ops = &raumfeld_ak4104_ops, 236 .ops = &raumfeld_ak4104_ops,
256}; 237 .codec_name = "ak4104-codec.0",
257 238},
258static struct snd_soc_card snd_soc_spdif_raumfeld = { 239{
259 .name = "Raumfeld S/PDIF", 240 .name = "CS4270",
260 .platform = &pxa2xx_soc_platform, 241 .stream_name = "CS4270",
261 .dai_link = &raumfeld_spdif_dai, 242 .cpu_dai_name = "pxa-ssp-dai.0",
262 .num_links = 1 243 .platform_name = "pxa-pcm-audio",
263}; 244 .codec_dai_name = "cs4270-hifi",
264 245 .codec_name = "cs4270-codec.0-0048",
265/* raumfeld_audio audio subsystem */ 246 .ops = &raumfeld_cs4270_ops,
266static struct snd_soc_device raumfeld_line_devdata = { 247},};
267 .card = &snd_soc_line_raumfeld,
268 .codec_dev = &soc_codec_device_cs4270,
269};
270 248
271static struct snd_soc_device raumfeld_spdif_devdata = { 249static struct snd_soc_card snd_soc_raumfeld = {
272 .card = &snd_soc_spdif_raumfeld, 250 .name = "Raumfeld",
273 .codec_dev = &soc_codec_device_ak4104, 251 .dai_link = raumfeld_dai,
252 .suspend_post = raumfeld_line_suspend,
253 .resume_pre = raumfeld_line_resume,
254 .num_links = ARRAY_SIZE(raumfeld_dai),
274}; 255};
275 256
276static struct platform_device *raumfeld_audio_line_device; 257static struct platform_device *raumfeld_audio_device;
277static struct platform_device *raumfeld_audio_spdif_device;
278 258
279static int __init raumfeld_audio_init(void) 259static int __init raumfeld_audio_init(void)
280{ 260{
@@ -292,38 +272,19 @@ static int __init raumfeld_audio_init(void)
292 272
293 set_max9485_clk(MAX9485_MCLK_FREQ_122880); 273 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
294 274
295 /* LINE */ 275 /* Register LINE and SPDIF */
296 raumfeld_audio_line_device = platform_device_alloc("soc-audio", 0); 276 raumfeld_audio_device = platform_device_alloc("soc-audio", 0);
297 if (!raumfeld_audio_line_device) 277 if (!raumfeld_audio_device)
298 return -ENOMEM; 278 return -ENOMEM;
299 279
300 platform_set_drvdata(raumfeld_audio_line_device, 280 platform_set_drvdata(raumfeld_audio_device,
301 &raumfeld_line_devdata); 281 &snd_soc_raumfeld);
302 raumfeld_line_devdata.dev = &raumfeld_audio_line_device->dev; 282 ret = platform_device_add(raumfeld_audio_device);
303 ret = platform_device_add(raumfeld_audio_line_device);
304 if (ret)
305 platform_device_put(raumfeld_audio_line_device);
306 283
307 /* no S/PDIF on Speakers */ 284 /* no S/PDIF on Speakers */
308 if (machine_is_raumfeld_speaker()) 285 if (machine_is_raumfeld_speaker())
309 return ret; 286 return ret;
310 287
311 /* S/PDIF */
312 raumfeld_audio_spdif_device = platform_device_alloc("soc-audio", 1);
313 if (!raumfeld_audio_spdif_device) {
314 platform_device_put(raumfeld_audio_line_device);
315 return -ENOMEM;
316 }
317
318 platform_set_drvdata(raumfeld_audio_spdif_device,
319 &raumfeld_spdif_devdata);
320 raumfeld_spdif_devdata.dev = &raumfeld_audio_spdif_device->dev;
321 ret = platform_device_add(raumfeld_audio_spdif_device);
322 if (ret) {
323 platform_device_put(raumfeld_audio_line_device);
324 platform_device_put(raumfeld_audio_spdif_device);
325 }
326
327 raumfeld_enable_audio(true); 288 raumfeld_enable_audio(true);
328 289
329 return ret; 290 return ret;
@@ -333,10 +294,7 @@ static void __exit raumfeld_audio_exit(void)
333{ 294{
334 raumfeld_enable_audio(false); 295 raumfeld_enable_audio(false);
335 296
336 platform_device_unregister(raumfeld_audio_line_device); 297 platform_device_unregister(raumfeld_audio_device);
337
338 if (machine_is_raumfeld_connector())
339 platform_device_unregister(raumfeld_audio_spdif_device);
340 298
341 i2c_unregister_device(max9486_client); 299 i2c_unregister_device(max9486_client);
342 300
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 1941a357e8c..f470f360f4d 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -28,7 +28,6 @@
28#include <asm/mach-types.h> 28#include <asm/mach-types.h>
29#include <mach/spitz.h> 29#include <mach/spitz.h>
30#include "../codecs/wm8750.h" 30#include "../codecs/wm8750.h"
31#include "pxa2xx-pcm.h"
32#include "pxa2xx-i2s.h" 31#include "pxa2xx-i2s.h"
33 32
34#define SPITZ_HP 0 33#define SPITZ_HP 0
@@ -107,7 +106,7 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
107static int spitz_startup(struct snd_pcm_substream *substream) 106static int spitz_startup(struct snd_pcm_substream *substream)
108{ 107{
109 struct snd_soc_pcm_runtime *rtd = substream->private_data; 108 struct snd_soc_pcm_runtime *rtd = substream->private_data;
110 struct snd_soc_codec *codec = rtd->socdev->card->codec; 109 struct snd_soc_codec *codec = rtd->codec;
111 110
112 /* check the jack status at stream startup */ 111 /* check the jack status at stream startup */
113 spitz_ext_control(codec); 112 spitz_ext_control(codec);
@@ -118,8 +117,8 @@ static int spitz_hw_params(struct snd_pcm_substream *substream,
118 struct snd_pcm_hw_params *params) 117 struct snd_pcm_hw_params *params)
119{ 118{
120 struct snd_soc_pcm_runtime *rtd = substream->private_data; 119 struct snd_soc_pcm_runtime *rtd = substream->private_data;
121 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 120 struct snd_soc_dai *codec_dai = rtd->codec_dai;
122 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 121 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
123 unsigned int clk = 0; 122 unsigned int clk = 0;
124 int ret = 0; 123 int ret = 0;
125 124
@@ -274,8 +273,9 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = {
274/* 273/*
275 * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device 274 * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device
276 */ 275 */
277static int spitz_wm8750_init(struct snd_soc_codec *codec) 276static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
278{ 277{
278 struct snd_soc_codec *codec = rtd->codec;
279 int err; 279 int err;
280 280
281 /* NC codec pins */ 281 /* NC codec pins */
@@ -308,8 +308,10 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec)
308static struct snd_soc_dai_link spitz_dai = { 308static struct snd_soc_dai_link spitz_dai = {
309 .name = "wm8750", 309 .name = "wm8750",
310 .stream_name = "WM8750", 310 .stream_name = "WM8750",
311 .cpu_dai = &pxa_i2s_dai, 311 .cpu_dai_name = "pxa-is2",
312 .codec_dai = &wm8750_dai, 312 .codec_dai_name = "wm8750-hifi",
313 .platform_name = "pxa-pcm-audio",
314 .codec_name = "wm8750-codec.0-001a",
313 .init = spitz_wm8750_init, 315 .init = spitz_wm8750_init,
314 .ops = &spitz_ops, 316 .ops = &spitz_ops,
315}; 317};
@@ -317,49 +319,10 @@ static struct snd_soc_dai_link spitz_dai = {
317/* spitz audio machine driver */ 319/* spitz audio machine driver */
318static struct snd_soc_card snd_soc_spitz = { 320static struct snd_soc_card snd_soc_spitz = {
319 .name = "Spitz", 321 .name = "Spitz",
320 .platform = &pxa2xx_soc_platform,
321 .dai_link = &spitz_dai, 322 .dai_link = &spitz_dai,
322 .num_links = 1, 323 .num_links = 1,
323}; 324};
324 325
325/* spitz audio subsystem */
326static struct snd_soc_device spitz_snd_devdata = {
327 .card = &snd_soc_spitz,
328 .codec_dev = &soc_codec_dev_wm8750,
329};
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
363static struct platform_device *spitz_snd_device; 326static struct platform_device *spitz_snd_device;
364 327
365static int __init spitz_init(void) 328static int __init spitz_init(void)
@@ -369,16 +332,11 @@ static int __init spitz_init(void)
369 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) 332 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
370 return -ENODEV; 333 return -ENODEV;
371 334
372 ret = wm8750_i2c_setup();
373 if (ret != 0)
374 return ret;
375
376 spitz_snd_device = platform_device_alloc("soc-audio", -1); 335 spitz_snd_device = platform_device_alloc("soc-audio", -1);
377 if (!spitz_snd_device) 336 if (!spitz_snd_device)
378 return -ENOMEM; 337 return -ENOMEM;
379 338
380 platform_set_drvdata(spitz_snd_device, &spitz_snd_devdata); 339 platform_set_drvdata(spitz_snd_device, &snd_soc_spitz);
381 spitz_snd_devdata.dev = &spitz_snd_device->dev;
382 ret = platform_device_add(spitz_snd_device); 340 ret = platform_device_add(spitz_snd_device);
383 341
384 if (ret) 342 if (ret)
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index dbbd3e9d163..a3bfb2e8b70 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -33,7 +33,6 @@
33#include <mach/audio.h> 33#include <mach/audio.h>
34 34
35#include "../codecs/wm9712.h" 35#include "../codecs/wm9712.h"
36#include "pxa2xx-pcm.h"
37#include "pxa2xx-ac97.h" 36#include "pxa2xx-ac97.h"
38 37
39static struct snd_soc_card tosa; 38static struct snd_soc_card tosa;
@@ -80,7 +79,7 @@ static void tosa_ext_control(struct snd_soc_codec *codec)
80static int tosa_startup(struct snd_pcm_substream *substream) 79static int tosa_startup(struct snd_pcm_substream *substream)
81{ 80{
82 struct snd_soc_pcm_runtime *rtd = substream->private_data; 81 struct snd_soc_pcm_runtime *rtd = substream->private_data;
83 struct snd_soc_codec *codec = rtd->socdev->card->codec; 82 struct snd_soc_codec *codec = rtd->card->codec;
84 83
85 /* check the jack status at stream startup */ 84 /* check the jack status at stream startup */
86 tosa_ext_control(codec); 85 tosa_ext_control(codec);
@@ -184,8 +183,9 @@ static const struct snd_kcontrol_new tosa_controls[] = {
184 tosa_set_spk), 183 tosa_set_spk),
185}; 184};
186 185
187static int tosa_ac97_init(struct snd_soc_codec *codec) 186static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
188{ 187{
188 struct snd_soc_codec *codec = rtd->codec;
189 int err; 189 int err;
190 190
191 snd_soc_dapm_nc_pin(codec, "OUT3"); 191 snd_soc_dapm_nc_pin(codec, "OUT3");
@@ -212,16 +212,20 @@ static struct snd_soc_dai_link tosa_dai[] = {
212{ 212{
213 .name = "AC97", 213 .name = "AC97",
214 .stream_name = "AC97 HiFi", 214 .stream_name = "AC97 HiFi",
215 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 215 .cpu_dai_name = "pxa-ac97.0",
216 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 216 .codec_dai_name = "wm9712-hifi",
217 .platform_name = "pxa-pcm-audio",
218 .codec_name = "wm9712-codec",
217 .init = tosa_ac97_init, 219 .init = tosa_ac97_init,
218 .ops = &tosa_ops, 220 .ops = &tosa_ops,
219}, 221},
220{ 222{
221 .name = "AC97 Aux", 223 .name = "AC97 Aux",
222 .stream_name = "AC97 Aux", 224 .stream_name = "AC97 Aux",
223 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 225 .cpu_dai_name = "pxa-ac97.1",
224 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 226 .codec_dai_name = "wm9712-aux",
227 .platform_name = "pxa-pcm-audio",
228 .codec_name = "wm9712-codec",
225 .ops = &tosa_ops, 229 .ops = &tosa_ops,
226}, 230},
227}; 231};
@@ -248,18 +252,12 @@ static int tosa_remove(struct platform_device *dev)
248 252
249static struct snd_soc_card tosa = { 253static struct snd_soc_card tosa = {
250 .name = "Tosa", 254 .name = "Tosa",
251 .platform = &pxa2xx_soc_platform,
252 .dai_link = tosa_dai, 255 .dai_link = tosa_dai,
253 .num_links = ARRAY_SIZE(tosa_dai), 256 .num_links = ARRAY_SIZE(tosa_dai),
254 .probe = tosa_probe, 257 .probe = tosa_probe,
255 .remove = tosa_remove, 258 .remove = tosa_remove,
256}; 259};
257 260
258static struct snd_soc_device tosa_snd_devdata = {
259 .card = &tosa,
260 .codec_dev = &soc_codec_dev_wm9712,
261};
262
263static struct platform_device *tosa_snd_device; 261static struct platform_device *tosa_snd_device;
264 262
265static int __init tosa_init(void) 263static int __init tosa_init(void)
@@ -275,8 +273,7 @@ static int __init tosa_init(void)
275 goto err_alloc; 273 goto err_alloc;
276 } 274 }
277 275
278 platform_set_drvdata(tosa_snd_device, &tosa_snd_devdata); 276 platform_set_drvdata(tosa_snd_device, &tosa);
279 tosa_snd_devdata.dev = &tosa_snd_device->dev;
280 ret = platform_device_add(tosa_snd_device); 277 ret = platform_device_add(tosa_snd_device);
281 278
282 if (!ret) 279 if (!ret)
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 4e4d2fa8ddc..704f74b56ab 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -30,7 +30,6 @@
30#include <mach/z2.h> 30#include <mach/z2.h>
31 31
32#include "../codecs/wm8750.h" 32#include "../codecs/wm8750.h"
33#include "pxa2xx-pcm.h"
34#include "pxa2xx-i2s.h" 33#include "pxa2xx-i2s.h"
35 34
36static struct snd_soc_card snd_soc_z2; 35static struct snd_soc_card snd_soc_z2;
@@ -39,8 +38,8 @@ static int z2_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params) 38 struct snd_pcm_hw_params *params)
40{ 39{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data; 40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 41 struct snd_soc_dai *codec_dai = rtd->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 unsigned int clk = 0; 43 unsigned int clk = 0;
45 int ret = 0; 44 int ret = 0;
46 45
@@ -138,8 +137,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
138/* 137/*
139 * Logic for a wm8750 as connected on a Z2 Device 138 * Logic for a wm8750 as connected on a Z2 Device
140 */ 139 */
141static int z2_wm8750_init(struct snd_soc_codec *codec) 140static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
142{ 141{
142 struct snd_soc_codec *codec = rtd->codec;
143 int ret; 143 int ret;
144 144
145 /* NC codec pins */ 145 /* NC codec pins */
@@ -160,7 +160,7 @@ static int z2_wm8750_init(struct snd_soc_codec *codec)
160 goto err; 160 goto err;
161 161
162 /* Jack detection API stuff */ 162 /* Jack detection API stuff */
163 ret = snd_soc_jack_new(&snd_soc_z2, "Headset Jack", SND_JACK_HEADSET, 163 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
164 &hs_jack); 164 &hs_jack);
165 if (ret) 165 if (ret)
166 goto err; 166 goto err;
@@ -189,8 +189,10 @@ static struct snd_soc_ops z2_ops = {
189static struct snd_soc_dai_link z2_dai = { 189static struct snd_soc_dai_link z2_dai = {
190 .name = "wm8750", 190 .name = "wm8750",
191 .stream_name = "WM8750", 191 .stream_name = "WM8750",
192 .cpu_dai = &pxa_i2s_dai, 192 .cpu_dai_name = "pxa-i2s",
193 .codec_dai = &wm8750_dai, 193 .codec_dai_name = "wm8750-hifi",
194 .platform_name = "pxa-pcm-audio",
195 .codec_name = "wm8750-codec.0-001a",
194 .init = z2_wm8750_init, 196 .init = z2_wm8750_init,
195 .ops = &z2_ops, 197 .ops = &z2_ops,
196}; 198};
@@ -198,17 +200,10 @@ static struct snd_soc_dai_link z2_dai = {
198/* z2 audio machine driver */ 200/* z2 audio machine driver */
199static struct snd_soc_card snd_soc_z2 = { 201static struct snd_soc_card snd_soc_z2 = {
200 .name = "Z2", 202 .name = "Z2",
201 .platform = &pxa2xx_soc_platform,
202 .dai_link = &z2_dai, 203 .dai_link = &z2_dai,
203 .num_links = 1, 204 .num_links = 1,
204}; 205};
205 206
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; 207static struct platform_device *z2_snd_device;
213 208
214static int __init z2_init(void) 209static int __init z2_init(void)
@@ -222,8 +217,7 @@ static int __init z2_init(void)
222 if (!z2_snd_device) 217 if (!z2_snd_device)
223 return -ENOMEM; 218 return -ENOMEM;
224 219
225 platform_set_drvdata(z2_snd_device, &z2_snd_devdata); 220 platform_set_drvdata(z2_snd_device, &snd_soc_z2);
226 z2_snd_devdata.dev = &z2_snd_device->dev;
227 ret = platform_device_add(z2_snd_device); 221 ret = platform_device_add(z2_snd_device);
228 222
229 if (ret) 223 if (ret)
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index dd678ae2439..d27e05af775 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -23,7 +23,6 @@
23#include <sound/soc-dapm.h> 23#include <sound/soc-dapm.h>
24 24
25#include "../codecs/wm9713.h" 25#include "../codecs/wm9713.h"
26#include "pxa2xx-pcm.h"
27#include "pxa2xx-ac97.h" 26#include "pxa2xx-ac97.h"
28#include "pxa-ssp.h" 27#include "pxa-ssp.h"
29 28
@@ -71,10 +70,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
71 { "Multiactor", NULL, "SPKR" }, 70 { "Multiactor", NULL, "SPKR" },
72}; 71};
73 72
74static int zylonite_wm9713_init(struct snd_soc_codec *codec) 73static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd)
75{ 74{
75 struct snd_soc_codec *codec = rtd->codec;
76
76 if (clk_pout) 77 if (clk_pout)
77 snd_soc_dai_set_pll(&codec->dai[0], 0, 0, 78 snd_soc_dai_set_pll(rtd->codec_dai, 0, 0,
78 clk_get_rate(pout), 0); 79 clk_get_rate(pout), 0);
79 80
80 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, 81 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
@@ -94,8 +95,8 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
94 struct snd_pcm_hw_params *params) 95 struct snd_pcm_hw_params *params)
95{ 96{
96 struct snd_soc_pcm_runtime *rtd = substream->private_data; 97 struct snd_soc_pcm_runtime *rtd = substream->private_data;
97 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 98 struct snd_soc_dai *codec_dai = rtd->codec_dai;
98 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 99 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
99 unsigned int pll_out = 0; 100 unsigned int pll_out = 0;
100 unsigned int wm9713_div = 0; 101 unsigned int wm9713_div = 0;
101 int ret = 0; 102 int ret = 0;
@@ -163,21 +164,27 @@ static struct snd_soc_dai_link zylonite_dai[] = {
163{ 164{
164 .name = "AC97", 165 .name = "AC97",
165 .stream_name = "AC97 HiFi", 166 .stream_name = "AC97 HiFi",
166 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 167 .codec_name = "wm9713-codec",
167 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI], 168 .platform_name = "pxa-pcm-audio",
169 .cpu_dai_name = "pxa-ac97.0",
170 .codec_name = "wm9713-hifi",
168 .init = zylonite_wm9713_init, 171 .init = zylonite_wm9713_init,
169}, 172},
170{ 173{
171 .name = "AC97 Aux", 174 .name = "AC97 Aux",
172 .stream_name = "AC97 Aux", 175 .stream_name = "AC97 Aux",
173 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 176 .codec_name = "wm9713-codec",
174 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX], 177 .platform_name = "pxa-pcm-audio",
178 .cpu_dai_name = "pxa-ac97.1",
179 .codec_name = "wm9713-aux",
175}, 180},
176{ 181{
177 .name = "WM9713 Voice", 182 .name = "WM9713 Voice",
178 .stream_name = "WM9713 Voice", 183 .stream_name = "WM9713 Voice",
179 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP3], 184 .codec_name = "wm9713-codec",
180 .codec_dai = &wm9713_dai[WM9713_DAI_PCM_VOICE], 185 .platform_name = "pxa-pcm-audio",
186 .cpu_dai_name = "pxa-ssp-dai.2",
187 .codec_name = "wm9713-voice",
181 .ops = &zylonite_voice_ops, 188 .ops = &zylonite_voice_ops,
182}, 189},
183}; 190};
@@ -248,14 +255,9 @@ static struct snd_soc_card zylonite = {
248 .remove = &zylonite_remove, 255 .remove = &zylonite_remove,
249 .suspend_post = &zylonite_suspend_post, 256 .suspend_post = &zylonite_suspend_post,
250 .resume_pre = &zylonite_resume_pre, 257 .resume_pre = &zylonite_resume_pre,
251 .platform = &pxa2xx_soc_platform,
252 .dai_link = zylonite_dai, 258 .dai_link = zylonite_dai,
253 .num_links = ARRAY_SIZE(zylonite_dai), 259 .num_links = ARRAY_SIZE(zylonite_dai),
254}; 260 .owner = THIS_MODULE,
255
256static struct snd_soc_device zylonite_snd_ac97_devdata = {
257 .card = &zylonite,
258 .codec_dev = &soc_codec_dev_wm9713,
259}; 261};
260 262
261static struct platform_device *zylonite_snd_ac97_device; 263static struct platform_device *zylonite_snd_ac97_device;
@@ -268,9 +270,7 @@ static int __init zylonite_init(void)
268 if (!zylonite_snd_ac97_device) 270 if (!zylonite_snd_ac97_device)
269 return -ENOMEM; 271 return -ENOMEM;
270 272
271 platform_set_drvdata(zylonite_snd_ac97_device, 273 platform_set_drvdata(zylonite_snd_ac97_device, &zylonite);
272 &zylonite_snd_ac97_devdata);
273 zylonite_snd_ac97_devdata.dev = &zylonite_snd_ac97_device->dev;
274 274
275 ret = platform_device_add(zylonite_snd_ac97_device); 275 ret = platform_device_add(zylonite_snd_ac97_device);
276 if (ret != 0) 276 if (ret != 0)
diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c
index 8c108b121c1..49605cd8394 100644
--- a/sound/soc/s3c24xx/jive_wm8750.c
+++ b/sound/soc/s3c24xx/jive_wm8750.c
@@ -49,8 +49,8 @@ static int jive_hw_params(struct snd_pcm_substream *substream,
49 struct snd_pcm_hw_params *params) 49 struct snd_pcm_hw_params *params)
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 *codec_dai = rtd->dai->codec_dai; 52 struct snd_soc_dai *codec_dai = rtd->codec_dai;
53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 53 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
54 struct s3c_i2sv2_rate_calc div; 54 struct s3c_i2sv2_rate_calc div;
55 unsigned int clk = 0; 55 unsigned int clk = 0;
56 int ret = 0; 56 int ret = 0;
@@ -108,8 +108,9 @@ static struct snd_soc_ops jive_ops = {
108 .hw_params = jive_hw_params, 108 .hw_params = jive_hw_params,
109}; 109};
110 110
111static int jive_wm8750_init(struct snd_soc_codec *codec) 111static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd)
112{ 112{
113 struct snd_soc_codec *codec = rtd->codec;
113 int err; 114 int err;
114 115
115 /* These endpoints are not being used. */ 116 /* These endpoints are not being used. */
@@ -138,8 +139,10 @@ static int jive_wm8750_init(struct snd_soc_codec *codec)
138static struct snd_soc_dai_link jive_dai = { 139static struct snd_soc_dai_link jive_dai = {
139 .name = "wm8750", 140 .name = "wm8750",
140 .stream_name = "WM8750", 141 .stream_name = "WM8750",
141 .cpu_dai = &s3c2412_i2s_dai, 142 .cpu_dai_name = "s3c2412-i2s",
142 .codec_dai = &wm8750_dai, 143 .codec_dai_name = "wm8750-hifi",
144 .platform_name = "s3c24xx-pcm-audio",
145 .codec_name = "wm8750-codec.0-0x1a",
143 .init = jive_wm8750_init, 146 .init = jive_wm8750_init,
144 .ops = &jive_ops, 147 .ops = &jive_ops,
145}; 148};
@@ -147,17 +150,10 @@ static struct snd_soc_dai_link jive_dai = {
147/* jive audio machine driver */ 150/* jive audio machine driver */
148static struct snd_soc_card snd_soc_machine_jive = { 151static struct snd_soc_card snd_soc_machine_jive = {
149 .name = "Jive", 152 .name = "Jive",
150 .platform = &s3c24xx_soc_platform,
151 .dai_link = &jive_dai, 153 .dai_link = &jive_dai,
152 .num_links = 1, 154 .num_links = 1,
153}; 155};
154 156
155/* jive audio subsystem */
156static struct snd_soc_device jive_snd_devdata = {
157 .card = &snd_soc_machine_jive,
158 .codec_dev = &soc_codec_dev_wm8750,
159};
160
161static struct platform_device *jive_snd_device; 157static struct platform_device *jive_snd_device;
162 158
163static int __init jive_init(void) 159static int __init jive_init(void)
@@ -173,8 +169,7 @@ static int __init jive_init(void)
173 if (!jive_snd_device) 169 if (!jive_snd_device)
174 return -ENOMEM; 170 return -ENOMEM;
175 171
176 platform_set_drvdata(jive_snd_device, &jive_snd_devdata); 172 platform_set_drvdata(jive_snd_device, &snd_soc_machine_jive);
177 jive_snd_devdata.dev = &jive_snd_device->dev;
178 ret = platform_device_add(jive_snd_device); 173 ret = platform_device_add(jive_snd_device);
179 174
180 if (ret) 175 if (ret)
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c
index ffa954fe693..abe64abe8c8 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c
@@ -23,7 +23,6 @@
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/soc-dapm.h> 24#include <sound/soc-dapm.h>
25 25
26#include "../codecs/ac97.h"
27#include "s3c-dma.h" 26#include "s3c-dma.h"
28#include "s3c-ac97.h" 27#include "s3c-ac97.h"
29 28
@@ -33,23 +32,19 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
33{ 32{
34 .name = "AC97", 33 .name = "AC97",
35 .stream_name = "AC97 HiFi", 34 .stream_name = "AC97 HiFi",
36 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM], 35 .cpu_dai_name = "s3c-ac97",
37 .codec_dai = &ac97_dai, 36 .codec_dai_name = "ac97-hifi",
37 .codec_name = "ac97-codec",
38 .platform_name = "s3c24xx-pcm-audio",
38}, 39},
39}; 40};
40 41
41static struct snd_soc_card ln2440sbc = { 42static struct snd_soc_card ln2440sbc = {
42 .name = "LN2440SBC", 43 .name = "LN2440SBC",
43 .platform = &s3c24xx_soc_platform,
44 .dai_link = ln2440sbc_dai, 44 .dai_link = ln2440sbc_dai,
45 .num_links = ARRAY_SIZE(ln2440sbc_dai), 45 .num_links = ARRAY_SIZE(ln2440sbc_dai),
46}; 46};
47 47
48static struct snd_soc_device ln2440sbc_snd_ac97_devdata = {
49 .card = &ln2440sbc,
50 .codec_dev = &soc_codec_dev_ac97,
51};
52
53static struct platform_device *ln2440sbc_snd_ac97_device; 48static struct platform_device *ln2440sbc_snd_ac97_device;
54 49
55static int __init ln2440sbc_init(void) 50static int __init ln2440sbc_init(void)
@@ -60,9 +55,7 @@ static int __init ln2440sbc_init(void)
60 if (!ln2440sbc_snd_ac97_device) 55 if (!ln2440sbc_snd_ac97_device)
61 return -ENOMEM; 56 return -ENOMEM;
62 57
63 platform_set_drvdata(ln2440sbc_snd_ac97_device, 58 platform_set_drvdata(ln2440sbc_snd_ac97_device, &ln2440sbc);
64 &ln2440sbc_snd_ac97_devdata);
65 ln2440sbc_snd_ac97_devdata.dev = &ln2440sbc_snd_ac97_device->dev;
66 ret = platform_device_add(ln2440sbc_snd_ac97_device); 59 ret = platform_device_add(ln2440sbc_snd_ac97_device);
67 60
68 if (ret) 61 if (ret)
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
index 209c25994c7..c457bfd8297 100644
--- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
@@ -41,8 +41,8 @@ static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params) 41 struct snd_pcm_hw_params *params)
42{ 42{
43 struct snd_soc_pcm_runtime *rtd = substream->private_data; 43 struct snd_soc_pcm_runtime *rtd = substream->private_data;
44 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 44 struct snd_soc_dai *codec_dai = rtd->codec_dai;
45 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 45 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
46 unsigned int pll_out = 0, bclk = 0; 46 unsigned int pll_out = 0, bclk = 0;
47 int ret = 0; 47 int ret = 0;
48 unsigned long iis_clkrate; 48 unsigned long iis_clkrate;
@@ -130,7 +130,7 @@ static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream,
130static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream) 130static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream)
131{ 131{
132 struct snd_soc_pcm_runtime *rtd = substream->private_data; 132 struct snd_soc_pcm_runtime *rtd = substream->private_data;
133 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 133 struct snd_soc_dai *codec_dai = rtd->codec_dai;
134 134
135 /* disable the PLL */ 135 /* disable the PLL */
136 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); 136 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
@@ -149,7 +149,7 @@ static int neo1973_gta02_voice_hw_params(
149 struct snd_pcm_hw_params *params) 149 struct snd_pcm_hw_params *params)
150{ 150{
151 struct snd_soc_pcm_runtime *rtd = substream->private_data; 151 struct snd_soc_pcm_runtime *rtd = substream->private_data;
152 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 152 struct snd_soc_dai *codec_dai = rtd->codec_dai;
153 unsigned int pcmdiv = 0; 153 unsigned int pcmdiv = 0;
154 int ret = 0; 154 int ret = 0;
155 unsigned long iis_clkrate; 155 unsigned long iis_clkrate;
@@ -194,7 +194,7 @@ static int neo1973_gta02_voice_hw_params(
194static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream) 194static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream)
195{ 195{
196 struct snd_soc_pcm_runtime *rtd = substream->private_data; 196 struct snd_soc_pcm_runtime *rtd = substream->private_data;
197 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 197 struct snd_soc_dai *codec_dai = rtd->codec_dai;
198 198
199 /* disable the PLL */ 199 /* disable the PLL */
200 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); 200 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
@@ -262,7 +262,7 @@ static int lm4853_event(struct snd_soc_dapm_widget *w,
262 struct snd_kcontrol *k, 262 struct snd_kcontrol *k,
263 int event) 263 int event)
264{ 264{
265 gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(value)); 265 gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event));
266 266
267 return 0; 267 return 0;
268} 268}
@@ -330,8 +330,9 @@ static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = {
330 * This is an example machine initialisation for a wm8753 connected to a 330 * This is an example machine initialisation for a wm8753 connected to a
331 * neo1973 GTA02. 331 * neo1973 GTA02.
332 */ 332 */
333static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) 333static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd)
334{ 334{
335 struct snd_soc_codec *codec = rtd->codec;
335 int err; 336 int err;
336 337
337 /* set up NC codec pins */ 338 /* set up NC codec pins */
@@ -378,9 +379,8 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
378/* 379/*
379 * BT Codec DAI 380 * BT Codec DAI
380 */ 381 */
381static struct snd_soc_dai bt_dai = { 382static struct snd_soc_dai_driver bt_dai = {
382 .name = "Bluetooth", 383 .name = "bluetooth-dai",
383 .id = 0,
384 .playback = { 384 .playback = {
385 .channels_min = 1, 385 .channels_min = 1,
386 .channels_max = 1, 386 .channels_max = 1,
@@ -397,32 +397,30 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = {
397{ /* Hifi Playback - for similatious use with voice below */ 397{ /* Hifi Playback - for similatious use with voice below */
398 .name = "WM8753", 398 .name = "WM8753",
399 .stream_name = "WM8753 HiFi", 399 .stream_name = "WM8753 HiFi",
400 .cpu_dai = &s3c24xx_i2s_dai, 400 .cpu_dai_name = "s3c24xx-i2s",
401 .codec_dai = &wm8753_dai[WM8753_DAI_HIFI], 401 .codec_dai_name = "wm8753-hifi",
402 .init = neo1973_gta02_wm8753_init, 402 .init = neo1973_gta02_wm8753_init,
403 .platform_name = "s3c24xx-pcm-audio",
404 .codec_name = "wm8753-codec.0-0x1a",
403 .ops = &neo1973_gta02_hifi_ops, 405 .ops = &neo1973_gta02_hifi_ops,
404}, 406},
405{ /* Voice via BT */ 407{ /* Voice via BT */
406 .name = "Bluetooth", 408 .name = "Bluetooth",
407 .stream_name = "Voice", 409 .stream_name = "Voice",
408 .cpu_dai = &bt_dai, 410 .cpu_dai_name = "bluetooth-dai",
409 .codec_dai = &wm8753_dai[WM8753_DAI_VOICE], 411 .codec_dai_name = "wm8753-voice",
410 .ops = &neo1973_gta02_voice_ops, 412 .ops = &neo1973_gta02_voice_ops,
413 .codec_name = "wm8753-codec.0-0x1a",
414 .platform_name = "s3c24xx-pcm-audio",
411}, 415},
412}; 416};
413 417
414static struct snd_soc_card neo1973_gta02 = { 418static struct snd_soc_card neo1973_gta02 = {
415 .name = "neo1973-gta02", 419 .name = "neo1973-gta02",
416 .platform = &s3c24xx_soc_platform,
417 .dai_link = neo1973_gta02_dai, 420 .dai_link = neo1973_gta02_dai,
418 .num_links = ARRAY_SIZE(neo1973_gta02_dai), 421 .num_links = ARRAY_SIZE(neo1973_gta02_dai),
419}; 422};
420 423
421static struct snd_soc_device neo1973_gta02_snd_devdata = {
422 .card = &neo1973_gta02,
423 .codec_dev = &soc_codec_dev_wm8753,
424};
425
426static struct platform_device *neo1973_gta02_snd_device; 424static struct platform_device *neo1973_gta02_snd_device;
427 425
428static int __init neo1973_gta02_init(void) 426static int __init neo1973_gta02_init(void)
@@ -435,18 +433,18 @@ static int __init neo1973_gta02_init(void)
435 return -ENODEV; 433 return -ENODEV;
436 } 434 }
437 435
438 /* register bluetooth DAI here */
439 ret = snd_soc_register_dai(&bt_dai);
440 if (ret)
441 return ret;
442
443 neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1); 436 neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1);
444 if (!neo1973_gta02_snd_device) 437 if (!neo1973_gta02_snd_device)
445 return -ENOMEM; 438 return -ENOMEM;
446 439
447 platform_set_drvdata(neo1973_gta02_snd_device, 440 /* register bluetooth DAI here */
448 &neo1973_gta02_snd_devdata); 441 ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, -1, &bt_dai);
449 neo1973_gta02_snd_devdata.dev = &neo1973_gta02_snd_device->dev; 442 if (ret) {
443 platform_device_put(neo1973_gta02_snd_device);
444 return ret;
445 }
446
447 platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02);
450 ret = platform_device_add(neo1973_gta02_snd_device); 448 ret = platform_device_add(neo1973_gta02_snd_device);
451 449
452 if (ret) { 450 if (ret) {
@@ -461,7 +459,7 @@ static int __init neo1973_gta02_init(void)
461 goto err_unregister_device; 459 goto err_unregister_device;
462 } 460 }
463 461
464 ret = gpio_direction_output(GTA02_GPIO_AMP_HP_IN, 1); 462 ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1);
465 if (ret) { 463 if (ret) {
466 pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_HP_IN); 464 pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_HP_IN);
467 goto err_free_gpio_hp_in; 465 goto err_free_gpio_hp_in;
@@ -493,7 +491,7 @@ module_init(neo1973_gta02_init);
493 491
494static void __exit neo1973_gta02_exit(void) 492static void __exit neo1973_gta02_exit(void)
495{ 493{
496 snd_soc_unregister_dai(&bt_dai); 494 snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev, -1);
497 platform_device_unregister(neo1973_gta02_snd_device); 495 platform_device_unregister(neo1973_gta02_snd_device);
498 gpio_free(GTA02_GPIO_HP_IN); 496 gpio_free(GTA02_GPIO_HP_IN);
499 gpio_free(GTA02_GPIO_AMP_SHUT); 497 gpio_free(GTA02_GPIO_AMP_SHUT);
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 0cb4f86f6d1..d7a39a0fe99 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -57,8 +57,8 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
57 struct snd_pcm_hw_params *params) 57 struct snd_pcm_hw_params *params)
58{ 58{
59 struct snd_soc_pcm_runtime *rtd = substream->private_data; 59 struct snd_soc_pcm_runtime *rtd = substream->private_data;
60 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 60 struct snd_soc_dai *codec_dai = rtd->codec_dai;
61 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 61 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
62 unsigned int pll_out = 0, bclk = 0; 62 unsigned int pll_out = 0, bclk = 0;
63 int ret = 0; 63 int ret = 0;
64 unsigned long iis_clkrate; 64 unsigned long iis_clkrate;
@@ -147,7 +147,7 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
147static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) 147static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
148{ 148{
149 struct snd_soc_pcm_runtime *rtd = substream->private_data; 149 struct snd_soc_pcm_runtime *rtd = substream->private_data;
150 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 150 struct snd_soc_dai *codec_dai = rtd->codec_dai;
151 151
152 pr_debug("Entered %s\n", __func__); 152 pr_debug("Entered %s\n", __func__);
153 153
@@ -167,7 +167,7 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
167 struct snd_pcm_hw_params *params) 167 struct snd_pcm_hw_params *params)
168{ 168{
169 struct snd_soc_pcm_runtime *rtd = substream->private_data; 169 struct snd_soc_pcm_runtime *rtd = substream->private_data;
170 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 170 struct snd_soc_dai *codec_dai = rtd->codec_dai;
171 unsigned int pcmdiv = 0; 171 unsigned int pcmdiv = 0;
172 int ret = 0; 172 int ret = 0;
173 unsigned long iis_clkrate; 173 unsigned long iis_clkrate;
@@ -213,7 +213,7 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
213static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) 213static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
214{ 214{
215 struct snd_soc_pcm_runtime *rtd = substream->private_data; 215 struct snd_soc_pcm_runtime *rtd = substream->private_data;
216 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 216 struct snd_soc_dai *codec_dai = rtd->codec_dai;
217 217
218 pr_debug("Entered %s\n", __func__); 218 pr_debug("Entered %s\n", __func__);
219 219
@@ -499,8 +499,9 @@ static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
499 * neo1973 II. It is missing logic to detect hp/mic insertions and logic 499 * neo1973 II. It is missing logic to detect hp/mic insertions and logic
500 * to re-route the audio in such an event. 500 * to re-route the audio in such an event.
501 */ 501 */
502static int neo1973_wm8753_init(struct snd_soc_codec *codec) 502static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
503{ 503{
504 struct snd_soc_codec *codec = rtd->codec;
504 int err; 505 int err;
505 506
506 pr_debug("Entered %s\n", __func__); 507 pr_debug("Entered %s\n", __func__);
@@ -538,8 +539,7 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
538 * BT Codec DAI 539 * BT Codec DAI
539 */ 540 */
540static struct snd_soc_dai bt_dai = { 541static struct snd_soc_dai bt_dai = {
541 .name = "Bluetooth", 542 .name = "bluetooth-dai",
542 .id = 0,
543 .playback = { 543 .playback = {
544 .channels_min = 1, 544 .channels_min = 1,
545 .channels_max = 1, 545 .channels_max = 1,
@@ -556,32 +556,30 @@ static struct snd_soc_dai_link neo1973_dai[] = {
556{ /* Hifi Playback - for similatious use with voice below */ 556{ /* Hifi Playback - for similatious use with voice below */
557 .name = "WM8753", 557 .name = "WM8753",
558 .stream_name = "WM8753 HiFi", 558 .stream_name = "WM8753 HiFi",
559 .cpu_dai = &s3c24xx_i2s_dai, 559 .platform_name = "s3c24xx-pcm-audio",
560 .codec_dai = &wm8753_dai[WM8753_DAI_HIFI], 560 .cpu_dai_name = "s3c24xx-i2s",
561 .codec_dai_name = "wm8753-hifi",
562 .codec_name = "wm8753-codec.0-0x1a",
561 .init = neo1973_wm8753_init, 563 .init = neo1973_wm8753_init,
562 .ops = &neo1973_hifi_ops, 564 .ops = &neo1973_hifi_ops,
563}, 565},
564{ /* Voice via BT */ 566{ /* Voice via BT */
565 .name = "Bluetooth", 567 .name = "Bluetooth",
566 .stream_name = "Voice", 568 .stream_name = "Voice",
567 .cpu_dai = &bt_dai, 569 .platform_name = "s3c24xx-pcm-audio",
568 .codec_dai = &wm8753_dai[WM8753_DAI_VOICE], 570 .cpu_dai_name = "bluetooth-dai",
571 .codec_dai_name = "wm8753-voice",
572 .codec_name = "wm8753-codec.0-0x1a",
569 .ops = &neo1973_voice_ops, 573 .ops = &neo1973_voice_ops,
570}, 574},
571}; 575};
572 576
573static struct snd_soc_card neo1973 = { 577static struct snd_soc_card neo1973 = {
574 .name = "neo1973", 578 .name = "neo1973",
575 .platform = &s3c24xx_soc_platform,
576 .dai_link = neo1973_dai, 579 .dai_link = neo1973_dai,
577 .num_links = ARRAY_SIZE(neo1973_dai), 580 .num_links = ARRAY_SIZE(neo1973_dai),
578}; 581};
579 582
580static struct snd_soc_device neo1973_snd_devdata = {
581 .card = &neo1973,
582 .codec_dev = &soc_codec_dev_wm8753,
583};
584
585static int lm4857_i2c_probe(struct i2c_client *client, 583static int lm4857_i2c_probe(struct i2c_client *client,
586 const struct i2c_device_id *id) 584 const struct i2c_device_id *id)
587{ 585{
@@ -673,8 +671,7 @@ static int __init neo1973_init(void)
673 if (!neo1973_snd_device) 671 if (!neo1973_snd_device)
674 return -ENOMEM; 672 return -ENOMEM;
675 673
676 platform_set_drvdata(neo1973_snd_device, &neo1973_snd_devdata); 674 platform_set_drvdata(neo1973_snd_device, &neo1973);
677 neo1973_snd_devdata.dev = &neo1973_snd_device->dev;
678 ret = platform_device_add(neo1973_snd_device); 675 ret = platform_device_add(neo1973_snd_device);
679 676
680 if (ret) { 677 if (ret) {
diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c
index 31f6d45b638..86f4a9b4a86 100644
--- a/sound/soc/s3c24xx/s3c-ac97.c
+++ b/sound/soc/s3c24xx/s3c-ac97.c
@@ -222,7 +222,7 @@ static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
222 struct snd_soc_dai *dai) 222 struct snd_soc_dai *dai)
223{ 223{
224 struct snd_soc_pcm_runtime *rtd = substream->private_data; 224 struct snd_soc_pcm_runtime *rtd = substream->private_data;
225 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 225 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
226 struct s3c_dma_params *dma_data; 226 struct s3c_dma_params *dma_data;
227 227
228 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 228 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -241,7 +241,7 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
241 u32 ac_glbctrl; 241 u32 ac_glbctrl;
242 struct snd_soc_pcm_runtime *rtd = substream->private_data; 242 struct snd_soc_pcm_runtime *rtd = substream->private_data;
243 struct s3c_dma_params *dma_data = 243 struct s3c_dma_params *dma_data =
244 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 244 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
245 245
246 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); 246 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
247 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 247 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -277,7 +277,7 @@ static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream,
277 struct snd_soc_dai *dai) 277 struct snd_soc_dai *dai)
278{ 278{
279 struct snd_soc_pcm_runtime *rtd = substream->private_data; 279 struct snd_soc_pcm_runtime *rtd = substream->private_data;
280 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 280 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
281 281
282 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 282 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
283 return -ENODEV; 283 return -ENODEV;
@@ -293,7 +293,7 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
293 u32 ac_glbctrl; 293 u32 ac_glbctrl;
294 struct snd_soc_pcm_runtime *rtd = substream->private_data; 294 struct snd_soc_pcm_runtime *rtd = substream->private_data;
295 struct s3c_dma_params *dma_data = 295 struct s3c_dma_params *dma_data =
296 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 296 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
297 297
298 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); 298 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
299 ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; 299 ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK;
@@ -328,10 +328,9 @@ static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
328 .trigger = s3c_ac97_mic_trigger, 328 .trigger = s3c_ac97_mic_trigger,
329}; 329};
330 330
331struct snd_soc_dai s3c_ac97_dai[] = { 331static struct snd_soc_dai_driver s3c_ac97_dai[] = {
332 [S3C_AC97_DAI_PCM] = { 332 [S3C_AC97_DAI_PCM] = {
333 .name = "s3c-ac97", 333 .name = "s3c-ac97",
334 .id = S3C_AC97_DAI_PCM,
335 .ac97_control = 1, 334 .ac97_control = 1,
336 .playback = { 335 .playback = {
337 .stream_name = "AC97 Playback", 336 .stream_name = "AC97 Playback",
@@ -349,7 +348,6 @@ struct snd_soc_dai s3c_ac97_dai[] = {
349 }, 348 },
350 [S3C_AC97_DAI_MIC] = { 349 [S3C_AC97_DAI_MIC] = {
351 .name = "s3c-ac97-mic", 350 .name = "s3c-ac97-mic",
352 .id = S3C_AC97_DAI_MIC,
353 .ac97_control = 1, 351 .ac97_control = 1,
354 .capture = { 352 .capture = {
355 .stream_name = "AC97 Mic Capture", 353 .stream_name = "AC97 Mic Capture",
@@ -360,7 +358,6 @@ struct snd_soc_dai s3c_ac97_dai[] = {
360 .ops = &s3c_ac97_mic_dai_ops, 358 .ops = &s3c_ac97_mic_dai_ops,
361 }, 359 },
362}; 360};
363EXPORT_SYMBOL_GPL(s3c_ac97_dai);
364 361
365static __devinit int s3c_ac97_probe(struct platform_device *pdev) 362static __devinit int s3c_ac97_probe(struct platform_device *pdev)
366{ 363{
@@ -449,10 +446,8 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
449 goto err4; 446 goto err4;
450 } 447 }
451 448
452 s3c_ac97_dai[S3C_AC97_DAI_PCM].dev = &pdev->dev; 449 ret = snd_soc_register_dais(&pdev->dev, s3c_ac97_dai,
453 s3c_ac97_dai[S3C_AC97_DAI_MIC].dev = &pdev->dev; 450 ARRAY_SIZE(s3c_ac97_dai));
454
455 ret = snd_soc_register_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
456 if (ret) 451 if (ret)
457 goto err5; 452 goto err5;
458 453
@@ -476,7 +471,7 @@ static __devexit int s3c_ac97_remove(struct platform_device *pdev)
476{ 471{
477 struct resource *mem_res, *irq_res; 472 struct resource *mem_res, *irq_res;
478 473
479 snd_soc_unregister_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); 474 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai));
480 475
481 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 476 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
482 if (irq_res) 477 if (irq_res)
diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/s3c24xx/s3c-ac97.h
index 278198379de..5dcedd07fdb 100644
--- a/sound/soc/s3c24xx/s3c-ac97.h
+++ b/sound/soc/s3c24xx/s3c-ac97.h
@@ -18,6 +18,4 @@
18#define S3C_AC97_DAI_PCM 0 18#define S3C_AC97_DAI_PCM 0
19#define S3C_AC97_DAI_MIC 1 19#define S3C_AC97_DAI_MIC 1
20 20
21extern struct snd_soc_dai s3c_ac97_dai[];
22
23#endif /* __S3C_AC97_H_ */ 21#endif /* __S3C_AC97_H_ */
diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/s3c24xx/s3c-dma.c
index 1b61c23ff30..9f91b2d5145 100644
--- a/sound/soc/s3c24xx/s3c-dma.c
+++ b/sound/soc/s3c24xx/s3c-dma.c
@@ -147,7 +147,7 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
147 struct snd_soc_pcm_runtime *rtd = substream->private_data; 147 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 unsigned long totbytes = params_buffer_bytes(params); 148 unsigned long totbytes = params_buffer_bytes(params);
149 struct s3c_dma_params *dma = 149 struct s3c_dma_params *dma =
150 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 150 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
151 int ret = 0; 151 int ret = 0;
152 152
153 153
@@ -441,14 +441,14 @@ static int s3c_dma_new(struct snd_card *card,
441 if (!card->dev->coherent_dma_mask) 441 if (!card->dev->coherent_dma_mask)
442 card->dev->coherent_dma_mask = 0xffffffff; 442 card->dev->coherent_dma_mask = 0xffffffff;
443 443
444 if (dai->playback.channels_min) { 444 if (dai->driver->playback.channels_min) {
445 ret = s3c_preallocate_dma_buffer(pcm, 445 ret = s3c_preallocate_dma_buffer(pcm,
446 SNDRV_PCM_STREAM_PLAYBACK); 446 SNDRV_PCM_STREAM_PLAYBACK);
447 if (ret) 447 if (ret)
448 goto out; 448 goto out;
449 } 449 }
450 450
451 if (dai->capture.channels_min) { 451 if (dai->driver->capture.channels_min) {
452 ret = s3c_preallocate_dma_buffer(pcm, 452 ret = s3c_preallocate_dma_buffer(pcm,
453 SNDRV_PCM_STREAM_CAPTURE); 453 SNDRV_PCM_STREAM_CAPTURE);
454 if (ret) 454 if (ret)
@@ -458,25 +458,44 @@ static int s3c_dma_new(struct snd_card *card,
458 return ret; 458 return ret;
459} 459}
460 460
461struct snd_soc_platform s3c24xx_soc_platform = { 461static struct snd_soc_platform_driver s3c24xx_soc_platform = {
462 .name = "s3c24xx-audio", 462 .ops = &s3c_dma_ops,
463 .pcm_ops = &s3c_dma_ops,
464 .pcm_new = s3c_dma_new, 463 .pcm_new = s3c_dma_new,
465 .pcm_free = s3c_dma_free_dma_buffers, 464 .pcm_free = s3c_dma_free_dma_buffers,
466}; 465};
467EXPORT_SYMBOL_GPL(s3c24xx_soc_platform);
468 466
469static int __init s3c24xx_soc_platform_init(void) 467static int __devinit s3c24xx_soc_platform_probe(struct platform_device *pdev)
470{ 468{
471 return snd_soc_register_platform(&s3c24xx_soc_platform); 469 return snd_soc_register_platform(&pdev->dev, &s3c24xx_soc_platform);
472} 470}
473module_init(s3c24xx_soc_platform_init);
474 471
475static void __exit s3c24xx_soc_platform_exit(void) 472static int __devexit s3c24xx_soc_platform_remove(struct platform_device *pdev)
476{ 473{
477 snd_soc_unregister_platform(&s3c24xx_soc_platform); 474 snd_soc_unregister_platform(&pdev->dev);
475 return 0;
476}
477
478static struct platform_driver s3c24xx_pcm_driver = {
479 .driver = {
480 .name = "s3c24xx-pcm-audio",
481 .owner = THIS_MODULE,
482 },
483
484 .probe = s3c24xx_soc_platform_probe,
485 .remove = __devexit_p(s3c24xx_soc_platform_remove),
486};
487
488static int __init snd_s3c24xx_pcm_init(void)
489{
490 return platform_driver_register(&s3c24xx_pcm_driver);
491}
492module_init(snd_s3c24xx_pcm_init);
493
494static void __exit snd_s3c24xx_pcm_exit(void)
495{
496 platform_driver_unregister(&s3c24xx_pcm_driver);
478} 497}
479module_exit(s3c24xx_soc_platform_exit); 498module_exit(snd_s3c24xx_pcm_exit);
480 499
481MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 500MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
482MODULE_DESCRIPTION("Samsung S3C Audio DMA module"); 501MODULE_DESCRIPTION("Samsung S3C Audio DMA module");
diff --git a/sound/soc/s3c24xx/s3c-dma.h b/sound/soc/s3c24xx/s3c-dma.h
index 69bb6bf6fc1..748c07d7c07 100644
--- a/sound/soc/s3c24xx/s3c-dma.h
+++ b/sound/soc/s3c24xx/s3c-dma.h
@@ -25,7 +25,6 @@ struct s3c_dma_params {
25#define S3C24XX_DAI_I2S 0 25#define S3C24XX_DAI_I2S 0
26 26
27/* platform data */ 27/* platform data */
28extern struct snd_soc_platform s3c24xx_soc_platform;
29extern struct snd_ac97_bus_ops s3c24xx_ac97_ops; 28extern struct snd_ac97_bus_ops s3c24xx_ac97_ops;
30 29
31#endif 30#endif
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index 64376b2aac7..f4fbc0e6173 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -49,7 +49,7 @@
49 49
50static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) 50static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
51{ 51{
52 return cpu_dai->private_data; 52 return snd_soc_dai_get_drvdata(cpu_dai);
53} 53}
54 54
55#define bit_set(v, b) (((v) & (b)) ? 1 : 0) 55#define bit_set(v, b) (((v) & (b)) ? 1 : 0)
@@ -307,11 +307,9 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
307 307
308static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream, 308static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream,
309 struct snd_pcm_hw_params *params, 309 struct snd_pcm_hw_params *params,
310 struct snd_soc_dai *socdai) 310 struct snd_soc_dai *dai)
311{ 311{
312 struct snd_soc_pcm_runtime *rtd = substream->private_data; 312 struct s3c_i2sv2_info *i2s = to_info(dai);
313 struct snd_soc_dai_link *dai = rtd->dai;
314 struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai);
315 struct s3c_dma_params *dma_data; 313 struct s3c_dma_params *dma_data;
316 u32 iismod; 314 u32 iismod;
317 315
@@ -322,7 +320,7 @@ static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream,
322 else 320 else
323 dma_data = i2s->dma_capture; 321 dma_data = i2s->dma_capture;
324 322
325 snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data); 323 snd_soc_dai_set_dma_data(dai, substream, dma_data);
326 324
327 /* Working copies of register */ 325 /* Working copies of register */
328 iismod = readl(i2s->regs + S3C2412_IISMOD); 326 iismod = readl(i2s->regs + S3C2412_IISMOD);
@@ -396,12 +394,12 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
396 struct snd_soc_dai *dai) 394 struct snd_soc_dai *dai)
397{ 395{
398 struct snd_soc_pcm_runtime *rtd = substream->private_data; 396 struct snd_soc_pcm_runtime *rtd = substream->private_data;
399 struct s3c_i2sv2_info *i2s = to_info(rtd->dai->cpu_dai); 397 struct s3c_i2sv2_info *i2s = to_info(rtd->cpu_dai);
400 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 398 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
401 unsigned long irqs; 399 unsigned long irqs;
402 int ret = 0; 400 int ret = 0;
403 struct s3c_dma_params *dma_data = 401 struct s3c_dma_params *dma_data =
404 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 402 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
405 403
406 pr_debug("Entered %s\n", __func__); 404 pr_debug("Entered %s\n", __func__);
407 405
@@ -640,36 +638,17 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
640} 638}
641EXPORT_SYMBOL_GPL(s3c_i2sv2_iis_calc_rate); 639EXPORT_SYMBOL_GPL(s3c_i2sv2_iis_calc_rate);
642 640
643int s3c_i2sv2_probe(struct platform_device *pdev, 641int s3c_i2sv2_probe(struct snd_soc_dai *dai,
644 struct snd_soc_dai *dai,
645 struct s3c_i2sv2_info *i2s, 642 struct s3c_i2sv2_info *i2s,
646 unsigned long base) 643 unsigned long base)
647{ 644{
648 struct device *dev = &pdev->dev; 645 struct device *dev = dai->dev;
649 unsigned int iismod; 646 unsigned int iismod;
650 647
651 i2s->dev = dev; 648 i2s->dev = dev;
652 649
653 /* record our i2s structure for later use in the callbacks */ 650 /* record our i2s structure for later use in the callbacks */
654 dai->private_data = i2s; 651 snd_soc_dai_set_drvdata(dai, i2s);
655
656 if (!base) {
657 struct resource *res = platform_get_resource(pdev,
658 IORESOURCE_MEM,
659 0);
660 if (!res) {
661 dev_err(dev, "Unable to get register resource\n");
662 return -ENXIO;
663 }
664
665 if (!request_mem_region(res->start, resource_size(res),
666 "s3c64xx-i2s-v4")) {
667 dev_err(dev, "Unable to request register region\n");
668 return -EBUSY;
669 }
670
671 base = res->start;
672 }
673 652
674 i2s->regs = ioremap(base, 0x100); 653 i2s->regs = ioremap(base, 0x100);
675 if (i2s->regs == NULL) { 654 if (i2s->regs == NULL) {
@@ -752,9 +731,10 @@ static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
752#define s3c2412_i2s_resume NULL 731#define s3c2412_i2s_resume NULL
753#endif 732#endif
754 733
755int s3c_i2sv2_register_dai(struct snd_soc_dai *dai) 734int s3c_i2sv2_register_dai(struct device *dev, int id,
735 struct snd_soc_dai_driver *drv)
756{ 736{
757 struct snd_soc_dai_ops *ops = dai->ops; 737 struct snd_soc_dai_ops *ops = drv->ops;
758 738
759 ops->trigger = s3c2412_i2s_trigger; 739 ops->trigger = s3c2412_i2s_trigger;
760 if (!ops->hw_params) 740 if (!ops->hw_params)
@@ -767,10 +747,10 @@ int s3c_i2sv2_register_dai(struct snd_soc_dai *dai)
767 if (!ops->delay) 747 if (!ops->delay)
768 ops->delay = s3c2412_i2s_delay; 748 ops->delay = s3c2412_i2s_delay;
769 749
770 dai->suspend = s3c2412_i2s_suspend; 750 drv->suspend = s3c2412_i2s_suspend;
771 dai->resume = s3c2412_i2s_resume; 751 drv->resume = s3c2412_i2s_resume;
772 752
773 return snd_soc_register_dai(dai); 753 return snd_soc_register_dai(dev, id, drv);
774} 754}
775EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai); 755EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai);
776 756
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/s3c24xx/s3c-i2s-v2.h
index 766f43a13d8..d4583015148 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.h
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.h
@@ -66,6 +66,8 @@ struct s3c_i2sv2_info {
66 u32 suspend_iismod; 66 u32 suspend_iismod;
67 u32 suspend_iiscon; 67 u32 suspend_iiscon;
68 u32 suspend_iispsr; 68 u32 suspend_iispsr;
69
70 unsigned long base;
69}; 71};
70 72
71extern struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai); 73extern struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai);
@@ -81,23 +83,24 @@ extern int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
81 83
82/** 84/**
83 * s3c_i2sv2_probe - probe for i2s device helper 85 * s3c_i2sv2_probe - probe for i2s device helper
84 * @pdev: The platform device supplied to the original probe.
85 * @dai: The ASoC DAI structure supplied to the original probe. 86 * @dai: The ASoC DAI structure supplied to the original probe.
86 * @i2s: Our local i2s structure to fill in. 87 * @i2s: Our local i2s structure to fill in.
87 * @base: The base address for the registers. 88 * @base: The base address for the registers.
88 */ 89 */
89extern int s3c_i2sv2_probe(struct platform_device *pdev, 90extern int s3c_i2sv2_probe(struct snd_soc_dai *dai,
90 struct snd_soc_dai *dai,
91 struct s3c_i2sv2_info *i2s, 91 struct s3c_i2sv2_info *i2s,
92 unsigned long base); 92 unsigned long base);
93 93
94/** 94/**
95 * s3c_i2sv2_register_dai - register dai with soc core 95 * s3c_i2sv2_register_dai - register dai with soc core
96 * @dai: The snd_soc_dai structure to register 96 * @dev: DAI device
97 * @id: DAI ID
98 * @drv: The driver structure to register
97 * 99 *
98 * Fill in any missing fields and then register the given dai with the 100 * Fill in any missing fields and then register the given dai with the
99 * soc core. 101 * soc core.
100 */ 102 */
101extern int s3c_i2sv2_register_dai(struct snd_soc_dai *dai); 103extern int s3c_i2sv2_register_dai(struct device *dev, int id,
104 struct snd_soc_dai_driver *drv);
102 105
103#endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */ 106#endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c
index 326f0a9e7e3..653ffa27091 100644
--- a/sound/soc/s3c24xx/s3c-pcm.c
+++ b/sound/soc/s3c24xx/s3c-pcm.c
@@ -64,11 +64,6 @@ static struct s3c_dma_params s3c_pcm_stereo_in[] = {
64 64
65static struct s3c_pcm_info s3c_pcm[2]; 65static struct s3c_pcm_info s3c_pcm[2];
66 66
67static inline struct s3c_pcm_info *to_info(struct snd_soc_dai *cpu_dai)
68{
69 return cpu_dai->private_data;
70}
71
72static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on) 67static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on)
73{ 68{
74 void __iomem *regs = pcm->regs; 69 void __iomem *regs = pcm->regs;
@@ -132,7 +127,7 @@ static int s3c_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
132 struct snd_soc_dai *dai) 127 struct snd_soc_dai *dai)
133{ 128{
134 struct snd_soc_pcm_runtime *rtd = substream->private_data; 129 struct snd_soc_pcm_runtime *rtd = substream->private_data;
135 struct s3c_pcm_info *pcm = to_info(rtd->dai->cpu_dai); 130 struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai);
136 unsigned long flags; 131 unsigned long flags;
137 132
138 dev_dbg(pcm->dev, "Entered %s\n", __func__); 133 dev_dbg(pcm->dev, "Entered %s\n", __func__);
@@ -176,8 +171,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
176 struct snd_soc_dai *socdai) 171 struct snd_soc_dai *socdai)
177{ 172{
178 struct snd_soc_pcm_runtime *rtd = substream->private_data; 173 struct snd_soc_pcm_runtime *rtd = substream->private_data;
179 struct snd_soc_dai_link *dai = rtd->dai; 174 struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai);
180 struct s3c_pcm_info *pcm = to_info(dai->cpu_dai);
181 struct s3c_dma_params *dma_data; 175 struct s3c_dma_params *dma_data;
182 void __iomem *regs = pcm->regs; 176 void __iomem *regs = pcm->regs;
183 struct clk *clk; 177 struct clk *clk;
@@ -192,7 +186,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
192 else 186 else
193 dma_data = pcm->dma_capture; 187 dma_data = pcm->dma_capture;
194 188
195 snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data); 189 snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);
196 190
197 /* Strictly check for sample size */ 191 /* Strictly check for sample size */
198 switch (params_format(params)) { 192 switch (params_format(params)) {
@@ -242,7 +236,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
242static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai, 236static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai,
243 unsigned int fmt) 237 unsigned int fmt)
244{ 238{
245 struct s3c_pcm_info *pcm = to_info(cpu_dai); 239 struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai);
246 void __iomem *regs = pcm->regs; 240 void __iomem *regs = pcm->regs;
247 unsigned long flags; 241 unsigned long flags;
248 int ret = 0; 242 int ret = 0;
@@ -313,7 +307,7 @@ exit:
313static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai, 307static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai,
314 int div_id, int div) 308 int div_id, int div)
315{ 309{
316 struct s3c_pcm_info *pcm = to_info(cpu_dai); 310 struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai);
317 311
318 switch (div_id) { 312 switch (div_id) {
319 case S3C_PCM_SCLK_PER_FS: 313 case S3C_PCM_SCLK_PER_FS:
@@ -330,7 +324,7 @@ static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai,
330static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai, 324static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai,
331 int clk_id, unsigned int freq, int dir) 325 int clk_id, unsigned int freq, int dir)
332{ 326{
333 struct s3c_pcm_info *pcm = to_info(cpu_dai); 327 struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai);
334 void __iomem *regs = pcm->regs; 328 void __iomem *regs = pcm->regs;
335 u32 clkctl = readl(regs + S3C_PCM_CLKCTL); 329 u32 clkctl = readl(regs + S3C_PCM_CLKCTL);
336 330
@@ -366,10 +360,9 @@ static struct snd_soc_dai_ops s3c_pcm_dai_ops = {
366 360
367#define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 361#define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000
368 362
369#define S3C_PCM_DECLARE(n) \ 363#define S3C_PCM_DAI_DECLARE \
370{ \ 364{ \
371 .name = "samsung-pcm", \ 365 .name = "samsung-dai", \
372 .id = (n), \
373 .symmetric_rates = 1, \ 366 .symmetric_rates = 1, \
374 .ops = &s3c_pcm_dai_ops, \ 367 .ops = &s3c_pcm_dai_ops, \
375 .playback = { \ 368 .playback = { \
@@ -386,16 +379,15 @@ static struct snd_soc_dai_ops s3c_pcm_dai_ops = {
386 }, \ 379 }, \
387} 380}
388 381
389struct snd_soc_dai s3c_pcm_dai[] = { 382struct snd_soc_dai_driver s3c_pcm_dai[] = {
390 S3C_PCM_DECLARE(0), 383 S3C_PCM_DAI_DECLARE,
391 S3C_PCM_DECLARE(1), 384 S3C_PCM_DAI_DECLARE,
392}; 385};
393EXPORT_SYMBOL_GPL(s3c_pcm_dai); 386EXPORT_SYMBOL_GPL(s3c_pcm_dai);
394 387
395static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) 388static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
396{ 389{
397 struct s3c_pcm_info *pcm; 390 struct s3c_pcm_info *pcm;
398 struct snd_soc_dai *dai;
399 struct resource *mem_res, *dmatx_res, *dmarx_res; 391 struct resource *mem_res, *dmatx_res, *dmarx_res;
400 struct s3c_audio_pdata *pcm_pdata; 392 struct s3c_audio_pdata *pcm_pdata;
401 int ret; 393 int ret;
@@ -437,9 +429,6 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
437 429
438 spin_lock_init(&pcm->lock); 430 spin_lock_init(&pcm->lock);
439 431
440 dai = &s3c_pcm_dai[pdev->id];
441 dai->dev = &pdev->dev;
442
443 /* Default is 128fs */ 432 /* Default is 128fs */
444 pcm->sclk_per_fs = 128; 433 pcm->sclk_per_fs = 128;
445 434
@@ -452,7 +441,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
452 clk_enable(pcm->cclk); 441 clk_enable(pcm->cclk);
453 442
454 /* record our pcm structure for later use in the callbacks */ 443 /* record our pcm structure for later use in the callbacks */
455 dai->private_data = pcm; 444 dev_set_drvdata(&pdev->dev, pcm);
456 445
457 if (!request_mem_region(mem_res->start, 446 if (!request_mem_region(mem_res->start,
458 resource_size(mem_res), "samsung-pcm")) { 447 resource_size(mem_res), "samsung-pcm")) {
@@ -476,7 +465,7 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
476 } 465 }
477 clk_enable(pcm->pclk); 466 clk_enable(pcm->pclk);
478 467
479 ret = snd_soc_register_dai(dai); 468 ret = snd_soc_register_dai(&pdev->dev, s3c_pcm_dai);
480 if (ret != 0) { 469 if (ret != 0) {
481 dev_err(&pdev->dev, "failed to get pcm_clock\n"); 470 dev_err(&pdev->dev, "failed to get pcm_clock\n");
482 goto err5; 471 goto err5;
@@ -514,6 +503,8 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev)
514 struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; 503 struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id];
515 struct resource *mem_res; 504 struct resource *mem_res;
516 505
506 snd_soc_unregister_dai(&pdev->dev);
507
517 iounmap(pcm->regs); 508 iounmap(pcm->regs);
518 509
519 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 510 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -531,7 +522,7 @@ static struct platform_driver s3c_pcm_driver = {
531 .probe = s3c_pcm_dev_probe, 522 .probe = s3c_pcm_dev_probe,
532 .remove = s3c_pcm_dev_remove, 523 .remove = s3c_pcm_dev_remove,
533 .driver = { 524 .driver = {
534 .name = "samsung-pcm", 525 .name = "samsung-pcm-audio",
535 .owner = THIS_MODULE, 526 .owner = THIS_MODULE,
536 }, 527 },
537}; 528};
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index 709adef9d04..acd00962ac3 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -65,26 +65,20 @@ static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
65 65
66static struct s3c_i2sv2_info s3c2412_i2s; 66static struct s3c_i2sv2_info s3c2412_i2s;
67 67
68static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) 68static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
69{
70 return cpu_dai->private_data;
71}
72
73static int s3c2412_i2s_probe(struct platform_device *pdev,
74 struct snd_soc_dai *dai)
75{ 69{
76 int ret; 70 int ret;
77 71
78 pr_debug("Entered %s\n", __func__); 72 pr_debug("Entered %s\n", __func__);
79 73
80 ret = s3c_i2sv2_probe(pdev, dai, &s3c2412_i2s, S3C2410_PA_IIS); 74 ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS);
81 if (ret) 75 if (ret)
82 return ret; 76 return ret;
83 77
84 s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in; 78 s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in;
85 s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; 79 s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
86 80
87 s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk"); 81 s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk");
88 if (s3c2412_i2s.iis_cclk == NULL) { 82 if (s3c2412_i2s.iis_cclk == NULL) {
89 pr_err("failed to get i2sclk clock\n"); 83 pr_err("failed to get i2sclk clock\n");
90 iounmap(s3c2412_i2s.regs); 84 iounmap(s3c2412_i2s.regs);
@@ -108,11 +102,20 @@ static int s3c2412_i2s_probe(struct platform_device *pdev,
108 return 0; 102 return 0;
109} 103}
110 104
105static int s3c2412_i2s_remove(struct snd_soc_dai *dai)
106{
107 clk_disable(s3c2412_i2s.iis_cclk);
108 clk_put(s3c2412_i2s.iis_cclk);
109 iounmap(s3c2412_i2s.regs);
110
111 return 0;
112}
113
111static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, 114static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
112 struct snd_pcm_hw_params *params, 115 struct snd_pcm_hw_params *params,
113 struct snd_soc_dai *cpu_dai) 116 struct snd_soc_dai *cpu_dai)
114{ 117{
115 struct s3c_i2sv2_info *i2s = to_info(cpu_dai); 118 struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
116 struct s3c_dma_params *dma_data; 119 struct s3c_dma_params *dma_data;
117 u32 iismod; 120 u32 iismod;
118 121
@@ -152,10 +155,9 @@ static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = {
152 .hw_params = s3c2412_i2s_hw_params, 155 .hw_params = s3c2412_i2s_hw_params,
153}; 156};
154 157
155struct snd_soc_dai s3c2412_i2s_dai = { 158static struct snd_soc_dai_driver s3c2412_i2s_dai = {
156 .name = "s3c2412-i2s",
157 .id = 0,
158 .probe = s3c2412_i2s_probe, 159 .probe = s3c2412_i2s_probe,
160 .remove = s3c2412_i2s_remove,
159 .playback = { 161 .playback = {
160 .channels_min = 2, 162 .channels_min = 2,
161 .channels_max = 2, 163 .channels_max = 2,
@@ -170,17 +172,36 @@ struct snd_soc_dai s3c2412_i2s_dai = {
170 }, 172 },
171 .ops = &s3c2412_i2s_dai_ops, 173 .ops = &s3c2412_i2s_dai_ops,
172}; 174};
173EXPORT_SYMBOL_GPL(s3c2412_i2s_dai); 175
176static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev)
177{
178 return snd_soc_register_dai(&pdev->dev, &s3c2412_i2s_dai);
179}
180
181static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev)
182{
183 snd_soc_unregister_dai(&pdev->dev);
184 return 0;
185}
186
187static struct platform_driver s3c2412_iis_driver = {
188 .probe = s3c2412_iis_dev_probe,
189 .remove = s3c2412_iis_dev_remove,
190 .driver = {
191 .name = "s3c2412-iis",
192 .owner = THIS_MODULE,
193 },
194};
174 195
175static int __init s3c2412_i2s_init(void) 196static int __init s3c2412_i2s_init(void)
176{ 197{
177 return s3c_i2sv2_register_dai(&s3c2412_i2s_dai); 198 return platform_driver_register(&s3c2412_iis_driver);
178} 199}
179module_init(s3c2412_i2s_init); 200module_init(s3c2412_i2s_init);
180 201
181static void __exit s3c2412_i2s_exit(void) 202static void __exit s3c2412_i2s_exit(void)
182{ 203{
183 snd_soc_unregister_dai(&s3c2412_i2s_dai); 204 platform_driver_unregister(&s3c2412_iis_driver);
184} 205}
185module_exit(s3c2412_i2s_exit); 206module_exit(s3c2412_i2s_exit);
186 207
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/s3c24xx/s3c2412-i2s.h
index 0b5686b4d5c..01a0471ac65 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.h
+++ b/sound/soc/s3c24xx/s3c2412-i2s.h
@@ -24,6 +24,4 @@
24#define S3C2412_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK 24#define S3C2412_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK
25#define S3C2412_CLKSRC_I2SCLK S3C_I2SV2_CLKSRC_AUDIOBUS 25#define S3C2412_CLKSRC_I2SCLK S3C_I2SV2_CLKSRC_AUDIOBUS
26 26
27extern struct snd_soc_dai s3c2412_i2s_dai;
28
29#endif /* __SND_SOC_S3C24XX_S3C2412_I2S_H */ 27#endif /* __SND_SOC_S3C24XX_S3C2412_I2S_H */
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index c3ac890a398..1d0bade10d3 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -252,7 +252,7 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
252 else 252 else
253 dma_data = &s3c24xx_i2s_pcm_stereo_in; 253 dma_data = &s3c24xx_i2s_pcm_stereo_in;
254 254
255 snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_data); 255 snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);
256 256
257 /* Working copies of register */ 257 /* Working copies of register */
258 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); 258 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -280,9 +280,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
280 struct snd_soc_dai *dai) 280 struct snd_soc_dai *dai)
281{ 281{
282 int ret = 0; 282 int ret = 0;
283 struct snd_soc_pcm_runtime *rtd = substream->private_data;
284 struct s3c_dma_params *dma_data = 283 struct s3c_dma_params *dma_data =
285 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); 284 snd_soc_dai_get_dma_data(dai, substream);
286 285
287 pr_debug("Entered %s\n", __func__); 286 pr_debug("Entered %s\n", __func__);
288 287
@@ -387,8 +386,7 @@ u32 s3c24xx_i2s_get_clockrate(void)
387} 386}
388EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); 387EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate);
389 388
390static int s3c24xx_i2s_probe(struct platform_device *pdev, 389static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
391 struct snd_soc_dai *dai)
392{ 390{
393 pr_debug("Entered %s\n", __func__); 391 pr_debug("Entered %s\n", __func__);
394 392
@@ -396,7 +394,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev,
396 if (s3c24xx_i2s.regs == NULL) 394 if (s3c24xx_i2s.regs == NULL)
397 return -ENXIO; 395 return -ENXIO;
398 396
399 s3c24xx_i2s.iis_clk = clk_get(&pdev->dev, "iis"); 397 s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis");
400 if (s3c24xx_i2s.iis_clk == NULL) { 398 if (s3c24xx_i2s.iis_clk == NULL) {
401 pr_err("failed to get iis_clock\n"); 399 pr_err("failed to get iis_clock\n");
402 iounmap(s3c24xx_i2s.regs); 400 iounmap(s3c24xx_i2s.regs);
@@ -465,9 +463,7 @@ static struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = {
465 .set_sysclk = s3c24xx_i2s_set_sysclk, 463 .set_sysclk = s3c24xx_i2s_set_sysclk,
466}; 464};
467 465
468struct snd_soc_dai s3c24xx_i2s_dai = { 466static struct snd_soc_dai_driver s3c24xx_i2s_dai = {
469 .name = "s3c24xx-i2s",
470 .id = 0,
471 .probe = s3c24xx_i2s_probe, 467 .probe = s3c24xx_i2s_probe,
472 .suspend = s3c24xx_i2s_suspend, 468 .suspend = s3c24xx_i2s_suspend,
473 .resume = s3c24xx_i2s_resume, 469 .resume = s3c24xx_i2s_resume,
@@ -483,17 +479,36 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
483 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, 479 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
484 .ops = &s3c24xx_i2s_dai_ops, 480 .ops = &s3c24xx_i2s_dai_ops,
485}; 481};
486EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai); 482
483static __devinit int s3c24xx_iis_dev_probe(struct platform_device *pdev)
484{
485 return snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai);
486}
487
488static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev)
489{
490 snd_soc_unregister_dai(&pdev->dev);
491 return 0;
492}
493
494static struct platform_driver s3c24xx_iis_driver = {
495 .probe = s3c24xx_iis_dev_probe,
496 .remove = s3c24xx_iis_dev_remove,
497 .driver = {
498 .name = "s3c24xx-iis",
499 .owner = THIS_MODULE,
500 },
501};
487 502
488static int __init s3c24xx_i2s_init(void) 503static int __init s3c24xx_i2s_init(void)
489{ 504{
490 return snd_soc_register_dai(&s3c24xx_i2s_dai); 505 return platform_driver_register(&s3c24xx_iis_driver);
491} 506}
492module_init(s3c24xx_i2s_init); 507module_init(s3c24xx_i2s_init);
493 508
494static void __exit s3c24xx_i2s_exit(void) 509static void __exit s3c24xx_i2s_exit(void)
495{ 510{
496 snd_soc_unregister_dai(&s3c24xx_i2s_dai); 511 platform_driver_unregister(&s3c24xx_iis_driver);
497} 512}
498module_exit(s3c24xx_i2s_exit); 513module_exit(s3c24xx_i2s_exit);
499 514
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/s3c24xx/s3c24xx-i2s.h
index 726d91cf4e1..f9ca04edacb 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.h
@@ -32,6 +32,4 @@
32 32
33u32 s3c24xx_i2s_get_clockrate(void); 33u32 s3c24xx_i2s_get_clockrate(void);
34 34
35extern struct snd_soc_dai s3c24xx_i2s_dai;
36
37#endif /*S3C24XXI2S_H_*/ 35#endif /*S3C24XXI2S_H_*/
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c
index 4984754f329..c4c11144201 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.c
+++ b/sound/soc/s3c24xx/s3c24xx_simtec.c
@@ -139,8 +139,10 @@ static const struct snd_kcontrol_new amp_unmute_controls[] = {
139 speaker_unmute_get, speaker_unmute_put), 139 speaker_unmute_get, speaker_unmute_put),
140}; 140};
141 141
142void simtec_audio_init(struct snd_soc_codec *codec) 142void simtec_audio_init(struct snd_soc_pcm_runtime *rtd)
143{ 143{
144 struct snd_soc_codec *codec = rtd->codec;
145
144 if (pdata->amp_gpio > 0) { 146 if (pdata->amp_gpio > 0) {
145 pr_debug("%s: adding amp routes\n", __func__); 147 pr_debug("%s: adding amp routes\n", __func__);
146 148
@@ -170,8 +172,8 @@ static int simtec_hw_params(struct snd_pcm_substream *substream,
170 struct snd_pcm_hw_params *params) 172 struct snd_pcm_hw_params *params)
171{ 173{
172 struct snd_soc_pcm_runtime *rtd = substream->private_data; 174 struct snd_soc_pcm_runtime *rtd = substream->private_data;
173 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 175 struct snd_soc_dai *codec_dai = rtd->codec_dai;
174 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 176 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
175 int ret; 177 int ret;
176 178
177 /* Set the CODEC as the bus clock master, I2S */ 179 /* Set the CODEC as the bus clock master, I2S */
@@ -319,12 +321,12 @@ EXPORT_SYMBOL_GPL(simtec_audio_pmops);
319#endif 321#endif
320 322
321int __devinit simtec_audio_core_probe(struct platform_device *pdev, 323int __devinit simtec_audio_core_probe(struct platform_device *pdev,
322 struct snd_soc_device *socdev) 324 struct snd_soc_card *card)
323{ 325{
324 struct platform_device *snd_dev; 326 struct platform_device *snd_dev;
325 int ret; 327 int ret;
326 328
327 socdev->card->dai_link->ops = &simtec_snd_ops; 329 card->dai_link->ops = &simtec_snd_ops;
328 330
329 pdata = pdev->dev.platform_data; 331 pdata = pdev->dev.platform_data;
330 if (!pdata) { 332 if (!pdata) {
@@ -353,8 +355,7 @@ int __devinit simtec_audio_core_probe(struct platform_device *pdev,
353 goto err_gpio; 355 goto err_gpio;
354 } 356 }
355 357
356 platform_set_drvdata(snd_dev, socdev); 358 platform_set_drvdata(snd_dev, card);
357 socdev->dev = &snd_dev->dev;
358 359
359 ret = platform_device_add(snd_dev); 360 ret = platform_device_add(snd_dev);
360 if (ret) { 361 if (ret) {
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/s3c24xx/s3c24xx_simtec.h
index e18faee30cc..e63d5ff9c41 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.h
+++ b/sound/soc/s3c24xx/s3c24xx_simtec.h
@@ -7,10 +7,10 @@
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8*/ 8*/
9 9
10extern void simtec_audio_init(struct snd_soc_codec *codec); 10extern void simtec_audio_init(struct snd_soc_pcm_runtime *rtd);
11 11
12extern int simtec_audio_core_probe(struct platform_device *pdev, 12extern int simtec_audio_core_probe(struct platform_device *pdev,
13 struct snd_soc_device *socdev); 13 struct snd_soc_card *card);
14 14
15extern int simtec_audio_remove(struct platform_device *pdev); 15extern int simtec_audio_remove(struct platform_device *pdev);
16 16
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
index bdf8951af8e..f88453735ae 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
+++ b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
@@ -73,8 +73,10 @@ static const struct snd_soc_dapm_route base_map[] = {
73 * Attach our controls and configure the necessary codec 73 * Attach our controls and configure the necessary codec
74 * mappings for our sound card instance. 74 * mappings for our sound card instance.
75*/ 75*/
76static int simtec_hermes_init(struct snd_soc_codec *codec) 76static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd)
77{ 77{
78 struct snd_soc_codec *codec = rtd->codec;
79
78 snd_soc_dapm_new_controls(codec, dapm_widgets, 80 snd_soc_dapm_new_controls(codec, dapm_widgets,
79 ARRAY_SIZE(dapm_widgets)); 81 ARRAY_SIZE(dapm_widgets));
80 82
@@ -85,42 +87,33 @@ static int simtec_hermes_init(struct snd_soc_codec *codec)
85 snd_soc_dapm_enable_pin(codec, "Line Out"); 87 snd_soc_dapm_enable_pin(codec, "Line Out");
86 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 88 snd_soc_dapm_enable_pin(codec, "Mic Jack");
87 89
88 simtec_audio_init(codec); 90 simtec_audio_init(rtd);
89 snd_soc_dapm_sync(codec); 91 snd_soc_dapm_sync(codec);
90 92
91 return 0; 93 return 0;
92} 94}
93 95
94static struct aic3x_setup_data codec_setup = {
95};
96
97static struct snd_soc_dai_link simtec_dai_aic33 = { 96static struct snd_soc_dai_link simtec_dai_aic33 = {
98 .name = "tlv320aic33", 97 .name = "tlv320aic33",
99 .stream_name = "TLV320AIC33", 98 .stream_name = "TLV320AIC33",
100 .cpu_dai = &s3c24xx_i2s_dai, 99 .codec_name = "tlv320aic3x-codec.0-0x1a",
101 .codec_dai = &aic3x_dai, 100 .cpu_dai_name = "s3c24xx-i2s",
101 .codec_dai_name = "tlv320aic3x-hifi",
102 .platform_name = "s3c24xx-pcm-audio",
102 .init = simtec_hermes_init, 103 .init = simtec_hermes_init,
103}; 104};
104 105
105/* simtec audio machine driver */ 106/* simtec audio machine driver */
106static struct snd_soc_card snd_soc_machine_simtec_aic33 = { 107static struct snd_soc_card snd_soc_machine_simtec_aic33 = {
107 .name = "Simtec-Hermes", 108 .name = "Simtec-Hermes",
108 .platform = &s3c24xx_soc_platform,
109 .dai_link = &simtec_dai_aic33, 109 .dai_link = &simtec_dai_aic33,
110 .num_links = 1, 110 .num_links = 1,
111}; 111};
112 112
113/* simtec audio subsystem */
114static struct snd_soc_device simtec_snd_devdata_aic33 = {
115 .card = &snd_soc_machine_simtec_aic33,
116 .codec_dev = &soc_codec_dev_aic3x,
117 .codec_data = &codec_setup,
118};
119
120static int __devinit simtec_audio_hermes_probe(struct platform_device *pd) 113static int __devinit simtec_audio_hermes_probe(struct platform_device *pd)
121{ 114{
122 dev_info(&pd->dev, "probing....\n"); 115 dev_info(&pd->dev, "probing....\n");
123 return simtec_audio_core_probe(pd, &simtec_snd_devdata_aic33); 116 return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic33);
124} 117}
125 118
126static struct platform_driver simtec_audio_hermes_platdrv = { 119static struct platform_driver simtec_audio_hermes_platdrv = {
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
index 185c0acb5ce..c0967593510 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
@@ -62,8 +62,10 @@ static const struct snd_soc_dapm_route base_map[] = {
62 * Attach our controls and configure the necessary codec 62 * Attach our controls and configure the necessary codec
63 * mappings for our sound card instance. 63 * mappings for our sound card instance.
64*/ 64*/
65static int simtec_tlv320aic23_init(struct snd_soc_codec *codec) 65static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
66{ 66{
67 struct snd_soc_codec *codec = rtd->codec;
68
67 snd_soc_dapm_new_controls(codec, dapm_widgets, 69 snd_soc_dapm_new_controls(codec, dapm_widgets,
68 ARRAY_SIZE(dapm_widgets)); 70 ARRAY_SIZE(dapm_widgets));
69 71
@@ -74,7 +76,7 @@ static int simtec_tlv320aic23_init(struct snd_soc_codec *codec)
74 snd_soc_dapm_enable_pin(codec, "Line Out"); 76 snd_soc_dapm_enable_pin(codec, "Line Out");
75 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 77 snd_soc_dapm_enable_pin(codec, "Mic Jack");
76 78
77 simtec_audio_init(codec); 79 simtec_audio_init(rtd);
78 snd_soc_dapm_sync(codec); 80 snd_soc_dapm_sync(codec);
79 81
80 return 0; 82 return 0;
@@ -83,28 +85,23 @@ static int simtec_tlv320aic23_init(struct snd_soc_codec *codec)
83static struct snd_soc_dai_link simtec_dai_aic23 = { 85static struct snd_soc_dai_link simtec_dai_aic23 = {
84 .name = "tlv320aic23", 86 .name = "tlv320aic23",
85 .stream_name = "TLV320AIC23", 87 .stream_name = "TLV320AIC23",
86 .cpu_dai = &s3c24xx_i2s_dai, 88 .codec_name = "tlv320aic3x-codec.0-0x1a",
87 .codec_dai = &tlv320aic23_dai, 89 .cpu_dai_name = "s3c24xx-i2s",
90 .codec_dai_name = "tlv320aic3x-hifi",
91 .platform_name = "s3c24xx-pcm-audio",
88 .init = simtec_tlv320aic23_init, 92 .init = simtec_tlv320aic23_init,
89}; 93};
90 94
91/* simtec audio machine driver */ 95/* simtec audio machine driver */
92static struct snd_soc_card snd_soc_machine_simtec_aic23 = { 96static struct snd_soc_card snd_soc_machine_simtec_aic23 = {
93 .name = "Simtec", 97 .name = "Simtec",
94 .platform = &s3c24xx_soc_platform,
95 .dai_link = &simtec_dai_aic23, 98 .dai_link = &simtec_dai_aic23,
96 .num_links = 1, 99 .num_links = 1,
97}; 100};
98 101
99/* simtec audio subsystem */
100static struct snd_soc_device simtec_snd_devdata_aic23 = {
101 .card = &snd_soc_machine_simtec_aic23,
102 .codec_dev = &soc_codec_dev_tlv320aic23,
103};
104
105static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd) 102static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd)
106{ 103{
107 return simtec_audio_core_probe(pd, &simtec_snd_devdata_aic23); 104 return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic23);
108} 105}
109 106
110static struct platform_driver simtec_audio_tlv320aic23_platdrv = { 107static struct platform_driver simtec_audio_tlv320aic23_platdrv = {
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c
index 052d59659c2..bd48ffbde88 100644
--- a/sound/soc/s3c24xx/s3c24xx_uda134x.c
+++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c
@@ -133,8 +133,8 @@ static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
133 struct snd_pcm_hw_params *params) 133 struct snd_pcm_hw_params *params)
134{ 134{
135 struct snd_soc_pcm_runtime *rtd = substream->private_data; 135 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 136 struct snd_soc_dai *codec_dai = rtd->codec_dai;
137 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 137 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
138 unsigned int clk = 0; 138 unsigned int clk = 0;
139 int ret = 0; 139 int ret = 0;
140 int clk_source, fs_mode; 140 int clk_source, fs_mode;
@@ -227,14 +227,15 @@ static struct snd_soc_ops s3c24xx_uda134x_ops = {
227static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { 227static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
228 .name = "UDA134X", 228 .name = "UDA134X",
229 .stream_name = "UDA134X", 229 .stream_name = "UDA134X",
230 .codec_dai = &uda134x_dai, 230 .codec_name = "uda134x-hifi",
231 .cpu_dai = &s3c24xx_i2s_dai, 231 .codec_dai_name = "uda134x-hifi",
232 .cpu_dai_name = "s3c24xx-i2s",
232 .ops = &s3c24xx_uda134x_ops, 233 .ops = &s3c24xx_uda134x_ops,
234 .platform_name = "s3c24xx-pcm-audio",
233}; 235};
234 236
235static struct snd_soc_card snd_soc_s3c24xx_uda134x = { 237static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
236 .name = "S3C24XX_UDA134X", 238 .name = "S3C24XX_UDA134X",
237 .platform = &s3c24xx_soc_platform,
238 .dai_link = &s3c24xx_uda134x_dai_link, 239 .dai_link = &s3c24xx_uda134x_dai_link,
239 .num_links = 1, 240 .num_links = 1,
240}; 241};
@@ -256,6 +257,7 @@ static void setmode(int v)
256 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0); 257 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);
257} 258}
258 259
260/* FIXME - This must be codec platform data but in which board file ?? */
259static struct uda134x_platform_data s3c24xx_uda134x = { 261static struct uda134x_platform_data s3c24xx_uda134x = {
260 .l3 = { 262 .l3 = {
261 .setdat = setdat, 263 .setdat = setdat,
@@ -270,12 +272,6 @@ static struct uda134x_platform_data s3c24xx_uda134x = {
270 }, 272 },
271}; 273};
272 274
273static struct snd_soc_device s3c24xx_uda134x_snd_devdata = {
274 .card = &snd_soc_s3c24xx_uda134x,
275 .codec_dev = &soc_codec_dev_uda134x,
276 .codec_data = &s3c24xx_uda134x,
277};
278
279static int s3c24xx_uda134x_setup_pin(int pin, char *fun) 275static int s3c24xx_uda134x_setup_pin(int pin, char *fun)
280{ 276{
281 if (gpio_request(pin, "s3c24xx_uda134x") < 0) { 277 if (gpio_request(pin, "s3c24xx_uda134x") < 0) {
@@ -325,8 +321,7 @@ static int s3c24xx_uda134x_probe(struct platform_device *pdev)
325 } 321 }
326 322
327 platform_set_drvdata(s3c24xx_uda134x_snd_device, 323 platform_set_drvdata(s3c24xx_uda134x_snd_device,
328 &s3c24xx_uda134x_snd_devdata); 324 &snd_soc_s3c24xx_uda134x);
329 s3c24xx_uda134x_snd_devdata.dev = &s3c24xx_uda134x_snd_device->dev;
330 ret = platform_device_add(s3c24xx_uda134x_snd_device); 325 ret = platform_device_add(s3c24xx_uda134x_snd_device);
331 if (ret) { 326 if (ret) {
332 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n"); 327 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
index 06db130030a..7cab4fcf1f1 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
@@ -16,9 +16,7 @@
16#include <sound/soc.h> 16#include <sound/soc.h>
17#include <sound/pcm_params.h> 17#include <sound/pcm_params.h>
18 18
19#include <mach/gpio-bank-c.h> 19#include <plat/audio.h>
20#include <mach/gpio-bank-h.h>
21#include <plat/gpio-cfg.h>
22 20
23#include <mach/map.h> 21#include <mach/map.h>
24#include <mach/dma.h> 22#include <mach/dma.h>
@@ -39,34 +37,23 @@ static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_out;
39static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_in; 37static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_in;
40static struct s3c_i2sv2_info s3c64xx_i2sv4; 38static struct s3c_i2sv2_info s3c64xx_i2sv4;
41 39
42struct snd_soc_dai s3c64xx_i2s_v4_dai; 40static int s3c64xx_i2sv4_probe(struct snd_soc_dai *dai)
43EXPORT_SYMBOL_GPL(s3c64xx_i2s_v4_dai);
44
45static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
46{ 41{
47 return cpu_dai->private_data; 42 struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4;
48} 43 int ret = 0;
49 44
50static int s3c64xx_i2sv4_probe(struct platform_device *pdev, 45 snd_soc_dai_set_drvdata(dai, i2s);
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 46
62 return 0; 47 ret = s3c_i2sv2_probe(dai, i2s, i2s->base);
48
49 return ret;
63} 50}
64 51
65static int s3c_i2sv4_hw_params(struct snd_pcm_substream *substream, 52static int s3c_i2sv4_hw_params(struct snd_pcm_substream *substream,
66 struct snd_pcm_hw_params *params, 53 struct snd_pcm_hw_params *params,
67 struct snd_soc_dai *cpu_dai) 54 struct snd_soc_dai *cpu_dai)
68{ 55{
69 struct s3c_i2sv2_info *i2s = to_info(cpu_dai); 56 struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
70 struct s3c_dma_params *dma_data; 57 struct s3c_dma_params *dma_data;
71 u32 iismod; 58 u32 iismod;
72 59
@@ -104,51 +91,79 @@ static struct snd_soc_dai_ops s3c64xx_i2sv4_dai_ops = {
104 .hw_params = s3c_i2sv4_hw_params, 91 .hw_params = s3c_i2sv4_hw_params,
105}; 92};
106 93
94static struct snd_soc_dai_driver s3c64xx_i2s_v4_dai = {
95 .symmetric_rates = 1,
96 .playback = {
97 .channels_min = 2,
98 .channels_max = 2,
99 .rates = S3C64XX_I2S_RATES,
100 .formats = S3C64XX_I2S_FMTS,
101 },
102 .capture = {
103 .channels_min = 2,
104 .channels_max = 2,
105 .rates = S3C64XX_I2S_RATES,
106 .formats = S3C64XX_I2S_FMTS,
107 },
108 .probe = s3c64xx_i2sv4_probe,
109 .ops = &s3c64xx_i2sv4_dai_ops,
110};
111
107static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev) 112static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev)
108{ 113{
114 struct s3c_audio_pdata *i2s_pdata;
109 struct s3c_i2sv2_info *i2s; 115 struct s3c_i2sv2_info *i2s;
110 struct snd_soc_dai *dai; 116 struct resource *res;
111 int ret; 117 int ret;
112 118
113 i2s = &s3c64xx_i2sv4; 119 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 120
137 i2s->feature |= S3C_FEATURE_CDCLKCON; 121 i2s->feature |= S3C_FEATURE_CDCLKCON;
138 122
139 i2s->dma_capture = &s3c64xx_i2sv4_pcm_stereo_in; 123 i2s->dma_capture = &s3c64xx_i2sv4_pcm_stereo_in;
140 i2s->dma_playback = &s3c64xx_i2sv4_pcm_stereo_out; 124 i2s->dma_playback = &s3c64xx_i2sv4_pcm_stereo_out;
141 125
142 i2s->dma_capture->channel = DMACH_HSI_I2SV40_RX; 126 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
143 i2s->dma_capture->dma_addr = S3C64XX_PA_IISV4 + S3C2412_IISRXD; 127 if (!res) {
144 i2s->dma_playback->channel = DMACH_HSI_I2SV40_TX; 128 dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
145 i2s->dma_playback->dma_addr = S3C64XX_PA_IISV4 + S3C2412_IISTXD; 129 return -ENXIO;
130 }
131 i2s->dma_playback->channel = res->start;
132
133 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
134 if (!res) {
135 dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
136 return -ENXIO;
137 }
138 i2s->dma_capture->channel = res->start;
139
140 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
141 if (!res) {
142 dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
143 return -ENXIO;
144 }
145
146 if (!request_mem_region(res->start, resource_size(res),
147 "s3c64xx-i2s-v4")) {
148 dev_err(&pdev->dev, "Unable to request SFR region\n");
149 return -EBUSY;
150 }
151 i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD;
152 i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD;
146 153
147 i2s->dma_capture->client = &s3c64xx_dma_client_in; 154 i2s->dma_capture->client = &s3c64xx_dma_client_in;
148 i2s->dma_capture->dma_size = 4; 155 i2s->dma_capture->dma_size = 4;
149 i2s->dma_playback->client = &s3c64xx_dma_client_out; 156 i2s->dma_playback->client = &s3c64xx_dma_client_out;
150 i2s->dma_playback->dma_size = 4; 157 i2s->dma_playback->dma_size = 4;
151 158
159 i2s->base = res->start;
160
161 i2s_pdata = pdev->dev.platform_data;
162 if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
163 dev_err(&pdev->dev, "Unable to configure gpio\n");
164 return -EINVAL;
165 }
166
152 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); 167 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
153 if (IS_ERR(i2s->iis_cclk)) { 168 if (IS_ERR(i2s->iis_cclk)) {
154 dev_err(&pdev->dev, "failed to get audio-bus\n"); 169 dev_err(&pdev->dev, "failed to get audio-bus\n");
@@ -158,19 +173,13 @@ static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev)
158 173
159 clk_enable(i2s->iis_cclk); 174 clk_enable(i2s->iis_cclk);
160 175
161 ret = s3c_i2sv2_probe(pdev, dai, i2s, 0); 176 ret = s3c_i2sv2_register_dai(&pdev->dev, pdev->id, &s3c64xx_i2s_v4_dai);
162 if (ret)
163 goto err_clk;
164
165 ret = s3c_i2sv2_register_dai(dai);
166 if (ret != 0) 177 if (ret != 0)
167 goto err_i2sv2; 178 goto err_i2sv2;
168 179
169 return 0; 180 return 0;
170 181
171err_i2sv2: 182err_i2sv2:
172 /* Not implemented for I2Sv2 core yet */
173err_clk:
174 clk_put(i2s->iis_cclk); 183 clk_put(i2s->iis_cclk);
175err: 184err:
176 return ret; 185 return ret;
@@ -178,7 +187,7 @@ err:
178 187
179static __devexit int s3c64xx_i2sv4_dev_remove(struct platform_device *pdev) 188static __devexit int s3c64xx_i2sv4_dev_remove(struct platform_device *pdev)
180{ 189{
181 dev_err(&pdev->dev, "Device removal not yet supported\n"); 190 snd_soc_unregister_dai(&pdev->dev);
182 return 0; 191 return 0;
183} 192}
184 193
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index 1d85cb85a7d..a1d0b256641 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -12,15 +12,15 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/module.h>
15#include <linux/clk.h> 16#include <linux/clk.h>
16#include <linux/gpio.h> 17#include <linux/gpio.h>
17#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/slab.h>
18 20
19#include <sound/soc.h> 21#include <sound/soc.h>
20 22
21#include <mach/gpio-bank-d.h> 23#include <plat/audio.h>
22#include <mach/gpio-bank-e.h>
23#include <plat/gpio-cfg.h>
24 24
25#include <mach/map.h> 25#include <mach/map.h>
26#include <mach/dma.h> 26#include <mach/dma.h>
@@ -46,45 +46,107 @@ static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3];
46static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3]; 46static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3];
47static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3]; 47static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3];
48 48
49struct snd_soc_dai s3c64xx_i2s_dai[MAX_I2SV3]; 49struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
50EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
51
52static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
53{ 50{
54 return cpu_dai->private_data; 51 struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai);
52 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
53
54 if (iismod & S3C2412_IISMOD_IMS_SYSMUX)
55 return i2s->iis_cclk;
56 else
57 return i2s->iis_pclk;
55} 58}
59EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
56 60
57static int s3c64xx_i2s_probe(struct platform_device *pdev, 61static int s3c64xx_i2s_probe(struct snd_soc_dai *dai)
58 struct snd_soc_dai *dai)
59{ 62{
60 /* configure GPIO for i2s port */ 63 struct s3c_i2sv2_info *i2s;
61 switch (dai->id) { 64 int ret;
62 case 0: 65
63 s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); 66 if (dai->id >= MAX_I2SV3) {
64 s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK); 67 dev_err(dai->dev, "id %d out of range\n", dai->id);
65 s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK); 68 return -EINVAL;
66 s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI); 69 }
67 s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0); 70
68 break; 71 i2s = &s3c64xx_i2s[dai->id];
69 case 1: 72 snd_soc_dai_set_drvdata(dai, i2s);
70 s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK); 73
71 s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK); 74 i2s->iis_cclk = clk_get(dai->dev, "audio-bus");
72 s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK); 75 if (IS_ERR(i2s->iis_cclk)) {
73 s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI); 76 dev_err(dai->dev, "failed to get audio-bus\n");
74 s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0); 77 ret = PTR_ERR(i2s->iis_cclk);
78 goto err;
75 } 79 }
76 80
81 clk_enable(i2s->iis_cclk);
82
83 ret = s3c_i2sv2_probe(dai, i2s, i2s->base);
84 if (ret)
85 goto err_clk;
86
77 return 0; 87 return 0;
88
89err_clk:
90 clk_disable(i2s->iis_cclk);
91 clk_put(i2s->iis_cclk);
92err:
93 kfree(i2s);
94 return ret;
78} 95}
79 96
97static int s3c64xx_i2s_remove(struct snd_soc_dai *dai)
98{
99 struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai);
100
101 clk_disable(i2s->iis_cclk);
102 clk_put(i2s->iis_cclk);
103 kfree(i2s);
104 return 0;
105}
80 106
81static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops; 107static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops;
82 108
109static struct snd_soc_dai_driver s3c64xx_i2s_dai[MAX_I2SV3] = {
110{
111 .name = "s3c64xx-i2s-0",
112 .probe = s3c64xx_i2s_probe,
113 .remove = s3c64xx_i2s_remove,
114 .playback = {
115 .channels_min = 2,
116 .channels_max = 2,
117 .rates = S3C64XX_I2S_RATES,
118 .formats = S3C64XX_I2S_FMTS,},
119 .capture = {
120 .channels_min = 2,
121 .channels_max = 2,
122 .rates = S3C64XX_I2S_RATES,
123 .formats = S3C64XX_I2S_FMTS,},
124 .ops = &s3c64xx_i2s_dai_ops,
125 .symmetric_rates = 1,
126}, {
127 .name = "s3c64xx-i2s-1",
128 .probe = s3c64xx_i2s_probe,
129 .remove = s3c64xx_i2s_remove,
130 .playback = {
131 .channels_min = 2,
132 .channels_max = 2,
133 .rates = S3C64XX_I2S_RATES,
134 .formats = S3C64XX_I2S_FMTS,},
135 .capture = {
136 .channels_min = 2,
137 .channels_max = 2,
138 .rates = S3C64XX_I2S_RATES,
139 .formats = S3C64XX_I2S_FMTS,},
140 .ops = &s3c64xx_i2s_dai_ops,
141 .symmetric_rates = 1,
142},};
143
83static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) 144static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
84{ 145{
146 struct s3c_audio_pdata *i2s_pdata;
85 struct s3c_i2sv2_info *i2s; 147 struct s3c_i2sv2_info *i2s;
86 struct snd_soc_dai *dai; 148 struct resource *res;
87 int ret; 149 int i, ret;
88 150
89 if (pdev->id >= MAX_I2SV3) { 151 if (pdev->id >= MAX_I2SV3) {
90 dev_err(&pdev->dev, "id %d out of range\n", pdev->id); 152 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
@@ -92,74 +154,63 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
92 } 154 }
93 155
94 i2s = &s3c64xx_i2s[pdev->id]; 156 i2s = &s3c64xx_i2s[pdev->id];
95 dai = &s3c64xx_i2s_dai[pdev->id];
96 dai->dev = &pdev->dev;
97 dai->name = "s3c64xx-i2s";
98 dai->id = pdev->id;
99 dai->symmetric_rates = 1;
100 dai->playback.channels_min = 2;
101 dai->playback.channels_max = 2;
102 dai->playback.rates = S3C64XX_I2S_RATES;
103 dai->playback.formats = S3C64XX_I2S_FMTS;
104 dai->capture.channels_min = 2;
105 dai->capture.channels_max = 2;
106 dai->capture.rates = S3C64XX_I2S_RATES;
107 dai->capture.formats = S3C64XX_I2S_FMTS;
108 dai->probe = s3c64xx_i2s_probe;
109 dai->ops = &s3c64xx_i2s_dai_ops;
110
111 i2s->feature |= S3C_FEATURE_CDCLKCON;
112 157
113 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; 158 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
114 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; 159 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
115 160
116 if (pdev->id == 0) { 161 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
117 i2s->dma_capture->channel = DMACH_I2S0_IN; 162 if (!res) {
118 i2s->dma_capture->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD; 163 dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
119 i2s->dma_playback->channel = DMACH_I2S0_OUT; 164 return -ENXIO;
120 i2s->dma_playback->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD; 165 }
121 } else { 166 i2s->dma_playback->channel = res->start;
122 i2s->dma_capture->channel = DMACH_I2S1_IN; 167
123 i2s->dma_capture->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD; 168 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
124 i2s->dma_playback->channel = DMACH_I2S1_OUT; 169 if (!res) {
125 i2s->dma_playback->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD; 170 dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
171 return -ENXIO;
172 }
173 i2s->dma_capture->channel = res->start;
174
175 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
176 if (!res) {
177 dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
178 return -ENXIO;
126 } 179 }
127 180
181 if (!request_mem_region(res->start, resource_size(res),
182 "s3c64xx-i2s")) {
183 dev_err(&pdev->dev, "Unable to request SFR region\n");
184 return -EBUSY;
185 }
186 i2s->base = res->start;
187
188 i2s_pdata = pdev->dev.platform_data;
189 if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
190 dev_err(&pdev->dev, "Unable to configure gpio\n");
191 return -EINVAL;
192 }
193 i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD;
194 i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD;
195
128 i2s->dma_capture->client = &s3c64xx_dma_client_in; 196 i2s->dma_capture->client = &s3c64xx_dma_client_in;
129 i2s->dma_capture->dma_size = 4; 197 i2s->dma_capture->dma_size = 4;
130 i2s->dma_playback->client = &s3c64xx_dma_client_out; 198 i2s->dma_playback->client = &s3c64xx_dma_client_out;
131 i2s->dma_playback->dma_size = 4; 199 i2s->dma_playback->dma_size = 4;
132 200
133 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); 201 for (i = 0; i < ARRAY_SIZE(s3c64xx_i2s_dai); i++) {
134 if (IS_ERR(i2s->iis_cclk)) { 202 ret = s3c_i2sv2_register_dai(&pdev->dev, i,
135 dev_err(&pdev->dev, "failed to get audio-bus\n"); 203 &s3c64xx_i2s_dai[i]);
136 ret = PTR_ERR(i2s->iis_cclk); 204 if (ret != 0)
137 goto err; 205 return ret;
138 } 206 }
139 207
140 clk_enable(i2s->iis_cclk);
141
142 ret = s3c_i2sv2_probe(pdev, dai, i2s, 0);
143 if (ret)
144 goto err_clk;
145
146 ret = s3c_i2sv2_register_dai(dai);
147 if (ret != 0)
148 goto err_i2sv2;
149
150 return 0; 208 return 0;
151
152err_i2sv2:
153 /* Not implemented for I2Sv2 core yet */
154err_clk:
155 clk_put(i2s->iis_cclk);
156err:
157 return ret;
158} 209}
159 210
160static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev) 211static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev)
161{ 212{
162 dev_err(&pdev->dev, "Device removal not yet supported\n"); 213 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c64xx_i2s_dai));
163 return 0; 214 return 0;
164} 215}
165 216
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
index 7a40f43d1d5..19bd444bf8a 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.h
@@ -36,7 +36,5 @@ struct clk;
36 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ 36 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
37 SNDRV_PCM_FMTBIT_S24_LE) 37 SNDRV_PCM_FMTBIT_S24_LE)
38 38
39extern struct snd_soc_dai s3c64xx_i2s_dai[];
40extern struct snd_soc_dai s3c64xx_i2s_v4_dai;
41 39
42#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ 40#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */
diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/s3c24xx/smartq_wm8987.c
index b480348140b..dd20ca7f468 100644
--- a/sound/soc/s3c24xx/smartq_wm8987.c
+++ b/sound/soc/s3c24xx/smartq_wm8987.c
@@ -211,8 +211,10 @@ static struct snd_soc_dai_link smartq_dai[] = {
211 { 211 {
212 .name = "wm8987", 212 .name = "wm8987",
213 .stream_name = "SmartQ Hi-Fi", 213 .stream_name = "SmartQ Hi-Fi",
214 .cpu_dai = &s3c64xx_i2s_dai[0], 214 .cpu_dai_name = "s3c64xx-i2s.0",
215 .codec_dai = &wm8750_dai, 215 .codec_dai_name = "wm8750-hifi",
216 .platform_name = "s3c24xx-pcm-audio",
217 .codec_name = "wm8750-codec.0-0x1a",
216 .init = smartq_wm8987_init, 218 .init = smartq_wm8987_init,
217 .ops = &smartq_hifi_ops, 219 .ops = &smartq_hifi_ops,
218 }, 220 },
@@ -220,16 +222,10 @@ static struct snd_soc_dai_link smartq_dai[] = {
220 222
221static struct snd_soc_card snd_soc_smartq = { 223static struct snd_soc_card snd_soc_smartq = {
222 .name = "SmartQ", 224 .name = "SmartQ",
223 .platform = &s3c24xx_soc_platform,
224 .dai_link = smartq_dai, 225 .dai_link = smartq_dai,
225 .num_links = ARRAY_SIZE(smartq_dai), 226 .num_links = ARRAY_SIZE(smartq_dai),
226}; 227};
227 228
228static struct snd_soc_device smartq_snd_devdata = {
229 .card = &snd_soc_smartq,
230 .codec_dev = &soc_codec_dev_wm8750,
231};
232
233static struct platform_device *smartq_snd_device; 229static struct platform_device *smartq_snd_device;
234 230
235static int __init smartq_init(void) 231static int __init smartq_init(void)
@@ -245,8 +241,7 @@ static int __init smartq_init(void)
245 if (!smartq_snd_device) 241 if (!smartq_snd_device)
246 return -ENOMEM; 242 return -ENOMEM;
247 243
248 platform_set_drvdata(smartq_snd_device, &smartq_snd_devdata); 244 platform_set_drvdata(smartq_snd_device, &snd_soc_smartq);
249 smartq_snd_devdata.dev = &smartq_snd_device->dev;
250 245
251 ret = platform_device_add(smartq_snd_device); 246 ret = platform_device_add(smartq_snd_device);
252 if (ret) { 247 if (ret) {
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
index 362258835e8..66f9e222220 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
@@ -19,7 +19,6 @@
19#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/soc-dapm.h> 20#include <sound/soc-dapm.h>
21 21
22#include "../codecs/ac97.h"
23#include "s3c-dma.h" 22#include "s3c-dma.h"
24#include "s3c-ac97.h" 23#include "s3c-ac97.h"
25 24
@@ -29,23 +28,19 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
29{ 28{
30 .name = "AC97", 29 .name = "AC97",
31 .stream_name = "AC97 HiFi", 30 .stream_name = "AC97 HiFi",
32 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM], 31 .cpu_dai_name = "s3c-ac97-dai",
33 .codec_dai = &ac97_dai, 32 .codec_dai_name = "ac97-hifi",
33 .codec_name = "ac97-codec",
34 .platform_name = "s3c24xx-pcm-audio",
34}, 35},
35}; 36};
36 37
37static struct snd_soc_card smdk2443 = { 38static struct snd_soc_card smdk2443 = {
38 .name = "SMDK2443", 39 .name = "SMDK2443",
39 .platform = &s3c24xx_soc_platform,
40 .dai_link = smdk2443_dai, 40 .dai_link = smdk2443_dai,
41 .num_links = ARRAY_SIZE(smdk2443_dai), 41 .num_links = ARRAY_SIZE(smdk2443_dai),
42}; 42};
43 43
44static struct snd_soc_device smdk2443_snd_ac97_devdata = {
45 .card = &smdk2443,
46 .codec_dev = &soc_codec_dev_ac97,
47};
48
49static struct platform_device *smdk2443_snd_ac97_device; 44static struct platform_device *smdk2443_snd_ac97_device;
50 45
51static int __init smdk2443_init(void) 46static int __init smdk2443_init(void)
@@ -56,9 +51,7 @@ static int __init smdk2443_init(void)
56 if (!smdk2443_snd_ac97_device) 51 if (!smdk2443_snd_ac97_device)
57 return -ENOMEM; 52 return -ENOMEM;
58 53
59 platform_set_drvdata(smdk2443_snd_ac97_device, 54 platform_set_drvdata(smdk2443_snd_ac97_device, &smdk2443);
60 &smdk2443_snd_ac97_devdata);
61 smdk2443_snd_ac97_devdata.dev = &smdk2443_snd_ac97_device->dev;
62 ret = platform_device_add(smdk2443_snd_ac97_device); 55 ret = platform_device_add(smdk2443_snd_ac97_device);
63 56
64 if (ret) 57 if (ret)
diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c
index 07e8e51d10d..634acfc4160 100644
--- a/sound/soc/s3c24xx/smdk64xx_wm8580.c
+++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c
@@ -29,8 +29,8 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
29 struct snd_pcm_hw_params *params) 29 struct snd_pcm_hw_params *params)
30{ 30{
31 struct snd_soc_pcm_runtime *rtd = substream->private_data; 31 struct snd_soc_pcm_runtime *rtd = substream->private_data;
32 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 32 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
33 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 33 struct snd_soc_dai *codec_dai = rtd->codec_dai;
34 unsigned int pll_out; 34 unsigned int pll_out;
35 int bfs, rfs, ret; 35 int bfs, rfs, ret;
36 36
@@ -174,8 +174,10 @@ static const struct snd_soc_dapm_route audio_map_rx[] = {
174 {"Rear-L/R", NULL, "VOUT3R"}, 174 {"Rear-L/R", NULL, "VOUT3R"},
175}; 175};
176 176
177static int smdk64xx_wm8580_init_paiftx(struct snd_soc_codec *codec) 177static int smdk64xx_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd)
178{ 178{
179 struct snd_soc_codec *codec = rtd->codec;
180
179 /* Add smdk64xx specific Capture widgets */ 181 /* Add smdk64xx specific Capture widgets */
180 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_cpt, 182 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_cpt,
181 ARRAY_SIZE(wm8580_dapm_widgets_cpt)); 183 ARRAY_SIZE(wm8580_dapm_widgets_cpt));
@@ -194,8 +196,10 @@ static int smdk64xx_wm8580_init_paiftx(struct snd_soc_codec *codec)
194 return 0; 196 return 0;
195} 197}
196 198
197static int smdk64xx_wm8580_init_paifrx(struct snd_soc_codec *codec) 199static int smdk64xx_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd)
198{ 200{
201 struct snd_soc_codec *codec = rtd->codec;
202
199 /* Add smdk64xx specific Playback widgets */ 203 /* Add smdk64xx specific Playback widgets */
200 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_pbk, 204 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_pbk,
201 ARRAY_SIZE(wm8580_dapm_widgets_pbk)); 205 ARRAY_SIZE(wm8580_dapm_widgets_pbk));
@@ -213,16 +217,20 @@ static struct snd_soc_dai_link smdk64xx_dai[] = {
213{ /* Primary Playback i/f */ 217{ /* Primary Playback i/f */
214 .name = "WM8580 PAIF RX", 218 .name = "WM8580 PAIF RX",
215 .stream_name = "Playback", 219 .stream_name = "Playback",
216 .cpu_dai = &s3c64xx_i2s_v4_dai, 220 .cpu_dai_name = "s3c64xx-iis-v4",
217 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFRX], 221 .codec_dai_name = "wm8580-hifi-playback",
222 .platform_name = "s3c24xx-pcm-audio",
223 .codec_name = "wm8580-codec.0-001b",
218 .init = smdk64xx_wm8580_init_paifrx, 224 .init = smdk64xx_wm8580_init_paifrx,
219 .ops = &smdk64xx_ops, 225 .ops = &smdk64xx_ops,
220}, 226},
221{ /* Primary Capture i/f */ 227{ /* Primary Capture i/f */
222 .name = "WM8580 PAIF TX", 228 .name = "WM8580 PAIF TX",
223 .stream_name = "Capture", 229 .stream_name = "Capture",
224 .cpu_dai = &s3c64xx_i2s_v4_dai, 230 .cpu_dai_name = "s3c64xx-iis-v4",
225 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFTX], 231 .codec_dai_name = "wm8580-hifi-capture",
232 .platform_name = "s3c24xx-pcm-audio",
233 .codec_name = "wm8580-codec.0-001b",
226 .init = smdk64xx_wm8580_init_paiftx, 234 .init = smdk64xx_wm8580_init_paiftx,
227 .ops = &smdk64xx_ops, 235 .ops = &smdk64xx_ops,
228}, 236},
@@ -230,16 +238,10 @@ static struct snd_soc_dai_link smdk64xx_dai[] = {
230 238
231static struct snd_soc_card smdk64xx = { 239static struct snd_soc_card smdk64xx = {
232 .name = "smdk64xx", 240 .name = "smdk64xx",
233 .platform = &s3c24xx_soc_platform,
234 .dai_link = smdk64xx_dai, 241 .dai_link = smdk64xx_dai,
235 .num_links = ARRAY_SIZE(smdk64xx_dai), 242 .num_links = ARRAY_SIZE(smdk64xx_dai),
236}; 243};
237 244
238static struct snd_soc_device smdk64xx_snd_devdata = {
239 .card = &smdk64xx,
240 .codec_dev = &soc_codec_dev_wm8580,
241};
242
243static struct platform_device *smdk64xx_snd_device; 245static struct platform_device *smdk64xx_snd_device;
244 246
245static int __init smdk64xx_audio_init(void) 247static int __init smdk64xx_audio_init(void)
@@ -250,8 +252,7 @@ static int __init smdk64xx_audio_init(void)
250 if (!smdk64xx_snd_device) 252 if (!smdk64xx_snd_device)
251 return -ENOMEM; 253 return -ENOMEM;
252 254
253 platform_set_drvdata(smdk64xx_snd_device, &smdk64xx_snd_devdata); 255 platform_set_drvdata(smdk64xx_snd_device, &smdk64xx);
254 smdk64xx_snd_devdata.dev = &smdk64xx_snd_device->dev;
255 ret = platform_device_add(smdk64xx_snd_device); 256 ret = platform_device_add(smdk64xx_snd_device);
256 257
257 if (ret) 258 if (ret)
diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c
index 5527b9e88c9..90108a7a0a8 100644
--- a/sound/soc/s3c24xx/smdk_wm9713.c
+++ b/sound/soc/s3c24xx/smdk_wm9713.c
@@ -46,40 +46,50 @@ static struct snd_soc_card smdk;
46static struct snd_soc_dai_link smdk_dai = { 46static struct snd_soc_dai_link smdk_dai = {
47 .name = "AC97", 47 .name = "AC97",
48 .stream_name = "AC97 PCM", 48 .stream_name = "AC97 PCM",
49 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM], 49 .platform_name = "s3c24xx-pcm-audio",
50 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI], 50 .cpu_dai_name = "s3c-ac97-dai",
51 .codec_dai_name = "wm9713-hifi",
52 .codec_name = "wm9713-codec",
51}; 53};
52 54
53static struct snd_soc_card smdk = { 55static struct snd_soc_card smdk = {
54 .name = "SMDK", 56 .name = "SMDK",
55 .platform = &s3c24xx_soc_platform,
56 .dai_link = &smdk_dai, 57 .dai_link = &smdk_dai,
57 .num_links = 1, 58 .num_links = 1,
58}; 59};
59 60
60static struct snd_soc_device smdk_snd_ac97_devdata = { 61static struct platform_device *smdk_snd_wm9713_device;
61 .card = &smdk,
62 .codec_dev = &soc_codec_dev_wm9713,
63};
64
65static struct platform_device *smdk_snd_ac97_device; 62static struct platform_device *smdk_snd_ac97_device;
66 63
67static int __init smdk_init(void) 64static int __init smdk_init(void)
68{ 65{
69 int ret; 66 int ret;
70 67
71 smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1); 68 smdk_snd_wm9713_device = platform_device_alloc("wm9713-codec", -1);
72 if (!smdk_snd_ac97_device) 69 if (!smdk_snd_wm9713_device)
73 return -ENOMEM; 70 return -ENOMEM;
74 71
75 platform_set_drvdata(smdk_snd_ac97_device, 72 ret = platform_device_add(smdk_snd_wm9713_device);
76 &smdk_snd_ac97_devdata); 73 if (ret)
77 smdk_snd_ac97_devdata.dev = &smdk_snd_ac97_device->dev; 74 goto err;
75
76 smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1);
77 if (!smdk_snd_ac97_device) {
78 ret = -ENOMEM;
79 goto err;
80 }
81
82 platform_set_drvdata(smdk_snd_ac97_device, &smdk);
78 83
79 ret = platform_device_add(smdk_snd_ac97_device); 84 ret = platform_device_add(smdk_snd_ac97_device);
80 if (ret) 85 if (ret) {
81 platform_device_put(smdk_snd_ac97_device); 86 platform_device_put(smdk_snd_ac97_device);
87 goto err;
88 }
82 89
90 return 0;
91err:
92 platform_device_put(smdk_snd_wm9713_device);
83 return ret; 93 return ret;
84} 94}
85 95
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index 59e3fa7bcb0..8778faa174a 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -140,7 +140,7 @@ static void s6000_i2s_stop_channel(struct s6000_i2s_dev *dev, int channel)
140static void s6000_i2s_start(struct snd_pcm_substream *substream) 140static void s6000_i2s_start(struct snd_pcm_substream *substream)
141{ 141{
142 struct snd_soc_pcm_runtime *rtd = substream->private_data; 142 struct snd_soc_pcm_runtime *rtd = substream->private_data;
143 struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data; 143 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(rtd->cpu_dai);
144 int channel; 144 int channel;
145 145
146 channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 146 channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
@@ -152,7 +152,7 @@ static void s6000_i2s_start(struct snd_pcm_substream *substream)
152static void s6000_i2s_stop(struct snd_pcm_substream *substream) 152static void s6000_i2s_stop(struct snd_pcm_substream *substream)
153{ 153{
154 struct snd_soc_pcm_runtime *rtd = substream->private_data; 154 struct snd_soc_pcm_runtime *rtd = substream->private_data;
155 struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data; 155 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(rtd->cpu_dai);
156 int channel; 156 int channel;
157 157
158 channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 158 channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
@@ -194,7 +194,7 @@ static unsigned int s6000_i2s_int_sources(struct s6000_i2s_dev *dev)
194 194
195static unsigned int s6000_i2s_check_xrun(struct snd_soc_dai *cpu_dai) 195static unsigned int s6000_i2s_check_xrun(struct snd_soc_dai *cpu_dai)
196{ 196{
197 struct s6000_i2s_dev *dev = cpu_dai->private_data; 197 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
198 unsigned int errors; 198 unsigned int errors;
199 unsigned int ret; 199 unsigned int ret;
200 200
@@ -232,7 +232,7 @@ static void s6000_i2s_wait_disabled(struct s6000_i2s_dev *dev)
232static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 232static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
233 unsigned int fmt) 233 unsigned int fmt)
234{ 234{
235 struct s6000_i2s_dev *dev = cpu_dai->private_data; 235 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
236 u32 w; 236 u32 w;
237 237
238 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 238 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -273,7 +273,7 @@ static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
273 273
274static int s6000_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) 274static int s6000_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
275{ 275{
276 struct s6000_i2s_dev *dev = dai->private_data; 276 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
277 277
278 if (!div || (div & 1) || div > (S6_I2S_DIV_MASK + 1) * 2) 278 if (!div || (div & 1) || div > (S6_I2S_DIV_MASK + 1) * 2)
279 return -EINVAL; 279 return -EINVAL;
@@ -287,7 +287,7 @@ static int s6000_i2s_hw_params(struct snd_pcm_substream *substream,
287 struct snd_pcm_hw_params *params, 287 struct snd_pcm_hw_params *params,
288 struct snd_soc_dai *dai) 288 struct snd_soc_dai *dai)
289{ 289{
290 struct s6000_i2s_dev *dev = dai->private_data; 290 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
291 int interf; 291 int interf;
292 u32 w = 0; 292 u32 w = 0;
293 293
@@ -326,15 +326,17 @@ static int s6000_i2s_hw_params(struct snd_pcm_substream *substream,
326 return 0; 326 return 0;
327} 327}
328 328
329static int s6000_i2s_dai_probe(struct platform_device *pdev, 329static int s6000_i2s_dai_probe(struct snd_soc_dai *dai)
330 struct snd_soc_dai *dai)
331{ 330{
332 struct s6000_i2s_dev *dev = dai->private_data; 331 struct s6000_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
333 struct s6000_snd_platform_data *pdata = pdev->dev.platform_data; 332 struct s6000_snd_platform_data *pdata = dai->dev->platform_data;
334 333
335 if (!pdata) 334 if (!pdata)
336 return -EINVAL; 335 return -EINVAL;
337 336
337 dai->capture_dma_data = &dev->dma_params;
338 dai->playback_dma_data = &dev->dma_params;
339
338 dev->wide = pdata->wide; 340 dev->wide = pdata->wide;
339 dev->channel_in = pdata->channel_in; 341 dev->channel_in = pdata->channel_in;
340 dev->channel_out = pdata->channel_out; 342 dev->channel_out = pdata->channel_out;
@@ -352,10 +354,10 @@ static int s6000_i2s_dai_probe(struct platform_device *pdev,
352 354
353 dev->channel_in = 0; 355 dev->channel_in = 0;
354 dev->channel_out = 1; 356 dev->channel_out = 1;
355 dai->capture.channels_min = 2 * dev->lines_in; 357 dai->driver->capture.channels_min = 2 * dev->lines_in;
356 dai->capture.channels_max = dai->capture.channels_min; 358 dai->driver->capture.channels_max = dai->driver->capture.channels_min;
357 dai->playback.channels_min = 2 * dev->lines_out; 359 dai->driver->playback.channels_min = 2 * dev->lines_out;
358 dai->playback.channels_max = dai->playback.channels_min; 360 dai->driver->playback.channels_max = dai->driver->playback.channels_min;
359 361
360 for (i = 0; i < dev->lines_out; i++) 362 for (i = 0; i < dev->lines_out; i++)
361 s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_OUT); 363 s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_OUT);
@@ -372,10 +374,10 @@ static int s6000_i2s_dai_probe(struct platform_device *pdev,
372 if (dev->lines_in > 1 || dev->lines_out > 1) 374 if (dev->lines_in > 1 || dev->lines_out > 1)
373 return -EINVAL; 375 return -EINVAL;
374 376
375 dai->capture.channels_min = 2 * dev->lines_in; 377 dai->driver->capture.channels_min = 2 * dev->lines_in;
376 dai->capture.channels_max = 8 * dev->lines_in; 378 dai->driver->capture.channels_max = 8 * dev->lines_in;
377 dai->playback.channels_min = 2 * dev->lines_out; 379 dai->driver->playback.channels_min = 2 * dev->lines_out;
378 dai->playback.channels_max = 8 * dev->lines_out; 380 dai->driver->playback.channels_max = 8 * dev->lines_out;
379 381
380 if (dev->lines_in) 382 if (dev->lines_in)
381 cfg[dev->channel_in] = S6_I2S_IN; 383 cfg[dev->channel_in] = S6_I2S_IN;
@@ -413,9 +415,7 @@ static struct snd_soc_dai_ops s6000_i2s_dai_ops = {
413 .hw_params = s6000_i2s_hw_params, 415 .hw_params = s6000_i2s_hw_params,
414}; 416};
415 417
416struct snd_soc_dai s6000_i2s_dai = { 418static struct snd_soc_dai_driver s6000_i2s_dai = {
417 .name = "s6000-i2s",
418 .id = 0,
419 .probe = s6000_i2s_dai_probe, 419 .probe = s6000_i2s_dai_probe,
420 .playback = { 420 .playback = {
421 .channels_min = 2, 421 .channels_min = 2,
@@ -435,7 +435,6 @@ struct snd_soc_dai s6000_i2s_dai = {
435 }, 435 },
436 .ops = &s6000_i2s_dai_ops, 436 .ops = &s6000_i2s_dai_ops,
437} 437}
438EXPORT_SYMBOL_GPL(s6000_i2s_dai);
439 438
440static int __devinit s6000_i2s_probe(struct platform_device *pdev) 439static int __devinit s6000_i2s_probe(struct platform_device *pdev)
441{ 440{
@@ -513,11 +512,7 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
513 ret = -ENOMEM; 512 ret = -ENOMEM;
514 goto err_release_dma2; 513 goto err_release_dma2;
515 } 514 }
516 515 dev_set_drvdata(&pdev->dev, dev);
517 s6000_i2s_dai.dev = &pdev->dev;
518 s6000_i2s_dai.private_data = dev;
519 s6000_i2s_dai.capture.dma_data = &dev->dma_params;
520 s6000_i2s_dai.playback.dma_data = &dev->dma_params;
521 516
522 dev->sifbase = sifmem->start; 517 dev->sifbase = sifmem->start;
523 dev->scbbase = mmio; 518 dev->scbbase = mmio;
@@ -548,7 +543,7 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
548 S6_I2S_INT_UNDERRUN | 543 S6_I2S_INT_UNDERRUN |
549 S6_I2S_INT_OVERRUN); 544 S6_I2S_INT_OVERRUN);
550 545
551 ret = snd_soc_register_dai(&s6000_i2s_dai); 546 ret = snd_soc_register_dai(&pdev->dev, &s6000_i2s_dai);
552 if (ret) 547 if (ret)
553 goto err_release_dev; 548 goto err_release_dev;
554 549
@@ -573,17 +568,16 @@ err_release_none:
573 568
574static void __devexit s6000_i2s_remove(struct platform_device *pdev) 569static void __devexit s6000_i2s_remove(struct platform_device *pdev)
575{ 570{
576 struct s6000_i2s_dev *dev = s6000_i2s_dai.private_data; 571 struct s6000_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
577 struct resource *region; 572 struct resource *region;
578 void __iomem *mmio = dev->scbbase; 573 void __iomem *mmio = dev->scbbase;
579 574
580 snd_soc_unregister_dai(&s6000_i2s_dai); 575 snd_soc_unregister_dai(&pdev->dev);
581 576
582 s6000_i2s_stop_channel(dev, 0); 577 s6000_i2s_stop_channel(dev, 0);
583 s6000_i2s_stop_channel(dev, 1); 578 s6000_i2s_stop_channel(dev, 1);
584 579
585 s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0); 580 s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0);
586 s6000_i2s_dai.private_data = 0;
587 kfree(dev); 581 kfree(dev);
588 582
589 region = platform_get_resource(pdev, IORESOURCE_DMA, 0); 583 region = platform_get_resource(pdev, IORESOURCE_DMA, 0);
diff --git a/sound/soc/s6000/s6000-i2s.h b/sound/soc/s6000/s6000-i2s.h
index 2375fdfe6db..86aa1921c89 100644
--- a/sound/soc/s6000/s6000-i2s.h
+++ b/sound/soc/s6000/s6000-i2s.h
@@ -12,8 +12,6 @@
12#ifndef _S6000_I2S_H 12#ifndef _S6000_I2S_H
13#define _S6000_I2S_H 13#define _S6000_I2S_H
14 14
15extern struct snd_soc_dai s6000_i2s_dai;
16
17struct s6000_snd_platform_data { 15struct s6000_snd_platform_data {
18 int lines_in; 16 int lines_in;
19 int lines_out; 17 int lines_out;
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 9c7f7f00ceb..271fd222bf1 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -65,7 +65,7 @@ static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
65 dma_addr_t dma_pos; 65 dma_addr_t dma_pos;
66 dma_addr_t src, dst; 66 dma_addr_t src, dst;
67 67
68 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 68 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
69 69
70 period_size = snd_pcm_lib_period_bytes(substream); 70 period_size = snd_pcm_lib_period_bytes(substream);
71 dma_offset = prtd->period * period_size; 71 dma_offset = prtd->period * period_size;
@@ -103,23 +103,25 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
103{ 103{
104 struct snd_pcm *pcm = data; 104 struct snd_pcm *pcm = data;
105 struct snd_soc_pcm_runtime *runtime = pcm->private_data; 105 struct snd_soc_pcm_runtime *runtime = pcm->private_data;
106 struct s6000_pcm_dma_params *params =
107 snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
108 struct s6000_runtime_data *prtd; 106 struct s6000_runtime_data *prtd;
109 unsigned int has_xrun; 107 unsigned int has_xrun;
110 int i, ret = IRQ_NONE; 108 int i, ret = IRQ_NONE;
111 u32 channel[2] = {
112 [SNDRV_PCM_STREAM_PLAYBACK] = params->dma_out,
113 [SNDRV_PCM_STREAM_CAPTURE] = params->dma_in
114 };
115
116 has_xrun = params->check_xrun(runtime->dai->cpu_dai);
117 109
118 for (i = 0; i < ARRAY_SIZE(channel); ++i) { 110 for (i = 0; i < 2; ++i) {
119 struct snd_pcm_substream *substream = pcm->streams[i].substream; 111 struct snd_pcm_substream *substream = pcm->streams[i].substream;
112 struct s6000_pcm_dma_params *params =
113 snd_soc_dai_get_dma_data(runtime->cpu_dai, substream);
114 u32 channel;
120 unsigned int pending; 115 unsigned int pending;
121 116
122 if (!channel[i]) 117 if (substream == SNDRV_PCM_STREAM_PLAYBACK)
118 channel = params->dma_out;
119 else
120 channel = params->dma_in;
121
122 has_xrun = params->check_xrun(runtime->cpu_dai);
123
124 if (!channel)
123 continue; 125 continue;
124 126
125 if (unlikely(has_xrun & (1 << i)) && 127 if (unlikely(has_xrun & (1 << i)) &&
@@ -130,8 +132,8 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
130 ret = IRQ_HANDLED; 132 ret = IRQ_HANDLED;
131 } 133 }
132 134
133 pending = s6dmac_int_sources(DMA_MASK_DMAC(channel[i]), 135 pending = s6dmac_int_sources(DMA_MASK_DMAC(channel),
134 DMA_INDEX_CHNL(channel[i])); 136 DMA_INDEX_CHNL(channel));
135 137
136 if (pending & 1) { 138 if (pending & 1) {
137 ret = IRQ_HANDLED; 139 ret = IRQ_HANDLED;
@@ -139,10 +141,10 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
139 snd_pcm_running(substream))) { 141 snd_pcm_running(substream))) {
140 snd_pcm_period_elapsed(substream); 142 snd_pcm_period_elapsed(substream);
141 dev_dbg(pcm->dev, "period elapsed %x %x\n", 143 dev_dbg(pcm->dev, "period elapsed %x %x\n",
142 s6dmac_cur_src(DMA_MASK_DMAC(channel[i]), 144 s6dmac_cur_src(DMA_MASK_DMAC(channel),
143 DMA_INDEX_CHNL(channel[i])), 145 DMA_INDEX_CHNL(channel)),
144 s6dmac_cur_dst(DMA_MASK_DMAC(channel[i]), 146 s6dmac_cur_dst(DMA_MASK_DMAC(channel),
145 DMA_INDEX_CHNL(channel[i]))); 147 DMA_INDEX_CHNL(channel)));
146 prtd = substream->runtime->private_data; 148 prtd = substream->runtime->private_data;
147 spin_lock(&prtd->lock); 149 spin_lock(&prtd->lock);
148 s6000_pcm_enqueue_dma(substream); 150 s6000_pcm_enqueue_dma(substream);
@@ -154,16 +156,16 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
154 if (pending & (1 << 3)) 156 if (pending & (1 << 3))
155 printk(KERN_WARNING 157 printk(KERN_WARNING
156 "s6000-pcm: DMA %x Underflow\n", 158 "s6000-pcm: DMA %x Underflow\n",
157 channel[i]); 159 channel);
158 if (pending & (1 << 4)) 160 if (pending & (1 << 4))
159 printk(KERN_WARNING 161 printk(KERN_WARNING
160 "s6000-pcm: DMA %x Overflow\n", 162 "s6000-pcm: DMA %x Overflow\n",
161 channel[i]); 163 channel);
162 if (pending & 0x1e0) 164 if (pending & 0x1e0)
163 printk(KERN_WARNING 165 printk(KERN_WARNING
164 "s6000-pcm: DMA %x Master Error " 166 "s6000-pcm: DMA %x Master Error "
165 "(mask %x)\n", 167 "(mask %x)\n",
166 channel[i], pending >> 5); 168 channel, pending >> 5);
167 169
168 } 170 }
169 } 171 }
@@ -180,7 +182,7 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream)
180 int srcinc; 182 int srcinc;
181 u32 dma; 183 u32 dma;
182 184
183 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 185 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
184 186
185 spin_lock_irqsave(&prtd->lock, flags); 187 spin_lock_irqsave(&prtd->lock, flags);
186 188
@@ -221,7 +223,7 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
221 unsigned long flags; 223 unsigned long flags;
222 u32 channel; 224 u32 channel;
223 225
224 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 226 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
225 227
226 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 228 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
227 channel = par->dma_out; 229 channel = par->dma_out;
@@ -246,7 +248,7 @@ static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
246 struct s6000_pcm_dma_params *par; 248 struct s6000_pcm_dma_params *par;
247 int ret; 249 int ret;
248 250
249 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 251 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
250 252
251 ret = par->trigger(substream, cmd, 0); 253 ret = par->trigger(substream, cmd, 0);
252 if (ret < 0) 254 if (ret < 0)
@@ -291,7 +293,7 @@ static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
291 unsigned int offset; 293 unsigned int offset;
292 dma_addr_t count; 294 dma_addr_t count;
293 295
294 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 296 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
295 297
296 spin_lock_irqsave(&prtd->lock, flags); 298 spin_lock_irqsave(&prtd->lock, flags);
297 299
@@ -321,7 +323,7 @@ static int s6000_pcm_open(struct snd_pcm_substream *substream)
321 struct s6000_runtime_data *prtd; 323 struct s6000_runtime_data *prtd;
322 int ret; 324 int ret;
323 325
324 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 326 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
325 snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware); 327 snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);
326 328
327 ret = snd_pcm_hw_constraint_step(runtime, 0, 329 ret = snd_pcm_hw_constraint_step(runtime, 0,
@@ -385,7 +387,7 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
385 return ret; 387 return ret;
386 } 388 }
387 389
388 par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 390 par = snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
389 391
390 if (par->same_rate) { 392 if (par->same_rate) {
391 spin_lock(&par->lock); 393 spin_lock(&par->lock);
@@ -407,7 +409,7 @@ static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
407{ 409{
408 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 410 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
409 struct s6000_pcm_dma_params *par = 411 struct s6000_pcm_dma_params *par =
410 snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 412 snd_soc_dai_get_dma_data(soc_runtime->cpu_dai, substream);
411 413
412 spin_lock(&par->lock); 414 spin_lock(&par->lock);
413 par->in_use &= ~(1 << substream->stream); 415 par->in_use &= ~(1 << substream->stream);
@@ -433,7 +435,7 @@ static void s6000_pcm_free(struct snd_pcm *pcm)
433{ 435{
434 struct snd_soc_pcm_runtime *runtime = pcm->private_data; 436 struct snd_soc_pcm_runtime *runtime = pcm->private_data;
435 struct s6000_pcm_dma_params *params = 437 struct s6000_pcm_dma_params *params =
436 snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 438 snd_soc_dai_get_dma_data(runtime->cpu_dai, pcm->streams[0].substream);
437 439
438 free_irq(params->irq, pcm); 440 free_irq(params->irq, pcm);
439 snd_pcm_lib_preallocate_free_for_all(pcm); 441 snd_pcm_lib_preallocate_free_for_all(pcm);
@@ -448,7 +450,8 @@ static int s6000_pcm_new(struct snd_card *card,
448 struct s6000_pcm_dma_params *params; 450 struct s6000_pcm_dma_params *params;
449 int res; 451 int res;
450 452
451 params = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); 453 params = snd_soc_dai_get_dma_data(runtime->cpu_dai,
454 pcm->streams[0].substream);
452 455
453 if (!card->dev->dma_mask) 456 if (!card->dev->dma_mask)
454 card->dev->dma_mask = &s6000_pcm_dmamask; 457 card->dev->dma_mask = &s6000_pcm_dmamask;
@@ -490,25 +493,44 @@ static int s6000_pcm_new(struct snd_card *card,
490 return 0; 493 return 0;
491} 494}
492 495
493struct snd_soc_platform s6000_soc_platform = { 496static struct snd_soc_platform_driver s6000_soc_platform = {
494 .name = "s6000-audio", 497 .ops = &s6000_pcm_ops,
495 .pcm_ops = &s6000_pcm_ops,
496 .pcm_new = s6000_pcm_new, 498 .pcm_new = s6000_pcm_new,
497 .pcm_free = s6000_pcm_free, 499 .pcm_free = s6000_pcm_free,
498}; 500};
499EXPORT_SYMBOL_GPL(s6000_soc_platform);
500 501
501static int __init s6000_pcm_init(void) 502static int __devinit s6000_soc_platform_probe(struct platform_device *pdev)
503{
504 return snd_soc_register_platform(&pdev->dev, &s6000_soc_platform);
505}
506
507static int __devexit s6000_soc_platform_remove(struct platform_device *pdev)
508{
509 snd_soc_unregister_platform(&pdev->dev);
510 return 0;
511}
512
513static struct platform_driver s6000_pcm_driver = {
514 .driver = {
515 .name = "s6000-pcm-audio",
516 .owner = THIS_MODULE,
517 },
518
519 .probe = s6000_soc_platform_probe,
520 .remove = __devexit_p(s6000_soc_platform_remove),
521};
522
523static int __init snd_s6000_pcm_init(void)
502{ 524{
503 return snd_soc_register_platform(&s6000_soc_platform); 525 return platform_driver_register(&s6000_pcm_driver);
504} 526}
505module_init(s6000_pcm_init); 527module_init(snd_s6000_pcm_init);
506 528
507static void __exit s6000_pcm_exit(void) 529static void __exit snd_s6000_pcm_exit(void)
508{ 530{
509 snd_soc_unregister_platform(&s6000_soc_platform); 531 platform_driver_unregister(&s6000_pcm_driver);
510} 532}
511module_exit(s6000_pcm_exit); 533module_exit(snd_s6000_pcm_exit);
512 534
513MODULE_AUTHOR("Daniel Gloeckner"); 535MODULE_AUTHOR("Daniel Gloeckner");
514MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module"); 536MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module");
diff --git a/sound/soc/s6000/s6000-pcm.h b/sound/soc/s6000/s6000-pcm.h
index 96f23f6f52b..09d9b883e58 100644
--- a/sound/soc/s6000/s6000-pcm.h
+++ b/sound/soc/s6000/s6000-pcm.h
@@ -30,6 +30,4 @@ struct s6000_pcm_dma_params {
30 int rate; 30 int rate;
31}; 31};
32 32
33extern struct snd_soc_platform s6000_soc_platform;
34
35#endif 33#endif
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
index c1b40ac22c0..96c05e13753 100644
--- a/sound/soc/s6000/s6105-ipcam.c
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -32,8 +32,8 @@ static int s6105_hw_params(struct snd_pcm_substream *substream,
32 struct snd_pcm_hw_params *params) 32 struct snd_pcm_hw_params *params)
33{ 33{
34 struct snd_soc_pcm_runtime *rtd = substream->private_data; 34 struct snd_soc_pcm_runtime *rtd = substream->private_data;
35 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 35 struct snd_soc_dai *codec_dai = rtd->codec_dai;
36 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 36 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
37 int ret = 0; 37 int ret = 0;
38 38
39 /* set codec DAI configuration */ 39 /* set codec DAI configuration */
@@ -134,8 +134,10 @@ static const struct snd_kcontrol_new audio_out_mux = {
134}; 134};
135 135
136/* Logic for a aic3x as connected on the s6105 ip camera ref design */ 136/* Logic for a aic3x as connected on the s6105 ip camera ref design */
137static int s6105_aic3x_init(struct snd_soc_codec *codec) 137static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
138{ 138{
139 struct snd_soc_codec *codec = rtd->codec;
140
139 /* Add s6105 specific widgets */ 141 /* Add s6105 specific widgets */
140 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, 142 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets,
141 ARRAY_SIZE(aic3x_dapm_widgets)); 143 ARRAY_SIZE(aic3x_dapm_widgets));
@@ -165,7 +167,7 @@ static int s6105_aic3x_init(struct snd_soc_codec *codec)
165 167
166 snd_soc_dapm_sync(codec); 168 snd_soc_dapm_sync(codec);
167 169
168 snd_ctl_add(codec->card, snd_ctl_new1(&audio_out_mux, codec)); 170 snd_ctl_add(codec->snd_card, snd_ctl_new1(&audio_out_mux, codec));
169 171
170 return 0; 172 return 0;
171} 173}
@@ -174,8 +176,10 @@ static int s6105_aic3x_init(struct snd_soc_codec *codec)
174static struct snd_soc_dai_link s6105_dai = { 176static struct snd_soc_dai_link s6105_dai = {
175 .name = "TLV320AIC31", 177 .name = "TLV320AIC31",
176 .stream_name = "AIC31", 178 .stream_name = "AIC31",
177 .cpu_dai = &s6000_i2s_dai, 179 .cpu_dai_name = "s6000-i2s",
178 .codec_dai = &aic3x_dai, 180 .codec_dai_name = "tlv320aic3x-hifi",
181 .platform_name = "s6000-pcm-audio",
182 .codec_name = "tlv320aic3x-codec.0-001a",
179 .init = s6105_aic3x_init, 183 .init = s6105_aic3x_init,
180 .ops = &s6105_ops, 184 .ops = &s6105_ops,
181}; 185};
@@ -183,22 +187,10 @@ static struct snd_soc_dai_link s6105_dai = {
183/* s6105 audio machine driver */ 187/* s6105 audio machine driver */
184static struct snd_soc_card snd_soc_card_s6105 = { 188static struct snd_soc_card snd_soc_card_s6105 = {
185 .name = "Stretch IP Camera", 189 .name = "Stretch IP Camera",
186 .platform = &s6000_soc_platform,
187 .dai_link = &s6105_dai, 190 .dai_link = &s6105_dai,
188 .num_links = 1, 191 .num_links = 1,
189}; 192};
190 193
191/* s6105 audio private data */
192static struct aic3x_setup_data s6105_aic3x_setup = {
193};
194
195/* s6105 audio subsystem */
196static struct snd_soc_device s6105_snd_devdata = {
197 .card = &snd_soc_card_s6105,
198 .codec_dev = &soc_codec_dev_aic3x,
199 .codec_data = &s6105_aic3x_setup,
200};
201
202static struct s6000_snd_platform_data __initdata s6105_snd_data = { 194static struct s6000_snd_platform_data __initdata s6105_snd_data = {
203 .wide = 0, 195 .wide = 0,
204 .channel_in = 0, 196 .channel_in = 0,
@@ -227,8 +219,7 @@ static int __init s6105_init(void)
227 if (!s6105_snd_device) 219 if (!s6105_snd_device)
228 return -ENOMEM; 220 return -ENOMEM;
229 221
230 platform_set_drvdata(s6105_snd_device, &s6105_snd_devdata); 222 platform_set_drvdata(s6105_snd_device, &snd_soc_card_s6105);
231 s6105_snd_devdata.dev = &s6105_snd_device->dev;
232 platform_device_add_data(s6105_snd_device, &s6105_snd_data, 223 platform_device_add_data(s6105_snd_device, &s6105_snd_data,
233 sizeof(s6105_snd_data)); 224 sizeof(s6105_snd_data));
234 225
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index 0d8bdf07729..c326d29992f 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -137,7 +137,7 @@ static void camelot_rxdma(void *data)
137static int camelot_pcm_open(struct snd_pcm_substream *substream) 137static int camelot_pcm_open(struct snd_pcm_substream *substream)
138{ 138{
139 struct snd_soc_pcm_runtime *rtd = substream->private_data; 139 struct snd_soc_pcm_runtime *rtd = substream->private_data;
140 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; 140 struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
141 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; 141 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
142 int ret, dmairq; 142 int ret, dmairq;
143 143
@@ -150,7 +150,7 @@ static int camelot_pcm_open(struct snd_pcm_substream *substream)
150 ret = dmabrg_request_irq(dmairq, camelot_rxdma, cam); 150 ret = dmabrg_request_irq(dmairq, camelot_rxdma, cam);
151 if (unlikely(ret)) { 151 if (unlikely(ret)) {
152 pr_debug("audio unit %d irqs already taken!\n", 152 pr_debug("audio unit %d irqs already taken!\n",
153 rtd->dai->cpu_dai->id); 153 rtd->cpu_dai->id);
154 return -EBUSY; 154 return -EBUSY;
155 } 155 }
156 (void)dmabrg_request_irq(dmairq + 1,camelot_rxdma, cam); 156 (void)dmabrg_request_irq(dmairq + 1,camelot_rxdma, cam);
@@ -159,7 +159,7 @@ static int camelot_pcm_open(struct snd_pcm_substream *substream)
159 ret = dmabrg_request_irq(dmairq, camelot_txdma, cam); 159 ret = dmabrg_request_irq(dmairq, camelot_txdma, cam);
160 if (unlikely(ret)) { 160 if (unlikely(ret)) {
161 pr_debug("audio unit %d irqs already taken!\n", 161 pr_debug("audio unit %d irqs already taken!\n",
162 rtd->dai->cpu_dai->id); 162 rtd->cpu_dai->id);
163 return -EBUSY; 163 return -EBUSY;
164 } 164 }
165 (void)dmabrg_request_irq(dmairq + 1, camelot_txdma, cam); 165 (void)dmabrg_request_irq(dmairq + 1, camelot_txdma, cam);
@@ -170,7 +170,7 @@ static int camelot_pcm_open(struct snd_pcm_substream *substream)
170static int camelot_pcm_close(struct snd_pcm_substream *substream) 170static int camelot_pcm_close(struct snd_pcm_substream *substream)
171{ 171{
172 struct snd_soc_pcm_runtime *rtd = substream->private_data; 172 struct snd_soc_pcm_runtime *rtd = substream->private_data;
173 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; 173 struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
174 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; 174 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
175 int dmairq; 175 int dmairq;
176 176
@@ -191,7 +191,7 @@ static int camelot_hw_params(struct snd_pcm_substream *substream,
191 struct snd_pcm_hw_params *hw_params) 191 struct snd_pcm_hw_params *hw_params)
192{ 192{
193 struct snd_soc_pcm_runtime *rtd = substream->private_data; 193 struct snd_soc_pcm_runtime *rtd = substream->private_data;
194 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; 194 struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
195 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; 195 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
196 int ret; 196 int ret;
197 197
@@ -219,7 +219,7 @@ static int camelot_prepare(struct snd_pcm_substream *substream)
219{ 219{
220 struct snd_pcm_runtime *runtime = substream->runtime; 220 struct snd_pcm_runtime *runtime = substream->runtime;
221 struct snd_soc_pcm_runtime *rtd = substream->private_data; 221 struct snd_soc_pcm_runtime *rtd = substream->private_data;
222 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; 222 struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
223 223
224 pr_debug("PCM data: addr 0x%08ulx len %d\n", 224 pr_debug("PCM data: addr 0x%08ulx len %d\n",
225 (u32)runtime->dma_addr, runtime->dma_bytes); 225 (u32)runtime->dma_addr, runtime->dma_bytes);
@@ -266,7 +266,7 @@ static inline void dmabrg_rec_dma_stop(struct camelot_pcm *cam)
266static int camelot_trigger(struct snd_pcm_substream *substream, int cmd) 266static int camelot_trigger(struct snd_pcm_substream *substream, int cmd)
267{ 267{
268 struct snd_soc_pcm_runtime *rtd = substream->private_data; 268 struct snd_soc_pcm_runtime *rtd = substream->private_data;
269 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; 269 struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
270 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; 270 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
271 271
272 switch (cmd) { 272 switch (cmd) {
@@ -293,7 +293,7 @@ static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream)
293{ 293{
294 struct snd_pcm_runtime *runtime = substream->runtime; 294 struct snd_pcm_runtime *runtime = substream->runtime;
295 struct snd_soc_pcm_runtime *rtd = substream->private_data; 295 struct snd_soc_pcm_runtime *rtd = substream->private_data;
296 struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; 296 struct camelot_pcm *cam = &cam_pcm_data[rtd->cpu_dai->id];
297 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; 297 int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1;
298 unsigned long pos; 298 unsigned long pos;
299 299
@@ -342,25 +342,44 @@ static int camelot_pcm_new(struct snd_card *card,
342 return 0; 342 return 0;
343} 343}
344 344
345struct snd_soc_platform sh7760_soc_platform = { 345static struct snd_soc_platform sh7760_soc_platform = {
346 .name = "sh7760-pcm",
347 .pcm_ops = &camelot_pcm_ops, 346 .pcm_ops = &camelot_pcm_ops,
348 .pcm_new = camelot_pcm_new, 347 .pcm_new = camelot_pcm_new,
349 .pcm_free = camelot_pcm_free, 348 .pcm_free = camelot_pcm_free,
350}; 349};
351EXPORT_SYMBOL_GPL(sh7760_soc_platform);
352 350
353static int __init sh7760_soc_platform_init(void) 351static int __devinit sh7760_soc_platform_probe(struct platform_device *pdev)
354{ 352{
355 return snd_soc_register_platform(&sh7760_soc_platform); 353 return snd_soc_register_platform(&pdev->dev, &sh7760_soc_platform);
356} 354}
357module_init(sh7760_soc_platform_init);
358 355
359static void __exit sh7760_soc_platform_exit(void) 356static int __devexit sh7760_soc_platform_remove(struct platform_device *pdev)
360{ 357{
361 snd_soc_unregister_platform(&sh7760_soc_platform); 358 snd_soc_unregister_platform(&pdev->dev);
359 return 0;
360}
361
362static struct platform_driver sh7760_pcm_driver = {
363 .driver = {
364 .name = "sh7760-pcm-audio",
365 .owner = THIS_MODULE,
366 },
367
368 .probe = sh7760_soc_platform_probe,
369 .remove = __devexit_p(sh7760_soc_platform_remove),
370};
371
372static int __init snd_sh7760_pcm_init(void)
373{
374 return platform_driver_register(&sh7760_pcm_driver);
375}
376module_init(snd_sh7760_pcm_init);
377
378static void __exit snd_sh7760_pcm_exit(void)
379{
380 platform_driver_unregister(&sh7760_pcm_driver);
362} 381}
363module_exit(sh7760_soc_platform_exit); 382module_exit(snd_sh7760_pcm_exit);
364 383
365MODULE_LICENSE("GPL"); 384MODULE_LICENSE("GPL");
366MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver"); 385MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver");
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index dad575a2262..9e107a9c401 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -11,17 +11,17 @@
11 11
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <sound/sh_fsi.h> 13#include <sound/sh_fsi.h>
14#include <../sound/soc/codecs/ak4642.h>
15 14
16static int fsi_ak4642_dai_init(struct snd_soc_codec *codec) 15static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
17{ 16{
17 struct snd_soc_dai *dai = rtd->codec_dai;
18 int ret; 18 int ret;
19 19
20 ret = snd_soc_dai_set_fmt(&ak4642_dai, SND_SOC_DAIFMT_CBM_CFM); 20 ret = snd_soc_dai_set_fmt(dai, SND_SOC_DAIFMT_CBM_CFM);
21 if (ret < 0) 21 if (ret < 0)
22 return ret; 22 return ret;
23 23
24 ret = snd_soc_dai_set_sysclk(&ak4642_dai, 0, 11289600, 0); 24 ret = snd_soc_dai_set_sysclk(dai, 0, 11289600, 0);
25 25
26 return ret; 26 return ret;
27} 27}
@@ -29,24 +29,20 @@ static int fsi_ak4642_dai_init(struct snd_soc_codec *codec)
29static struct snd_soc_dai_link fsi_dai_link = { 29static struct snd_soc_dai_link fsi_dai_link = {
30 .name = "AK4642", 30 .name = "AK4642",
31 .stream_name = "AK4642", 31 .stream_name = "AK4642",
32 .cpu_dai = &fsi_soc_dai[FSI_PORT_A], 32 .cpu_dai_name = "fsia-dai", /* fsi A */
33 .codec_dai = &ak4642_dai, 33 .codec_dai_name = "ak4642-hifi",
34 .platform_name = "fsi-pcm-audio",
35 .codec_name = "ak4642-codec.0-0012",
34 .init = fsi_ak4642_dai_init, 36 .init = fsi_ak4642_dai_init,
35 .ops = NULL, 37 .ops = NULL,
36}; 38};
37 39
38static struct snd_soc_card fsi_soc_card = { 40static struct snd_soc_card fsi_soc_card = {
39 .name = "FSI", 41 .name = "FSI",
40 .platform = &fsi_soc_platform,
41 .dai_link = &fsi_dai_link, 42 .dai_link = &fsi_dai_link,
42 .num_links = 1, 43 .num_links = 1,
43}; 44};
44 45
45static struct snd_soc_device fsi_snd_devdata = {
46 .card = &fsi_soc_card,
47 .codec_dev = &soc_codec_dev_ak4642,
48};
49
50static struct platform_device *fsi_snd_device; 46static struct platform_device *fsi_snd_device;
51 47
52static int __init fsi_ak4642_init(void) 48static int __init fsi_ak4642_init(void)
@@ -57,9 +53,7 @@ static int __init fsi_ak4642_init(void)
57 if (!fsi_snd_device) 53 if (!fsi_snd_device)
58 goto out; 54 goto out;
59 55
60 platform_set_drvdata(fsi_snd_device, 56 platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
61 &fsi_snd_devdata);
62 fsi_snd_devdata.dev = &fsi_snd_device->dev;
63 ret = platform_device_add(fsi_snd_device); 57 ret = platform_device_add(fsi_snd_device);
64 58
65 if (ret) 59 if (ret)
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
index 121bbb07bb0..4f9298f4521 100644
--- a/sound/soc/sh/fsi-da7210.c
+++ b/sound/soc/sh/fsi-da7210.c
@@ -12,11 +12,12 @@
12 12
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <sound/sh_fsi.h> 14#include <sound/sh_fsi.h>
15#include "../codecs/da7210.h"
16 15
17static int fsi_da7210_init(struct snd_soc_codec *codec) 16static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
18{ 17{
19 return snd_soc_dai_set_fmt(&da7210_dai, 18 struct snd_soc_dai *dai = rtd->codec_dai;
19
20 return snd_soc_dai_set_fmt(dai,
20 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 21 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
21 SND_SOC_DAIFMT_CBM_CFM); 22 SND_SOC_DAIFMT_CBM_CFM);
22} 23}
@@ -24,23 +25,19 @@ static int fsi_da7210_init(struct snd_soc_codec *codec)
24static struct snd_soc_dai_link fsi_da7210_dai = { 25static struct snd_soc_dai_link fsi_da7210_dai = {
25 .name = "DA7210", 26 .name = "DA7210",
26 .stream_name = "DA7210", 27 .stream_name = "DA7210",
27 .cpu_dai = &fsi_soc_dai[FSI_PORT_B], 28 .cpu_dai_name = "fsib-dai", /* FSI B */
28 .codec_dai = &da7210_dai, 29 .codec_dai_name = "da7210-hifi",
30 .platform_name = "fsi-pcm-audio",
31 .codec_name = "da7210-codec.0-001a",
29 .init = fsi_da7210_init, 32 .init = fsi_da7210_init,
30}; 33};
31 34
32static struct snd_soc_card fsi_soc_card = { 35static struct snd_soc_card fsi_soc_card = {
33 .name = "FSI", 36 .name = "FSI",
34 .platform = &fsi_soc_platform,
35 .dai_link = &fsi_da7210_dai, 37 .dai_link = &fsi_da7210_dai,
36 .num_links = 1, 38 .num_links = 1,
37}; 39};
38 40
39static struct snd_soc_device fsi_da7210_snd_devdata = {
40 .card = &fsi_soc_card,
41 .codec_dev = &soc_codec_dev_da7210,
42};
43
44static struct platform_device *fsi_da7210_snd_device; 41static struct platform_device *fsi_da7210_snd_device;
45 42
46static int __init fsi_da7210_sound_init(void) 43static int __init fsi_da7210_sound_init(void)
@@ -51,8 +48,7 @@ static int __init fsi_da7210_sound_init(void)
51 if (!fsi_da7210_snd_device) 48 if (!fsi_da7210_snd_device)
52 return -ENOMEM; 49 return -ENOMEM;
53 50
54 platform_set_drvdata(fsi_da7210_snd_device, &fsi_da7210_snd_devdata); 51 platform_set_drvdata(fsi_da7210_snd_device, &fsi_soc_card);
55 fsi_da7210_snd_devdata.dev = &fsi_da7210_snd_device->dev;
56 ret = platform_device_add(fsi_da7210_snd_device); 52 ret = platform_device_add(fsi_da7210_snd_device);
57 if (ret) 53 if (ret)
58 platform_device_put(fsi_da7210_snd_device); 54 platform_device_put(fsi_da7210_snd_device);
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 58c6bec642d..abc6d830960 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -271,16 +271,19 @@ static int fsi_is_port_a(struct fsi_priv *fsi)
271static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream) 271static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
272{ 272{
273 struct snd_soc_pcm_runtime *rtd = substream->private_data; 273 struct snd_soc_pcm_runtime *rtd = substream->private_data;
274 struct snd_soc_dai_link *machine = rtd->dai;
275 274
276 return machine->cpu_dai; 275 return rtd->cpu_dai;
277} 276}
278 277
279static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream) 278static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
280{ 279{
281 struct snd_soc_dai *dai = fsi_get_dai(substream); 280 struct snd_soc_dai *dai = fsi_get_dai(substream);
281 struct fsi_master *master = snd_soc_dai_get_drvdata(dai);
282 282
283 return dai->private_data; 283 if (dai->id == 0)
284 return &master->fsia;
285 else
286 return &master->fsib;
284} 287}
285 288
286static u32 fsi_get_info_flags(struct fsi_priv *fsi) 289static u32 fsi_get_info_flags(struct fsi_priv *fsi)
@@ -1025,10 +1028,9 @@ static int fsi_pcm_new(struct snd_card *card,
1025 1028
1026 1029
1027************************************************************************/ 1030************************************************************************/
1028struct snd_soc_dai fsi_soc_dai[] = { 1031static struct snd_soc_dai_driver fsi_soc_dai[] = {
1029 { 1032 {
1030 .name = "FSIA", 1033 .name = "fsia-dai",
1031 .id = 0,
1032 .playback = { 1034 .playback = {
1033 .rates = FSI_RATES, 1035 .rates = FSI_RATES,
1034 .formats = FSI_FMTS, 1036 .formats = FSI_FMTS,
@@ -1044,8 +1046,7 @@ struct snd_soc_dai fsi_soc_dai[] = {
1044 .ops = &fsi_dai_ops, 1046 .ops = &fsi_dai_ops,
1045 }, 1047 },
1046 { 1048 {
1047 .name = "FSIB", 1049 .name = "fsib-dai",
1048 .id = 1,
1049 .playback = { 1050 .playback = {
1050 .rates = FSI_RATES, 1051 .rates = FSI_RATES,
1051 .formats = FSI_FMTS, 1052 .formats = FSI_FMTS,
@@ -1061,15 +1062,12 @@ struct snd_soc_dai fsi_soc_dai[] = {
1061 .ops = &fsi_dai_ops, 1062 .ops = &fsi_dai_ops,
1062 }, 1063 },
1063}; 1064};
1064EXPORT_SYMBOL_GPL(fsi_soc_dai);
1065 1065
1066struct snd_soc_platform fsi_soc_platform = { 1066static struct snd_soc_platform_driver fsi_soc_platform = {
1067 .name = "fsi-pcm", 1067 .ops = &fsi_pcm_ops,
1068 .pcm_ops = &fsi_pcm_ops,
1069 .pcm_new = fsi_pcm_new, 1068 .pcm_new = fsi_pcm_new,
1070 .pcm_free = fsi_pcm_free, 1069 .pcm_free = fsi_pcm_free,
1071}; 1070};
1072EXPORT_SYMBOL_GPL(fsi_soc_platform);
1073 1071
1074/************************************************************************ 1072/************************************************************************
1075 1073
@@ -1132,11 +1130,7 @@ static int fsi_probe(struct platform_device *pdev)
1132 1130
1133 pm_runtime_enable(&pdev->dev); 1131 pm_runtime_enable(&pdev->dev);
1134 pm_runtime_resume(&pdev->dev); 1132 pm_runtime_resume(&pdev->dev);
1135 1133 dev_set_drvdata(&pdev->dev, master);
1136 fsi_soc_dai[0].dev = &pdev->dev;
1137 fsi_soc_dai[0].private_data = &master->fsia;
1138 fsi_soc_dai[1].dev = &pdev->dev;
1139 fsi_soc_dai[1].private_data = &master->fsib;
1140 1134
1141 fsi_soft_all_reset(master); 1135 fsi_soft_all_reset(master);
1142 1136
@@ -1147,13 +1141,13 @@ static int fsi_probe(struct platform_device *pdev)
1147 goto exit_iounmap; 1141 goto exit_iounmap;
1148 } 1142 }
1149 1143
1150 ret = snd_soc_register_platform(&fsi_soc_platform); 1144 ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform);
1151 if (ret < 0) { 1145 if (ret < 0) {
1152 dev_err(&pdev->dev, "cannot snd soc register\n"); 1146 dev_err(&pdev->dev, "cannot snd soc register\n");
1153 goto exit_free_irq; 1147 goto exit_free_irq;
1154 } 1148 }
1155 1149
1156 return snd_soc_register_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); 1150 return snd_soc_register_dais(&pdev->dev, fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
1157 1151
1158exit_free_irq: 1152exit_free_irq:
1159 free_irq(irq, master); 1153 free_irq(irq, master);
@@ -1171,10 +1165,10 @@ static int fsi_remove(struct platform_device *pdev)
1171{ 1165{
1172 struct fsi_master *master; 1166 struct fsi_master *master;
1173 1167
1174 master = fsi_get_master(fsi_soc_dai[0].private_data); 1168 master = dev_get_drvdata(&pdev->dev);
1175 1169
1176 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); 1170 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai));
1177 snd_soc_unregister_platform(&fsi_soc_platform); 1171 snd_soc_unregister_platform(&pdev->dev);
1178 1172
1179 pm_runtime_disable(&pdev->dev); 1173 pm_runtime_disable(&pdev->dev);
1180 1174
@@ -1183,11 +1177,6 @@ static int fsi_remove(struct platform_device *pdev)
1183 iounmap(master->base); 1177 iounmap(master->base);
1184 kfree(master); 1178 kfree(master);
1185 1179
1186 fsi_soc_dai[0].dev = NULL;
1187 fsi_soc_dai[0].private_data = NULL;
1188 fsi_soc_dai[1].dev = NULL;
1189 fsi_soc_dai[1].private_data = NULL;
1190
1191 return 0; 1180 return 0;
1192} 1181}
1193 1182
@@ -1233,7 +1222,7 @@ static struct platform_device_id fsi_id_table[] = {
1233 1222
1234static struct platform_driver fsi_driver = { 1223static struct platform_driver fsi_driver = {
1235 .driver = { 1224 .driver = {
1236 .name = "sh_fsi", 1225 .name = "fsi-pcm-audio",
1237 .pm = &fsi_pm_ops, 1226 .pm = &fsi_pm_ops,
1238 }, 1227 },
1239 .probe = fsi_probe, 1228 .probe = fsi_probe,
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index 41db75af3c6..c87e3ff28a0 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -239,8 +239,7 @@ static int hac_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *params, 239 struct snd_pcm_hw_params *params,
240 struct snd_soc_dai *dai) 240 struct snd_soc_dai *dai)
241{ 241{
242 struct snd_soc_pcm_runtime *rtd = substream->private_data; 242 struct hac_priv *hac = &hac_cpu_data[dai->id];
243 struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id];
244 int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; 243 int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
245 244
246 switch (params->msbits) { 245 switch (params->msbits) {
@@ -271,10 +270,9 @@ static struct snd_soc_dai_ops hac_dai_ops = {
271 .hw_params = hac_hw_params, 270 .hw_params = hac_hw_params,
272}; 271};
273 272
274struct snd_soc_dai sh4_hac_dai[] = { 273static struct snd_soc_dai_driver sh4_hac_dai[] = {
275{ 274{
276 .name = "HAC0", 275 .name = "hac-dai.0",
277 .id = 0,
278 .ac97_control = 1, 276 .ac97_control = 1,
279 .playback = { 277 .playback = {
280 .rates = AC97_RATES, 278 .rates = AC97_RATES,
@@ -292,8 +290,7 @@ struct snd_soc_dai sh4_hac_dai[] = {
292}, 290},
293#ifdef CONFIG_CPU_SUBTYPE_SH7760 291#ifdef CONFIG_CPU_SUBTYPE_SH7760
294{ 292{
295 .name = "HAC1", 293 .name = "hac-dai.1",
296 .ac97_control = 1,
297 .id = 1, 294 .id = 1,
298 .playback = { 295 .playback = {
299 .rates = AC97_RATES, 296 .rates = AC97_RATES,
@@ -312,19 +309,40 @@ struct snd_soc_dai sh4_hac_dai[] = {
312}, 309},
313#endif 310#endif
314}; 311};
315EXPORT_SYMBOL_GPL(sh4_hac_dai);
316 312
317static int __init sh4_hac_init(void) 313static int __devinit hac_soc_platform_probe(struct platform_device *pdev)
314{
315 return snd_soc_register_dais(&pdev->dev, sh4_hac_dai,
316 ARRAY_SIZE(sh4_hac_dai));
317}
318
319static int __devexit hac_soc_platform_remove(struct platform_device *pdev)
320{
321 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_hac_dai));
322 return 0;
323}
324
325static struct platform_driver hac_pcm_driver = {
326 .driver = {
327 .name = "hac-pcm-audio",
328 .owner = THIS_MODULE,
329 },
330
331 .probe = hac_soc_platform_probe,
332 .remove = __devexit_p(hac_soc_platform_remove),
333};
334
335static int __init sh4_hac_pcm_init(void)
318{ 336{
319 return snd_soc_register_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai)); 337 return platform_driver_register(&hac_pcm_driver);
320} 338}
321module_init(sh4_hac_init); 339module_init(sh4_hac_pcm_init);
322 340
323static void __exit sh4_hac_exit(void) 341static void __exit sh4_hac_pcm_exit(void)
324{ 342{
325 snd_soc_unregister_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai)); 343 platform_driver_unregister(&hac_pcm_driver);
326} 344}
327module_exit(sh4_hac_exit); 345module_exit(sh4_hac_pcm_exit);
328 346
329MODULE_LICENSE("GPL"); 347MODULE_LICENSE("GPL");
330MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver"); 348MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
index b823a5c9b9b..866d78fb839 100644
--- a/sound/soc/sh/migor.c
+++ b/sound/soc/sh/migor.c
@@ -50,7 +50,7 @@ static int migor_hw_params(struct snd_pcm_substream *substream,
50 struct snd_pcm_hw_params *params) 50 struct snd_pcm_hw_params *params)
51{ 51{
52 struct snd_soc_pcm_runtime *rtd = substream->private_data; 52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 53 struct snd_soc_dai *codec_dai = rtd->codec_dai;
54 int ret; 54 int ret;
55 unsigned int rate = params_rate(params); 55 unsigned int rate = params_rate(params);
56 56
@@ -68,7 +68,7 @@ static int migor_hw_params(struct snd_pcm_substream *substream,
68 if (ret < 0) 68 if (ret < 0)
69 return ret; 69 return ret;
70 70
71 ret = snd_soc_dai_set_fmt(rtd->dai->cpu_dai, SND_SOC_DAIFMT_NB_IF | 71 ret = snd_soc_dai_set_fmt(rtd->cpu_dai, SND_SOC_DAIFMT_NB_IF |
72 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS); 72 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
73 if (ret < 0) 73 if (ret < 0)
74 return ret; 74 return ret;
@@ -81,7 +81,7 @@ static int migor_hw_params(struct snd_pcm_substream *substream,
81 clk_set_rate(&siumckb_clk, codec_freq); 81 clk_set_rate(&siumckb_clk, codec_freq);
82 dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq); 82 dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq);
83 83
84 ret = snd_soc_dai_set_sysclk(rtd->dai->cpu_dai, SIU_CLKB_EXT, 84 ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, SIU_CLKB_EXT,
85 codec_freq / 2, SND_SOC_CLOCK_IN); 85 codec_freq / 2, SND_SOC_CLOCK_IN);
86 86
87 if (!ret) 87 if (!ret)
@@ -93,7 +93,7 @@ static int migor_hw_params(struct snd_pcm_substream *substream,
93static int migor_hw_free(struct snd_pcm_substream *substream) 93static int migor_hw_free(struct snd_pcm_substream *substream)
94{ 94{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data; 95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 96 struct snd_soc_dai *codec_dai = rtd->codec_dai;
97 97
98 if (use_count) { 98 if (use_count) {
99 use_count--; 99 use_count--;
@@ -136,8 +136,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
136 { "Mic Bias", NULL, "External Microphone" }, 136 { "Mic Bias", NULL, "External Microphone" },
137}; 137};
138 138
139static int migor_dai_init(struct snd_soc_codec *codec) 139static int migor_dai_init(struct snd_soc_pcm_runtime *rtd)
140{ 140{
141 struct snd_soc_codec *codec = rtd->codec;
142
141 snd_soc_dapm_new_controls(codec, migor_dapm_widgets, 143 snd_soc_dapm_new_controls(codec, migor_dapm_widgets,
142 ARRAY_SIZE(migor_dapm_widgets)); 144 ARRAY_SIZE(migor_dapm_widgets));
143 145
@@ -150,8 +152,10 @@ static int migor_dai_init(struct snd_soc_codec *codec)
150static struct snd_soc_dai_link migor_dai = { 152static struct snd_soc_dai_link migor_dai = {
151 .name = "wm8978", 153 .name = "wm8978",
152 .stream_name = "WM8978", 154 .stream_name = "WM8978",
153 .cpu_dai = &siu_i2s_dai, 155 .cpu_dai_name = "siu-i2s-dai",
154 .codec_dai = &wm8978_dai, 156 .codec_dai_name = "wm8978-hifi",
157 .platform_name = "siu-pcm-audio",
158 .codec_name = "wm8978-codec.0-001a",
155 .ops = &migor_dai_ops, 159 .ops = &migor_dai_ops,
156 .init = migor_dai_init, 160 .init = migor_dai_init,
157}; 161};
@@ -159,17 +163,10 @@ static struct snd_soc_dai_link migor_dai = {
159/* migor audio machine driver */ 163/* migor audio machine driver */
160static struct snd_soc_card snd_soc_migor = { 164static struct snd_soc_card snd_soc_migor = {
161 .name = "Migo-R", 165 .name = "Migo-R",
162 .platform = &siu_platform,
163 .dai_link = &migor_dai, 166 .dai_link = &migor_dai,
164 .num_links = 1, 167 .num_links = 1,
165}; 168};
166 169
167/* migor audio subsystem */
168static struct snd_soc_device migor_snd_devdata = {
169 .card = &snd_soc_migor,
170 .codec_dev = &soc_codec_dev_wm8978,
171};
172
173static struct platform_device *migor_snd_device; 170static struct platform_device *migor_snd_device;
174 171
175static int __init migor_init(void) 172static int __init migor_init(void)
@@ -187,9 +184,7 @@ static int __init migor_init(void)
187 goto epdevalloc; 184 goto epdevalloc;
188 } 185 }
189 186
190 platform_set_drvdata(migor_snd_device, &migor_snd_devdata); 187 platform_set_drvdata(migor_snd_device, &snd_soc_migor);
191
192 migor_snd_devdata.dev = &migor_snd_device->dev;
193 188
194 ret = platform_device_add(migor_snd_device); 189 ret = platform_device_add(migor_snd_device);
195 if (ret) 190 if (ret)
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index ce7f95b59de..b897f7b96d8 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -15,41 +15,35 @@
15#include <sound/soc-dapm.h> 15#include <sound/soc-dapm.h>
16#include <asm/io.h> 16#include <asm/io.h>
17 17
18#include "../codecs/ac97.h"
19
20#define IPSEL 0xFE400034 18#define IPSEL 0xFE400034
21 19
22/* platform specific structs can be declared here */ 20/* platform specific structs can be declared here */
23extern struct snd_soc_dai sh4_hac_dai[2]; 21extern struct snd_soc_dai_driver sh4_hac_dai[2];
24extern struct snd_soc_platform sh7760_soc_platform; 22extern struct snd_soc_platform_driver sh7760_soc_platform;
25 23
26static int machine_init(struct snd_soc_codec *codec) 24static int machine_init(struct snd_soc_pcm_runtime *rtd)
27{ 25{
28 snd_soc_dapm_sync(codec); 26 snd_soc_dapm_sync(rtd->codec);
29 return 0; 27 return 0;
30} 28}
31 29
32static struct snd_soc_dai_link sh7760_ac97_dai = { 30static struct snd_soc_dai_link sh7760_ac97_dai = {
33 .name = "AC97", 31 .name = "AC97",
34 .stream_name = "AC97 HiFi", 32 .stream_name = "AC97 HiFi",
35 .cpu_dai = &sh4_hac_dai[0], /* HAC0 */ 33 .cpu_dai_name = "hac-dai.0", /* HAC0 */
36 .codec_dai = &ac97_dai, 34 .codec_dai_name = "ac97-hifi",
35 .platform_name = "sh7760-pcm-audio",
36 .codec_name = "ac97-codec",
37 .init = machine_init, 37 .init = machine_init,
38 .ops = NULL, 38 .ops = NULL,
39}; 39};
40 40
41static struct snd_soc_card sh7760_ac97_soc_machine = { 41static struct snd_soc_card sh7760_ac97_soc_machine = {
42 .name = "SH7760 AC97", 42 .name = "SH7760 AC97",
43 .platform = &sh7760_soc_platform,
44 .dai_link = &sh7760_ac97_dai, 43 .dai_link = &sh7760_ac97_dai,
45 .num_links = 1, 44 .num_links = 1,
46}; 45};
47 46
48static struct snd_soc_device sh7760_ac97_snd_devdata = {
49 .card = &sh7760_ac97_soc_machine,
50 .codec_dev = &soc_codec_dev_ac97,
51};
52
53static struct platform_device *sh7760_ac97_snd_device; 47static struct platform_device *sh7760_ac97_snd_device;
54 48
55static int __init sh7760_ac97_init(void) 49static int __init sh7760_ac97_init(void)
@@ -67,8 +61,7 @@ static int __init sh7760_ac97_init(void)
67 goto out; 61 goto out;
68 62
69 platform_set_drvdata(sh7760_ac97_snd_device, 63 platform_set_drvdata(sh7760_ac97_snd_device,
70 &sh7760_ac97_snd_devdata); 64 &sh7760_ac97_soc_machine);
71 sh7760_ac97_snd_devdata.dev = &sh7760_ac97_snd_device->dev;
72 ret = platform_device_add(sh7760_ac97_snd_device); 65 ret = platform_device_add(sh7760_ac97_snd_device);
73 66
74 if (ret) 67 if (ret)
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
index 492b1cae24c..aa239ff7310 100644
--- a/sound/soc/sh/siu.h
+++ b/sound/soc/sh/siu.h
@@ -181,8 +181,9 @@ static inline u32 siu_read32(u32 __iomem *addr)
181#define SIU_BRGBSEL (0x108 / sizeof(u32)) 181#define SIU_BRGBSEL (0x108 / sizeof(u32))
182#define SIU_BRRB (0x10c / sizeof(u32)) 182#define SIU_BRRB (0x10c / sizeof(u32))
183 183
184extern struct snd_soc_platform siu_platform; 184extern struct snd_soc_platform_driver siu_platform;
185extern struct snd_soc_dai siu_i2s_dai; 185extern struct snd_soc_dai_driver siu_i2s_dai;
186extern struct siu_info *siu_i2s_data;
186 187
187int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card); 188int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card);
188void siu_free_port(struct siu_port *port_info); 189void siu_free_port(struct siu_port *port_info);
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index eeed5edd722..827940a8e24 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -71,6 +71,9 @@ struct port_flag {
71 struct format_flag capture; 71 struct format_flag capture;
72}; 72};
73 73
74struct siu_info *siu_i2s_data = NULL;
75EXPORT_SYMBOL_GPL(siu_i2s_data);
76
74static struct port_flag siu_flags[SIU_PORT_NUM] = { 77static struct port_flag siu_flags[SIU_PORT_NUM] = {
75 [SIU_PORT_A] = { 78 [SIU_PORT_A] = {
76 .playback = { 79 .playback = {
@@ -104,13 +107,13 @@ static struct port_flag siu_flags[SIU_PORT_NUM] = {
104 107
105static void siu_dai_start(struct siu_port *port_info) 108static void siu_dai_start(struct siu_port *port_info)
106{ 109{
107 struct siu_info *info = siu_i2s_dai.private_data; 110 struct siu_info *info = siu_i2s_data;
108 u32 __iomem *base = info->reg; 111 u32 __iomem *base = info->reg;
109 112
110 dev_dbg(port_info->pcm->card->dev, "%s\n", __func__); 113 dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
111 114
112 /* Turn on SIU clock */ 115 /* Turn on SIU clock */
113 pm_runtime_get_sync(siu_i2s_dai.dev); 116 pm_runtime_get_sync(port_info->pcm->card->dev);
114 117
115 /* Issue software reset to siu */ 118 /* Issue software reset to siu */
116 siu_write32(base + SIU_SRCTL, 0); 119 siu_write32(base + SIU_SRCTL, 0);
@@ -148,21 +151,21 @@ static void siu_dai_start(struct siu_port *port_info)
148 siu_write32(base + SIU_SBDVCB, port_info->capture.volume); 151 siu_write32(base + SIU_SBDVCB, port_info->capture.volume);
149} 152}
150 153
151static void siu_dai_stop(void) 154static void siu_dai_stop(struct siu_port *port_info)
152{ 155{
153 struct siu_info *info = siu_i2s_dai.private_data; 156 struct siu_info *info = siu_i2s_data;
154 u32 __iomem *base = info->reg; 157 u32 __iomem *base = info->reg;
155 158
156 /* SIU software reset */ 159 /* SIU software reset */
157 siu_write32(base + SIU_SRCTL, 0); 160 siu_write32(base + SIU_SRCTL, 0);
158 161
159 /* Turn off SIU clock */ 162 /* Turn off SIU clock */
160 pm_runtime_put_sync(siu_i2s_dai.dev); 163 pm_runtime_put_sync(port_info->pcm->card->dev);
161} 164}
162 165
163static void siu_dai_spbAselect(struct siu_port *port_info) 166static void siu_dai_spbAselect(struct siu_port *port_info)
164{ 167{
165 struct siu_info *info = siu_i2s_dai.private_data; 168 struct siu_info *info = siu_i2s_data;
166 struct siu_firmware *fw = &info->fw; 169 struct siu_firmware *fw = &info->fw;
167 u32 *ydef = fw->yram0; 170 u32 *ydef = fw->yram0;
168 u32 idx; 171 u32 idx;
@@ -187,7 +190,7 @@ static void siu_dai_spbAselect(struct siu_port *port_info)
187 190
188static void siu_dai_spbBselect(struct siu_port *port_info) 191static void siu_dai_spbBselect(struct siu_port *port_info)
189{ 192{
190 struct siu_info *info = siu_i2s_dai.private_data; 193 struct siu_info *info = siu_i2s_data;
191 struct siu_firmware *fw = &info->fw; 194 struct siu_firmware *fw = &info->fw;
192 u32 *ydef = fw->yram0; 195 u32 *ydef = fw->yram0;
193 u32 idx; 196 u32 idx;
@@ -207,7 +210,7 @@ static void siu_dai_spbBselect(struct siu_port *port_info)
207 210
208static void siu_dai_open(struct siu_stream *siu_stream) 211static void siu_dai_open(struct siu_stream *siu_stream)
209{ 212{
210 struct siu_info *info = siu_i2s_dai.private_data; 213 struct siu_info *info = siu_i2s_data;
211 u32 __iomem *base = info->reg; 214 u32 __iomem *base = info->reg;
212 u32 srctl, ifctl; 215 u32 srctl, ifctl;
213 216
@@ -238,7 +241,7 @@ static void siu_dai_open(struct siu_stream *siu_stream)
238 */ 241 */
239static void siu_dai_pcmdatapack(struct siu_stream *siu_stream) 242static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
240{ 243{
241 struct siu_info *info = siu_i2s_dai.private_data; 244 struct siu_info *info = siu_i2s_data;
242 u32 __iomem *base = info->reg; 245 u32 __iomem *base = info->reg;
243 u32 dpak; 246 u32 dpak;
244 247
@@ -258,7 +261,7 @@ static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
258 261
259static int siu_dai_spbstart(struct siu_port *port_info) 262static int siu_dai_spbstart(struct siu_port *port_info)
260{ 263{
261 struct siu_info *info = siu_i2s_dai.private_data; 264 struct siu_info *info = siu_i2s_data;
262 u32 __iomem *base = info->reg; 265 u32 __iomem *base = info->reg;
263 struct siu_firmware *fw = &info->fw; 266 struct siu_firmware *fw = &info->fw;
264 u32 *ydef = fw->yram0; 267 u32 *ydef = fw->yram0;
@@ -323,7 +326,7 @@ static int siu_dai_spbstart(struct siu_port *port_info)
323 326
324static void siu_dai_spbstop(struct siu_port *port_info) 327static void siu_dai_spbstop(struct siu_port *port_info)
325{ 328{
326 struct siu_info *info = siu_i2s_dai.private_data; 329 struct siu_info *info = siu_i2s_data;
327 u32 __iomem *base = info->reg; 330 u32 __iomem *base = info->reg;
328 331
329 siu_write32(base + SIU_SBACTIV, 0); 332 siu_write32(base + SIU_SBACTIV, 0);
@@ -402,7 +405,7 @@ static int siu_dai_put_volume(struct snd_kcontrol *kctrl,
402{ 405{
403 struct siu_port *port_info = snd_kcontrol_chip(kctrl); 406 struct siu_port *port_info = snd_kcontrol_chip(kctrl);
404 struct device *dev = port_info->pcm->card->dev; 407 struct device *dev = port_info->pcm->card->dev;
405 struct siu_info *info = siu_i2s_dai.private_data; 408 struct siu_info *info = siu_i2s_data;
406 u32 __iomem *base = info->reg; 409 u32 __iomem *base = info->reg;
407 u32 new_vol; 410 u32 new_vol;
408 u32 cur_vol; 411 u32 cur_vol;
@@ -510,7 +513,7 @@ void siu_free_port(struct siu_port *port_info)
510static int siu_dai_startup(struct snd_pcm_substream *substream, 513static int siu_dai_startup(struct snd_pcm_substream *substream,
511 struct snd_soc_dai *dai) 514 struct snd_soc_dai *dai)
512{ 515{
513 struct siu_info *info = siu_i2s_dai.private_data; 516 struct siu_info *info = snd_soc_dai_get_drvdata(dai);
514 struct snd_pcm_runtime *rt = substream->runtime; 517 struct snd_pcm_runtime *rt = substream->runtime;
515 struct siu_port *port_info = siu_port_info(substream); 518 struct siu_port *port_info = siu_port_info(substream);
516 int ret; 519 int ret;
@@ -532,7 +535,7 @@ static int siu_dai_startup(struct snd_pcm_substream *substream,
532static void siu_dai_shutdown(struct snd_pcm_substream *substream, 535static void siu_dai_shutdown(struct snd_pcm_substream *substream,
533 struct snd_soc_dai *dai) 536 struct snd_soc_dai *dai)
534{ 537{
535 struct siu_info *info = siu_i2s_dai.private_data; 538 struct siu_info *info = snd_soc_dai_get_drvdata(dai);
536 struct siu_port *port_info = siu_port_info(substream); 539 struct siu_port *port_info = siu_port_info(substream);
537 540
538 dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__, 541 dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
@@ -548,7 +551,7 @@ static void siu_dai_shutdown(struct snd_pcm_substream *substream,
548 /* during stmread or stmwrite ? */ 551 /* during stmread or stmwrite ? */
549 BUG_ON(port_info->playback.rw_flg || port_info->capture.rw_flg); 552 BUG_ON(port_info->playback.rw_flg || port_info->capture.rw_flg);
550 siu_dai_spbstop(port_info); 553 siu_dai_spbstop(port_info);
551 siu_dai_stop(); 554 siu_dai_stop(port_info);
552 } 555 }
553} 556}
554 557
@@ -556,7 +559,7 @@ static void siu_dai_shutdown(struct snd_pcm_substream *substream,
556static int siu_dai_prepare(struct snd_pcm_substream *substream, 559static int siu_dai_prepare(struct snd_pcm_substream *substream,
557 struct snd_soc_dai *dai) 560 struct snd_soc_dai *dai)
558{ 561{
559 struct siu_info *info = siu_i2s_dai.private_data; 562 struct siu_info *info = snd_soc_dai_get_drvdata(dai);
560 struct snd_pcm_runtime *rt = substream->runtime; 563 struct snd_pcm_runtime *rt = substream->runtime;
561 struct siu_port *port_info = siu_port_info(substream); 564 struct siu_port *port_info = siu_port_info(substream);
562 struct siu_stream *siu_stream; 565 struct siu_stream *siu_stream;
@@ -605,7 +608,7 @@ fail:
605static int siu_dai_set_fmt(struct snd_soc_dai *dai, 608static int siu_dai_set_fmt(struct snd_soc_dai *dai,
606 unsigned int fmt) 609 unsigned int fmt)
607{ 610{
608 struct siu_info *info = siu_i2s_dai.private_data; 611 struct siu_info *info = snd_soc_dai_get_drvdata(dai);
609 u32 __iomem *base = info->reg; 612 u32 __iomem *base = info->reg;
610 u32 ifctl; 613 u32 ifctl;
611 614
@@ -671,11 +674,11 @@ static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
671 return -EINVAL; 674 return -EINVAL;
672 } 675 }
673 676
674 siu_clk = clk_get(siu_i2s_dai.dev, siu_name); 677 siu_clk = clk_get(dai->dev, siu_name);
675 if (IS_ERR(siu_clk)) 678 if (IS_ERR(siu_clk))
676 return PTR_ERR(siu_clk); 679 return PTR_ERR(siu_clk);
677 680
678 parent_clk = clk_get(siu_i2s_dai.dev, parent_name); 681 parent_clk = clk_get(dai->dev, parent_name);
679 if (!IS_ERR(parent_clk)) { 682 if (!IS_ERR(parent_clk)) {
680 ret = clk_set_parent(siu_clk, parent_clk); 683 ret = clk_set_parent(siu_clk, parent_clk);
681 if (!ret) 684 if (!ret)
@@ -696,9 +699,8 @@ static struct snd_soc_dai_ops siu_dai_ops = {
696 .set_fmt = siu_dai_set_fmt, 699 .set_fmt = siu_dai_set_fmt,
697}; 700};
698 701
699struct snd_soc_dai siu_i2s_dai = { 702static struct snd_soc_dai_driver siu_i2s_dai = {
700 .name = "sh-siu", 703 .name = "sui-i2s-dai",
701 .id = 0,
702 .playback = { 704 .playback = {
703 .channels_min = 2, 705 .channels_min = 2,
704 .channels_max = 2, 706 .channels_max = 2,
@@ -713,7 +715,6 @@ struct snd_soc_dai siu_i2s_dai = {
713 }, 715 },
714 .ops = &siu_dai_ops, 716 .ops = &siu_dai_ops,
715}; 717};
716EXPORT_SYMBOL_GPL(siu_i2s_dai);
717 718
718static int __devinit siu_probe(struct platform_device *pdev) 719static int __devinit siu_probe(struct platform_device *pdev)
719{ 720{
@@ -725,6 +726,7 @@ static int __devinit siu_probe(struct platform_device *pdev)
725 info = kmalloc(sizeof(*info), GFP_KERNEL); 726 info = kmalloc(sizeof(*info), GFP_KERNEL);
726 if (!info) 727 if (!info)
727 return -ENOMEM; 728 return -ENOMEM;
729 siu_i2s_data = info;
728 730
729 ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev); 731 ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
730 if (ret) 732 if (ret)
@@ -767,14 +769,14 @@ static int __devinit siu_probe(struct platform_device *pdev)
767 if (!info->reg) 769 if (!info->reg)
768 goto emapreg; 770 goto emapreg;
769 771
770 siu_i2s_dai.dev = &pdev->dev; 772 dev_set_drvdata(&pdev->dev, info);
771 siu_i2s_dai.private_data = info;
772 773
773 ret = snd_soc_register_dais(&siu_i2s_dai, 1); 774 /* register using ARRAY version so we can keep dai name */
775 ret = snd_soc_register_dais(&pdev->dev, &siu_i2s_dai, 1);
774 if (ret < 0) 776 if (ret < 0)
775 goto edaiinit; 777 goto edaiinit;
776 778
777 ret = snd_soc_register_platform(&siu_platform); 779 ret = snd_soc_register_platform(&pdev->dev, &siu_platform);
778 if (ret < 0) 780 if (ret < 0)
779 goto esocregp; 781 goto esocregp;
780 782
@@ -783,7 +785,7 @@ static int __devinit siu_probe(struct platform_device *pdev)
783 return ret; 785 return ret;
784 786
785esocregp: 787esocregp:
786 snd_soc_unregister_dais(&siu_i2s_dai, 1); 788 snd_soc_unregister_dai(&pdev->dev);
787edaiinit: 789edaiinit:
788 iounmap(info->reg); 790 iounmap(info->reg);
789emapreg: 791emapreg:
@@ -804,13 +806,13 @@ ereqfw:
804 806
805static int __devexit siu_remove(struct platform_device *pdev) 807static int __devexit siu_remove(struct platform_device *pdev)
806{ 808{
807 struct siu_info *info = siu_i2s_dai.private_data; 809 struct siu_info *info = dev_get_drvdata(&pdev->dev);
808 struct resource *res; 810 struct resource *res;
809 811
810 pm_runtime_disable(&pdev->dev); 812 pm_runtime_disable(&pdev->dev);
811 813
812 snd_soc_unregister_platform(&siu_platform); 814 snd_soc_unregister_platform(&pdev->dev);
813 snd_soc_unregister_dais(&siu_i2s_dai, 1); 815 snd_soc_unregister_dai(&pdev->dev);
814 816
815 iounmap(info->reg); 817 iounmap(info->reg);
816 iounmap(info->yram); 818 iounmap(info->yram);
@@ -826,7 +828,7 @@ static int __devexit siu_remove(struct platform_device *pdev)
826 828
827static struct platform_driver siu_driver = { 829static struct platform_driver siu_driver = {
828 .driver = { 830 .driver = {
829 .name = "sh_siu", 831 .name = "siu-pcm-audio",
830 }, 832 },
831 .probe = siu_probe, 833 .probe = siu_probe,
832 .remove = __devexit_p(siu_remove), 834 .remove = __devexit_p(siu_remove),
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index 36170be15aa..44047699332 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -48,7 +48,7 @@ struct siu_port *siu_ports[SIU_PORT_NUM];
48/* transfersize is number of u32 dma transfers per period */ 48/* transfersize is number of u32 dma transfers per period */
49static int siu_pcm_stmwrite_stop(struct siu_port *port_info) 49static int siu_pcm_stmwrite_stop(struct siu_port *port_info)
50{ 50{
51 struct siu_info *info = siu_i2s_dai.private_data; 51 struct siu_info *info = siu_i2s_data;
52 u32 __iomem *base = info->reg; 52 u32 __iomem *base = info->reg;
53 struct siu_stream *siu_stream = &port_info->playback; 53 struct siu_stream *siu_stream = &port_info->playback;
54 u32 stfifo; 54 u32 stfifo;
@@ -114,7 +114,7 @@ static void siu_dma_tx_complete(void *arg)
114static int siu_pcm_wr_set(struct siu_port *port_info, 114static int siu_pcm_wr_set(struct siu_port *port_info,
115 dma_addr_t buff, u32 size) 115 dma_addr_t buff, u32 size)
116{ 116{
117 struct siu_info *info = siu_i2s_dai.private_data; 117 struct siu_info *info = siu_i2s_data;
118 u32 __iomem *base = info->reg; 118 u32 __iomem *base = info->reg;
119 struct siu_stream *siu_stream = &port_info->playback; 119 struct siu_stream *siu_stream = &port_info->playback;
120 struct snd_pcm_substream *substream = siu_stream->substream; 120 struct snd_pcm_substream *substream = siu_stream->substream;
@@ -161,7 +161,7 @@ static int siu_pcm_wr_set(struct siu_port *port_info,
161static int siu_pcm_rd_set(struct siu_port *port_info, 161static int siu_pcm_rd_set(struct siu_port *port_info,
162 dma_addr_t buff, size_t size) 162 dma_addr_t buff, size_t size)
163{ 163{
164 struct siu_info *info = siu_i2s_dai.private_data; 164 struct siu_info *info = siu_i2s_data;
165 u32 __iomem *base = info->reg; 165 u32 __iomem *base = info->reg;
166 struct siu_stream *siu_stream = &port_info->capture; 166 struct siu_stream *siu_stream = &port_info->capture;
167 struct snd_pcm_substream *substream = siu_stream->substream; 167 struct snd_pcm_substream *substream = siu_stream->substream;
@@ -270,7 +270,7 @@ static int siu_pcm_stmread_start(struct siu_port *port_info)
270 270
271static int siu_pcm_stmread_stop(struct siu_port *port_info) 271static int siu_pcm_stmread_stop(struct siu_port *port_info)
272{ 272{
273 struct siu_info *info = siu_i2s_dai.private_data; 273 struct siu_info *info = siu_i2s_data;
274 u32 __iomem *base = info->reg; 274 u32 __iomem *base = info->reg;
275 struct siu_stream *siu_stream = &port_info->capture; 275 struct siu_stream *siu_stream = &port_info->capture;
276 struct device *dev = siu_stream->substream->pcm->card->dev; 276 struct device *dev = siu_stream->substream->pcm->card->dev;
@@ -294,7 +294,7 @@ static int siu_pcm_stmread_stop(struct siu_port *port_info)
294static int siu_pcm_hw_params(struct snd_pcm_substream *ss, 294static int siu_pcm_hw_params(struct snd_pcm_substream *ss,
295 struct snd_pcm_hw_params *hw_params) 295 struct snd_pcm_hw_params *hw_params)
296{ 296{
297 struct siu_info *info = siu_i2s_dai.private_data; 297 struct siu_info *info = siu_i2s_data;
298 struct device *dev = ss->pcm->card->dev; 298 struct device *dev = ss->pcm->card->dev;
299 int ret; 299 int ret;
300 300
@@ -309,7 +309,7 @@ static int siu_pcm_hw_params(struct snd_pcm_substream *ss,
309 309
310static int siu_pcm_hw_free(struct snd_pcm_substream *ss) 310static int siu_pcm_hw_free(struct snd_pcm_substream *ss)
311{ 311{
312 struct siu_info *info = siu_i2s_dai.private_data; 312 struct siu_info *info = siu_i2s_data;
313 struct siu_port *port_info = siu_port_info(ss); 313 struct siu_port *port_info = siu_port_info(ss);
314 struct device *dev = ss->pcm->card->dev; 314 struct device *dev = ss->pcm->card->dev;
315 struct siu_stream *siu_stream; 315 struct siu_stream *siu_stream;
@@ -340,11 +340,12 @@ static bool filter(struct dma_chan *chan, void *slave)
340static int siu_pcm_open(struct snd_pcm_substream *ss) 340static int siu_pcm_open(struct snd_pcm_substream *ss)
341{ 341{
342 /* Playback / Capture */ 342 /* Playback / Capture */
343 struct siu_info *info = siu_i2s_dai.private_data; 343 struct snd_soc_pcm_runtime *rtd = ss->private_data;
344 struct siu_platform *pdata = snd_soc_platform_get_drvdata(rtd->platform);
345 struct siu_info *info = siu_i2s_data;
344 struct siu_port *port_info = siu_port_info(ss); 346 struct siu_port *port_info = siu_port_info(ss);
345 struct siu_stream *siu_stream; 347 struct siu_stream *siu_stream;
346 u32 port = info->port_id; 348 u32 port = info->port_id;
347 struct siu_platform *pdata = siu_i2s_dai.dev->platform_data;
348 struct device *dev = ss->pcm->card->dev; 349 struct device *dev = ss->pcm->card->dev;
349 dma_cap_mask_t mask; 350 dma_cap_mask_t mask;
350 struct sh_dmae_slave *param; 351 struct sh_dmae_slave *param;
@@ -381,7 +382,7 @@ static int siu_pcm_open(struct snd_pcm_substream *ss)
381 382
382static int siu_pcm_close(struct snd_pcm_substream *ss) 383static int siu_pcm_close(struct snd_pcm_substream *ss)
383{ 384{
384 struct siu_info *info = siu_i2s_dai.private_data; 385 struct siu_info *info = siu_i2s_data;
385 struct device *dev = ss->pcm->card->dev; 386 struct device *dev = ss->pcm->card->dev;
386 struct siu_port *port_info = siu_port_info(ss); 387 struct siu_port *port_info = siu_port_info(ss);
387 struct siu_stream *siu_stream; 388 struct siu_stream *siu_stream;
@@ -403,7 +404,7 @@ static int siu_pcm_close(struct snd_pcm_substream *ss)
403 404
404static int siu_pcm_prepare(struct snd_pcm_substream *ss) 405static int siu_pcm_prepare(struct snd_pcm_substream *ss)
405{ 406{
406 struct siu_info *info = siu_i2s_dai.private_data; 407 struct siu_info *info = siu_i2s_data;
407 struct siu_port *port_info = siu_port_info(ss); 408 struct siu_port *port_info = siu_port_info(ss);
408 struct device *dev = ss->pcm->card->dev; 409 struct device *dev = ss->pcm->card->dev;
409 struct snd_pcm_runtime *rt = ss->runtime; 410 struct snd_pcm_runtime *rt = ss->runtime;
@@ -449,7 +450,7 @@ static int siu_pcm_prepare(struct snd_pcm_substream *ss)
449 450
450static int siu_pcm_trigger(struct snd_pcm_substream *ss, int cmd) 451static int siu_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
451{ 452{
452 struct siu_info *info = siu_i2s_dai.private_data; 453 struct siu_info *info = siu_i2s_data;
453 struct device *dev = ss->pcm->card->dev; 454 struct device *dev = ss->pcm->card->dev;
454 struct siu_port *port_info = siu_port_info(ss); 455 struct siu_port *port_info = siu_port_info(ss);
455 int ret; 456 int ret;
@@ -492,7 +493,7 @@ static int siu_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
492static snd_pcm_uframes_t siu_pcm_pointer_dma(struct snd_pcm_substream *ss) 493static snd_pcm_uframes_t siu_pcm_pointer_dma(struct snd_pcm_substream *ss)
493{ 494{
494 struct device *dev = ss->pcm->card->dev; 495 struct device *dev = ss->pcm->card->dev;
495 struct siu_info *info = siu_i2s_dai.private_data; 496 struct siu_info *info = siu_i2s_data;
496 u32 __iomem *base = info->reg; 497 u32 __iomem *base = info->reg;
497 struct siu_port *port_info = siu_port_info(ss); 498 struct siu_port *port_info = siu_port_info(ss);
498 struct snd_pcm_runtime *rt = ss->runtime; 499 struct snd_pcm_runtime *rt = ss->runtime;
@@ -528,7 +529,7 @@ static int siu_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
528 struct snd_pcm *pcm) 529 struct snd_pcm *pcm)
529{ 530{
530 /* card->dev == socdev->dev, see snd_soc_new_pcms() */ 531 /* card->dev == socdev->dev, see snd_soc_new_pcms() */
531 struct siu_info *info = siu_i2s_dai.private_data; 532 struct siu_info *info = siu_i2s_data;
532 struct platform_device *pdev = to_platform_device(card->dev); 533 struct platform_device *pdev = to_platform_device(card->dev);
533 int ret; 534 int ret;
534 int i; 535 int i;
@@ -605,9 +606,8 @@ static struct snd_pcm_ops siu_pcm_ops = {
605 .pointer = siu_pcm_pointer_dma, 606 .pointer = siu_pcm_pointer_dma,
606}; 607};
607 608
608struct snd_soc_platform siu_platform = { 609struct snd_soc_platform_driver siu_platform = {
609 .name = "siu-audio", 610 .ops = &siu_pcm_ops,
610 .pcm_ops = &siu_pcm_ops,
611 .pcm_new = siu_pcm_new, 611 .pcm_new = siu_pcm_new,
612 .pcm_free = siu_pcm_free, 612 .pcm_free = siu_pcm_free,
613}; 613};
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index b378096cadb..40bbdf1591d 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -92,8 +92,7 @@ struct ssi_priv {
92static int ssi_startup(struct snd_pcm_substream *substream, 92static int ssi_startup(struct snd_pcm_substream *substream,
93 struct snd_soc_dai *dai) 93 struct snd_soc_dai *dai)
94{ 94{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data; 95 struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
96 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
97 if (ssi->inuse) { 96 if (ssi->inuse) {
98 pr_debug("ssi: already in use!\n"); 97 pr_debug("ssi: already in use!\n");
99 return -EBUSY; 98 return -EBUSY;
@@ -105,8 +104,7 @@ static int ssi_startup(struct snd_pcm_substream *substream,
105static void ssi_shutdown(struct snd_pcm_substream *substream, 104static void ssi_shutdown(struct snd_pcm_substream *substream,
106 struct snd_soc_dai *dai) 105 struct snd_soc_dai *dai)
107{ 106{
108 struct snd_soc_pcm_runtime *rtd = substream->private_data; 107 struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
109 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
110 108
111 ssi->inuse = 0; 109 ssi->inuse = 0;
112} 110}
@@ -114,8 +112,7 @@ static void ssi_shutdown(struct snd_pcm_substream *substream,
114static int ssi_trigger(struct snd_pcm_substream *substream, int cmd, 112static int ssi_trigger(struct snd_pcm_substream *substream, int cmd,
115 struct snd_soc_dai *dai) 113 struct snd_soc_dai *dai)
116{ 114{
117 struct snd_soc_pcm_runtime *rtd = substream->private_data; 115 struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
118 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
119 116
120 switch (cmd) { 117 switch (cmd) {
121 case SNDRV_PCM_TRIGGER_START: 118 case SNDRV_PCM_TRIGGER_START:
@@ -135,8 +132,7 @@ static int ssi_hw_params(struct snd_pcm_substream *substream,
135 struct snd_pcm_hw_params *params, 132 struct snd_pcm_hw_params *params,
136 struct snd_soc_dai *dai) 133 struct snd_soc_dai *dai)
137{ 134{
138 struct snd_soc_pcm_runtime *rtd = substream->private_data; 135 struct ssi_priv *ssi = &ssi_cpu_data[dai->id];
139 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
140 unsigned long ssicr = SSIREG(SSICR); 136 unsigned long ssicr = SSIREG(SSICR);
141 unsigned int bits, channels, swl, recv, i; 137 unsigned int bits, channels, swl, recv, i;
142 138
@@ -346,10 +342,9 @@ static struct snd_soc_dai_ops ssi_dai_ops = {
346 .set_fmt = ssi_set_fmt, 342 .set_fmt = ssi_set_fmt,
347}; 343};
348 344
349struct snd_soc_dai sh4_ssi_dai[] = { 345struct snd_soc_dai_driver sh4_ssi_dai[] = {
350{ 346{
351 .name = "SSI0", 347 .name = "ssi-dai.0",
352 .id = 0,
353 .playback = { 348 .playback = {
354 .rates = SSI_RATES, 349 .rates = SSI_RATES,
355 .formats = SSI_FMTS, 350 .formats = SSI_FMTS,
@@ -366,8 +361,7 @@ struct snd_soc_dai sh4_ssi_dai[] = {
366}, 361},
367#ifdef CONFIG_CPU_SUBTYPE_SH7760 362#ifdef CONFIG_CPU_SUBTYPE_SH7760
368{ 363{
369 .name = "SSI1", 364 .name = "ssi-dai.1",
370 .id = 1,
371 .playback = { 365 .playback = {
372 .rates = SSI_RATES, 366 .rates = SSI_RATES,
373 .formats = SSI_FMTS, 367 .formats = SSI_FMTS,
@@ -384,19 +378,40 @@ struct snd_soc_dai sh4_ssi_dai[] = {
384}, 378},
385#endif 379#endif
386}; 380};
387EXPORT_SYMBOL_GPL(sh4_ssi_dai);
388 381
389static int __init sh4_ssi_init(void) 382static int __devinit sh4_soc_dai_probe(struct platform_device *pdev)
383{
384 return snd_soc_register_dais(&pdev->dev, sh4_ssi_dai,
385 ARRAY_SIZE(sh4_ssi_dai));
386}
387
388static int __devexit sh4_soc_dai_remove(struct platform_device *pdev)
389{
390 snd_soc_unregister_dai(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai));
391 return 0;
392}
393
394static struct platform_driver sh4_ssi_driver = {
395 .driver = {
396 .name = "sh4-ssi-dai",
397 .owner = THIS_MODULE,
398 },
399
400 .probe = sh4_soc_dai_probe,
401 .remove = __devexit_p(sh4_soc_dai_remove),
402};
403
404static int __init snd_sh4_ssi_init(void)
390{ 405{
391 return snd_soc_register_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai)); 406 return platform_driver_register(&sh4_ssi_driver);
392} 407}
393module_init(sh4_ssi_init); 408module_init(snd_sh4_ssi_init);
394 409
395static void __exit sh4_ssi_exit(void) 410static void __exit snd_sh4_ssi_exit(void)
396{ 411{
397 snd_soc_unregister_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai)); 412 platform_driver_unregister(&sh4_ssi_driver);
398} 413}
399module_exit(sh4_ssi_exit); 414module_exit(snd_sh4_ssi_exit);
400 415
401MODULE_LICENSE("GPL"); 416MODULE_LICENSE("GPL");
402MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver"); 417MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver");
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 472af38188c..83cd8ed944b 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -19,7 +19,7 @@ static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
19 unsigned int reg) 19 unsigned int reg)
20{ 20{
21 u16 *cache = codec->reg_cache; 21 u16 *cache = codec->reg_cache;
22 if (reg >= codec->reg_cache_size) 22 if (reg >= codec->driver->reg_cache_size)
23 return -1; 23 return -1;
24 return cache[reg]; 24 return cache[reg];
25} 25}
@@ -31,12 +31,12 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
31 u8 data[2]; 31 u8 data[2];
32 int ret; 32 int ret;
33 33
34 BUG_ON(codec->volatile_register); 34 BUG_ON(codec->driver->volatile_register);
35 35
36 data[0] = (reg << 4) | ((value >> 8) & 0x000f); 36 data[0] = (reg << 4) | ((value >> 8) & 0x000f);
37 data[1] = value & 0x00ff; 37 data[1] = value & 0x00ff;
38 38
39 if (reg < codec->reg_cache_size) 39 if (reg < codec->driver->reg_cache_size)
40 cache[reg] = value; 40 cache[reg] = value;
41 41
42 if (codec->cache_only) { 42 if (codec->cache_only) {
@@ -89,7 +89,7 @@ static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
89 unsigned int reg) 89 unsigned int reg)
90{ 90{
91 u16 *cache = codec->reg_cache; 91 u16 *cache = codec->reg_cache;
92 if (reg >= codec->reg_cache_size) 92 if (reg >= codec->driver->reg_cache_size)
93 return -1; 93 return -1;
94 return cache[reg]; 94 return cache[reg];
95} 95}
@@ -101,12 +101,12 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
101 u8 data[2]; 101 u8 data[2];
102 int ret; 102 int ret;
103 103
104 BUG_ON(codec->volatile_register); 104 BUG_ON(codec->driver->volatile_register);
105 105
106 data[0] = (reg << 1) | ((value >> 8) & 0x0001); 106 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
107 data[1] = value & 0x00ff; 107 data[1] = value & 0x00ff;
108 108
109 if (reg < codec->reg_cache_size) 109 if (reg < codec->driver->reg_cache_size)
110 cache[reg] = value; 110 cache[reg] = value;
111 111
112 if (codec->cache_only) { 112 if (codec->cache_only) {
@@ -161,13 +161,13 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
161 u8 *cache = codec->reg_cache; 161 u8 *cache = codec->reg_cache;
162 u8 data[2]; 162 u8 data[2];
163 163
164 BUG_ON(codec->volatile_register); 164 BUG_ON(codec->driver->volatile_register);
165 165
166 reg &= 0xff; 166 reg &= 0xff;
167 data[0] = reg; 167 data[0] = reg;
168 data[1] = value & 0xff; 168 data[1] = value & 0xff;
169 169
170 if (reg < codec->reg_cache_size) 170 if (reg < codec->driver->reg_cache_size)
171 cache[reg] = value; 171 cache[reg] = value;
172 172
173 if (codec->cache_only) { 173 if (codec->cache_only) {
@@ -188,7 +188,7 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
188{ 188{
189 u8 *cache = codec->reg_cache; 189 u8 *cache = codec->reg_cache;
190 reg &= 0xff; 190 reg &= 0xff;
191 if (reg >= codec->reg_cache_size) 191 if (reg >= codec->driver->reg_cache_size)
192 return -1; 192 return -1;
193 return cache[reg]; 193 return cache[reg];
194} 194}
@@ -224,7 +224,7 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
224{ 224{
225 u16 *cache = codec->reg_cache; 225 u16 *cache = codec->reg_cache;
226 226
227 if (reg >= codec->reg_cache_size || 227 if (reg >= codec->driver->reg_cache_size ||
228 snd_soc_codec_volatile_register(codec, reg)) { 228 snd_soc_codec_volatile_register(codec, reg)) {
229 if (codec->cache_only) 229 if (codec->cache_only)
230 return -EINVAL; 230 return -EINVAL;
@@ -343,7 +343,7 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
343 u16 *cache = codec->reg_cache; 343 u16 *cache = codec->reg_cache;
344 344
345 reg &= 0xff; 345 reg &= 0xff;
346 if (reg >= codec->reg_cache_size) 346 if (reg >= codec->driver->reg_cache_size)
347 return -1; 347 return -1;
348 return cache[reg]; 348 return cache[reg];
349} 349}
@@ -355,14 +355,14 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
355 u8 data[3]; 355 u8 data[3];
356 int ret; 356 int ret;
357 357
358 BUG_ON(codec->volatile_register); 358 BUG_ON(codec->driver->volatile_register);
359 359
360 data[0] = (reg >> 8) & 0xff; 360 data[0] = (reg >> 8) & 0xff;
361 data[1] = reg & 0xff; 361 data[1] = reg & 0xff;
362 data[2] = value; 362 data[2] = value;
363 363
364 reg &= 0xff; 364 reg &= 0xff;
365 if (reg < codec->reg_cache_size) 365 if (reg < codec->driver->reg_cache_size)
366 cache[reg] = value; 366 cache[reg] = value;
367 367
368 if (codec->cache_only) { 368 if (codec->cache_only) {
@@ -451,7 +451,7 @@ static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
451{ 451{
452 u16 *cache = codec->reg_cache; 452 u16 *cache = codec->reg_cache;
453 453
454 if (reg >= codec->reg_cache_size || 454 if (reg >= codec->driver->reg_cache_size ||
455 snd_soc_codec_volatile_register(codec, reg)) { 455 snd_soc_codec_volatile_register(codec, reg)) {
456 if (codec->cache_only) 456 if (codec->cache_only)
457 return -EINVAL; 457 return -EINVAL;
@@ -474,7 +474,7 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
474 data[2] = (value >> 8) & 0xff; 474 data[2] = (value >> 8) & 0xff;
475 data[3] = value & 0xff; 475 data[3] = value & 0xff;
476 476
477 if (reg < codec->reg_cache_size) 477 if (reg < codec->driver->reg_cache_size)
478 cache[reg] = value; 478 cache[reg] = value;
479 479
480 if (codec->cache_only) { 480 if (codec->cache_only) {
@@ -571,8 +571,8 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
571 return -EINVAL; 571 return -EINVAL;
572 } 572 }
573 573
574 codec->write = io_types[i].write; 574 codec->driver->write = io_types[i].write;
575 codec->read = io_types[i].read; 575 codec->driver->read = io_types[i].read;
576 576
577 switch (control) { 577 switch (control) {
578 case SND_SOC_CUSTOM: 578 case SND_SOC_CUSTOM:
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 5299932db0b..a004876a39a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3,6 +3,8 @@
3 * 3 *
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * Copyright (C) 2010 Slimlogic Ltd.
7 * Copyright (C) 2010 Texas Instruments Inc.
6 * 8 *
7 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 9 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
8 * with code, comments and ideas from :- 10 * with code, comments and ideas from :-
@@ -37,6 +39,8 @@
37#include <sound/soc-dapm.h> 39#include <sound/soc-dapm.h>
38#include <sound/initval.h> 40#include <sound/initval.h>
39 41
42#define NAME_SIZE 32
43
40static DEFINE_MUTEX(pcm_mutex); 44static DEFINE_MUTEX(pcm_mutex);
41static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq); 45static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
42 46
@@ -52,6 +56,7 @@ static LIST_HEAD(codec_list);
52 56
53static int snd_soc_register_card(struct snd_soc_card *card); 57static int snd_soc_register_card(struct snd_soc_card *card);
54static int snd_soc_unregister_card(struct snd_soc_card *card); 58static int snd_soc_unregister_card(struct snd_soc_card *card);
59static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
55 60
56/* 61/*
57 * This is a timeout to do a DAPM powerdown after a stream is closed(). 62 * This is a timeout to do a DAPM powerdown after a stream is closed().
@@ -86,30 +91,30 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
86{ 91{
87 int ret, i, step = 1, count = 0; 92 int ret, i, step = 1, count = 0;
88 93
89 if (!codec->reg_cache_size) 94 if (!codec->driver->reg_cache_size)
90 return 0; 95 return 0;
91 96
92 if (codec->reg_cache_step) 97 if (codec->driver->reg_cache_step)
93 step = codec->reg_cache_step; 98 step = codec->driver->reg_cache_step;
94 99
95 count += sprintf(buf, "%s registers\n", codec->name); 100 count += sprintf(buf, "%s registers\n", codec->name);
96 for (i = 0; i < codec->reg_cache_size; i += step) { 101 for (i = 0; i < codec->driver->reg_cache_size; i += step) {
97 if (codec->readable_register && !codec->readable_register(i)) 102 if (codec->driver->readable_register && !codec->driver->readable_register(i))
98 continue; 103 continue;
99 104
100 count += sprintf(buf + count, "%2x: ", i); 105 count += sprintf(buf + count, "%2x: ", i);
101 if (count >= PAGE_SIZE - 1) 106 if (count >= PAGE_SIZE - 1)
102 break; 107 break;
103 108
104 if (codec->display_register) { 109 if (codec->driver->display_register) {
105 count += codec->display_register(codec, buf + count, 110 count += codec->driver->display_register(codec, buf + count,
106 PAGE_SIZE - count, i); 111 PAGE_SIZE - count, i);
107 } else { 112 } else {
108 /* If the read fails it's almost certainly due to 113 /* If the read fails it's almost certainly due to
109 * the register being volatile and the device being 114 * the register being volatile and the device being
110 * powered off. 115 * powered off.
111 */ 116 */
112 ret = codec->read(codec, i); 117 ret = codec->driver->read(codec, i);
113 if (ret >= 0) 118 if (ret >= 0)
114 count += snprintf(buf + count, 119 count += snprintf(buf + count,
115 PAGE_SIZE - count, 120 PAGE_SIZE - count,
@@ -137,8 +142,10 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
137static ssize_t codec_reg_show(struct device *dev, 142static ssize_t codec_reg_show(struct device *dev,
138 struct device_attribute *attr, char *buf) 143 struct device_attribute *attr, char *buf)
139{ 144{
140 struct snd_soc_device *devdata = dev_get_drvdata(dev); 145 struct snd_soc_pcm_runtime *rtd =
141 return soc_codec_reg_show(devdata->card->codec, buf); 146 container_of(dev, struct snd_soc_pcm_runtime, dev);
147
148 return soc_codec_reg_show(rtd->codec, buf);
142} 149}
143 150
144static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); 151static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
@@ -146,20 +153,20 @@ static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
146static ssize_t pmdown_time_show(struct device *dev, 153static ssize_t pmdown_time_show(struct device *dev,
147 struct device_attribute *attr, char *buf) 154 struct device_attribute *attr, char *buf)
148{ 155{
149 struct snd_soc_device *socdev = dev_get_drvdata(dev); 156 struct snd_soc_pcm_runtime *rtd =
150 struct snd_soc_card *card = socdev->card; 157 container_of(dev, struct snd_soc_pcm_runtime, dev);
151 158
152 return sprintf(buf, "%ld\n", card->pmdown_time); 159 return sprintf(buf, "%ld\n", rtd->pmdown_time);
153} 160}
154 161
155static ssize_t pmdown_time_set(struct device *dev, 162static ssize_t pmdown_time_set(struct device *dev,
156 struct device_attribute *attr, 163 struct device_attribute *attr,
157 const char *buf, size_t count) 164 const char *buf, size_t count)
158{ 165{
159 struct snd_soc_device *socdev = dev_get_drvdata(dev); 166 struct snd_soc_pcm_runtime *rtd =
160 struct snd_soc_card *card = socdev->card; 167 container_of(dev, struct snd_soc_pcm_runtime, dev);
161 168
162 strict_strtol(buf, 10, &card->pmdown_time); 169 strict_strtol(buf, 10, &rtd->pmdown_time);
163 170
164 return count; 171 return count;
165} 172}
@@ -203,19 +210,19 @@ static ssize_t codec_reg_write_file(struct file *file,
203 return -EFAULT; 210 return -EFAULT;
204 buf[buf_size] = 0; 211 buf[buf_size] = 0;
205 212
206 if (codec->reg_cache_step) 213 if (codec->driver->reg_cache_step)
207 step = codec->reg_cache_step; 214 step = codec->driver->reg_cache_step;
208 215
209 while (*start == ' ') 216 while (*start == ' ')
210 start++; 217 start++;
211 reg = simple_strtoul(start, &start, 16); 218 reg = simple_strtoul(start, &start, 16);
212 if ((reg >= codec->reg_cache_size) || (reg % step)) 219 if ((reg >= codec->driver->reg_cache_size) || (reg % step))
213 return -EINVAL; 220 return -EINVAL;
214 while (*start == ' ') 221 while (*start == ' ')
215 start++; 222 start++;
216 if (strict_strtoul(start, 16, &value)) 223 if (strict_strtoul(start, 16, &value))
217 return -EINVAL; 224 return -EINVAL;
218 codec->write(codec, reg, value); 225 codec->driver->write(codec, reg, value);
219 return buf_size; 226 return buf_size;
220} 227}
221 228
@@ -305,7 +312,7 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
305 codec->ac97->dev.release = soc_ac97_device_release; 312 codec->ac97->dev.release = soc_ac97_device_release;
306 313
307 dev_set_name(&codec->ac97->dev, "%d-%d:%s", 314 dev_set_name(&codec->ac97->dev, "%d-%d:%s",
308 codec->card->number, 0, codec->name); 315 codec->card->snd_card->number, 0, codec->name);
309 err = device_register(&codec->ac97->dev); 316 err = device_register(&codec->ac97->dev);
310 if (err < 0) { 317 if (err < 0) {
311 snd_printk(KERN_ERR "Can't register ac97 bus\n"); 318 snd_printk(KERN_ERR "Can't register ac97 bus\n");
@@ -319,24 +326,21 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
319static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream) 326static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
320{ 327{
321 struct snd_soc_pcm_runtime *rtd = substream->private_data; 328 struct snd_soc_pcm_runtime *rtd = substream->private_data;
322 struct snd_soc_device *socdev = rtd->socdev; 329 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
323 struct snd_soc_card *card = socdev->card; 330 struct snd_soc_dai *codec_dai = rtd->codec_dai;
324 struct snd_soc_dai_link *machine = rtd->dai;
325 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
326 struct snd_soc_dai *codec_dai = machine->codec_dai;
327 int ret; 331 int ret;
328 332
329 if (codec_dai->symmetric_rates || cpu_dai->symmetric_rates || 333 if (codec_dai->driver->symmetric_rates || cpu_dai->driver->symmetric_rates ||
330 machine->symmetric_rates) { 334 rtd->dai_link->symmetric_rates) {
331 dev_dbg(card->dev, "Symmetry forces %dHz rate\n", 335 dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n",
332 machine->rate); 336 rtd->rate);
333 337
334 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 338 ret = snd_pcm_hw_constraint_minmax(substream->runtime,
335 SNDRV_PCM_HW_PARAM_RATE, 339 SNDRV_PCM_HW_PARAM_RATE,
336 machine->rate, 340 rtd->rate,
337 machine->rate); 341 rtd->rate);
338 if (ret < 0) { 342 if (ret < 0) {
339 dev_err(card->dev, 343 dev_err(&rtd->dev,
340 "Unable to apply rate symmetry constraint: %d\n", ret); 344 "Unable to apply rate symmetry constraint: %d\n", ret);
341 return ret; 345 return ret;
342 } 346 }
@@ -353,20 +357,19 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
353static int soc_pcm_open(struct snd_pcm_substream *substream) 357static int soc_pcm_open(struct snd_pcm_substream *substream)
354{ 358{
355 struct snd_soc_pcm_runtime *rtd = substream->private_data; 359 struct snd_soc_pcm_runtime *rtd = substream->private_data;
356 struct snd_soc_device *socdev = rtd->socdev;
357 struct snd_soc_card *card = socdev->card;
358 struct snd_pcm_runtime *runtime = substream->runtime; 360 struct snd_pcm_runtime *runtime = substream->runtime;
359 struct snd_soc_dai_link *machine = rtd->dai; 361 struct snd_soc_platform *platform = rtd->platform;
360 struct snd_soc_platform *platform = card->platform; 362 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
361 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 363 struct snd_soc_dai *codec_dai = rtd->codec_dai;
362 struct snd_soc_dai *codec_dai = machine->codec_dai; 364 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
365 struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver;
363 int ret = 0; 366 int ret = 0;
364 367
365 mutex_lock(&pcm_mutex); 368 mutex_lock(&pcm_mutex);
366 369
367 /* startup the audio subsystem */ 370 /* startup the audio subsystem */
368 if (cpu_dai->ops->startup) { 371 if (cpu_dai->driver->ops->startup) {
369 ret = cpu_dai->ops->startup(substream, cpu_dai); 372 ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
370 if (ret < 0) { 373 if (ret < 0) {
371 printk(KERN_ERR "asoc: can't open interface %s\n", 374 printk(KERN_ERR "asoc: can't open interface %s\n",
372 cpu_dai->name); 375 cpu_dai->name);
@@ -374,16 +377,16 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
374 } 377 }
375 } 378 }
376 379
377 if (platform->pcm_ops->open) { 380 if (platform->driver->ops->open) {
378 ret = platform->pcm_ops->open(substream); 381 ret = platform->driver->ops->open(substream);
379 if (ret < 0) { 382 if (ret < 0) {
380 printk(KERN_ERR "asoc: can't open platform %s\n", platform->name); 383 printk(KERN_ERR "asoc: can't open platform %s\n", platform->name);
381 goto platform_err; 384 goto platform_err;
382 } 385 }
383 } 386 }
384 387
385 if (codec_dai->ops->startup) { 388 if (codec_dai->driver->ops->startup) {
386 ret = codec_dai->ops->startup(substream, codec_dai); 389 ret = codec_dai->driver->ops->startup(substream, codec_dai);
387 if (ret < 0) { 390 if (ret < 0) {
388 printk(KERN_ERR "asoc: can't open codec %s\n", 391 printk(KERN_ERR "asoc: can't open codec %s\n",
389 codec_dai->name); 392 codec_dai->name);
@@ -391,10 +394,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
391 } 394 }
392 } 395 }
393 396
394 if (machine->ops && machine->ops->startup) { 397 if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
395 ret = machine->ops->startup(substream); 398 ret = rtd->dai_link->ops->startup(substream);
396 if (ret < 0) { 399 if (ret < 0) {
397 printk(KERN_ERR "asoc: %s startup failed\n", machine->name); 400 printk(KERN_ERR "asoc: %s startup failed\n", rtd->dai_link->name);
398 goto machine_err; 401 goto machine_err;
399 } 402 }
400 } 403 }
@@ -402,50 +405,50 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
402 /* Check that the codec and cpu DAI's are compatible */ 405 /* Check that the codec and cpu DAI's are compatible */
403 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 406 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
404 runtime->hw.rate_min = 407 runtime->hw.rate_min =
405 max(codec_dai->playback.rate_min, 408 max(codec_dai_drv->playback.rate_min,
406 cpu_dai->playback.rate_min); 409 cpu_dai_drv->playback.rate_min);
407 runtime->hw.rate_max = 410 runtime->hw.rate_max =
408 min(codec_dai->playback.rate_max, 411 min(codec_dai_drv->playback.rate_max,
409 cpu_dai->playback.rate_max); 412 cpu_dai_drv->playback.rate_max);
410 runtime->hw.channels_min = 413 runtime->hw.channels_min =
411 max(codec_dai->playback.channels_min, 414 max(codec_dai_drv->playback.channels_min,
412 cpu_dai->playback.channels_min); 415 cpu_dai_drv->playback.channels_min);
413 runtime->hw.channels_max = 416 runtime->hw.channels_max =
414 min(codec_dai->playback.channels_max, 417 min(codec_dai_drv->playback.channels_max,
415 cpu_dai->playback.channels_max); 418 cpu_dai_drv->playback.channels_max);
416 runtime->hw.formats = 419 runtime->hw.formats =
417 codec_dai->playback.formats & cpu_dai->playback.formats; 420 codec_dai_drv->playback.formats & cpu_dai_drv->playback.formats;
418 runtime->hw.rates = 421 runtime->hw.rates =
419 codec_dai->playback.rates & cpu_dai->playback.rates; 422 codec_dai_drv->playback.rates & cpu_dai_drv->playback.rates;
420 if (codec_dai->playback.rates 423 if (codec_dai_drv->playback.rates
421 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) 424 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
422 runtime->hw.rates |= cpu_dai->playback.rates; 425 runtime->hw.rates |= cpu_dai_drv->playback.rates;
423 if (cpu_dai->playback.rates 426 if (cpu_dai_drv->playback.rates
424 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) 427 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
425 runtime->hw.rates |= codec_dai->playback.rates; 428 runtime->hw.rates |= codec_dai_drv->playback.rates;
426 } else { 429 } else {
427 runtime->hw.rate_min = 430 runtime->hw.rate_min =
428 max(codec_dai->capture.rate_min, 431 max(codec_dai_drv->capture.rate_min,
429 cpu_dai->capture.rate_min); 432 cpu_dai_drv->capture.rate_min);
430 runtime->hw.rate_max = 433 runtime->hw.rate_max =
431 min(codec_dai->capture.rate_max, 434 min(codec_dai_drv->capture.rate_max,
432 cpu_dai->capture.rate_max); 435 cpu_dai_drv->capture.rate_max);
433 runtime->hw.channels_min = 436 runtime->hw.channels_min =
434 max(codec_dai->capture.channels_min, 437 max(codec_dai_drv->capture.channels_min,
435 cpu_dai->capture.channels_min); 438 cpu_dai_drv->capture.channels_min);
436 runtime->hw.channels_max = 439 runtime->hw.channels_max =
437 min(codec_dai->capture.channels_max, 440 min(codec_dai_drv->capture.channels_max,
438 cpu_dai->capture.channels_max); 441 cpu_dai_drv->capture.channels_max);
439 runtime->hw.formats = 442 runtime->hw.formats =
440 codec_dai->capture.formats & cpu_dai->capture.formats; 443 codec_dai_drv->capture.formats & cpu_dai_drv->capture.formats;
441 runtime->hw.rates = 444 runtime->hw.rates =
442 codec_dai->capture.rates & cpu_dai->capture.rates; 445 codec_dai_drv->capture.rates & cpu_dai_drv->capture.rates;
443 if (codec_dai->capture.rates 446 if (codec_dai_drv->capture.rates
444 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) 447 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
445 runtime->hw.rates |= cpu_dai->capture.rates; 448 runtime->hw.rates |= cpu_dai_drv->capture.rates;
446 if (cpu_dai->capture.rates 449 if (cpu_dai_drv->capture.rates
447 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) 450 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
448 runtime->hw.rates |= codec_dai->capture.rates; 451 runtime->hw.rates |= codec_dai_drv->capture.rates;
449 } 452 }
450 453
451 snd_pcm_limit_hw_rates(runtime); 454 snd_pcm_limit_hw_rates(runtime);
@@ -461,7 +464,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
461 } 464 }
462 if (!runtime->hw.channels_min || !runtime->hw.channels_max) { 465 if (!runtime->hw.channels_min || !runtime->hw.channels_max) {
463 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n", 466 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
464 codec_dai->name, cpu_dai->name); 467 codec_dai->name, cpu_dai->name);
465 goto config_err; 468 goto config_err;
466 } 469 }
467 470
@@ -472,7 +475,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
472 goto config_err; 475 goto config_err;
473 } 476 }
474 477
475 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); 478 pr_debug("asoc: %s <-> %s info:\n",
479 codec_dai->name, cpu_dai->name);
476 pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates); 480 pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
477 pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, 481 pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
478 runtime->hw.channels_max); 482 runtime->hw.channels_max);
@@ -480,33 +484,33 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
480 runtime->hw.rate_max); 484 runtime->hw.rate_max);
481 485
482 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 486 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
483 cpu_dai->playback.active++; 487 cpu_dai->playback_active++;
484 codec_dai->playback.active++; 488 codec_dai->playback_active++;
485 } else { 489 } else {
486 cpu_dai->capture.active++; 490 cpu_dai->capture_active++;
487 codec_dai->capture.active++; 491 codec_dai->capture_active++;
488 } 492 }
489 cpu_dai->active++; 493 cpu_dai->active++;
490 codec_dai->active++; 494 codec_dai->active++;
491 card->codec->active++; 495 rtd->codec->active++;
492 mutex_unlock(&pcm_mutex); 496 mutex_unlock(&pcm_mutex);
493 return 0; 497 return 0;
494 498
495config_err: 499config_err:
496 if (machine->ops && machine->ops->shutdown) 500 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
497 machine->ops->shutdown(substream); 501 rtd->dai_link->ops->shutdown(substream);
498 502
499machine_err: 503machine_err:
500 if (codec_dai->ops->shutdown) 504 if (codec_dai->driver->ops->shutdown)
501 codec_dai->ops->shutdown(substream, codec_dai); 505 codec_dai->driver->ops->shutdown(substream, codec_dai);
502 506
503codec_dai_err: 507codec_dai_err:
504 if (platform->pcm_ops->close) 508 if (platform->driver->ops->close)
505 platform->pcm_ops->close(substream); 509 platform->driver->ops->close(substream);
506 510
507platform_err: 511platform_err:
508 if (cpu_dai->ops->shutdown) 512 if (cpu_dai->driver->ops->shutdown)
509 cpu_dai->ops->shutdown(substream, cpu_dai); 513 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
510out: 514out:
511 mutex_unlock(&pcm_mutex); 515 mutex_unlock(&pcm_mutex);
512 return ret; 516 return ret;
@@ -519,29 +523,25 @@ out:
519 */ 523 */
520static void close_delayed_work(struct work_struct *work) 524static void close_delayed_work(struct work_struct *work)
521{ 525{
522 struct snd_soc_card *card = container_of(work, struct snd_soc_card, 526 struct snd_soc_pcm_runtime *rtd =
523 delayed_work.work); 527 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
524 struct snd_soc_codec *codec = card->codec; 528 struct snd_soc_dai *codec_dai = rtd->codec_dai;
525 struct snd_soc_dai *codec_dai;
526 int i;
527 529
528 mutex_lock(&pcm_mutex); 530 mutex_lock(&pcm_mutex);
529 for (i = 0; i < codec->num_dai; i++) { 531
530 codec_dai = &codec->dai[i]; 532 pr_debug("pop wq checking: %s status: %s waiting: %s\n",
531 533 codec_dai->driver->playback.stream_name,
532 pr_debug("pop wq checking: %s status: %s waiting: %s\n", 534 codec_dai->playback_active ? "active" : "inactive",
533 codec_dai->playback.stream_name, 535 codec_dai->pop_wait ? "yes" : "no");
534 codec_dai->playback.active ? "active" : "inactive", 536
535 codec_dai->pop_wait ? "yes" : "no"); 537 /* are we waiting on this codec DAI stream */
536 538 if (codec_dai->pop_wait == 1) {
537 /* are we waiting on this codec DAI stream */ 539 codec_dai->pop_wait = 0;
538 if (codec_dai->pop_wait == 1) { 540 snd_soc_dapm_stream_event(rtd,
539 codec_dai->pop_wait = 0; 541 codec_dai->driver->playback.stream_name,
540 snd_soc_dapm_stream_event(codec, 542 SND_SOC_DAPM_STREAM_STOP);
541 codec_dai->playback.stream_name,
542 SND_SOC_DAPM_STREAM_STOP);
543 }
544 } 543 }
544
545 mutex_unlock(&pcm_mutex); 545 mutex_unlock(&pcm_mutex);
546} 546}
547 547
@@ -553,22 +553,19 @@ static void close_delayed_work(struct work_struct *work)
553static int soc_codec_close(struct snd_pcm_substream *substream) 553static int soc_codec_close(struct snd_pcm_substream *substream)
554{ 554{
555 struct snd_soc_pcm_runtime *rtd = substream->private_data; 555 struct snd_soc_pcm_runtime *rtd = substream->private_data;
556 struct snd_soc_device *socdev = rtd->socdev; 556 struct snd_soc_platform *platform = rtd->platform;
557 struct snd_soc_card *card = socdev->card; 557 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
558 struct snd_soc_dai_link *machine = rtd->dai; 558 struct snd_soc_dai *codec_dai = rtd->codec_dai;
559 struct snd_soc_platform *platform = card->platform; 559 struct snd_soc_codec *codec = rtd->codec;
560 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
561 struct snd_soc_dai *codec_dai = machine->codec_dai;
562 struct snd_soc_codec *codec = card->codec;
563 560
564 mutex_lock(&pcm_mutex); 561 mutex_lock(&pcm_mutex);
565 562
566 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 563 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
567 cpu_dai->playback.active--; 564 cpu_dai->playback_active--;
568 codec_dai->playback.active--; 565 codec_dai->playback_active--;
569 } else { 566 } else {
570 cpu_dai->capture.active--; 567 cpu_dai->capture_active--;
571 codec_dai->capture.active--; 568 codec_dai->capture_active--;
572 } 569 }
573 570
574 cpu_dai->active--; 571 cpu_dai->active--;
@@ -581,27 +578,28 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
581 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 578 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
582 snd_soc_dai_digital_mute(codec_dai, 1); 579 snd_soc_dai_digital_mute(codec_dai, 1);
583 580
584 if (cpu_dai->ops->shutdown) 581 if (cpu_dai->driver->ops->shutdown)
585 cpu_dai->ops->shutdown(substream, cpu_dai); 582 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
586 583
587 if (codec_dai->ops->shutdown) 584 if (codec_dai->driver->ops->shutdown)
588 codec_dai->ops->shutdown(substream, codec_dai); 585 codec_dai->driver->ops->shutdown(substream, codec_dai);
589 586
590 if (machine->ops && machine->ops->shutdown) 587 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
591 machine->ops->shutdown(substream); 588 rtd->dai_link->ops->shutdown(substream);
592 589
593 if (platform->pcm_ops->close) 590 if (platform->driver->ops->close)
594 platform->pcm_ops->close(substream); 591 platform->driver->ops->close(substream);
592 cpu_dai->runtime = NULL;
595 593
596 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 594 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
597 /* start delayed pop wq here for playback streams */ 595 /* start delayed pop wq here for playback streams */
598 codec_dai->pop_wait = 1; 596 codec_dai->pop_wait = 1;
599 schedule_delayed_work(&card->delayed_work, 597 schedule_delayed_work(&rtd->delayed_work,
600 msecs_to_jiffies(card->pmdown_time)); 598 msecs_to_jiffies(rtd->pmdown_time));
601 } else { 599 } else {
602 /* capture streams can be powered down now */ 600 /* capture streams can be powered down now */
603 snd_soc_dapm_stream_event(codec, 601 snd_soc_dapm_stream_event(rtd,
604 codec_dai->capture.stream_name, 602 codec_dai->driver->capture.stream_name,
605 SND_SOC_DAPM_STREAM_STOP); 603 SND_SOC_DAPM_STREAM_STOP);
606 } 604 }
607 605
@@ -617,43 +615,39 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
617static int soc_pcm_prepare(struct snd_pcm_substream *substream) 615static int soc_pcm_prepare(struct snd_pcm_substream *substream)
618{ 616{
619 struct snd_soc_pcm_runtime *rtd = substream->private_data; 617 struct snd_soc_pcm_runtime *rtd = substream->private_data;
620 struct snd_soc_device *socdev = rtd->socdev; 618 struct snd_soc_platform *platform = rtd->platform;
621 struct snd_soc_card *card = socdev->card; 619 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
622 struct snd_soc_dai_link *machine = rtd->dai; 620 struct snd_soc_dai *codec_dai = rtd->codec_dai;
623 struct snd_soc_platform *platform = card->platform;
624 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
625 struct snd_soc_dai *codec_dai = machine->codec_dai;
626 struct snd_soc_codec *codec = card->codec;
627 int ret = 0; 621 int ret = 0;
628 622
629 mutex_lock(&pcm_mutex); 623 mutex_lock(&pcm_mutex);
630 624
631 if (machine->ops && machine->ops->prepare) { 625 if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
632 ret = machine->ops->prepare(substream); 626 ret = rtd->dai_link->ops->prepare(substream);
633 if (ret < 0) { 627 if (ret < 0) {
634 printk(KERN_ERR "asoc: machine prepare error\n"); 628 printk(KERN_ERR "asoc: machine prepare error\n");
635 goto out; 629 goto out;
636 } 630 }
637 } 631 }
638 632
639 if (platform->pcm_ops->prepare) { 633 if (platform->driver->ops->prepare) {
640 ret = platform->pcm_ops->prepare(substream); 634 ret = platform->driver->ops->prepare(substream);
641 if (ret < 0) { 635 if (ret < 0) {
642 printk(KERN_ERR "asoc: platform prepare error\n"); 636 printk(KERN_ERR "asoc: platform prepare error\n");
643 goto out; 637 goto out;
644 } 638 }
645 } 639 }
646 640
647 if (codec_dai->ops->prepare) { 641 if (codec_dai->driver->ops->prepare) {
648 ret = codec_dai->ops->prepare(substream, codec_dai); 642 ret = codec_dai->driver->ops->prepare(substream, codec_dai);
649 if (ret < 0) { 643 if (ret < 0) {
650 printk(KERN_ERR "asoc: codec DAI prepare error\n"); 644 printk(KERN_ERR "asoc: codec DAI prepare error\n");
651 goto out; 645 goto out;
652 } 646 }
653 } 647 }
654 648
655 if (cpu_dai->ops->prepare) { 649 if (cpu_dai->driver->ops->prepare) {
656 ret = cpu_dai->ops->prepare(substream, cpu_dai); 650 ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
657 if (ret < 0) { 651 if (ret < 0) {
658 printk(KERN_ERR "asoc: cpu DAI prepare error\n"); 652 printk(KERN_ERR "asoc: cpu DAI prepare error\n");
659 goto out; 653 goto out;
@@ -664,16 +658,16 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
664 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 658 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
665 codec_dai->pop_wait) { 659 codec_dai->pop_wait) {
666 codec_dai->pop_wait = 0; 660 codec_dai->pop_wait = 0;
667 cancel_delayed_work(&card->delayed_work); 661 cancel_delayed_work(&rtd->delayed_work);
668 } 662 }
669 663
670 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 664 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
671 snd_soc_dapm_stream_event(codec, 665 snd_soc_dapm_stream_event(rtd,
672 codec_dai->playback.stream_name, 666 codec_dai->driver->playback.stream_name,
673 SND_SOC_DAPM_STREAM_START); 667 SND_SOC_DAPM_STREAM_START);
674 else 668 else
675 snd_soc_dapm_stream_event(codec, 669 snd_soc_dapm_stream_event(rtd,
676 codec_dai->capture.stream_name, 670 codec_dai->driver->capture.stream_name,
677 SND_SOC_DAPM_STREAM_START); 671 SND_SOC_DAPM_STREAM_START);
678 672
679 snd_soc_dai_digital_mute(codec_dai, 0); 673 snd_soc_dai_digital_mute(codec_dai, 0);
@@ -692,26 +686,23 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
692 struct snd_pcm_hw_params *params) 686 struct snd_pcm_hw_params *params)
693{ 687{
694 struct snd_soc_pcm_runtime *rtd = substream->private_data; 688 struct snd_soc_pcm_runtime *rtd = substream->private_data;
695 struct snd_soc_device *socdev = rtd->socdev; 689 struct snd_soc_platform *platform = rtd->platform;
696 struct snd_soc_dai_link *machine = rtd->dai; 690 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
697 struct snd_soc_card *card = socdev->card; 691 struct snd_soc_dai *codec_dai = rtd->codec_dai;
698 struct snd_soc_platform *platform = card->platform;
699 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
700 struct snd_soc_dai *codec_dai = machine->codec_dai;
701 int ret = 0; 692 int ret = 0;
702 693
703 mutex_lock(&pcm_mutex); 694 mutex_lock(&pcm_mutex);
704 695
705 if (machine->ops && machine->ops->hw_params) { 696 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
706 ret = machine->ops->hw_params(substream, params); 697 ret = rtd->dai_link->ops->hw_params(substream, params);
707 if (ret < 0) { 698 if (ret < 0) {
708 printk(KERN_ERR "asoc: machine hw_params failed\n"); 699 printk(KERN_ERR "asoc: machine hw_params failed\n");
709 goto out; 700 goto out;
710 } 701 }
711 } 702 }
712 703
713 if (codec_dai->ops->hw_params) { 704 if (codec_dai->driver->ops->hw_params) {
714 ret = codec_dai->ops->hw_params(substream, params, codec_dai); 705 ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai);
715 if (ret < 0) { 706 if (ret < 0) {
716 printk(KERN_ERR "asoc: can't set codec %s hw params\n", 707 printk(KERN_ERR "asoc: can't set codec %s hw params\n",
717 codec_dai->name); 708 codec_dai->name);
@@ -719,8 +710,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
719 } 710 }
720 } 711 }
721 712
722 if (cpu_dai->ops->hw_params) { 713 if (cpu_dai->driver->ops->hw_params) {
723 ret = cpu_dai->ops->hw_params(substream, params, cpu_dai); 714 ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai);
724 if (ret < 0) { 715 if (ret < 0) {
725 printk(KERN_ERR "asoc: interface %s hw params failed\n", 716 printk(KERN_ERR "asoc: interface %s hw params failed\n",
726 cpu_dai->name); 717 cpu_dai->name);
@@ -728,8 +719,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
728 } 719 }
729 } 720 }
730 721
731 if (platform->pcm_ops->hw_params) { 722 if (platform->driver->ops->hw_params) {
732 ret = platform->pcm_ops->hw_params(substream, params); 723 ret = platform->driver->ops->hw_params(substream, params);
733 if (ret < 0) { 724 if (ret < 0) {
734 printk(KERN_ERR "asoc: platform %s hw params failed\n", 725 printk(KERN_ERR "asoc: platform %s hw params failed\n",
735 platform->name); 726 platform->name);
@@ -737,23 +728,23 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
737 } 728 }
738 } 729 }
739 730
740 machine->rate = params_rate(params); 731 rtd->rate = params_rate(params);
741 732
742out: 733out:
743 mutex_unlock(&pcm_mutex); 734 mutex_unlock(&pcm_mutex);
744 return ret; 735 return ret;
745 736
746platform_err: 737platform_err:
747 if (cpu_dai->ops->hw_free) 738 if (cpu_dai->driver->ops->hw_free)
748 cpu_dai->ops->hw_free(substream, cpu_dai); 739 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
749 740
750interface_err: 741interface_err:
751 if (codec_dai->ops->hw_free) 742 if (codec_dai->driver->ops->hw_free)
752 codec_dai->ops->hw_free(substream, codec_dai); 743 codec_dai->driver->ops->hw_free(substream, codec_dai);
753 744
754codec_err: 745codec_err:
755 if (machine->ops && machine->ops->hw_free) 746 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
756 machine->ops->hw_free(substream); 747 rtd->dai_link->ops->hw_free(substream);
757 748
758 mutex_unlock(&pcm_mutex); 749 mutex_unlock(&pcm_mutex);
759 return ret; 750 return ret;
@@ -765,13 +756,10 @@ codec_err:
765static int soc_pcm_hw_free(struct snd_pcm_substream *substream) 756static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
766{ 757{
767 struct snd_soc_pcm_runtime *rtd = substream->private_data; 758 struct snd_soc_pcm_runtime *rtd = substream->private_data;
768 struct snd_soc_device *socdev = rtd->socdev; 759 struct snd_soc_platform *platform = rtd->platform;
769 struct snd_soc_dai_link *machine = rtd->dai; 760 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
770 struct snd_soc_card *card = socdev->card; 761 struct snd_soc_dai *codec_dai = rtd->codec_dai;
771 struct snd_soc_platform *platform = card->platform; 762 struct snd_soc_codec *codec = rtd->codec;
772 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
773 struct snd_soc_dai *codec_dai = machine->codec_dai;
774 struct snd_soc_codec *codec = card->codec;
775 763
776 mutex_lock(&pcm_mutex); 764 mutex_lock(&pcm_mutex);
777 765
@@ -780,19 +768,19 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
780 snd_soc_dai_digital_mute(codec_dai, 1); 768 snd_soc_dai_digital_mute(codec_dai, 1);
781 769
782 /* free any machine hw params */ 770 /* free any machine hw params */
783 if (machine->ops && machine->ops->hw_free) 771 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
784 machine->ops->hw_free(substream); 772 rtd->dai_link->ops->hw_free(substream);
785 773
786 /* free any DMA resources */ 774 /* free any DMA resources */
787 if (platform->pcm_ops->hw_free) 775 if (platform->driver->ops->hw_free)
788 platform->pcm_ops->hw_free(substream); 776 platform->driver->ops->hw_free(substream);
789 777
790 /* now free hw params for the DAI's */ 778 /* now free hw params for the DAI's */
791 if (codec_dai->ops->hw_free) 779 if (codec_dai->driver->ops->hw_free)
792 codec_dai->ops->hw_free(substream, codec_dai); 780 codec_dai->driver->ops->hw_free(substream, codec_dai);
793 781
794 if (cpu_dai->ops->hw_free) 782 if (cpu_dai->driver->ops->hw_free)
795 cpu_dai->ops->hw_free(substream, cpu_dai); 783 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
796 784
797 mutex_unlock(&pcm_mutex); 785 mutex_unlock(&pcm_mutex);
798 return 0; 786 return 0;
@@ -801,28 +789,25 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
801static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 789static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
802{ 790{
803 struct snd_soc_pcm_runtime *rtd = substream->private_data; 791 struct snd_soc_pcm_runtime *rtd = substream->private_data;
804 struct snd_soc_device *socdev = rtd->socdev; 792 struct snd_soc_platform *platform = rtd->platform;
805 struct snd_soc_card *card= socdev->card; 793 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
806 struct snd_soc_dai_link *machine = rtd->dai; 794 struct snd_soc_dai *codec_dai = rtd->codec_dai;
807 struct snd_soc_platform *platform = card->platform;
808 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
809 struct snd_soc_dai *codec_dai = machine->codec_dai;
810 int ret; 795 int ret;
811 796
812 if (codec_dai->ops->trigger) { 797 if (codec_dai->driver->ops->trigger) {
813 ret = codec_dai->ops->trigger(substream, cmd, codec_dai); 798 ret = codec_dai->driver->ops->trigger(substream, cmd, codec_dai);
814 if (ret < 0) 799 if (ret < 0)
815 return ret; 800 return ret;
816 } 801 }
817 802
818 if (platform->pcm_ops->trigger) { 803 if (platform->driver->ops->trigger) {
819 ret = platform->pcm_ops->trigger(substream, cmd); 804 ret = platform->driver->ops->trigger(substream, cmd);
820 if (ret < 0) 805 if (ret < 0)
821 return ret; 806 return ret;
822 } 807 }
823 808
824 if (cpu_dai->ops->trigger) { 809 if (cpu_dai->driver->ops->trigger) {
825 ret = cpu_dai->ops->trigger(substream, cmd, cpu_dai); 810 ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai);
826 if (ret < 0) 811 if (ret < 0)
827 return ret; 812 return ret;
828 } 813 }
@@ -837,27 +822,24 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
837static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) 822static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
838{ 823{
839 struct snd_soc_pcm_runtime *rtd = substream->private_data; 824 struct snd_soc_pcm_runtime *rtd = substream->private_data;
840 struct snd_soc_device *socdev = rtd->socdev; 825 struct snd_soc_platform *platform = rtd->platform;
841 struct snd_soc_card *card = socdev->card; 826 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
842 struct snd_soc_platform *platform = card->platform; 827 struct snd_soc_dai *codec_dai = rtd->codec_dai;
843 struct snd_soc_dai_link *machine = rtd->dai;
844 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
845 struct snd_soc_dai *codec_dai = machine->codec_dai;
846 struct snd_pcm_runtime *runtime = substream->runtime; 828 struct snd_pcm_runtime *runtime = substream->runtime;
847 snd_pcm_uframes_t offset = 0; 829 snd_pcm_uframes_t offset = 0;
848 snd_pcm_sframes_t delay = 0; 830 snd_pcm_sframes_t delay = 0;
849 831
850 if (platform->pcm_ops->pointer) 832 if (platform->driver->ops->pointer)
851 offset = platform->pcm_ops->pointer(substream); 833 offset = platform->driver->ops->pointer(substream);
852 834
853 if (cpu_dai->ops->delay) 835 if (cpu_dai->driver->ops->delay)
854 delay += cpu_dai->ops->delay(substream, cpu_dai); 836 delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
855 837
856 if (codec_dai->ops->delay) 838 if (codec_dai->driver->ops->delay)
857 delay += codec_dai->ops->delay(substream, codec_dai); 839 delay += codec_dai->driver->ops->delay(substream, codec_dai);
858 840
859 if (platform->delay) 841 if (platform->driver->delay)
860 delay += platform->delay(substream, codec_dai); 842 delay += platform->driver->delay(substream, codec_dai);
861 843
862 runtime->delay = delay; 844 runtime->delay = delay;
863 845
@@ -880,104 +862,111 @@ static struct snd_pcm_ops soc_pcm_ops = {
880static int soc_suspend(struct device *dev) 862static int soc_suspend(struct device *dev)
881{ 863{
882 struct platform_device *pdev = to_platform_device(dev); 864 struct platform_device *pdev = to_platform_device(dev);
883 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 865 struct snd_soc_card *card = platform_get_drvdata(pdev);
884 struct snd_soc_card *card = socdev->card;
885 struct snd_soc_platform *platform = card->platform;
886 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
887 struct snd_soc_codec *codec = card->codec;
888 int i; 866 int i;
889 867
890 /* If the initialization of this soc device failed, there is no codec 868 /* If the initialization of this soc device failed, there is no codec
891 * associated with it. Just bail out in this case. 869 * associated with it. Just bail out in this case.
892 */ 870 */
893 if (!codec) 871 if (list_empty(&card->codec_dev_list))
894 return 0; 872 return 0;
895 873
896 /* Due to the resume being scheduled into a workqueue we could 874 /* Due to the resume being scheduled into a workqueue we could
897 * suspend before that's finished - wait for it to complete. 875 * suspend before that's finished - wait for it to complete.
898 */ 876 */
899 snd_power_lock(codec->card); 877 snd_power_lock(card->snd_card);
900 snd_power_wait(codec->card, SNDRV_CTL_POWER_D0); 878 snd_power_wait(card->snd_card, SNDRV_CTL_POWER_D0);
901 snd_power_unlock(codec->card); 879 snd_power_unlock(card->snd_card);
902 880
903 /* we're going to block userspace touching us until resume completes */ 881 /* we're going to block userspace touching us until resume completes */
904 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D3hot); 882 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);
905 883
906 /* mute any active DAC's */ 884 /* mute any active DAC's */
907 for (i = 0; i < card->num_links; i++) { 885 for (i = 0; i < card->num_rtd; i++) {
908 struct snd_soc_dai *dai = card->dai_link[i].codec_dai; 886 struct snd_soc_dai *dai = card->rtd[i].codec_dai;
887 struct snd_soc_dai_driver *drv = dai->driver;
909 888
910 if (card->dai_link[i].ignore_suspend) 889 if (card->rtd[i].dai_link->ignore_suspend)
911 continue; 890 continue;
912 891
913 if (dai->ops->digital_mute && dai->playback.active) 892 if (drv->ops->digital_mute && dai->playback_active)
914 dai->ops->digital_mute(dai, 1); 893 drv->ops->digital_mute(dai, 1);
915 } 894 }
916 895
917 /* suspend all pcms */ 896 /* suspend all pcms */
918 for (i = 0; i < card->num_links; i++) { 897 for (i = 0; i < card->num_rtd; i++) {
919 if (card->dai_link[i].ignore_suspend) 898 if (card->rtd[i].dai_link->ignore_suspend)
920 continue; 899 continue;
921 900
922 snd_pcm_suspend_all(card->dai_link[i].pcm); 901 snd_pcm_suspend_all(card->rtd[i].pcm);
923 } 902 }
924 903
925 if (card->suspend_pre) 904 if (card->suspend_pre)
926 card->suspend_pre(pdev, PMSG_SUSPEND); 905 card->suspend_pre(pdev, PMSG_SUSPEND);
927 906
928 for (i = 0; i < card->num_links; i++) { 907 for (i = 0; i < card->num_rtd; i++) {
929 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 908 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
909 struct snd_soc_platform *platform = card->rtd[i].platform;
930 910
931 if (card->dai_link[i].ignore_suspend) 911 if (card->rtd[i].dai_link->ignore_suspend)
932 continue; 912 continue;
933 913
934 if (cpu_dai->suspend && !cpu_dai->ac97_control) 914 if (cpu_dai->driver->suspend && !cpu_dai->driver->ac97_control)
935 cpu_dai->suspend(cpu_dai); 915 cpu_dai->driver->suspend(cpu_dai);
936 if (platform->suspend) 916 if (platform->driver->suspend && !platform->suspended) {
937 platform->suspend(&card->dai_link[i]); 917 platform->driver->suspend(cpu_dai);
918 platform->suspended = 1;
919 }
938 } 920 }
939 921
940 /* close any waiting streams and save state */ 922 /* close any waiting streams and save state */
941 run_delayed_work(&card->delayed_work); 923 for (i = 0; i < card->num_rtd; i++) {
942 codec->suspend_bias_level = codec->bias_level; 924 run_delayed_work(&card->rtd[i].delayed_work);
925 card->rtd[i].codec->suspend_bias_level = card->rtd[i].codec->bias_level;
926 }
943 927
944 for (i = 0; i < codec->num_dai; i++) { 928 for (i = 0; i < card->num_rtd; i++) {
945 char *stream = codec->dai[i].playback.stream_name; 929 struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver;
946 930
947 if (card->dai_link[i].ignore_suspend) 931 if (card->rtd[i].dai_link->ignore_suspend)
948 continue; 932 continue;
949 933
950 if (stream != NULL) 934 if (driver->playback.stream_name != NULL)
951 snd_soc_dapm_stream_event(codec, stream, 935 snd_soc_dapm_stream_event(&card->rtd[i], driver->playback.stream_name,
952 SND_SOC_DAPM_STREAM_SUSPEND); 936 SND_SOC_DAPM_STREAM_SUSPEND);
953 stream = codec->dai[i].capture.stream_name; 937
954 if (stream != NULL) 938 if (driver->capture.stream_name != NULL)
955 snd_soc_dapm_stream_event(codec, stream, 939 snd_soc_dapm_stream_event(&card->rtd[i], driver->capture.stream_name,
956 SND_SOC_DAPM_STREAM_SUSPEND); 940 SND_SOC_DAPM_STREAM_SUSPEND);
957 } 941 }
958 942
959 /* If there are paths active then the CODEC will be held with 943 /* suspend all CODECs */
960 * bias _ON and should not be suspended. */ 944 for (i = 0; i < card->num_rtd; i++) {
961 if (codec_dev->suspend) { 945 struct snd_soc_codec *codec = card->rtd[i].codec;
962 switch (codec->bias_level) { 946 /* If there are paths active then the CODEC will be held with
963 case SND_SOC_BIAS_STANDBY: 947 * bias _ON and should not be suspended. */
964 case SND_SOC_BIAS_OFF: 948 if (!codec->suspended && codec->driver->suspend) {
965 codec_dev->suspend(pdev, PMSG_SUSPEND); 949 switch (codec->bias_level) {
966 break; 950 case SND_SOC_BIAS_STANDBY:
967 default: 951 case SND_SOC_BIAS_OFF:
968 dev_dbg(socdev->dev, "CODEC is on over suspend\n"); 952 codec->driver->suspend(codec, PMSG_SUSPEND);
969 break; 953 codec->suspended = 1;
954 break;
955 default:
956 dev_dbg(codec->dev, "CODEC is on over suspend\n");
957 break;
958 }
970 } 959 }
971 } 960 }
972 961
973 for (i = 0; i < card->num_links; i++) { 962 for (i = 0; i < card->num_rtd; i++) {
974 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 963 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
975 964
976 if (card->dai_link[i].ignore_suspend) 965 if (card->rtd[i].dai_link->ignore_suspend)
977 continue; 966 continue;
978 967
979 if (cpu_dai->suspend && cpu_dai->ac97_control) 968 if (cpu_dai->driver->suspend && cpu_dai->driver->ac97_control)
980 cpu_dai->suspend(cpu_dai); 969 cpu_dai->driver->suspend(cpu_dai);
981 } 970 }
982 971
983 if (card->suspend_post) 972 if (card->suspend_post)
@@ -991,127 +980,127 @@ static int soc_suspend(struct device *dev)
991 */ 980 */
992static void soc_resume_deferred(struct work_struct *work) 981static void soc_resume_deferred(struct work_struct *work)
993{ 982{
994 struct snd_soc_card *card = container_of(work, 983 struct snd_soc_card *card =
995 struct snd_soc_card, 984 container_of(work, struct snd_soc_card, deferred_resume_work);
996 deferred_resume_work); 985 struct platform_device *pdev = to_platform_device(card->dev);
997 struct snd_soc_device *socdev = card->socdev;
998 struct snd_soc_platform *platform = card->platform;
999 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
1000 struct snd_soc_codec *codec = card->codec;
1001 struct platform_device *pdev = to_platform_device(socdev->dev);
1002 int i; 986 int i;
1003 987
1004 /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time, 988 /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time,
1005 * so userspace apps are blocked from touching us 989 * so userspace apps are blocked from touching us
1006 */ 990 */
1007 991
1008 dev_dbg(socdev->dev, "starting resume work\n"); 992 dev_dbg(card->dev, "starting resume work\n");
1009 993
1010 /* Bring us up into D2 so that DAPM starts enabling things */ 994 /* Bring us up into D2 so that DAPM starts enabling things */
1011 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D2); 995 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2);
1012 996
1013 if (card->resume_pre) 997 if (card->resume_pre)
1014 card->resume_pre(pdev); 998 card->resume_pre(pdev);
1015 999
1016 for (i = 0; i < card->num_links; i++) { 1000 /* resume AC97 DAIs */
1017 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 1001 for (i = 0; i < card->num_rtd; i++) {
1002 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
1018 1003
1019 if (card->dai_link[i].ignore_suspend) 1004 if (card->rtd[i].dai_link->ignore_suspend)
1020 continue; 1005 continue;
1021 1006
1022 if (cpu_dai->resume && cpu_dai->ac97_control) 1007 if (cpu_dai->driver->resume && cpu_dai->driver->ac97_control)
1023 cpu_dai->resume(cpu_dai); 1008 cpu_dai->driver->resume(cpu_dai);
1024 } 1009 }
1025 1010
1026 /* If the CODEC was idle over suspend then it will have been 1011 for (i = 0; i < card->num_rtd; i++) {
1027 * left with bias OFF or STANDBY and suspended so we must now 1012 struct snd_soc_codec *codec = card->rtd[i].codec;
1028 * resume. Otherwise the suspend was suppressed. 1013 /* If the CODEC was idle over suspend then it will have been
1029 */ 1014 * left with bias OFF or STANDBY and suspended so we must now
1030 if (codec_dev->resume) { 1015 * resume. Otherwise the suspend was suppressed.
1031 switch (codec->bias_level) { 1016 */
1032 case SND_SOC_BIAS_STANDBY: 1017 if (codec->driver->resume && codec->suspended) {
1033 case SND_SOC_BIAS_OFF: 1018 switch (codec->bias_level) {
1034 codec_dev->resume(pdev); 1019 case SND_SOC_BIAS_STANDBY:
1035 break; 1020 case SND_SOC_BIAS_OFF:
1036 default: 1021 codec->driver->resume(codec);
1037 dev_dbg(socdev->dev, "CODEC was on over suspend\n"); 1022 codec->suspended = 0;
1038 break; 1023 break;
1024 default:
1025 dev_dbg(codec->dev, "CODEC was on over suspend\n");
1026 break;
1027 }
1039 } 1028 }
1040 } 1029 }
1041 1030
1042 for (i = 0; i < codec->num_dai; i++) { 1031 for (i = 0; i < card->num_rtd; i++) {
1043 char *stream = codec->dai[i].playback.stream_name; 1032 struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver;
1044 1033
1045 if (card->dai_link[i].ignore_suspend) 1034 if (card->rtd[i].dai_link->ignore_suspend)
1046 continue; 1035 continue;
1047 1036
1048 if (stream != NULL) 1037 if (driver->playback.stream_name != NULL)
1049 snd_soc_dapm_stream_event(codec, stream, 1038 snd_soc_dapm_stream_event(&card->rtd[i], driver->playback.stream_name,
1050 SND_SOC_DAPM_STREAM_RESUME); 1039 SND_SOC_DAPM_STREAM_RESUME);
1051 stream = codec->dai[i].capture.stream_name; 1040
1052 if (stream != NULL) 1041 if (driver->capture.stream_name != NULL)
1053 snd_soc_dapm_stream_event(codec, stream, 1042 snd_soc_dapm_stream_event(&card->rtd[i], driver->capture.stream_name,
1054 SND_SOC_DAPM_STREAM_RESUME); 1043 SND_SOC_DAPM_STREAM_RESUME);
1055 } 1044 }
1056 1045
1057 /* unmute any active DACs */ 1046 /* unmute any active DACs */
1058 for (i = 0; i < card->num_links; i++) { 1047 for (i = 0; i < card->num_rtd; i++) {
1059 struct snd_soc_dai *dai = card->dai_link[i].codec_dai; 1048 struct snd_soc_dai *dai = card->rtd[i].codec_dai;
1049 struct snd_soc_dai_driver *drv = dai->driver;
1060 1050
1061 if (card->dai_link[i].ignore_suspend) 1051 if (card->rtd[i].dai_link->ignore_suspend)
1062 continue; 1052 continue;
1063 1053
1064 if (dai->ops->digital_mute && dai->playback.active) 1054 if (drv->ops->digital_mute && dai->playback_active)
1065 dai->ops->digital_mute(dai, 0); 1055 drv->ops->digital_mute(dai, 0);
1066 } 1056 }
1067 1057
1068 for (i = 0; i < card->num_links; i++) { 1058 for (i = 0; i < card->num_rtd; i++) {
1069 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 1059 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
1060 struct snd_soc_platform *platform = card->rtd[i].platform;
1070 1061
1071 if (card->dai_link[i].ignore_suspend) 1062 if (card->rtd[i].dai_link->ignore_suspend)
1072 continue; 1063 continue;
1073 1064
1074 if (cpu_dai->resume && !cpu_dai->ac97_control) 1065 if (cpu_dai->driver->resume && !cpu_dai->driver->ac97_control)
1075 cpu_dai->resume(cpu_dai); 1066 cpu_dai->driver->resume(cpu_dai);
1076 if (platform->resume) 1067 if (platform->driver->resume && platform->suspended) {
1077 platform->resume(&card->dai_link[i]); 1068 platform->driver->resume(cpu_dai);
1069 platform->suspended = 0;
1070 }
1078 } 1071 }
1079 1072
1080 if (card->resume_post) 1073 if (card->resume_post)
1081 card->resume_post(pdev); 1074 card->resume_post(pdev);
1082 1075
1083 dev_dbg(socdev->dev, "resume work completed\n"); 1076 dev_dbg(card->dev, "resume work completed\n");
1084 1077
1085 /* userspace can access us now we are back as we were before */ 1078 /* userspace can access us now we are back as we were before */
1086 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D0); 1079 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0);
1087} 1080}
1088 1081
1089/* powers up audio subsystem after a suspend */ 1082/* powers up audio subsystem after a suspend */
1090static int soc_resume(struct device *dev) 1083static int soc_resume(struct device *dev)
1091{ 1084{
1092 struct platform_device *pdev = to_platform_device(dev); 1085 struct platform_device *pdev = to_platform_device(dev);
1093 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1086 struct snd_soc_card *card = platform_get_drvdata(pdev);
1094 struct snd_soc_card *card = socdev->card; 1087 int i;
1095 struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai;
1096
1097 /* If the initialization of this soc device failed, there is no codec
1098 * associated with it. Just bail out in this case.
1099 */
1100 if (!card->codec)
1101 return 0;
1102 1088
1103 /* AC97 devices might have other drivers hanging off them so 1089 /* AC97 devices might have other drivers hanging off them so
1104 * need to resume immediately. Other drivers don't have that 1090 * need to resume immediately. Other drivers don't have that
1105 * problem and may take a substantial amount of time to resume 1091 * problem and may take a substantial amount of time to resume
1106 * due to I/O costs and anti-pop so handle them out of line. 1092 * due to I/O costs and anti-pop so handle them out of line.
1107 */ 1093 */
1108 if (cpu_dai->ac97_control) { 1094 for (i = 0; i < card->num_rtd; i++) {
1109 dev_dbg(socdev->dev, "Resuming AC97 immediately\n"); 1095 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
1110 soc_resume_deferred(&card->deferred_resume_work); 1096 if (cpu_dai->driver->ac97_control) {
1111 } else { 1097 dev_dbg(dev, "Resuming AC97 immediately\n");
1112 dev_dbg(socdev->dev, "Scheduling resume work\n"); 1098 soc_resume_deferred(&card->deferred_resume_work);
1113 if (!schedule_work(&card->deferred_resume_work)) 1099 } else {
1114 dev_err(socdev->dev, "resume work item may be lost\n"); 1100 dev_dbg(dev, "Scheduling resume work\n");
1101 if (!schedule_work(&card->deferred_resume_work))
1102 dev_err(dev, "resume work item may be lost\n");
1103 }
1115 } 1104 }
1116 1105
1117 return 0; 1106 return 0;
@@ -1124,198 +1113,429 @@ static int soc_resume(struct device *dev)
1124static struct snd_soc_dai_ops null_dai_ops = { 1113static struct snd_soc_dai_ops null_dai_ops = {
1125}; 1114};
1126 1115
1127static void snd_soc_instantiate_card(struct snd_soc_card *card) 1116static int soc_bind_dai_link(struct snd_soc_card *card, int num)
1128{ 1117{
1129 struct platform_device *pdev = container_of(card->dev, 1118 struct snd_soc_dai_link *dai_link = &card->dai_link[num];
1130 struct platform_device, 1119 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1131 dev);
1132 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;
1133 struct snd_soc_codec *codec; 1120 struct snd_soc_codec *codec;
1134 struct snd_soc_platform *platform; 1121 struct snd_soc_platform *platform;
1135 struct snd_soc_dai *dai; 1122 struct snd_soc_dai *codec_dai, *cpu_dai;
1136 int i, found, ret, ac97;
1137 1123
1138 if (card->instantiated) 1124 if (rtd->complete)
1139 return; 1125 return 1;
1126 dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num);
1140 1127
1141 found = 0; 1128 /* do we already have the CPU DAI for this link ? */
1142 list_for_each_entry(platform, &platform_list, list) 1129 if (rtd->cpu_dai) {
1143 if (card->platform == platform) { 1130 goto find_codec;
1144 found = 1; 1131 }
1145 break; 1132 /* no, then find CPU DAI from registered DAIs*/
1133 list_for_each_entry(cpu_dai, &dai_list, list) {
1134 if (!strcmp(cpu_dai->name, dai_link->cpu_dai_name)) {
1135
1136 if (!try_module_get(cpu_dai->dev->driver->owner))
1137 return -ENODEV;
1138
1139 rtd->cpu_dai = cpu_dai;
1140 goto find_codec;
1146 } 1141 }
1147 if (!found) {
1148 dev_dbg(card->dev, "Platform %s not registered\n",
1149 card->platform->name);
1150 return;
1151 } 1142 }
1143 dev_dbg(card->dev, "CPU DAI %s not registered\n",
1144 dai_link->cpu_dai_name);
1152 1145
1153 ac97 = 0; 1146find_codec:
1154 for (i = 0; i < card->num_links; i++) { 1147 /* do we already have the CODEC for this link ? */
1155 found = 0; 1148 if (rtd->codec) {
1156 list_for_each_entry(dai, &dai_list, list) 1149 goto find_platform;
1157 if (card->dai_link[i].cpu_dai == dai) { 1150 }
1158 found = 1; 1151
1159 break; 1152 /* no, then find CODEC from registered CODECs*/
1153 list_for_each_entry(codec, &codec_list, list) {
1154 if (!strcmp(codec->name, dai_link->codec_name)) {
1155 rtd->codec = codec;
1156
1157 if (!try_module_get(codec->dev->driver->owner))
1158 return -ENODEV;
1159
1160 /* CODEC found, so find CODEC DAI from registered DAIs from this CODEC*/
1161 list_for_each_entry(codec_dai, &dai_list, list) {
1162 if (codec->dev == codec_dai->dev &&
1163 !strcmp(codec_dai->name, dai_link->codec_dai_name)) {
1164 rtd->codec_dai = codec_dai;
1165 goto find_platform;
1166 }
1160 } 1167 }
1161 if (!found) { 1168 dev_dbg(card->dev, "CODEC DAI %s not registered\n",
1162 dev_dbg(card->dev, "DAI %s not registered\n", 1169 dai_link->codec_dai_name);
1163 card->dai_link[i].cpu_dai->name); 1170
1164 return; 1171 goto find_platform;
1165 } 1172 }
1173 }
1174 dev_dbg(card->dev, "CODEC %s not registered\n",
1175 dai_link->codec_name);
1166 1176
1167 if (card->dai_link[i].cpu_dai->ac97_control) 1177find_platform:
1168 ac97 = 1; 1178 /* do we already have the CODEC DAI for this link ? */
1179 if (rtd->platform) {
1180 goto out;
1169 } 1181 }
1182 /* no, then find CPU DAI from registered DAIs*/
1183 list_for_each_entry(platform, &platform_list, list) {
1184 if (!strcmp(platform->name, dai_link->platform_name)) {
1170 1185
1171 for (i = 0; i < card->num_links; i++) { 1186 if (!try_module_get(platform->dev->driver->owner))
1172 if (!card->dai_link[i].codec_dai->ops) 1187 return -ENODEV;
1173 card->dai_link[i].codec_dai->ops = &null_dai_ops; 1188
1189 rtd->platform = platform;
1190 goto out;
1191 }
1174 } 1192 }
1175 1193
1176 /* If we have AC97 in the system then don't wait for the 1194 dev_dbg(card->dev, "platform %s not registered\n",
1177 * codec. This will need revisiting if we have to handle 1195 dai_link->platform_name);
1178 * systems with mixed AC97 and non-AC97 parts. Only check for 1196 return 0;
1179 * DAIs currently; we can't do this per link since some AC97 1197
1180 * codecs have non-AC97 DAIs. 1198out:
1181 */ 1199 /* mark rtd as complete if we found all 4 of our client devices */
1182 if (!ac97) 1200 if (rtd->codec && rtd->codec_dai && rtd->platform && rtd->cpu_dai) {
1183 for (i = 0; i < card->num_links; i++) { 1201 rtd->complete = 1;
1184 found = 0; 1202 card->num_rtd++;
1185 list_for_each_entry(dai, &dai_list, list) 1203 }
1186 if (card->dai_link[i].codec_dai == dai) { 1204 return 1;
1187 found = 1; 1205}
1188 break; 1206
1189 } 1207static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1190 if (!found) { 1208{
1191 dev_dbg(card->dev, "DAI %s not registered\n", 1209 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1192 card->dai_link[i].codec_dai->name); 1210 struct snd_soc_codec *codec = rtd->codec;
1193 return; 1211 struct snd_soc_platform *platform = rtd->platform;
1194 } 1212 struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai;
1213 int err;
1214
1215 /* unregister the rtd device */
1216 if (rtd->dev_registered) {
1217 device_remove_file(&rtd->dev, &dev_attr_pmdown_time);
1218 device_unregister(&rtd->dev);
1219 rtd->dev_registered = 0;
1220 }
1221
1222 /* remove the CODEC DAI */
1223 if (codec_dai && codec_dai->probed) {
1224 if (codec_dai->driver->remove) {
1225 err = codec_dai->driver->remove(codec_dai);
1226 if (err < 0)
1227 printk(KERN_ERR "asoc: failed to remove %s\n", codec_dai->name);
1195 } 1228 }
1229 codec_dai->probed = 0;
1230 list_del(&codec_dai->card_list);
1231 }
1196 1232
1197 /* Note that we do not current check for codec components */ 1233 /* remove the platform */
1234 if (platform && platform->probed) {
1235 if (platform->driver->remove) {
1236 err = platform->driver->remove(platform);
1237 if (err < 0)
1238 printk(KERN_ERR "asoc: failed to remove %s\n", platform->name);
1239 }
1240 platform->probed = 0;
1241 list_del(&platform->card_list);
1242 module_put(platform->dev->driver->owner);
1243 }
1198 1244
1199 dev_dbg(card->dev, "All components present, instantiating\n"); 1245 /* remove the CODEC */
1246 if (codec && codec->probed) {
1247 if (codec->driver->remove) {
1248 err = codec->driver->remove(codec);
1249 if (err < 0)
1250 printk(KERN_ERR "asoc: failed to remove %s\n", codec->name);
1251 }
1200 1252
1201 /* Found everything, bring it up */ 1253 /* Make sure all DAPM widgets are freed */
1202 card->pmdown_time = pmdown_time; 1254 snd_soc_dapm_free(codec);
1203 1255
1204 if (card->probe) { 1256 soc_cleanup_codec_debugfs(codec);
1205 ret = card->probe(pdev); 1257 device_remove_file(&rtd->dev, &dev_attr_codec_reg);
1206 if (ret < 0) 1258 codec->probed = 0;
1207 return; 1259 list_del(&codec->card_list);
1260 module_put(codec->dev->driver->owner);
1208 } 1261 }
1209 1262
1210 for (i = 0; i < card->num_links; i++) { 1263 /* remove the cpu_dai */
1211 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 1264 if (cpu_dai && cpu_dai->probed) {
1212 if (cpu_dai->probe) { 1265 if (cpu_dai->driver->remove) {
1213 ret = cpu_dai->probe(pdev, cpu_dai); 1266 err = cpu_dai->driver->remove(cpu_dai);
1214 if (ret < 0) 1267 if (err < 0)
1215 goto cpu_dai_err; 1268 printk(KERN_ERR "asoc: failed to remove %s\n", cpu_dai->name);
1216 } 1269 }
1270 cpu_dai->probed = 0;
1271 list_del(&cpu_dai->card_list);
1272 module_put(cpu_dai->dev->driver->owner);
1217 } 1273 }
1274}
1218 1275
1219 if (codec_dev->probe) { 1276static void rtd_release(struct device *dev) {}
1220 ret = codec_dev->probe(pdev); 1277
1221 if (ret < 0) 1278static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1222 goto cpu_dai_err; 1279{
1280 struct snd_soc_dai_link *dai_link = &card->dai_link[num];
1281 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1282 struct snd_soc_codec *codec = rtd->codec;
1283 struct snd_soc_platform *platform = rtd->platform;
1284 struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai;
1285 int ret;
1286
1287 dev_dbg(card->dev, "probe %s dai link %d\n", card->name, num);
1288
1289 /* config components */
1290 codec_dai->codec = codec;
1291 codec->card = card;
1292 cpu_dai->platform = platform;
1293 rtd->card = card;
1294 rtd->dev.parent = card->dev;
1295 codec_dai->card = card;
1296 cpu_dai->card = card;
1297
1298 /* set default power off timeout */
1299 rtd->pmdown_time = pmdown_time;
1300
1301 /* probe the cpu_dai */
1302 if (!cpu_dai->probed) {
1303 if (cpu_dai->driver->probe) {
1304 ret = cpu_dai->driver->probe(cpu_dai);
1305 if (ret < 0) {
1306 printk(KERN_ERR "asoc: failed to probe CPU DAI %s\n",
1307 cpu_dai->name);
1308 return ret;
1309 }
1310 }
1311 cpu_dai->probed = 1;
1312 /* mark cpu_dai as probed and add to card cpu_dai list */
1313 list_add(&cpu_dai->card_list, &card->dai_dev_list);
1223 } 1314 }
1224 codec = card->codec;
1225 1315
1226 if (platform->probe) { 1316 /* probe the CODEC */
1227 ret = platform->probe(pdev); 1317 if (!codec->probed) {
1228 if (ret < 0) 1318 if (codec->driver->probe) {
1229 goto platform_err; 1319 ret = codec->driver->probe(codec);
1320 if (ret < 0) {
1321 printk(KERN_ERR "asoc: failed to probe CODEC %s\n",
1322 codec->name);
1323 return ret;
1324 }
1325 }
1326 /* mark codec as probed and add to card codec list */
1327 codec->probed = 1;
1328 list_add(&codec->card_list, &card->codec_dev_list);
1230 } 1329 }
1231 1330
1232 /* DAPM stream work */ 1331 /* probe the platform */
1233 INIT_DELAYED_WORK(&card->delayed_work, close_delayed_work); 1332 if (!platform->probed) {
1234#ifdef CONFIG_PM 1333 if (platform->driver->probe) {
1235 /* deferred resume work */ 1334 ret = platform->driver->probe(platform);
1236 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 1335 if (ret < 0) {
1237#endif 1336 printk(KERN_ERR "asoc: failed to probe platform %s\n",
1337 platform->name);
1338 return ret;
1339 }
1340 }
1341 /* mark platform as probed and add to card platform list */
1342 platform->probed = 1;
1343 list_add(&platform->card_list, &card->platform_dev_list);
1344 }
1238 1345
1239 for (i = 0; i < card->num_links; i++) { 1346 /* probe the CODEC DAI */
1240 if (card->dai_link[i].init) { 1347 if (!codec_dai->probed) {
1241 ret = card->dai_link[i].init(codec); 1348 if (codec_dai->driver->probe) {
1349 ret = codec_dai->driver->probe(codec_dai);
1242 if (ret < 0) { 1350 if (ret < 0) {
1243 printk(KERN_ERR "asoc: failed to init %s\n", 1351 printk(KERN_ERR "asoc: failed to probe CODEC DAI %s\n",
1244 card->dai_link[i].stream_name); 1352 codec_dai->name);
1245 continue; 1353 return ret;
1246 } 1354 }
1247 } 1355 }
1248 if (card->dai_link[i].codec_dai->ac97_control) 1356
1249 ac97 = 1; 1357 /* mark cpu_dai as probed and add to card cpu_dai list */
1358 codec_dai->probed = 1;
1359 list_add(&codec_dai->card_list, &card->dai_dev_list);
1250 } 1360 }
1251 1361
1252 snprintf(codec->card->shortname, sizeof(codec->card->shortname), 1362 /* DAPM dai link stream work */
1253 "%s", card->name); 1363 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
1254 snprintf(codec->card->longname, sizeof(codec->card->longname), 1364
1255 "%s (%s)", card->name, codec->name); 1365 /* now that all clients have probed, initialise the DAI link */
1366 if (dai_link->init) {
1367 ret = dai_link->init(rtd);
1368 if (ret < 0) {
1369 printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name);
1370 return ret;
1371 }
1372 }
1256 1373
1257 /* Make sure all DAPM widgets are instantiated */ 1374 /* Make sure all DAPM widgets are instantiated */
1258 snd_soc_dapm_new_widgets(codec); 1375 snd_soc_dapm_new_widgets(codec);
1376 snd_soc_dapm_sync(codec);
1259 1377
1260 ret = snd_card_register(codec->card); 1378 /* register the rtd device */
1379 rtd->dev.init_name = rtd->dai_link->stream_name;
1380 rtd->dev.release = rtd_release;
1381 rtd->dev.init_name = dai_link->name;
1382 ret = device_register(&rtd->dev);
1261 if (ret < 0) { 1383 if (ret < 0) {
1262 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", 1384 printk(KERN_ERR "asoc: failed to register DAI runtime device %d\n", ret);
1263 codec->name); 1385 return ret;
1264 goto card_err;
1265 } 1386 }
1266 1387
1267 mutex_lock(&codec->mutex); 1388 rtd->dev_registered = 1;
1389 ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time);
1390 if (ret < 0)
1391 printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
1392
1393 /* add DAPM sysfs entries for this codec */
1394 ret = snd_soc_dapm_sys_add(&rtd->dev);
1395 if (ret < 0)
1396 printk(KERN_WARNING "asoc: failed to add codec dapm sysfs entries\n");
1397
1398 /* add codec sysfs entries */
1399 ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
1400 if (ret < 0)
1401 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1402
1403 soc_init_codec_debugfs(codec);
1404
1405 /* create the pcm */
1406 ret = soc_new_pcm(rtd, num);
1407 if (ret < 0) {
1408 printk(KERN_ERR "asoc: can't create pcm %s\n", dai_link->stream_name);
1409 return ret;
1410 }
1411
1412 /* add platform data for AC97 devices */
1413 if (rtd->codec_dai->driver->ac97_control)
1414 snd_ac97_dev_add_pdata(codec->ac97, rtd->cpu_dai->ac97_pdata);
1415
1416 return 0;
1417}
1418
1268#ifdef CONFIG_SND_SOC_AC97_BUS 1419#ifdef CONFIG_SND_SOC_AC97_BUS
1420static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd)
1421{
1422 int ret;
1423
1269 /* Only instantiate AC97 if not already done by the adaptor 1424 /* Only instantiate AC97 if not already done by the adaptor
1270 * for the generic AC97 subsystem. 1425 * for the generic AC97 subsystem.
1271 */ 1426 */
1272 if (ac97 && strcmp(codec->name, "AC97") != 0) { 1427 if (rtd->codec_dai->driver->ac97_control && !rtd->codec->ac97_registered) {
1273 ret = soc_ac97_dev_register(codec); 1428
1429 ret = soc_ac97_dev_register(rtd->codec);
1274 if (ret < 0) { 1430 if (ret < 0) {
1275 printk(KERN_ERR "asoc: AC97 device register failed\n"); 1431 printk(KERN_ERR "asoc: AC97 device register failed\n");
1276 snd_card_free(codec->card); 1432 return ret;
1277 mutex_unlock(&codec->mutex);
1278 goto card_err;
1279 } 1433 }
1434
1435 rtd->codec->ac97_registered = 1;
1280 } 1436 }
1437 return 0;
1438}
1439
1440static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
1441{
1442 if (codec->ac97_registered) {
1443 soc_ac97_dev_unregister(codec);
1444 codec->ac97_registered = 0;
1445 }
1446}
1281#endif 1447#endif
1282 1448
1283 ret = snd_soc_dapm_sys_add(card->socdev->dev); 1449static void snd_soc_instantiate_card(struct snd_soc_card *card)
1284 if (ret < 0) 1450{
1285 printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n"); 1451 struct platform_device *pdev = to_platform_device(card->dev);
1452 int ret, i;
1286 1453
1287 ret = device_create_file(card->socdev->dev, &dev_attr_pmdown_time); 1454 mutex_lock(&card->mutex);
1288 if (ret < 0)
1289 printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
1290 1455
1291 ret = device_create_file(card->socdev->dev, &dev_attr_codec_reg); 1456 if (card->instantiated) {
1292 if (ret < 0) 1457 mutex_unlock(&card->mutex);
1293 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); 1458 return;
1459 }
1294 1460
1295 soc_init_codec_debugfs(codec); 1461 /* bind DAIs */
1296 mutex_unlock(&codec->mutex); 1462 for (i = 0; i < card->num_links; i++)
1463 soc_bind_dai_link(card, i);
1297 1464
1298 card->instantiated = 1; 1465 /* bind completed ? */
1466 if (card->num_rtd != card->num_links) {
1467 mutex_unlock(&card->mutex);
1468 return;
1469 }
1299 1470
1300 return; 1471 /* card bind complete so register a sound card */
1472 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
1473 card->owner, 0, &card->snd_card);
1474 if (ret < 0) {
1475 printk(KERN_ERR "asoc: can't create sound card for card %s\n",
1476 card->name);
1477 mutex_unlock(&card->mutex);
1478 return;
1479 }
1480 card->snd_card->dev = card->dev;
1481
1482#ifdef CONFIG_PM
1483 /* deferred resume work */
1484 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
1485#endif
1301 1486
1302card_err: 1487 /* initialise the sound card only once */
1303 if (platform->remove) 1488 if (card->probe) {
1304 platform->remove(pdev); 1489 ret = card->probe(pdev);
1490 if (ret < 0)
1491 goto card_probe_error;
1492 }
1305 1493
1306platform_err: 1494 for (i = 0; i < card->num_links; i++) {
1307 if (codec_dev->remove) 1495 ret = soc_probe_dai_link(card, i);
1308 codec_dev->remove(pdev); 1496 if (ret < 0) {
1497 printk(KERN_ERR "asoc: failed to instanciate card %s\n", card->name);
1498 goto probe_dai_err;
1499 }
1500 }
1309 1501
1310cpu_dai_err: 1502 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1311 for (i--; i >= 0; i--) { 1503 "%s", card->name);
1312 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 1504 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
1313 if (cpu_dai->remove) 1505 "%s", card->name);
1314 cpu_dai->remove(pdev, cpu_dai); 1506
1507 ret = snd_card_register(card->snd_card);
1508 if (ret < 0) {
1509 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
1510 goto probe_dai_err;
1315 } 1511 }
1316 1512
1513#ifdef CONFIG_SND_SOC_AC97_BUS
1514 /* register any AC97 codecs */
1515 for (i = 0; i < card->num_rtd; i++) {
1516 ret = soc_register_ac97_dai_link(&card->rtd[i]);
1517 if (ret < 0) {
1518 printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
1519 goto probe_dai_err;
1520 }
1521 }
1522#endif
1523
1524 card->instantiated = 1;
1525 mutex_unlock(&card->mutex);
1526 return;
1527
1528probe_dai_err:
1529 for (i = 0; i < card->num_links; i++)
1530 soc_remove_dai_link(card, i);
1531
1532card_probe_error:
1317 if (card->remove) 1533 if (card->remove)
1318 card->remove(pdev); 1534 card->remove(pdev);
1535
1536 snd_card_free(card->snd_card);
1537
1538 mutex_unlock(&card->mutex);
1319} 1539}
1320 1540
1321/* 1541/*
@@ -1332,15 +1552,15 @@ static void snd_soc_instantiate_cards(void)
1332/* probes a new socdev */ 1552/* probes a new socdev */
1333static int soc_probe(struct platform_device *pdev) 1553static int soc_probe(struct platform_device *pdev)
1334{ 1554{
1555 struct snd_soc_card *card = platform_get_drvdata(pdev);
1335 int ret = 0; 1556 int ret = 0;
1336 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1337 struct snd_soc_card *card = socdev->card;
1338
1339 /* Bodge while we push things out of socdev */
1340 card->socdev = socdev;
1341 1557
1342 /* Bodge while we unpick instantiation */ 1558 /* Bodge while we unpick instantiation */
1343 card->dev = &pdev->dev; 1559 card->dev = &pdev->dev;
1560 INIT_LIST_HEAD(&card->dai_dev_list);
1561 INIT_LIST_HEAD(&card->codec_dev_list);
1562 INIT_LIST_HEAD(&card->platform_dev_list);
1563
1344 ret = snd_soc_register_card(card); 1564 ret = snd_soc_register_card(card);
1345 if (ret != 0) { 1565 if (ret != 0) {
1346 dev_err(&pdev->dev, "Failed to register card\n"); 1566 dev_err(&pdev->dev, "Failed to register card\n");
@@ -1353,50 +1573,49 @@ static int soc_probe(struct platform_device *pdev)
1353/* removes a socdev */ 1573/* removes a socdev */
1354static int soc_remove(struct platform_device *pdev) 1574static int soc_remove(struct platform_device *pdev)
1355{ 1575{
1576 struct snd_soc_card *card = platform_get_drvdata(pdev);
1356 int i; 1577 int i;
1357 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1358 struct snd_soc_card *card = socdev->card;
1359 struct snd_soc_platform *platform = card->platform;
1360 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
1361 1578
1362 if (card->instantiated) { 1579 if (card->instantiated) {
1363 run_delayed_work(&card->delayed_work);
1364 1580
1365 if (platform->remove) 1581 /* make sure any delayed work runs */
1366 platform->remove(pdev); 1582 for (i = 0; i < card->num_rtd; i++) {
1367 1583 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1368 if (codec_dev->remove) 1584 run_delayed_work(&rtd->delayed_work);
1369 codec_dev->remove(pdev);
1370
1371 for (i = 0; i < card->num_links; i++) {
1372 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
1373 if (cpu_dai->remove)
1374 cpu_dai->remove(pdev, cpu_dai);
1375 } 1585 }
1376 1586
1587 /* remove and free each DAI */
1588 for (i = 0; i < card->num_rtd; i++)
1589 soc_remove_dai_link(card, i);
1590
1591 /* remove the card */
1377 if (card->remove) 1592 if (card->remove)
1378 card->remove(pdev); 1593 card->remove(pdev);
1379 }
1380 1594
1595 kfree(card->rtd);
1596 snd_card_free(card->snd_card);
1597 }
1381 snd_soc_unregister_card(card); 1598 snd_soc_unregister_card(card);
1382
1383 return 0; 1599 return 0;
1384} 1600}
1385 1601
1386static int soc_poweroff(struct device *dev) 1602static int soc_poweroff(struct device *dev)
1387{ 1603{
1388 struct platform_device *pdev = to_platform_device(dev); 1604 struct platform_device *pdev = to_platform_device(dev);
1389 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1605 struct snd_soc_card *card = platform_get_drvdata(pdev);
1390 struct snd_soc_card *card = socdev->card; 1606 int i;
1391 1607
1392 if (!card->instantiated) 1608 if (!card->instantiated)
1393 return 0; 1609 return 0;
1394 1610
1395 /* Flush out pmdown_time work - we actually do want to run it 1611 /* Flush out pmdown_time work - we actually do want to run it
1396 * now, we're shutting down so no imminent restart. */ 1612 * now, we're shutting down so no imminent restart. */
1397 run_delayed_work(&card->delayed_work); 1613 for (i = 0; i < card->num_rtd; i++) {
1614 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1615 run_delayed_work(&rtd->delayed_work);
1616 }
1398 1617
1399 snd_soc_dapm_shutdown(socdev); 1618 snd_soc_dapm_shutdown(card);
1400 1619
1401 return 0; 1620 return 0;
1402} 1621}
@@ -1419,53 +1638,42 @@ static struct platform_driver soc_driver = {
1419}; 1638};
1420 1639
1421/* create a new pcm */ 1640/* create a new pcm */
1422static int soc_new_pcm(struct snd_soc_device *socdev, 1641static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
1423 struct snd_soc_dai_link *dai_link, int num) 1642{
1424{ 1643 struct snd_soc_codec *codec = rtd->codec;
1425 struct snd_soc_card *card = socdev->card; 1644 struct snd_soc_platform *platform = rtd->platform;
1426 struct snd_soc_codec *codec = card->codec; 1645 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1427 struct snd_soc_platform *platform = card->platform; 1646 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1428 struct snd_soc_dai *codec_dai = dai_link->codec_dai;
1429 struct snd_soc_dai *cpu_dai = dai_link->cpu_dai;
1430 struct snd_soc_pcm_runtime *rtd;
1431 struct snd_pcm *pcm; 1647 struct snd_pcm *pcm;
1432 char new_name[64]; 1648 char new_name[64];
1433 int ret = 0, playback = 0, capture = 0; 1649 int ret = 0, playback = 0, capture = 0;
1434 1650
1435 rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime), GFP_KERNEL);
1436 if (rtd == NULL)
1437 return -ENOMEM;
1438
1439 rtd->dai = dai_link;
1440 rtd->socdev = socdev;
1441 codec_dai->codec = card->codec;
1442
1443 /* check client and interface hw capabilities */ 1651 /* check client and interface hw capabilities */
1444 snprintf(new_name, sizeof(new_name), "%s %s-%d", 1652 snprintf(new_name, sizeof(new_name), "%s %s-%d",
1445 dai_link->stream_name, codec_dai->name, num); 1653 rtd->dai_link->stream_name, codec_dai->name, num);
1446 1654
1447 if (codec_dai->playback.channels_min) 1655 if (codec_dai->driver->playback.channels_min)
1448 playback = 1; 1656 playback = 1;
1449 if (codec_dai->capture.channels_min) 1657 if (codec_dai->driver->capture.channels_min)
1450 capture = 1; 1658 capture = 1;
1451 1659
1452 ret = snd_pcm_new(codec->card, new_name, codec->pcm_devs++, playback, 1660 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num,new_name);
1453 capture, &pcm); 1661 ret = snd_pcm_new(rtd->card->snd_card, new_name,
1662 num, playback, capture, &pcm);
1454 if (ret < 0) { 1663 if (ret < 0) {
1455 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", 1664 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name);
1456 codec->name);
1457 kfree(rtd);
1458 return ret; 1665 return ret;
1459 } 1666 }
1460 1667
1461 dai_link->pcm = pcm; 1668 rtd->pcm = pcm;
1462 pcm->private_data = rtd; 1669 pcm->private_data = rtd;
1463 soc_pcm_ops.mmap = platform->pcm_ops->mmap; 1670 soc_pcm_ops.mmap = platform->driver->ops->mmap;
1464 soc_pcm_ops.ioctl = platform->pcm_ops->ioctl; 1671 soc_pcm_ops.pointer = platform->driver->ops->pointer;
1465 soc_pcm_ops.copy = platform->pcm_ops->copy; 1672 soc_pcm_ops.ioctl = platform->driver->ops->ioctl;
1466 soc_pcm_ops.silence = platform->pcm_ops->silence; 1673 soc_pcm_ops.copy = platform->driver->ops->copy;
1467 soc_pcm_ops.ack = platform->pcm_ops->ack; 1674 soc_pcm_ops.silence = platform->driver->ops->silence;
1468 soc_pcm_ops.page = platform->pcm_ops->page; 1675 soc_pcm_ops.ack = platform->driver->ops->ack;
1676 soc_pcm_ops.page = platform->driver->ops->page;
1469 1677
1470 if (playback) 1678 if (playback)
1471 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops); 1679 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
@@ -1473,14 +1681,13 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
1473 if (capture) 1681 if (capture)
1474 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops); 1682 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
1475 1683
1476 ret = platform->pcm_new(codec->card, codec_dai, pcm); 1684 ret = platform->driver->pcm_new(rtd->card->snd_card, codec_dai, pcm);
1477 if (ret < 0) { 1685 if (ret < 0) {
1478 printk(KERN_ERR "asoc: platform pcm constructor failed\n"); 1686 printk(KERN_ERR "asoc: platform pcm constructor failed\n");
1479 kfree(rtd);
1480 return ret; 1687 return ret;
1481 } 1688 }
1482 1689
1483 pcm->private_free = platform->pcm_free; 1690 pcm->private_free = platform->driver->pcm_free;
1484 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, 1691 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
1485 cpu_dai->name); 1692 cpu_dai->name);
1486 return ret; 1693 return ret;
@@ -1496,8 +1703,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
1496 */ 1703 */
1497int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg) 1704int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg)
1498{ 1705{
1499 if (codec->volatile_register) 1706 if (codec->driver->volatile_register)
1500 return codec->volatile_register(reg); 1707 return codec->driver->volatile_register(reg);
1501 else 1708 else
1502 return 0; 1709 return 0;
1503} 1710}
@@ -1532,7 +1739,6 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
1532 1739
1533 codec->ac97->bus->ops = ops; 1740 codec->ac97->bus->ops = ops;
1534 codec->ac97->num = num; 1741 codec->ac97->num = num;
1535 codec->dev = &codec->ac97->dev;
1536 mutex_unlock(&codec->mutex); 1742 mutex_unlock(&codec->mutex);
1537 return 0; 1743 return 0;
1538} 1744}
@@ -1547,6 +1753,9 @@ EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
1547void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) 1753void snd_soc_free_ac97_codec(struct snd_soc_codec *codec)
1548{ 1754{
1549 mutex_lock(&codec->mutex); 1755 mutex_lock(&codec->mutex);
1756#ifdef CONFIG_SND_SOC_AC97_BUS
1757 soc_unregister_ac97_dai_link(codec);
1758#endif
1550 kfree(codec->ac97->bus); 1759 kfree(codec->ac97->bus);
1551 kfree(codec->ac97); 1760 kfree(codec->ac97);
1552 codec->ac97 = NULL; 1761 codec->ac97 = NULL;
@@ -1633,95 +1842,6 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
1633EXPORT_SYMBOL_GPL(snd_soc_test_bits); 1842EXPORT_SYMBOL_GPL(snd_soc_test_bits);
1634 1843
1635/** 1844/**
1636 * snd_soc_new_pcms - create new sound card and pcms
1637 * @socdev: the SoC audio device
1638 * @idx: ALSA card index
1639 * @xid: card identification
1640 *
1641 * Create a new sound card based upon the codec and interface pcms.
1642 *
1643 * Returns 0 for success, else error.
1644 */
1645int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1646{
1647 struct snd_soc_card *card = socdev->card;
1648 struct snd_soc_codec *codec = card->codec;
1649 int ret, i;
1650
1651 mutex_lock(&codec->mutex);
1652
1653 /* register a sound card */
1654 ret = snd_card_create(idx, xid, codec->owner, 0, &codec->card);
1655 if (ret < 0) {
1656 printk(KERN_ERR "asoc: can't create sound card for codec %s\n",
1657 codec->name);
1658 mutex_unlock(&codec->mutex);
1659 return ret;
1660 }
1661
1662 codec->socdev = socdev;
1663 codec->card->dev = socdev->dev;
1664 codec->card->private_data = codec;
1665 strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver));
1666
1667 /* create the pcms */
1668 for (i = 0; i < card->num_links; i++) {
1669 ret = soc_new_pcm(socdev, &card->dai_link[i], i);
1670 if (ret < 0) {
1671 printk(KERN_ERR "asoc: can't create pcm %s\n",
1672 card->dai_link[i].stream_name);
1673 mutex_unlock(&codec->mutex);
1674 return ret;
1675 }
1676 /* Check for codec->ac97 to handle the ac97.c fun */
1677 if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) {
1678 snd_ac97_dev_add_pdata(codec->ac97,
1679 card->dai_link[i].cpu_dai->ac97_pdata);
1680 }
1681 }
1682
1683 mutex_unlock(&codec->mutex);
1684 return ret;
1685}
1686EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1687
1688/**
1689 * snd_soc_free_pcms - free sound card and pcms
1690 * @socdev: the SoC audio device
1691 *
1692 * Frees sound card and pcms associated with the socdev.
1693 * Also unregister the codec if it is an AC97 device.
1694 */
1695void snd_soc_free_pcms(struct snd_soc_device *socdev)
1696{
1697 struct snd_soc_codec *codec = socdev->card->codec;
1698#ifdef CONFIG_SND_SOC_AC97_BUS
1699 struct snd_soc_dai *codec_dai;
1700 int i;
1701#endif
1702
1703 mutex_lock(&codec->mutex);
1704 soc_cleanup_codec_debugfs(codec);
1705#ifdef CONFIG_SND_SOC_AC97_BUS
1706 for (i = 0; i < codec->num_dai; i++) {
1707 codec_dai = &codec->dai[i];
1708 if (codec_dai->ac97_control && codec->ac97 &&
1709 strcmp(codec->name, "AC97") != 0) {
1710 soc_ac97_dev_unregister(codec);
1711 goto free_card;
1712 }
1713 }
1714free_card:
1715#endif
1716
1717 if (codec->card)
1718 snd_card_free(codec->card);
1719 device_remove_file(socdev->dev, &dev_attr_codec_reg);
1720 mutex_unlock(&codec->mutex);
1721}
1722EXPORT_SYMBOL_GPL(snd_soc_free_pcms);
1723
1724/**
1725 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters 1845 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
1726 * @substream: the pcm substream 1846 * @substream: the pcm substream
1727 * @hw: the hardware parameters 1847 * @hw: the hardware parameters
@@ -1782,7 +1902,7 @@ EXPORT_SYMBOL_GPL(snd_soc_cnew);
1782int snd_soc_add_controls(struct snd_soc_codec *codec, 1902int snd_soc_add_controls(struct snd_soc_codec *codec,
1783 const struct snd_kcontrol_new *controls, int num_controls) 1903 const struct snd_kcontrol_new *controls, int num_controls)
1784{ 1904{
1785 struct snd_card *card = codec->card; 1905 struct snd_card *card = codec->card->snd_card;
1786 int err, i; 1906 int err, i;
1787 1907
1788 for (i = 0; i < num_controls; i++) { 1908 for (i = 0; i < num_controls; i++) {
@@ -2337,7 +2457,7 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
2337int snd_soc_limit_volume(struct snd_soc_codec *codec, 2457int snd_soc_limit_volume(struct snd_soc_codec *codec,
2338 const char *name, int max) 2458 const char *name, int max)
2339{ 2459{
2340 struct snd_card *card = codec->card; 2460 struct snd_card *card = codec->card->snd_card;
2341 struct snd_kcontrol *kctl; 2461 struct snd_kcontrol *kctl;
2342 struct soc_mixer_control *mc; 2462 struct soc_mixer_control *mc;
2343 int found = 0; 2463 int found = 0;
@@ -2469,8 +2589,8 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
2469int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, 2589int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
2470 unsigned int freq, int dir) 2590 unsigned int freq, int dir)
2471{ 2591{
2472 if (dai->ops && dai->ops->set_sysclk) 2592 if (dai->driver && dai->driver->ops->set_sysclk)
2473 return dai->ops->set_sysclk(dai, clk_id, freq, dir); 2593 return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
2474 else 2594 else
2475 return -EINVAL; 2595 return -EINVAL;
2476} 2596}
@@ -2489,8 +2609,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
2489int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, 2609int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
2490 int div_id, int div) 2610 int div_id, int div)
2491{ 2611{
2492 if (dai->ops && dai->ops->set_clkdiv) 2612 if (dai->driver && dai->driver->ops->set_clkdiv)
2493 return dai->ops->set_clkdiv(dai, div_id, div); 2613 return dai->driver->ops->set_clkdiv(dai, div_id, div);
2494 else 2614 else
2495 return -EINVAL; 2615 return -EINVAL;
2496} 2616}
@@ -2509,8 +2629,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
2509int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source, 2629int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
2510 unsigned int freq_in, unsigned int freq_out) 2630 unsigned int freq_in, unsigned int freq_out)
2511{ 2631{
2512 if (dai->ops && dai->ops->set_pll) 2632 if (dai->driver && dai->driver->ops->set_pll)
2513 return dai->ops->set_pll(dai, pll_id, source, 2633 return dai->driver->ops->set_pll(dai, pll_id, source,
2514 freq_in, freq_out); 2634 freq_in, freq_out);
2515 else 2635 else
2516 return -EINVAL; 2636 return -EINVAL;
@@ -2526,8 +2646,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
2526 */ 2646 */
2527int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 2647int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2528{ 2648{
2529 if (dai->ops && dai->ops->set_fmt) 2649 if (dai->driver && dai->driver->ops->set_fmt)
2530 return dai->ops->set_fmt(dai, fmt); 2650 return dai->driver->ops->set_fmt(dai, fmt);
2531 else 2651 else
2532 return -EINVAL; 2652 return -EINVAL;
2533} 2653}
@@ -2547,8 +2667,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
2547int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, 2667int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
2548 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 2668 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
2549{ 2669{
2550 if (dai->ops && dai->ops->set_tdm_slot) 2670 if (dai->driver && dai->driver->ops->set_tdm_slot)
2551 return dai->ops->set_tdm_slot(dai, tx_mask, rx_mask, 2671 return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
2552 slots, slot_width); 2672 slots, slot_width);
2553 else 2673 else
2554 return -EINVAL; 2674 return -EINVAL;
@@ -2571,8 +2691,8 @@ int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
2571 unsigned int tx_num, unsigned int *tx_slot, 2691 unsigned int tx_num, unsigned int *tx_slot,
2572 unsigned int rx_num, unsigned int *rx_slot) 2692 unsigned int rx_num, unsigned int *rx_slot)
2573{ 2693{
2574 if (dai->ops && dai->ops->set_channel_map) 2694 if (dai->driver && dai->driver->ops->set_channel_map)
2575 return dai->ops->set_channel_map(dai, tx_num, tx_slot, 2695 return dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
2576 rx_num, rx_slot); 2696 rx_num, rx_slot);
2577 else 2697 else
2578 return -EINVAL; 2698 return -EINVAL;
@@ -2588,8 +2708,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
2588 */ 2708 */
2589int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate) 2709int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
2590{ 2710{
2591 if (dai->ops && dai->ops->set_tristate) 2711 if (dai->driver && dai->driver->ops->set_tristate)
2592 return dai->ops->set_tristate(dai, tristate); 2712 return dai->driver->ops->set_tristate(dai, tristate);
2593 else 2713 else
2594 return -EINVAL; 2714 return -EINVAL;
2595} 2715}
@@ -2604,8 +2724,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
2604 */ 2724 */
2605int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute) 2725int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
2606{ 2726{
2607 if (dai->ops && dai->ops->digital_mute) 2727 if (dai->driver && dai->driver->ops->digital_mute)
2608 return dai->ops->digital_mute(dai, mute); 2728 return dai->driver->ops->digital_mute(dai, mute);
2609 else 2729 else
2610 return -EINVAL; 2730 return -EINVAL;
2611} 2731}
@@ -2622,11 +2742,22 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
2622 */ 2742 */
2623static int snd_soc_register_card(struct snd_soc_card *card) 2743static int snd_soc_register_card(struct snd_soc_card *card)
2624{ 2744{
2745 int i;
2746
2625 if (!card->name || !card->dev) 2747 if (!card->name || !card->dev)
2626 return -EINVAL; 2748 return -EINVAL;
2627 2749
2750 card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) * card->num_links,
2751 GFP_KERNEL);
2752 if (card->rtd == NULL)
2753 return -ENOMEM;
2754
2755 for (i = 0; i < card->num_links; i++)
2756 card->rtd[i].dai_link = &card->dai_link[i];
2757
2628 INIT_LIST_HEAD(&card->list); 2758 INIT_LIST_HEAD(&card->list);
2629 card->instantiated = 0; 2759 card->instantiated = 0;
2760 mutex_init(&card->mutex);
2630 2761
2631 mutex_lock(&client_mutex); 2762 mutex_lock(&client_mutex);
2632 list_add(&card->list, &card_list); 2763 list_add(&card->list, &card_list);
@@ -2652,30 +2783,97 @@ static int snd_soc_unregister_card(struct snd_soc_card *card)
2652 mutex_lock(&client_mutex); 2783 mutex_lock(&client_mutex);
2653 list_del(&card->list); 2784 list_del(&card->list);
2654 mutex_unlock(&client_mutex); 2785 mutex_unlock(&client_mutex);
2655
2656 dev_dbg(card->dev, "Unregistered card '%s'\n", card->name); 2786 dev_dbg(card->dev, "Unregistered card '%s'\n", card->name);
2657 2787
2658 return 0; 2788 return 0;
2659} 2789}
2660 2790
2791/*
2792 * Simplify DAI link configuration by removing ".-1" from device names
2793 * and sanitizing names.
2794 */
2795static inline char *fmt_single_name(struct device *dev, int *id)
2796{
2797 char *found, name[NAME_SIZE];
2798 int id1, id2;
2799
2800 if (dev_name(dev) == NULL)
2801 return NULL;
2802
2803 strncpy(name, dev_name(dev), NAME_SIZE);
2804
2805 /* are we a "%s.%d" name (platform and SPI components) */
2806 found = strstr(name, dev->driver->name);
2807 if (found) {
2808 /* get ID */
2809 if (sscanf(&found[strlen(dev->driver->name)], ".%d", id) == 1) {
2810
2811 /* discard ID from name if ID == -1 */
2812 if (*id == -1)
2813 found[strlen(dev->driver->name)] = '\0';
2814 }
2815
2816 } else {
2817 /* I2C component devices are named "bus-addr" */
2818 if (sscanf(name, "%x-%x", &id1, &id2) == 2) {
2819 char tmp[NAME_SIZE];
2820
2821 /* create unique ID number from I2C addr and bus */
2822 *id = ((id1 && 0xffff) << 16) + id2;
2823
2824 /* sanitize component name for DAI link creation */
2825 snprintf(tmp, NAME_SIZE, "%s.%s", dev->driver->name, name);
2826 strncpy(name, tmp, NAME_SIZE);
2827 } else
2828 *id = 0;
2829 }
2830
2831 return kstrdup(name, GFP_KERNEL);
2832}
2833
2834/*
2835 * Simplify DAI link naming for single devices with multiple DAIs by removing
2836 * any ".-1" and using the DAI name (instead of device name).
2837 */
2838static inline char *fmt_multiple_name(struct device *dev,
2839 struct snd_soc_dai_driver *dai_drv)
2840{
2841 if (dai_drv->name == NULL) {
2842 printk(KERN_ERR "asoc: error - multiple DAI %s registered with no name\n",
2843 dev_name(dev));
2844 return NULL;
2845 }
2846
2847 return kstrdup(dai_drv->name, GFP_KERNEL);
2848}
2849
2661/** 2850/**
2662 * snd_soc_register_dai - Register a DAI with the ASoC core 2851 * snd_soc_register_dai - Register a DAI with the ASoC core
2663 * 2852 *
2664 * @dai: DAI to register 2853 * @dai: DAI to register
2665 */ 2854 */
2666int snd_soc_register_dai(struct snd_soc_dai *dai) 2855int snd_soc_register_dai(struct device *dev,
2856 struct snd_soc_dai_driver *dai_drv)
2667{ 2857{
2668 if (!dai->name) 2858 struct snd_soc_dai *dai;
2669 return -EINVAL; 2859
2860 dev_dbg(dev, "dai register %s\n", dev_name(dev));
2670 2861
2671 /* The device should become mandatory over time */ 2862 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
2672 if (!dai->dev) 2863 if (dai == NULL)
2673 printk(KERN_WARNING "No device for DAI %s\n", dai->name); 2864 return -ENOMEM;
2674 2865
2675 if (!dai->ops) 2866 /* create DAI component name */
2676 dai->ops = &null_dai_ops; 2867 dai->name = fmt_single_name(dev, &dai->id);
2868 if (dai->name == NULL) {
2869 kfree(dai);
2870 return -ENOMEM;
2871 }
2677 2872
2678 INIT_LIST_HEAD(&dai->list); 2873 dai->dev = dev;
2874 dai->driver = dai_drv;
2875 if (!dai->driver->ops)
2876 dai->driver->ops = &null_dai_ops;
2679 2877
2680 mutex_lock(&client_mutex); 2878 mutex_lock(&client_mutex);
2681 list_add(&dai->list, &dai_list); 2879 list_add(&dai->list, &dai_list);
@@ -2693,13 +2891,24 @@ EXPORT_SYMBOL_GPL(snd_soc_register_dai);
2693 * 2891 *
2694 * @dai: DAI to unregister 2892 * @dai: DAI to unregister
2695 */ 2893 */
2696void snd_soc_unregister_dai(struct snd_soc_dai *dai) 2894void snd_soc_unregister_dai(struct device *dev)
2697{ 2895{
2896 struct snd_soc_dai *dai;
2897
2898 list_for_each_entry(dai, &dai_list, list) {
2899 if (dev == dai->dev)
2900 goto found;
2901 }
2902 return;
2903
2904found:
2698 mutex_lock(&client_mutex); 2905 mutex_lock(&client_mutex);
2699 list_del(&dai->list); 2906 list_del(&dai->list);
2700 mutex_unlock(&client_mutex); 2907 mutex_unlock(&client_mutex);
2701 2908
2702 pr_debug("Unregistered DAI '%s'\n", dai->name); 2909 pr_debug("Unregistered DAI '%s'\n", dai->name);
2910 kfree(dai->name);
2911 kfree(dai);
2703} 2912}
2704EXPORT_SYMBOL_GPL(snd_soc_unregister_dai); 2913EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
2705 2914
@@ -2709,21 +2918,47 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
2709 * @dai: Array of DAIs to register 2918 * @dai: Array of DAIs to register
2710 * @count: Number of DAIs 2919 * @count: Number of DAIs
2711 */ 2920 */
2712int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count) 2921int snd_soc_register_dais(struct device *dev,
2922 struct snd_soc_dai_driver *dai_drv, size_t count)
2713{ 2923{
2714 int i, ret; 2924 struct snd_soc_dai *dai;
2925 int i, ret = 0;
2926
2927 dev_dbg(dev, "dai register %s #%d\n", dev_name(dev), count);
2715 2928
2716 for (i = 0; i < count; i++) { 2929 for (i = 0; i < count; i++) {
2717 ret = snd_soc_register_dai(&dai[i]); 2930
2718 if (ret != 0) 2931 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
2932 if (dai == NULL)
2933 return -ENOMEM;
2934
2935 /* create DAI component name */
2936 dai->name = fmt_multiple_name(dev, &dai_drv[i]);
2937 if (dai->name == NULL) {
2938 kfree(dai);
2939 ret = -EINVAL;
2719 goto err; 2940 goto err;
2941 }
2942
2943 dai->dev = dev;
2944 dai->id = i;
2945 dai->driver = &dai_drv[i];
2946 if (!dai->driver->ops)
2947 dai->driver->ops = &null_dai_ops;
2948
2949 mutex_lock(&client_mutex);
2950 list_add(&dai->list, &dai_list);
2951 mutex_unlock(&client_mutex);
2952
2953 pr_debug("Registered DAI '%s'\n", dai->name);
2720 } 2954 }
2721 2955
2956 snd_soc_instantiate_cards();
2722 return 0; 2957 return 0;
2723 2958
2724err: 2959err:
2725 for (i--; i >= 0; i--) 2960 for (i--; i >= 0; i--)
2726 snd_soc_unregister_dai(&dai[i]); 2961 snd_soc_unregister_dai(dev);
2727 2962
2728 return ret; 2963 return ret;
2729} 2964}
@@ -2735,12 +2970,12 @@ EXPORT_SYMBOL_GPL(snd_soc_register_dais);
2735 * @dai: Array of DAIs to unregister 2970 * @dai: Array of DAIs to unregister
2736 * @count: Number of DAIs 2971 * @count: Number of DAIs
2737 */ 2972 */
2738void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count) 2973void snd_soc_unregister_dais(struct device *dev, size_t count)
2739{ 2974{
2740 int i; 2975 int i;
2741 2976
2742 for (i = 0; i < count; i++) 2977 for (i = 0; i < count; i++)
2743 snd_soc_unregister_dai(&dai[i]); 2978 snd_soc_unregister_dai(dev);
2744} 2979}
2745EXPORT_SYMBOL_GPL(snd_soc_unregister_dais); 2980EXPORT_SYMBOL_GPL(snd_soc_unregister_dais);
2746 2981
@@ -2749,12 +2984,26 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_dais);
2749 * 2984 *
2750 * @platform: platform to register 2985 * @platform: platform to register
2751 */ 2986 */
2752int snd_soc_register_platform(struct snd_soc_platform *platform) 2987int snd_soc_register_platform(struct device *dev,
2988 struct snd_soc_platform_driver *platform_drv)
2753{ 2989{
2754 if (!platform->name) 2990 struct snd_soc_platform *platform;
2755 return -EINVAL; 2991
2992 dev_dbg(dev, "platform register %s\n", dev_name(dev));
2993
2994 platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL);
2995 if (platform == NULL)
2996 return -ENOMEM;
2997
2998 /* create platform component name */
2999 platform->name = fmt_single_name(dev, &platform->id);
3000 if (platform->name == NULL) {
3001 kfree(platform);
3002 return -ENOMEM;
3003 }
2756 3004
2757 INIT_LIST_HEAD(&platform->list); 3005 platform->dev = dev;
3006 platform->driver = platform_drv;
2758 3007
2759 mutex_lock(&client_mutex); 3008 mutex_lock(&client_mutex);
2760 list_add(&platform->list, &platform_list); 3009 list_add(&platform->list, &platform_list);
@@ -2772,13 +3021,24 @@ EXPORT_SYMBOL_GPL(snd_soc_register_platform);
2772 * 3021 *
2773 * @platform: platform to unregister 3022 * @platform: platform to unregister
2774 */ 3023 */
2775void snd_soc_unregister_platform(struct snd_soc_platform *platform) 3024void snd_soc_unregister_platform(struct device *dev)
2776{ 3025{
3026 struct snd_soc_platform *platform;
3027
3028 list_for_each_entry(platform, &platform_list, list) {
3029 if (dev == platform->dev)
3030 goto found;
3031 }
3032 return;
3033
3034found:
2777 mutex_lock(&client_mutex); 3035 mutex_lock(&client_mutex);
2778 list_del(&platform->list); 3036 list_del(&platform->list);
2779 mutex_unlock(&client_mutex); 3037 mutex_unlock(&client_mutex);
2780 3038
2781 pr_debug("Unregistered platform '%s'\n", platform->name); 3039 pr_debug("Unregistered platform '%s'\n", platform->name);
3040 kfree(platform->name);
3041 kfree(platform);
2782} 3042}
2783EXPORT_SYMBOL_GPL(snd_soc_unregister_platform); 3043EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
2784 3044
@@ -2820,32 +3080,78 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
2820 * 3080 *
2821 * @codec: codec to register 3081 * @codec: codec to register
2822 */ 3082 */
2823int snd_soc_register_codec(struct snd_soc_codec *codec) 3083int snd_soc_register_codec(struct device *dev,
3084 struct snd_soc_codec_driver *codec_drv,
3085 struct snd_soc_dai_driver *dai_drv, int num_dai)
2824{ 3086{
2825 int i; 3087 struct snd_soc_codec *codec;
3088 int ret, i;
2826 3089
2827 if (!codec->name) 3090 dev_dbg(dev, "codec register %s\n", dev_name(dev));
2828 return -EINVAL; 3091
3092 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
3093 if (codec == NULL)
3094 return -ENOMEM;
2829 3095
2830 /* The device should become mandatory over time */ 3096 /* create CODEC component name */
2831 if (!codec->dev) 3097 codec->name = fmt_single_name(dev, &codec->id);
2832 printk(KERN_WARNING "No device for codec %s\n", codec->name); 3098 if (codec->name == NULL) {
3099 kfree(codec);
3100 return -ENOMEM;
3101 }
3102
3103 /* allocate CODEC register cache */
3104 if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
2833 3105
2834 INIT_LIST_HEAD(&codec->list); 3106 if (codec_drv->reg_cache_default)
3107 codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
3108 codec_drv->reg_cache_size * codec_drv->reg_word_size, GFP_KERNEL);
3109 else
3110 codec->reg_cache = kzalloc(codec_drv->reg_cache_size *
3111 codec_drv->reg_word_size, GFP_KERNEL);
2835 3112
2836 for (i = 0; i < codec->num_dai; i++) { 3113 if (codec->reg_cache == NULL) {
2837 fixup_codec_formats(&codec->dai[i].playback); 3114 kfree(codec->name);
2838 fixup_codec_formats(&codec->dai[i].capture); 3115 kfree(codec);
3116 return -ENOMEM;
3117 }
2839 } 3118 }
2840 3119
3120 codec->dev = dev;
3121 codec->driver = codec_drv;
3122 codec->bias_level = SND_SOC_BIAS_OFF;
3123 codec->num_dai = num_dai;
3124 mutex_init(&codec->mutex);
3125 INIT_LIST_HEAD(&codec->dapm_widgets);
3126 INIT_LIST_HEAD(&codec->dapm_paths);
3127
3128 for (i = 0; i < num_dai; i++) {
3129 fixup_codec_formats(&dai_drv[i].playback);
3130 fixup_codec_formats(&dai_drv[i].capture);
3131 }
3132
3133 /* register DAIs */
3134 ret = snd_soc_register_dais(dev, dai_drv, num_dai);
3135 if (ret < 0)
3136 goto error;
3137
2841 mutex_lock(&client_mutex); 3138 mutex_lock(&client_mutex);
2842 list_add(&codec->list, &codec_list); 3139 list_add(&codec->list, &codec_list);
2843 snd_soc_instantiate_cards(); 3140 snd_soc_instantiate_cards();
2844 mutex_unlock(&client_mutex); 3141 mutex_unlock(&client_mutex);
2845 3142
2846 pr_debug("Registered codec '%s'\n", codec->name); 3143 pr_debug("Registered codec '%s'\n", codec->name);
2847
2848 return 0; 3144 return 0;
3145
3146error:
3147 for (i--; i >= 0; i--)
3148 snd_soc_unregister_dai(dev);
3149
3150 if (codec->reg_cache)
3151 kfree(codec->reg_cache);
3152 kfree(codec->name);
3153 kfree(codec);
3154 return ret;
2849} 3155}
2850EXPORT_SYMBOL_GPL(snd_soc_register_codec); 3156EXPORT_SYMBOL_GPL(snd_soc_register_codec);
2851 3157
@@ -2854,13 +3160,30 @@ EXPORT_SYMBOL_GPL(snd_soc_register_codec);
2854 * 3160 *
2855 * @codec: codec to unregister 3161 * @codec: codec to unregister
2856 */ 3162 */
2857void snd_soc_unregister_codec(struct snd_soc_codec *codec) 3163void snd_soc_unregister_codec(struct device *dev)
2858{ 3164{
3165 struct snd_soc_codec *codec;
3166 int i;
3167
3168 list_for_each_entry(codec, &codec_list, list) {
3169 if (dev == codec->dev)
3170 goto found;
3171 }
3172 return;
3173
3174found:
3175 for (i = 0; i < codec->num_dai; i++)
3176 snd_soc_unregister_dai(dev);
3177
2859 mutex_lock(&client_mutex); 3178 mutex_lock(&client_mutex);
2860 list_del(&codec->list); 3179 list_del(&codec->list);
2861 mutex_unlock(&client_mutex); 3180 mutex_unlock(&client_mutex);
2862 3181
2863 pr_debug("Unregistered codec '%s'\n", codec->name); 3182 pr_debug("Unregistered codec '%s'\n", codec->name);
3183
3184 if (codec->reg_cache)
3185 kfree(codec->reg_cache);
3186 kfree(codec);
2864} 3187}
2865EXPORT_SYMBOL_GPL(snd_soc_unregister_codec); 3188EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
2866 3189
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 03cb7c05ebe..035cab85cb6 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -112,43 +112,41 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
112 112
113/** 113/**
114 * snd_soc_dapm_set_bias_level - set the bias level for the system 114 * snd_soc_dapm_set_bias_level - set the bias level for the system
115 * @socdev: audio device 115 * @card: audio device
116 * @level: level to configure 116 * @level: level to configure
117 * 117 *
118 * Configure the bias (power) levels for the SoC audio device. 118 * Configure the bias (power) levels for the SoC audio device.
119 * 119 *
120 * Returns 0 for success else error. 120 * Returns 0 for success else error.
121 */ 121 */
122static int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, 122static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card,
123 enum snd_soc_bias_level level) 123 struct snd_soc_codec *codec, enum snd_soc_bias_level level)
124{ 124{
125 struct snd_soc_card *card = socdev->card;
126 struct snd_soc_codec *codec = socdev->card->codec;
127 int ret = 0; 125 int ret = 0;
128 126
129 switch (level) { 127 switch (level) {
130 case SND_SOC_BIAS_ON: 128 case SND_SOC_BIAS_ON:
131 dev_dbg(socdev->dev, "Setting full bias\n"); 129 dev_dbg(codec->dev, "Setting full bias\n");
132 break; 130 break;
133 case SND_SOC_BIAS_PREPARE: 131 case SND_SOC_BIAS_PREPARE:
134 dev_dbg(socdev->dev, "Setting bias prepare\n"); 132 dev_dbg(codec->dev, "Setting bias prepare\n");
135 break; 133 break;
136 case SND_SOC_BIAS_STANDBY: 134 case SND_SOC_BIAS_STANDBY:
137 dev_dbg(socdev->dev, "Setting standby bias\n"); 135 dev_dbg(codec->dev, "Setting standby bias\n");
138 break; 136 break;
139 case SND_SOC_BIAS_OFF: 137 case SND_SOC_BIAS_OFF:
140 dev_dbg(socdev->dev, "Setting bias off\n"); 138 dev_dbg(codec->dev, "Setting bias off\n");
141 break; 139 break;
142 default: 140 default:
143 dev_err(socdev->dev, "Setting invalid bias %d\n", level); 141 dev_err(codec->dev, "Setting invalid bias %d\n", level);
144 return -EINVAL; 142 return -EINVAL;
145 } 143 }
146 144
147 if (card->set_bias_level) 145 if (card && card->set_bias_level)
148 ret = card->set_bias_level(card, level); 146 ret = card->set_bias_level(card, level);
149 if (ret == 0) { 147 if (ret == 0) {
150 if (codec->set_bias_level) 148 if (codec->driver->set_bias_level)
151 ret = codec->set_bias_level(codec, level); 149 ret = codec->driver->set_bias_level(codec, level);
152 else 150 else
153 codec->bias_level = level; 151 codec->bias_level = level;
154 } 152 }
@@ -370,7 +368,7 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
370 368
371 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 369 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
372 path->long_name); 370 path->long_name);
373 ret = snd_ctl_add(codec->card, path->kcontrol); 371 ret = snd_ctl_add(codec->card->snd_card, path->kcontrol);
374 if (ret < 0) { 372 if (ret < 0) {
375 printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n", 373 printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n",
376 path->long_name, 374 path->long_name,
@@ -398,7 +396,7 @@ static int dapm_new_mux(struct snd_soc_codec *codec,
398 } 396 }
399 397
400 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); 398 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name);
401 ret = snd_ctl_add(codec->card, kcontrol); 399 ret = snd_ctl_add(codec->card->snd_card, kcontrol);
402 if (ret < 0) 400 if (ret < 0)
403 goto err; 401 goto err;
404 402
@@ -437,9 +435,9 @@ static inline void dapm_clear_walk(struct snd_soc_codec *codec)
437 */ 435 */
438static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) 436static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
439{ 437{
440 struct snd_soc_codec *codec = widget->codec; 438 int level = snd_power_get_state(widget->codec->card->snd_card);
441 439
442 switch (snd_power_get_state(codec->card)) { 440 switch (level) {
443 case SNDRV_CTL_POWER_D3hot: 441 case SNDRV_CTL_POWER_D3hot:
444 case SNDRV_CTL_POWER_D3cold: 442 case SNDRV_CTL_POWER_D3cold:
445 if (widget->ignore_suspend) 443 if (widget->ignore_suspend)
@@ -893,7 +891,7 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
893 */ 891 */
894static int dapm_power_widgets(struct snd_soc_codec *codec, int event) 892static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
895{ 893{
896 struct snd_soc_device *socdev = codec->socdev; 894 struct snd_soc_card *card = codec->card;
897 struct snd_soc_dapm_widget *w; 895 struct snd_soc_dapm_widget *w;
898 LIST_HEAD(up_list); 896 LIST_HEAD(up_list);
899 LIST_HEAD(down_list); 897 LIST_HEAD(down_list);
@@ -966,7 +964,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
966 } 964 }
967 965
968 if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) { 966 if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) {
969 ret = snd_soc_dapm_set_bias_level(socdev, 967 ret = snd_soc_dapm_set_bias_level(card, codec,
970 SND_SOC_BIAS_STANDBY); 968 SND_SOC_BIAS_STANDBY);
971 if (ret != 0) 969 if (ret != 0)
972 pr_err("Failed to turn on bias: %d\n", ret); 970 pr_err("Failed to turn on bias: %d\n", ret);
@@ -975,8 +973,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
975 /* If we're changing to all on or all off then prepare */ 973 /* If we're changing to all on or all off then prepare */
976 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || 974 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) ||
977 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { 975 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) {
978 ret = snd_soc_dapm_set_bias_level(socdev, 976 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_PREPARE);
979 SND_SOC_BIAS_PREPARE);
980 if (ret != 0) 977 if (ret != 0)
981 pr_err("Failed to prepare bias: %d\n", ret); 978 pr_err("Failed to prepare bias: %d\n", ret);
982 } 979 }
@@ -989,8 +986,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
989 986
990 /* If we just powered the last thing off drop to standby bias */ 987 /* If we just powered the last thing off drop to standby bias */
991 if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { 988 if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) {
992 ret = snd_soc_dapm_set_bias_level(socdev, 989 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_STANDBY);
993 SND_SOC_BIAS_STANDBY);
994 if (ret != 0) 990 if (ret != 0)
995 pr_err("Failed to apply standby bias: %d\n", ret); 991 pr_err("Failed to apply standby bias: %d\n", ret);
996 } 992 }
@@ -998,15 +994,14 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
998 /* If we're in standby and can support bias off then do that */ 994 /* If we're in standby and can support bias off then do that */
999 if (codec->bias_level == SND_SOC_BIAS_STANDBY && 995 if (codec->bias_level == SND_SOC_BIAS_STANDBY &&
1000 codec->idle_bias_off) { 996 codec->idle_bias_off) {
1001 ret = snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF); 997 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF);
1002 if (ret != 0) 998 if (ret != 0)
1003 pr_err("Failed to turn off bias: %d\n", ret); 999 pr_err("Failed to turn off bias: %d\n", ret);
1004 } 1000 }
1005 1001
1006 /* If we just powered up then move to active bias */ 1002 /* If we just powered up then move to active bias */
1007 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { 1003 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) {
1008 ret = snd_soc_dapm_set_bias_level(socdev, 1004 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_ON);
1009 SND_SOC_BIAS_ON);
1010 if (ret != 0) 1005 if (ret != 0)
1011 pr_err("Failed to apply active bias: %d\n", ret); 1006 pr_err("Failed to apply active bias: %d\n", ret);
1012 } 1007 }
@@ -1188,8 +1183,9 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1188static ssize_t dapm_widget_show(struct device *dev, 1183static ssize_t dapm_widget_show(struct device *dev,
1189 struct device_attribute *attr, char *buf) 1184 struct device_attribute *attr, char *buf)
1190{ 1185{
1191 struct snd_soc_device *devdata = dev_get_drvdata(dev); 1186 struct snd_soc_pcm_runtime *rtd =
1192 struct snd_soc_codec *codec = devdata->card->codec; 1187 container_of(dev, struct snd_soc_pcm_runtime, dev);
1188 struct snd_soc_codec *codec =rtd->codec;
1193 struct snd_soc_dapm_widget *w; 1189 struct snd_soc_dapm_widget *w;
1194 int count = 0; 1190 int count = 0;
1195 char *state = "not set"; 1191 char *state = "not set";
@@ -1998,9 +1994,10 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
1998 * 1994 *
1999 * Returns 0 for success else error. 1995 * Returns 0 for success else error.
2000 */ 1996 */
2001int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, 1997int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
2002 char *stream, int event) 1998 const char *stream, int event)
2003{ 1999{
2000 struct snd_soc_codec *codec = rtd->codec;
2004 struct snd_soc_dapm_widget *w; 2001 struct snd_soc_dapm_widget *w;
2005 2002
2006 if (stream == NULL) 2003 if (stream == NULL)
@@ -2168,25 +2165,19 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
2168 2165
2169/** 2166/**
2170 * snd_soc_dapm_free - free dapm resources 2167 * snd_soc_dapm_free - free dapm resources
2171 * @socdev: SoC device 2168 * @card: SoC device
2172 * 2169 *
2173 * Free all dapm widgets and resources. 2170 * Free all dapm widgets and resources.
2174 */ 2171 */
2175void snd_soc_dapm_free(struct snd_soc_device *socdev) 2172void snd_soc_dapm_free(struct snd_soc_codec *codec)
2176{ 2173{
2177 struct snd_soc_codec *codec = socdev->card->codec; 2174 snd_soc_dapm_sys_remove(codec->dev);
2178
2179 snd_soc_dapm_sys_remove(socdev->dev);
2180 dapm_free_widgets(codec); 2175 dapm_free_widgets(codec);
2181} 2176}
2182EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 2177EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
2183 2178
2184/* 2179static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec)
2185 * snd_soc_dapm_shutdown - callback for system shutdown
2186 */
2187void snd_soc_dapm_shutdown(struct snd_soc_device *socdev)
2188{ 2180{
2189 struct snd_soc_codec *codec = socdev->card->codec;
2190 struct snd_soc_dapm_widget *w; 2181 struct snd_soc_dapm_widget *w;
2191 LIST_HEAD(down_list); 2182 LIST_HEAD(down_list);
2192 int powerdown = 0; 2183 int powerdown = 0;
@@ -2203,12 +2194,23 @@ void snd_soc_dapm_shutdown(struct snd_soc_device *socdev)
2203 * standby. 2194 * standby.
2204 */ 2195 */
2205 if (powerdown) { 2196 if (powerdown) {
2206 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_PREPARE); 2197 snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_PREPARE);
2207 dapm_seq_run(codec, &down_list, 0, dapm_down_seq); 2198 dapm_seq_run(codec, &down_list, 0, dapm_down_seq);
2208 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_STANDBY); 2199 snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_STANDBY);
2209 } 2200 }
2201}
2202
2203/*
2204 * snd_soc_dapm_shutdown - callback for system shutdown
2205 */
2206void snd_soc_dapm_shutdown(struct snd_soc_card *card)
2207{
2208 struct snd_soc_codec *codec;
2209
2210 list_for_each_entry(codec, &card->codec_dev_list, list)
2211 soc_dapm_shutdown_codec(codec);
2210 2212
2211 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF); 2213 snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF);
2212} 2214}
2213 2215
2214/* Module information */ 2216/* Module information */
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 29159e1781d..8862770aa22 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -32,14 +32,14 @@
32 * Returns zero if successful, or a negative error code on failure. 32 * Returns zero if successful, or a negative error code on failure.
33 * On success jack will be initialised. 33 * On success jack will be initialised.
34 */ 34 */
35int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type, 35int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
36 struct snd_soc_jack *jack) 36 struct snd_soc_jack *jack)
37{ 37{
38 jack->card = card; 38 jack->codec = codec;
39 INIT_LIST_HEAD(&jack->pins); 39 INIT_LIST_HEAD(&jack->pins);
40 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); 40 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
41 41
42 return snd_jack_new(card->codec->card, id, type, &jack->jack); 42 return snd_jack_new(codec->card->snd_card, id, type, &jack->jack);
43} 43}
44EXPORT_SYMBOL_GPL(snd_soc_jack_new); 44EXPORT_SYMBOL_GPL(snd_soc_jack_new);
45 45
@@ -67,7 +67,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
67 if (!jack) 67 if (!jack)
68 return; 68 return;
69 69
70 codec = jack->card->codec; 70 codec = jack->codec;
71 71
72 mutex_lock(&codec->mutex); 72 mutex_lock(&codec->mutex);
73 73
@@ -268,7 +268,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
268 ret = request_irq(gpio_to_irq(gpios[i].gpio), 268 ret = request_irq(gpio_to_irq(gpios[i].gpio),
269 gpio_handler, 269 gpio_handler,
270 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 270 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
271 jack->card->dev->driver->name, 271 jack->codec->dev->driver->name,
272 &gpios[i]); 272 &gpios[i]);
273 if (ret) 273 if (ret)
274 goto err; 274 goto err;
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 0ec20b68e8c..743d07b82c0 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -36,13 +36,11 @@
36 36
37static DECLARE_WAIT_QUEUE_HEAD(ac97_waitq); 37static DECLARE_WAIT_QUEUE_HEAD(ac97_waitq);
38 38
39/* REVISIT: How to find txx9aclc_soc_device from snd_ac97? */ 39/* REVISIT: How to find txx9aclc_drvdata from snd_ac97? */
40static struct txx9aclc_soc_device *txx9aclc_soc_dev; 40static struct txx9aclc_plat_drvdata *txx9aclc_drvdata;
41 41
42static int txx9aclc_regready(struct txx9aclc_soc_device *dev) 42static int txx9aclc_regready(struct txx9aclc_plat_drvdata *drvdata)
43{ 43{
44 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev);
45
46 return __raw_readl(drvdata->base + ACINTSTS) & ACINT_REGACCRDY; 44 return __raw_readl(drvdata->base + ACINTSTS) & ACINT_REGACCRDY;
47} 45}
48 46
@@ -50,8 +48,7 @@ static int txx9aclc_regready(struct txx9aclc_soc_device *dev)
50static unsigned short txx9aclc_ac97_read(struct snd_ac97 *ac97, 48static unsigned short txx9aclc_ac97_read(struct snd_ac97 *ac97,
51 unsigned short reg) 49 unsigned short reg)
52{ 50{
53 struct txx9aclc_soc_device *dev = txx9aclc_soc_dev; 51 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
54 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev);
55 void __iomem *base = drvdata->base; 52 void __iomem *base = drvdata->base;
56 u32 dat; 53 u32 dat;
57 54
@@ -61,15 +58,15 @@ static unsigned short txx9aclc_ac97_read(struct snd_ac97 *ac97,
61 dat = (reg << ACREGACC_REG_SHIFT) | ACREGACC_READ; 58 dat = (reg << ACREGACC_REG_SHIFT) | ACREGACC_READ;
62 __raw_writel(dat, base + ACREGACC); 59 __raw_writel(dat, base + ACREGACC);
63 __raw_writel(ACINT_REGACCRDY, base + ACINTEN); 60 __raw_writel(ACINT_REGACCRDY, base + ACINTEN);
64 if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(dev), HZ)) { 61 if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(txx9aclc_drvdata), HZ)) {
65 __raw_writel(ACINT_REGACCRDY, base + ACINTDIS); 62 __raw_writel(ACINT_REGACCRDY, base + ACINTDIS);
66 dev_err(dev->soc_dev.dev, "ac97 read timeout (reg %#x)\n", reg); 63 printk(KERN_ERR "ac97 read timeout (reg %#x)\n", reg);
67 dat = 0xffff; 64 dat = 0xffff;
68 goto done; 65 goto done;
69 } 66 }
70 dat = __raw_readl(base + ACREGACC); 67 dat = __raw_readl(base + ACREGACC);
71 if (((dat >> ACREGACC_REG_SHIFT) & 0xff) != reg) { 68 if (((dat >> ACREGACC_REG_SHIFT) & 0xff) != reg) {
72 dev_err(dev->soc_dev.dev, "reg mismatch %x with %x\n", 69 printk(KERN_ERR "reg mismatch %x with %x\n",
73 dat, reg); 70 dat, reg);
74 dat = 0xffff; 71 dat = 0xffff;
75 goto done; 72 goto done;
@@ -84,16 +81,15 @@ done:
84static void txx9aclc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, 81static void txx9aclc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
85 unsigned short val) 82 unsigned short val)
86{ 83{
87 struct txx9aclc_soc_device *dev = txx9aclc_soc_dev; 84 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
88 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev);
89 void __iomem *base = drvdata->base; 85 void __iomem *base = drvdata->base;
90 86
91 __raw_writel(((reg | (ac97->num << 7)) << ACREGACC_REG_SHIFT) | 87 __raw_writel(((reg | (ac97->num << 7)) << ACREGACC_REG_SHIFT) |
92 (val << ACREGACC_DAT_SHIFT), 88 (val << ACREGACC_DAT_SHIFT),
93 base + ACREGACC); 89 base + ACREGACC);
94 __raw_writel(ACINT_REGACCRDY, base + ACINTEN); 90 __raw_writel(ACINT_REGACCRDY, base + ACINTEN);
95 if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(dev), HZ)) { 91 if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(txx9aclc_drvdata), HZ)) {
96 dev_err(dev->soc_dev.dev, 92 printk(KERN_ERR
97 "ac97 write timeout (reg %#x)\n", reg); 93 "ac97 write timeout (reg %#x)\n", reg);
98 } 94 }
99 __raw_writel(ACINT_REGACCRDY, base + ACINTDIS); 95 __raw_writel(ACINT_REGACCRDY, base + ACINTDIS);
@@ -101,8 +97,7 @@ static void txx9aclc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
101 97
102static void txx9aclc_ac97_cold_reset(struct snd_ac97 *ac97) 98static void txx9aclc_ac97_cold_reset(struct snd_ac97 *ac97)
103{ 99{
104 struct txx9aclc_soc_device *dev = txx9aclc_soc_dev; 100 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
105 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev);
106 void __iomem *base = drvdata->base; 101 void __iomem *base = drvdata->base;
107 u32 ready = ACINT_CODECRDY(ac97->num) | ACINT_REGACCRDY; 102 u32 ready = ACINT_CODECRDY(ac97->num) | ACINT_REGACCRDY;
108 103
@@ -141,31 +136,23 @@ static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id)
141 return IRQ_HANDLED; 136 return IRQ_HANDLED;
142} 137}
143 138
144static int txx9aclc_ac97_probe(struct platform_device *pdev, 139static int txx9aclc_ac97_probe(struct snd_soc_dai *dai)
145 struct snd_soc_dai *dai)
146{ 140{
147 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 141 txx9aclc_drvdata = snd_soc_dai_get_drvdata(dai);
148 struct txx9aclc_soc_device *dev =
149 container_of(socdev, struct txx9aclc_soc_device, soc_dev);
150
151 dev->aclc_pdev = to_platform_device(dai->dev);
152 txx9aclc_soc_dev = dev;
153 return 0; 142 return 0;
154} 143}
155 144
156static void txx9aclc_ac97_remove(struct platform_device *pdev, 145static int txx9aclc_ac97_remove(struct snd_soc_dai *dai)
157 struct snd_soc_dai *dai)
158{ 146{
159 struct platform_device *aclc_pdev = to_platform_device(dai->dev); 147 struct txx9aclc_plat_drvdata *drvdata = snd_soc_dai_get_drvdata(dai);
160 struct txx9aclc_plat_drvdata *drvdata = platform_get_drvdata(aclc_pdev);
161 148
162 /* disable AC-link */ 149 /* disable AC-link */
163 __raw_writel(ACCTL_ENLINK, drvdata->base + ACCTLDIS); 150 __raw_writel(ACCTL_ENLINK, drvdata->base + ACCTLDIS);
164 txx9aclc_soc_dev = NULL; 151 txx9aclc_drvdata = NULL;
152 return 0;
165} 153}
166 154
167struct snd_soc_dai txx9aclc_ac97_dai = { 155static struct snd_soc_dai_driver txx9aclc_ac97_dai = {
168 .name = "txx9aclc_ac97",
169 .ac97_control = 1, 156 .ac97_control = 1,
170 .probe = txx9aclc_ac97_probe, 157 .probe = txx9aclc_ac97_probe,
171 .remove = txx9aclc_ac97_remove, 158 .remove = txx9aclc_ac97_remove,
@@ -182,7 +169,6 @@ struct snd_soc_dai txx9aclc_ac97_dai = {
182 .channels_max = 2, 169 .channels_max = 2,
183 }, 170 },
184}; 171};
185EXPORT_SYMBOL_GPL(txx9aclc_ac97_dai);
186 172
187static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev) 173static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev)
188{ 174{
@@ -219,13 +205,12 @@ static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev)
219 if (err < 0) 205 if (err < 0)
220 return err; 206 return err;
221 207
222 txx9aclc_ac97_dai.dev = &pdev->dev; 208 return snd_soc_register_dai(&pdev->dev, &txx9aclc_ac97_dai);
223 return snd_soc_register_dai(&txx9aclc_ac97_dai);
224} 209}
225 210
226static int __devexit txx9aclc_ac97_dev_remove(struct platform_device *pdev) 211static int __devexit txx9aclc_ac97_dev_remove(struct platform_device *pdev)
227{ 212{
228 snd_soc_unregister_dai(&txx9aclc_ac97_dai); 213 snd_soc_unregister_dai(&pdev->dev);
229 return 0; 214 return 0;
230} 215}
231 216
diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c
index 95b17f731ae..6770e7166be 100644
--- a/sound/soc/txx9/txx9aclc-generic.c
+++ b/sound/soc/txx9/txx9aclc-generic.c
@@ -19,54 +19,44 @@
19#include <sound/core.h> 19#include <sound/core.h>
20#include <sound/pcm.h> 20#include <sound/pcm.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include "../codecs/ac97.h"
23#include "txx9aclc.h" 22#include "txx9aclc.h"
24 23
25static struct snd_soc_dai_link txx9aclc_generic_dai = { 24static struct snd_soc_dai_link txx9aclc_generic_dai = {
26 .name = "AC97", 25 .name = "AC97",
27 .stream_name = "AC97 HiFi", 26 .stream_name = "AC97 HiFi",
28 .cpu_dai = &txx9aclc_ac97_dai, 27 .cpu_dai_name = "txx9aclc-ac97",
29 .codec_dai = &ac97_dai, 28 .codec_dai_name = "ac97-hifi",
29 .platform_name = "txx9aclc-pcm-audio",
30 .codec_name = "ac97-codec",
30}; 31};
31 32
32static struct snd_soc_card txx9aclc_generic_card = { 33static struct snd_soc_card txx9aclc_generic_card = {
33 .name = "Generic TXx9 ACLC Audio", 34 .name = "Generic TXx9 ACLC Audio",
34 .platform = &txx9aclc_soc_platform,
35 .dai_link = &txx9aclc_generic_dai, 35 .dai_link = &txx9aclc_generic_dai,
36 .num_links = 1, 36 .num_links = 1,
37}; 37};
38 38
39static struct txx9aclc_soc_device txx9aclc_generic_soc_device = { 39static struct platform_device *soc_pdev;
40 .soc_dev = {
41 .card = &txx9aclc_generic_card,
42 .codec_dev = &soc_codec_dev_ac97,
43 },
44};
45 40
46static int __init txx9aclc_generic_probe(struct platform_device *pdev) 41static int __init txx9aclc_generic_probe(struct platform_device *pdev)
47{ 42{
48 struct txx9aclc_soc_device *dev = &txx9aclc_generic_soc_device;
49 struct platform_device *soc_pdev;
50 int ret; 43 int ret;
51 44
52 soc_pdev = platform_device_alloc("soc-audio", -1); 45 soc_pdev = platform_device_alloc("soc-audio", -1);
53 if (!soc_pdev) 46 if (!soc_pdev)
54 return -ENOMEM; 47 return -ENOMEM;
55 platform_set_drvdata(soc_pdev, &dev->soc_dev); 48 platform_set_drvdata(soc_pdev, &txx9aclc_generic_card);
56 dev->soc_dev.dev = &soc_pdev->dev;
57 ret = platform_device_add(soc_pdev); 49 ret = platform_device_add(soc_pdev);
58 if (ret) { 50 if (ret) {
59 platform_device_put(soc_pdev); 51 platform_device_put(soc_pdev);
60 return ret; 52 return ret;
61 } 53 }
62 platform_set_drvdata(pdev, soc_pdev); 54
63 return 0; 55 return 0;
64} 56}
65 57
66static int __exit txx9aclc_generic_remove(struct platform_device *pdev) 58static int __exit txx9aclc_generic_remove(struct platform_device *pdev)
67{ 59{
68 struct platform_device *soc_pdev = platform_get_drvdata(pdev);
69
70 platform_device_unregister(soc_pdev); 60 platform_device_unregister(soc_pdev);
71 return 0; 61 return 0;
72} 62}
diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c
index 0e3452303ea..f4aa4e03c88 100644
--- a/sound/soc/txx9/txx9aclc.c
+++ b/sound/soc/txx9/txx9aclc.c
@@ -22,6 +22,16 @@
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include "txx9aclc.h" 23#include "txx9aclc.h"
24 24
25static struct txx9aclc_soc_device {
26 struct txx9aclc_dmadata dmadata[2];
27} txx9aclc_soc_device;
28
29/* REVISIT: How to find txx9aclc_drvdata from snd_ac97? */
30static struct txx9aclc_plat_drvdata *txx9aclc_drvdata;
31
32static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev,
33 struct txx9aclc_dmadata *dmadata);
34
25static const struct snd_pcm_hardware txx9aclc_pcm_hardware = { 35static const struct snd_pcm_hardware txx9aclc_pcm_hardware = {
26 /* 36 /*
27 * REVISIT: SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID 37 * REVISIT: SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
@@ -46,7 +56,6 @@ static int txx9aclc_pcm_hw_params(struct snd_pcm_substream *substream,
46 struct snd_pcm_hw_params *params) 56 struct snd_pcm_hw_params *params)
47{ 57{
48 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 58 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
49 struct snd_soc_device *socdev = rtd->socdev;
50 struct snd_pcm_runtime *runtime = substream->runtime; 59 struct snd_pcm_runtime *runtime = substream->runtime;
51 struct txx9aclc_dmadata *dmadata = runtime->private_data; 60 struct txx9aclc_dmadata *dmadata = runtime->private_data;
52 int ret; 61 int ret;
@@ -55,13 +64,13 @@ static int txx9aclc_pcm_hw_params(struct snd_pcm_substream *substream,
55 if (ret < 0) 64 if (ret < 0)
56 return ret; 65 return ret;
57 66
58 dev_dbg(socdev->dev, 67 dev_dbg(rtd->platform->dev,
59 "runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd " 68 "runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd "
60 "runtime->min_align %ld\n", 69 "runtime->min_align %ld\n",
61 (unsigned long)runtime->dma_area, 70 (unsigned long)runtime->dma_area,
62 (unsigned long)runtime->dma_addr, runtime->dma_bytes, 71 (unsigned long)runtime->dma_addr, runtime->dma_bytes,
63 runtime->min_align); 72 runtime->min_align);
64 dev_dbg(socdev->dev, 73 dev_dbg(rtd->platform->dev,
65 "periods %d period_bytes %d stream %d\n", 74 "periods %d period_bytes %d stream %d\n",
66 params_periods(params), params_period_bytes(params), 75 params_periods(params), params_period_bytes(params),
67 substream->stream); 76 substream->stream);
@@ -152,11 +161,7 @@ static void txx9aclc_dma_tasklet(unsigned long data)
152 161
153 spin_lock_irqsave(&dmadata->dma_lock, flags); 162 spin_lock_irqsave(&dmadata->dma_lock, flags);
154 if (dmadata->frag_count < 0) { 163 if (dmadata->frag_count < 0) {
155 struct txx9aclc_soc_device *dev = 164 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
156 container_of(dmadata, struct txx9aclc_soc_device,
157 dmadata[substream->stream]);
158 struct txx9aclc_plat_drvdata *drvdata =
159 txx9aclc_get_plat_drvdata(dev);
160 void __iomem *base = drvdata->base; 165 void __iomem *base = drvdata->base;
161 166
162 spin_unlock_irqrestore(&dmadata->dma_lock, flags); 167 spin_unlock_irqrestore(&dmadata->dma_lock, flags);
@@ -202,10 +207,7 @@ static void txx9aclc_dma_tasklet(unsigned long data)
202static int txx9aclc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 207static int txx9aclc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
203{ 208{
204 struct txx9aclc_dmadata *dmadata = substream->runtime->private_data; 209 struct txx9aclc_dmadata *dmadata = substream->runtime->private_data;
205 struct snd_soc_pcm_runtime *rtd = substream->private_data; 210 struct txx9aclc_plat_drvdata *drvdata =txx9aclc_drvdata;
206 struct txx9aclc_soc_device *dev =
207 container_of(rtd->socdev, struct txx9aclc_soc_device, soc_dev);
208 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev);
209 void __iomem *base = drvdata->base; 211 void __iomem *base = drvdata->base;
210 unsigned long flags; 212 unsigned long flags;
211 int ret = 0; 213 int ret = 0;
@@ -244,9 +246,7 @@ txx9aclc_pcm_pointer(struct snd_pcm_substream *substream)
244 246
245static int txx9aclc_pcm_open(struct snd_pcm_substream *substream) 247static int txx9aclc_pcm_open(struct snd_pcm_substream *substream)
246{ 248{
247 struct snd_soc_pcm_runtime *rtd = substream->private_data; 249 struct txx9aclc_soc_device *dev = &txx9aclc_soc_device;
248 struct txx9aclc_soc_device *dev =
249 container_of(rtd->socdev, struct txx9aclc_soc_device, soc_dev);
250 struct txx9aclc_dmadata *dmadata = &dev->dmadata[substream->stream]; 250 struct txx9aclc_dmadata *dmadata = &dev->dmadata[substream->stream];
251 int ret; 251 int ret;
252 252
@@ -291,8 +291,38 @@ static void txx9aclc_pcm_free_dma_buffers(struct snd_pcm *pcm)
291static int txx9aclc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, 291static int txx9aclc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
292 struct snd_pcm *pcm) 292 struct snd_pcm *pcm)
293{ 293{
294 struct platform_device *pdev = to_platform_device(dai->platform->dev);
295 struct txx9aclc_soc_device *dev;
296 struct resource *r;
297 int i;
298 int ret;
299
300 /* at this point onwards the AC97 component has probed and this will be valid */
301 dev = snd_soc_dai_get_drvdata(dai);
302
303 dev->dmadata[0].stream = SNDRV_PCM_STREAM_PLAYBACK;
304 dev->dmadata[1].stream = SNDRV_PCM_STREAM_CAPTURE;
305 for (i = 0; i < 2; i++) {
306 r = platform_get_resource(pdev, IORESOURCE_DMA, i);
307 if (!r) {
308 ret = -EBUSY;
309 goto exit;
310 }
311 dev->dmadata[i].dma_res = r;
312 ret = txx9aclc_dma_init(dev, &dev->dmadata[i]);
313 if (ret)
314 goto exit;
315 }
294 return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 316 return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
295 card->dev, 64 * 1024, 4 * 1024 * 1024); 317 card->dev, 64 * 1024, 4 * 1024 * 1024);
318
319exit:
320 for (i = 0; i < 2; i++) {
321 if (dev->dmadata[i].dma_chan)
322 dma_release_channel(dev->dmadata[i].dma_chan);
323 dev->dmadata[i].dma_chan = NULL;
324 }
325 return ret;
296} 326}
297 327
298static bool filter(struct dma_chan *chan, void *param) 328static bool filter(struct dma_chan *chan, void *param)
@@ -314,7 +344,7 @@ static bool filter(struct dma_chan *chan, void *param)
314static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev, 344static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev,
315 struct txx9aclc_dmadata *dmadata) 345 struct txx9aclc_dmadata *dmadata)
316{ 346{
317 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); 347 struct txx9aclc_plat_drvdata *drvdata =txx9aclc_drvdata;
318 struct txx9dmac_slave *ds = &dmadata->dma_slave; 348 struct txx9dmac_slave *ds = &dmadata->dma_slave;
319 dma_cap_mask_t mask; 349 dma_cap_mask_t mask;
320 350
@@ -334,7 +364,7 @@ static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev,
334 dma_cap_set(DMA_SLAVE, mask); 364 dma_cap_set(DMA_SLAVE, mask);
335 dmadata->dma_chan = dma_request_channel(mask, filter, dmadata); 365 dmadata->dma_chan = dma_request_channel(mask, filter, dmadata);
336 if (!dmadata->dma_chan) { 366 if (!dmadata->dma_chan) {
337 dev_err(dev->soc_dev.dev, 367 printk(KERN_ERR
338 "DMA channel for %s is not available\n", 368 "DMA channel for %s is not available\n",
339 dmadata->stream == SNDRV_PCM_STREAM_PLAYBACK ? 369 dmadata->stream == SNDRV_PCM_STREAM_PLAYBACK ?
340 "playback" : "capture"); 370 "playback" : "capture");
@@ -345,45 +375,16 @@ static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev,
345 return 0; 375 return 0;
346} 376}
347 377
348static int txx9aclc_pcm_probe(struct platform_device *pdev) 378static int txx9aclc_pcm_probe(struct snd_soc_platform *platform)
349{ 379{
350 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 380 snd_soc_platform_set_drvdata(platform, &txx9aclc_soc_device);
351 struct txx9aclc_soc_device *dev =
352 container_of(socdev, struct txx9aclc_soc_device, soc_dev);
353 struct resource *r;
354 int i;
355 int ret;
356
357 dev->dmadata[0].stream = SNDRV_PCM_STREAM_PLAYBACK;
358 dev->dmadata[1].stream = SNDRV_PCM_STREAM_CAPTURE;
359 for (i = 0; i < 2; i++) {
360 r = platform_get_resource(dev->aclc_pdev, IORESOURCE_DMA, i);
361 if (!r) {
362 ret = -EBUSY;
363 goto exit;
364 }
365 dev->dmadata[i].dma_res = r;
366 ret = txx9aclc_dma_init(dev, &dev->dmadata[i]);
367 if (ret)
368 goto exit;
369 }
370 return 0; 381 return 0;
371
372exit:
373 for (i = 0; i < 2; i++) {
374 if (dev->dmadata[i].dma_chan)
375 dma_release_channel(dev->dmadata[i].dma_chan);
376 dev->dmadata[i].dma_chan = NULL;
377 }
378 return ret;
379} 382}
380 383
381static int txx9aclc_pcm_remove(struct platform_device *pdev) 384static int txx9aclc_pcm_remove(struct snd_soc_platform *platform)
382{ 385{
383 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 386 struct txx9aclc_soc_device *dev = snd_soc_platform_get_drvdata(platform);
384 struct txx9aclc_soc_device *dev = 387 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
385 container_of(socdev, struct txx9aclc_soc_device, soc_dev);
386 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev);
387 void __iomem *base = drvdata->base; 388 void __iomem *base = drvdata->base;
388 int i; 389 int i;
389 390
@@ -406,28 +407,46 @@ static int txx9aclc_pcm_remove(struct platform_device *pdev)
406 return 0; 407 return 0;
407} 408}
408 409
409struct snd_soc_platform txx9aclc_soc_platform = { 410static struct snd_soc_platform_driver txx9aclc_soc_platform = {
410 .name = "txx9aclc-audio",
411 .probe = txx9aclc_pcm_probe, 411 .probe = txx9aclc_pcm_probe,
412 .remove = txx9aclc_pcm_remove, 412 .remove = txx9aclc_pcm_remove,
413 .pcm_ops = &txx9aclc_pcm_ops, 413 .ops = &txx9aclc_pcm_ops,
414 .pcm_new = txx9aclc_pcm_new, 414 .pcm_new = txx9aclc_pcm_new,
415 .pcm_free = txx9aclc_pcm_free_dma_buffers, 415 .pcm_free = txx9aclc_pcm_free_dma_buffers,
416}; 416};
417EXPORT_SYMBOL_GPL(txx9aclc_soc_platform);
418 417
419static int __init txx9aclc_soc_platform_init(void) 418static int __devinit txx9aclc_soc_platform_probe(struct platform_device *pdev)
420{ 419{
421 return snd_soc_register_platform(&txx9aclc_soc_platform); 420 return snd_soc_register_platform(&pdev->dev, &txx9aclc_soc_platform);
422} 421}
423 422
424static void __exit txx9aclc_soc_platform_exit(void) 423static int __devexit txx9aclc_soc_platform_remove(struct platform_device *pdev)
425{ 424{
426 snd_soc_unregister_platform(&txx9aclc_soc_platform); 425 snd_soc_unregister_platform(&pdev->dev);
426 return 0;
427} 427}
428 428
429module_init(txx9aclc_soc_platform_init); 429static struct platform_driver txx9aclc_pcm_driver = {
430module_exit(txx9aclc_soc_platform_exit); 430 .driver = {
431 .name = "txx9aclc-pcm-audio",
432 .owner = THIS_MODULE,
433 },
434
435 .probe = txx9aclc_soc_platform_probe,
436 .remove = __devexit_p(txx9aclc_soc_platform_remove),
437};
438
439static int __init snd_txx9aclc_pcm_init(void)
440{
441 return platform_driver_register(&txx9aclc_pcm_driver);
442}
443module_init(snd_txx9aclc_pcm_init);
444
445static void __exit snd_txx9aclc_pcm_exit(void)
446{
447 platform_driver_unregister(&txx9aclc_pcm_driver);
448}
449module_exit(snd_txx9aclc_pcm_exit);
431 450
432MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); 451MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
433MODULE_DESCRIPTION("TXx9 ACLC Audio DMA driver"); 452MODULE_DESCRIPTION("TXx9 ACLC Audio DMA driver");
diff --git a/sound/soc/txx9/txx9aclc.h b/sound/soc/txx9/txx9aclc.h
index 6769aab41b3..9c2de84fec3 100644
--- a/sound/soc/txx9/txx9aclc.h
+++ b/sound/soc/txx9/txx9aclc.h
@@ -65,19 +65,10 @@ struct txx9aclc_plat_drvdata {
65 u64 physbase; 65 u64 physbase;
66}; 66};
67 67
68struct txx9aclc_soc_device {
69 struct snd_soc_device soc_dev;
70 struct platform_device *aclc_pdev; /* for ioresources, drvdata */
71 struct txx9aclc_dmadata dmadata[2];
72};
73
74static inline struct txx9aclc_plat_drvdata *txx9aclc_get_plat_drvdata( 68static inline struct txx9aclc_plat_drvdata *txx9aclc_get_plat_drvdata(
75 struct txx9aclc_soc_device *sdev) 69 struct snd_soc_dai *dai)
76{ 70{
77 return platform_get_drvdata(sdev->aclc_pdev); 71 return dev_get_drvdata(dai->dev);
78} 72}
79 73
80extern struct snd_soc_platform txx9aclc_soc_platform;
81extern struct snd_soc_dai txx9aclc_ac97_dai;
82
83#endif /* __TXX9ACLC_H */ 74#endif /* __TXX9ACLC_H */